简体   繁体   中英

Uniquely identify a Java class implementation

I have been dealing with poorly branched projects that left me with dependiencies that include several classes with the exact same fully qualified name. Consequently, I have been getting the AbstractMethodError for calling methods on the wrong implementations. My solution was to rename the class packages which worked just fine.

However, I now wonder whether there is a better way - can we uniquely identify a Java class implementation?

You can check OSGI as solution. You can specify dependencies between modules and load exact class for each module

Classes are equal if they have the same fully qualified name and are loaded by the same class loader. So if you have different class loaders (and every class loader only knows one of the implementations, eg in an OSGi environment), you could in theory identify them by checking their corresponding class loader.

However, in general having multiple classes with the same fully qualified name is the problem and there is really no other solution you'd want to implement if you can rename the packages. There might be special cases, but you should have very good reasons.

You can check if two classes (or the classes of two objects) are identical:

o1.getClass() == o2.getClass()

This expression is true exactly when the classes are identical (ie loaded by the same class loader).

AFAIK there is no way to determine if a class at runtime got created from a specific file.

There is something called "ImplementationVersion" wich you can access like this:

public class TestClassVersion {

public static void main(String[] args) {
    System.out.println("TestClassVersion: " + TestClassVersion.class.getPackage().getImplementationVersion());
    System.out.println("String: " + String.class.getPackage().getImplementationVersion());
    System.out.println("org.apache.commons.logging.Log: " + org.apache.commons.logging.Log.class.getPackage().getImplementationVersion());
}

}

Output:

TestClassVersion: null
String: 1.8.0_45
org.apache.commons.logging.Log: 1.0.4

The downside to this is, that one have to set this Version in the META-INF\\MANIFEST.MF -File (there it s called Implementation-Version`) at Compile-Time - if you don't specify it it will be null.

See:

https://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html

http://docs.oracle.com/javase/8/docs/api/java/lang/Package.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM