2

I have an android project that relies on two jar files. Each jar file contains org.slf4j.impl.StaticLoggerBinder. The implementation of this class is different in each file. When I try to build this is causing the following exception:

com.android.dex.DexException: Multiple dex files define Lorg/slf4j/impl/StaticLoggerBinder;

One of these libraries is logback-android, the other is closed source.

Is there any way to get these both working?

rhnoble
  • 559
  • 4
  • 12
  • You can reference the class using the fully qualified name, to avoid ambiguity. I'm not sure that is the best or most efficient way to go, though. – Jonathon Anderson Sep 02 '14 at 22:33
  • @NonSecwitter - You miss the point. The classes have the same fully qualified name. – Stephen C Sep 02 '14 at 22:34
  • Sounds like the closed source is including slf4j; maybe you can omit it from logback-android and have everything work – antlersoft Sep 02 '14 at 22:35
  • Depends which one he wants to implement. – Jonathon Anderson Sep 02 '14 at 22:36
  • @NonSecwitter what do u mean? – eldjon Sep 02 '14 at 22:37
  • You could rename the class and rebuild logback. Just make sure you distribute the jar with your project. – Jonathon Anderson Sep 02 '14 at 22:37
  • @eldjon - each implementation is different, so if he wants the logback implementation, he can't simply omit it. – Jonathon Anderson Sep 02 '14 at 22:37
  • @NonSecwitter I tried renaming the classes in logback, it compiled fine and when added to my Android project that built correctly as well. Unfortunately it broke the functionality that I wanted from logback. I'm not too sure about how the library itself works, but I believe it requires those classes to have those names in order to interact with the slf4j library correctly. But maybe someone with more slf4j experience could speak to that. – rhnoble Sep 02 '14 at 22:41
  • Oh .yea... good point. I didn't think that deeply into it. You would have to go through the logback source and rename every call to that method. – Jonathon Anderson Sep 02 '14 at 22:41
  • And I believe if I did that in the slf4j source it would break logging for the other library with the old names anyway. Although I suppose if there were no other option I could maybe live with that. – rhnoble Sep 02 '14 at 22:44
  • according to the second answer in this question, you can write your own classloader to handle the problem http://stackoverflow.com/a/6879929/3290507 – Jonathon Anderson Sep 02 '14 at 22:46
  • possible duplicate of [Possible to use two java classes with same name and same package?](http://stackoverflow.com/questions/6879652/possible-to-use-two-java-classes-with-same-name-and-same-package) – Jonathon Anderson Sep 02 '14 at 22:48

1 Answers1

1

Having two jars with the same class inside is not forbidden in Java, but is dangerous and that's why Android is being conservative and raising an error.

What could happen is that having two different versions of the class (say 1.0 and 1.1), when loading the class, one or the other gets loaded in no really predictable way. So, if the compiler let you call a given method on version 1.1, the JVM will not find that method cause it loaded version 1.0 which didn't have it. Replace method with everything else (constructor, field etc..), and consider that usually this happens with full packages and not single classes, so you'll have a lot of classes of version 1.1 not finding methods on other classes of version 1.0 and so on.

Java itself does not have a standard solution to this. However, jar files are nothing more than zip files, and unless they are signed they can be opened and modified and re-jarred.

You could open the closed source .jar, remove it's org/slf4j folder, re-jar it, and try if it works with the other version of org.slf4j.

Or better yet, tell those guys that having a "single jar" with every kind of stuff inside is not cooler than having the jars separated.

Simone Gianni
  • 11,426
  • 40
  • 49