Duplicate class

Hello,

I am receiving this error while synching:

Duplicate class org.java_websocket.AbstractWebSocket found in modules jetified-Java-WebSocket-1.3.9 (org.java-websocket:Java-WebSocket:1.3.9) and jetified-java-websocket-1.3.9 (eu.electronicid.android:java-websocket:1.3.9)

There’s a long list of these, I posted just the first one. All of them pertain to the same package. I’m not sure uh… exactly what to do. It seems there’s a clash between the two modules, but how to solve this?

I am currently reading through https://developer.android.com/studio/build/dependencies#resolution_errors

I recognize the first one (org.java-websocket:Java-WebSocket), as I happen to be using that on a project. The second one doesn’t even show up in a Google search, so I am uncertain where that is coming from.

You could run a Gradle dependency report. You get one by running the dependencies Gradle task for your desired module, either from the Gradle tool in Android Studio (dependencies is in the “help” category) or from the command line (e.g., ./gradlew app:dependencies to run dependencies for your app module). That should help you identify where those two libraries are being pulled in.

In a recent question, you asked:

So then what is the exclude keyword used for?

This is a possible scenario for exclude. Somebody repackaged org.java-websocket:Java-WebSocket into their own artifact (eu.electronicid.android:java-websocket), and it is unclear why. You can try choosing one of those two artifacts and using exclude to block the other one. The good news is that this should eliminate the duplicate-class problem. The bad news is that if the classes are different between those two artifacts, you might have code that is depending on the one that you excluded. The only way to find out really is by thorough testing and see if you crash.

So I tried doing it like this:

implementation “eu.electronicid.android:videoid-sdk:6.1.11”, {
exclude group: ‘io.reactivex.rxjava2’, module: ‘rxjava’
exclude group: ‘org.java-websocket’, module: ‘Java-WebSocket’
exclude group: ‘com.github.NaikSoftware’, module: ‘StompProtocolAndroid’
}

But I still get the error:

Duplicate class org.java_websocket.AbstractWebSocket found in modules jetified-Java-WebSocket-1.3.9 (org.java-websocket:Java-WebSocket:1.3.9) and jetified-java-websocket-1.3.9 (eu.electronicid.android:java-websocket:1.3.9)

Should I have written the exclude block differently?

My guess is “yes”, but that is just a guess, as this is not my project. :grinning:

exclude is saying “in the transitive dependencies from this dependency, block this particular artifact”. My guess is that eu.electronicid.android:videoid-sdk is not requesting the org.java-websocket edition of the websocket code, but its own eu.electronicid.android:java-websocket one.

So, either:

  • Keep the exclude where you have it but change the artifact, or
  • Consider keeping the eu.electronicid.android:java-websocket dependency, see where you are pulling in the org.java-websocket one, and move your exclude to whatever dependency you are using that is pulling in org.java-websocket

I made it work like this:

implementation “eu.electronicid.android:videoid-sdk:6.1.11”, {
exclude group: ‘io.reactivex.rxjava2’, module: ‘rxjava’
exclude group: ‘eu.electronicid.android’, module: ‘java-websocket’
exclude group: ‘eu.electronicid.android’, module: ‘stomp-android’
}

If this will ultimately work or not… remains to be seen. Thanks!

PS. I tried running the app now and I can’t log in - the electronic id part doesn’t work :smiley:

Yeah, well, that is not too surprising.

I don’t know who is behind eu.electronicid.android, but if practical, you might want to contact them and ask why they have their own artifacts that are clones of public artifacts, where they did not repackage the classes in those artifacts. Had they moved their fork of the websocket code into a eu.electronicid.android package, then there would be no collisions on the class names, and you would not need to go through this work.

Alternatively, you could remove this exclude and aim to exclude org.java-websocket:Java-WebSocket from whatever dependency is using it, and see what happens.

I managed to solve it, like this:

qaImplementation "mylibrary", {
        exclude group: 'org.java-websocket', module: 'Java-WebSocket'
        exclude group: 'com.github.NaikSoftware', module: 'StompProtocolAndroid'
    }
    productionImplementation "mylibrary", {
        exclude group: 'org.java-websocket', module: 'Java-WebSocket'
        exclude group: 'com.github.NaikSoftware', module: 'StompProtocolAndroid'
    }
    canaryImplementation "mylibrary", {
        exclude group: 'org.java-websocket', module: 'Java-WebSocket'
        exclude group: 'com.github.NaikSoftware', module: 'StompProtocolAndroid'
    }