1

I have two jars for zookeeper . One is the official one and the other is a modified one which has only the implementations for using zookeeper with LDAP. Now there is a class called ZooDefs which is in org.apache.zookeeper .

This class is present in both the jars but the modified jar has one more variable included in it.

Now I want to use that variable in my code but I am totally clueless as to how to use it.

I referred this . But this has two different package names. But the jars I am dealing with have the same names, except for the logic inside them. I know this is totally wrong in terms of best practices , but I am asked to deal with this.

Please suggest how to deal with this.

Community
  • 1
  • 1
v1shnu
  • 2,211
  • 8
  • 39
  • 68
  • 1
    Have your modified jar present in classpath before other jar. – Sujit Chaitanya Jun 24 '15 at 07:37
  • How do I do that in Eclipse ? – v1shnu Jun 24 '15 at 07:38
  • 1
    `Project -> Properties -> Java Build Path -> Order and Export`... And you can reorder whichever jar you want first... – Codebender Jun 24 '15 at 07:41
  • 1
    If your jars are identical apart from the new field, you should use only one of them in order to avoid mayhem and confusion. – xea Jun 24 '15 at 07:42
  • @AbishekManoharan Perfect ! – v1shnu Jun 24 '15 at 07:44
  • In other words you can't have two classes with the same FQDN, unless you're using classloading magic, eg. OSGi. – xea Jun 24 '15 at 07:44
  • @xea The modified jar containes few more new classes too. I did not have problems with those classes , only with the one with the same names. – v1shnu Jun 24 '15 at 07:46
  • @ViChU: this is due to how class-loading works. Classes present in only one jar are always picked up (in theory at least) at loading but if you've got the same class (FQDN-wise) in multiple jars on the classpath then you might get trouble. – xea Jun 24 '15 at 07:48
  • @xea doesn't the order of the classes in the classpath work when I compile this into a jar ?? or does it work only in eclipse ? – v1shnu Jun 24 '15 at 07:50
  • @ViChU that's eclipse only. Eclipse has little to no control over what's happening at run-time when your program is run outside of Eclipse. – xea Jun 24 '15 at 07:51
  • @xea so what is the solution then ? – v1shnu Jun 24 '15 at 07:53
  • @ViChU: I'll post an answer about it in – xea Jun 24 '15 at 07:53

2 Answers2

1

Here you go...

Project -> Properties -> Java Build Path -> Order and Export... And you can reorder whichever jar you want first...

Codebender
  • 14,221
  • 7
  • 48
  • 85
  • since your solution is a temporary one and not the final solution , I have changes the best answer to the other one. But I have voted up your answer since it helped me alot. Sorry and Thanks. – v1shnu Jun 24 '15 at 09:30
0

Usually, when you're not confident about how class loading works, it's not a good idea to have multiple JARs containing classes with the same FQDN. This is because JARs aren't logical units in terms of class loading and they aren't versioned (don't get fooled by filenames like mylibrary-1.0.0.jar, those are only file names), plus class loading happens "secretly" in the background and without having explicit control over it you can't be sure which physical files will get loaded when you refer to a class. This could lead to a host of strange errors ranging from silent errors through NullPointerExceptions to NoClassDefFoundErrors.

Under normal circumstances, ie. when each class is present only once, this means no problem because when you refer to a class, the class loader will find only one instance of that class on the class path so it can be considered deterministic.

In your case, an easy solution would be simply replacing the original JAR with the modified one where the modified has all the classes the original has (and they are backwards-compatible too). Of course, this could possible mean that you need to slightly change your build process, for example installing your version of zookeeper into your local Maven repository and use that version.

A more advanced (and more interesting) solution could be using OSGi (or other class loader-magic frameworks). OSGi works by adding extra package metadata to the manifest where you can specify bundle ID-s and version numbers. This allows loading multiple classes with the same FQDN but with different version numbers.

While Eclipse and other IDEs often offer the ability to declare the order of imports, this isn't the best solution because they rely on they have control over the class loading mechanism. This means, for example, when you build a runnable JAR and run it outside your IDE, your application might start failing because they have little to no control over class loading happening outside of them.

xea
  • 1,204
  • 12
  • 23
  • "they have little to no control over class loading happening outside of them" - you say they have little to no control. So in my case, will there be control ? The problem in my case is that the modified jar does not contain all the components of the original jar but only the features which are added on top of it. So I would be requiring both the jars . What is the solution in this case ? – v1shnu Jun 24 '15 at 09:01
  • Can't you make a single jar out of both that contains exactly those classes that you need - effectively overwriting the out-of-date classes? – xea Jun 24 '15 at 09:18
  • Ultimately that is the only solution I think,. Anyway thanks for your detailed answer. – v1shnu Jun 24 '15 at 09:28