I developed a small application that stores data coming from a device: I chose to store data in JSON format, and the serialization/deserialization of the data works just fine, even if it involves some custom types created by me...but only I work in the IDE (Eclipse, for that matter).
When I export a runnable JAR file though, the deserialization of the data encounters some kind of problem, because the software always throws this exception:
Caused by: java.lang.UnsupportedOperationException: Cannot allocate class LocalDateTime
at com.google.gson.internal.UnsafeAllocator$4.newInstance(UnsafeAllocator.java:104)
at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:225)
... 88 common frames omitted
I thought I'd encounter problems with custom types, not a built-in one. At this point, I discovered two things:
- if I use a full JRE 9 to run the JAR file, the exception is not thrown: I double checked the modules included in the custom JRE I created with Jlink.exe, and everything is included correctly. I still want to use a smaller JRE, so I did not investigate further yet (I guess this explains why in the IDE it works perfectly)
- I added a custom deserializer to the Gson object (see below), with which I simply manually converted the JSON string into a valid data, and that avoided the exception on the LocalDateTime class...but the exception reappeared simply on another class, this time a custom-made one.
At this point, I guess I can simply add a deserializer for each data type that causes problem, but I'm wondering why the issue won't happen with a full JRE, and why a smaller JRE causes this, even if all the modules required are included. Maybe it's worth mentioning also that I added no custom serializer to the Gson object that saves the data, it is all serialized as per Gson default.
LocalDateTime
deserializer:
@Override
public LocalDateTime deserialize(JsonElement json, java.lang.reflect.Type type,
JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject joDate = json.getAsJsonObject().get("date").getAsJsonObject();
JsonObject joTime = json.getAsJsonObject().get("time").getAsJsonObject();
//JSON example: {"date":{"year":2019,"month":1,"day":9},"time":{"hour":6,"minute":14,"second":1,"nano":0}
return LocalDateTime.of(joDate.get("year").getAsInt(),
joDate.get("month").getAsInt(),
joDate.get("day").getAsInt(),
joTime.get("hour").getAsInt(),
joTime.get("minute").getAsInt(),
joTime.get("second").getAsInt(),
joTime.get("nano").getAsInt());
}
}
Jdeps.deps modules list:
com.google.gson
java.base
javafx.base
javafx.controls
javafx.fxml
javafx.graphics
org.slf4j
After the answer I received, I opened an issue here.