反序列化器定义如下,它在使用 java 运行的 jar 文件中完美运行:
public static class Deserializer extends StdDeserializer<Subscriber> {
public Deserializer() {
this(null);
}
public Deserializer(Class<?> vc) {
super(vc);
}
@Override
public Subscriber deserialize(JsonParser jp, DeserializationContext ctx)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
if (node.isEmpty()) {
return null;
}
JsonNode v = node.get("statusId");
int id = v == null ? -1 : v.asInt(-1);
v = node.get("name");
String name = v == null ? null : v.asText(null);
v = node.get("password");
String password = v == null ? null : v.asText(null);
ConcurrentHashMap<Integer, Account> accounts = null;
v = node.get("accounts");
if (v != null) {
accounts = (new ObjectMapper()).convertValue(v,
new TypeReference<ConcurrentHashMap<Integer, Account>>() {
});
}
return new Subscriber(id, name, password, accounts);
}
}
但是当我使用 GraalVM 的本机映像工具将 jar 文件转换为本机映像之后;它在运行时引发了以下异常(在第
convertValue
行):
java.lang.IllegalArgumentException: Cannot construct instance of `java.util.concurrent.ConcurrentHashMap` (no Creators, like default constructor, exist): no default constructor found
at [Source: UNKNOWN; byte offset: #UNKNOWN]
at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4449)
at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:4400)
at myclient.sub.Subscriber$Deserializer.deserialize(Subscriber.java:78)
at myclient.sub.Subscriber$Deserializer.deserialize(Subscriber.java:46)
at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4444)
at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:4380)
我尝试使用
MapType type = jsonObjectMapper.getTypeFactory().constructMapType(ConcurrentHashMap.class, Integer.class, Account.class)
而不是 TypeReference
,结果是一样的。
native-image --version
native-image 21.0.2 2024-01-16
GraalVM Runtime Environment Oracle GraalVM 21.0.2+13.1 (build 21.0.2+13-LTS-jvmci-23.1-b30)
Substrate VM Oracle GraalVM 21.0.2+13.1 (build 21.0.2+13-LTS, serial gc, compressed references)
问题来自 Jackson 数据绑定。我在 Github 上报告了它(issue #4400)。更新到2.17.0-rc1版本后,问题已解决。