デバイスからのデータを保存する小さなアプリケーションを開発しました。JSON 形式でデータを保存することを選択しました。データのシリアル化/逆シリアル化は、私が作成したカスタム型が含まれていても問題なく機能します...しかし、私だけがIDEで作業します(Eclipse、さらに言えば)。
ただし、実行可能な JAR ファイルをエクスポートすると、ソフトウェアが常に次の例外をスローするため、データの逆シリアル化で何らかの問題が発生します。
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
組み込み型ではなく、カスタム型で問題が発生すると思いました。この時点で、次の 2 つのことがわかりました。
- 完全な JRE 9 を使用して JAR ファイルを実行すると、例外はスローされません。Jlink.exe で作成したカスタム JRE に含まれるモジュールを再確認したところ、すべてが正しく含まれていました。私はまだ小さい JRE を使用したいので、これ以上調査しませんでした (IDE で完全に動作する理由はこれで説明できると思います)。
- カスタム デシリアライザーを Gson オブジェクトに追加し (以下を参照)、JSON 文字列を有効なデータに手動で変換するだけで、LocalDateTime クラスでの例外を回避できましたが、例外は別のクラスで単純に再表示されました。カスタムメイドの時間。
この時点で、問題を引き起こすデータ型ごとにデシリアライザーを追加するだけでよいと思いますが、完全な JRE で問題が発生しない理由と、すべてのモジュールが必要なものが含まれています。データを保存する Gson オブジェクトにカスタム シリアライザーを追加していないことにも言及する価値があるかもしれません。すべて Gson の既定値に従ってシリアル化されます。
LocalDateTime
デシリアライザー:
@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 モジュール リスト:
com.google.gson
java.base
javafx.base
javafx.controls
javafx.fxml
javafx.graphics
org.slf4j
受け取った回答の後、ここで問題を開きました。