2

Like the title says, is there a way to deal with this? I have imported two separate third party libraries and they have a fully qualified class name conflict.

Right now both libraries are being imported in jar form, and it appears that in some environments (command line invocation, Eclipse) the correct class is found and in others (Maven) the wrong class is found and I get a missing method exception. If no solution can be found, I can fall back to re-factoring one of these libraries and rebuilding the jar, but I would rather not have to repeat that work every time the library has an update.

Edit: If anyone sees this later and is confused, I accepted Dave Newton's answer because it would be the correct way to do this if you were diligent enough to catch this problem before writing all of your code. Fixing the imports automagically after writing all the code appears to be impossible, as I suspected.

Alex N.
  • 654
  • 8
  • 21
  • 1
    These are two different libraries? With same class? What libraries and class are they? – zvez Oct 10 '12 at 15:42
  • org.openstreetmap.osmosis.core.database.DatabaseLoginCredentials. It exists in both the core Open Streetmap Libraries and in the libraries for a sub-project called Traveling Salesman. An they are slightly different. – Alex N. Oct 10 '12 at 16:29

1 Answers1

1

You either shade, bust them apart and remove the dupes, or...

When you have multiple implementations you are at the mercy of your classloader(s) unless you take active steps to mitigate the dupes.

Further discussion at this SO question.

Community
  • 1
  • 1
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • I read your other answer and that looks like an interesting idea, but I'm lost on one key point. Right now i have imports that look like import foo.bar.baz; that are ambiguous because that class is in two separate jars. If I have it repack and rename one jar, how will the code know if it needs to look in the old jar or the new jar? – Alex N. Oct 10 '12 at 16:15
  • @AlexN. Remember that an `import` statement is simply a syntactic convenience: in bytecode classes are always fully-qualified. When you shade your "imports" are updated (if you're shading) to the new name, as well as the shaded packages being shaded. From *your* point of view it's not "looking in one jar or another", it's "finding the fully qualified class on the classpath", regardless of its location. – Dave Newton Oct 10 '12 at 16:58
  • True, but I still don't understand how it can possibly know how to update the class. Even if I was to write out the fully qualified class every time, how can it tell which class I even meant originally? Do I need to generate the dependency-reduced-pom.xml and then edit my code to match it? I actually tried to add the shade plugin into Maven, and it generated the jar and new pom, but it did not correctly update the classpath. – Alex N. Oct 10 '12 at 19:15
  • @AlexN. What do you mean by "did not correctly update the classpath"? The dependencies determine which "chunks" need which jars. You can exclude a dependency from a Maven `` if you need to. – Dave Newton Oct 10 '12 at 19:46
  • Hmmm. I seem to be having a hard time wording this. If the current source has imports that import identical classes, how can anything tell which class I want at each mention? I have actually read enough now that I think this is impossible to do automagically, which is what I was afraid of. Thanks for the help. – Alex N. Oct 11 '12 at 15:20
  • @AlexN. Correct; if your code has been relying on the vagaries of classloading you'll need to curate your dependency(ies) manually. If your code *mixes* version requirements that's particularly troublesome. You still may be able to use excludes, but w/o further details it's difficult to tell. – Dave Newton Oct 11 '12 at 17:03
  • This is exactly correct. We had apparently been getting lucky for quite some time but nobody had noticed it. Thanks again for your help. It really did push me in the right direction. – Alex N. Oct 11 '12 at 22:02