Chris B
Chris B

Reputation: 1

NoClassDefFoundError for ProtoEnum after upgrading Square Wire libraries

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.

Upvotes: 0

Views: 1432

Answers (1)

Chris B
Chris B

Reputation: 1

I figured it out. The Order class that I am deserializing extends the Message class from version 1.x of the com.squareup.wire library, and this uses the ProtoEnum 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.

Upvotes: 0

Related Questions