After upgrading my com.squareup.wire libraries from 1.8 to 3.4+ (to address security vulnerabilities), I get the NoClassDefFoundError below when trying to deserialize an object from JSON:
java.lang.NoClassDefFoundError: com/squareup/wire/ProtoEnum
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at java.base/java.lang.Class.getDeclaredFields0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredFields(Class.java:3061)
at java.base/java.lang.Class.getField0(Class.java:3246)
at java.base/java.lang.Class.getField(Class.java:1997)
at com.squareup.wire.ProtoAdapter$Companion.get(ProtoAdapter.kt:257)
at com.squareup.wire.internal.ReflectionKt.createRuntimeMessageAdapter(reflection.kt:95)
at com.squareup.wire.WireTypeAdapterFactory.create(WireTypeAdapterFactory.kt:82)
at com.google.gson.Gson.getAdapter(Gson.java:489)
at com.google.gson.Gson.fromJson(Gson.java:962)
at com.google.gson.Gson.fromJson(Gson.java:928)
at com.google.gson.Gson.fromJson(Gson.java:877)
at com.google.gson.Gson.fromJson(Gson.java:848)
at <...>.OrderMessageProcessor.deserializeOrder(OrderMessageProcessor.java:164)
...
Caused by: java.lang.ClassNotFoundException: com.squareup.wire.ProtoEnum
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 78 more
Where do I get this ProtoEnum
class from?
build.gradle
// without this I get NoClassDefFoundError: kotlin/enums/EnumEntriesKt
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.9.10'
implementation 'com.squareup.wire:wire-runtime:4.9.1'
implementation 'com.squareup.wire:wire-gson-support:4.9.1'
OrderMessageProcessor.java
import com.amazonaws.services.sqs.model.Message;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.squareup.wire.WireTypeAdapterFactory;
// ...
public class OrderMessageProcessor {
private static final Gson WIRE_GSON = new GsonBuilder()
.registerTypeAdapterFactory(new WireTypeAdapterFactory())
.create();
// ...
protected Order deserializeOrder(Message message) {
return WIRE_GSON.fromJson(message.getBody(), Order.class);
}
Order.java
public final class Order extends com.squareup.wire.Message {
public final String order_date;
// more fields and a Message.Builder<Order> inner class...
Note that using other deserialization libraries like Jackson's ObjectMapper
are problematic because the Order
class has no zero-arg constructor and no setter methods. I do not own the Order class and cannot modify it.
I tried using various versions of the com.squareup.wire libraries between 3.4 and the latest, 4.9.1. They all result in the same NoClassDefFoundError. Reverting to version 1.8 works.
I figured it out. The
Order
class that I am deserializing extends theMessage
class from version 1.x of thecom.squareup.wire
library, and this uses theProtoEnum
class, which no longer exists in later versions.No solution yet, but that is the cause of the problem.
UPDATE
Assuming the producer of the serialized Order doesn't upgrade to a compatible version of Square Wire, I may need to generate the Order class myself from the protobuf schema using my version of Square Wire.