Samuel Negri
Samuel Negri

Reputation: 519

Find classes with same full qualified name in Java during runtime

Lets say I have a jar a.jar with a class com.company.ma.MyClass

package com.company.ma
public class MyClass {
  public void someMethod() {
    System.out.println("Hey");
  }
}

Also another jar b.jar with a class com.company.ma.MyClass but different implementation.

package com.company.ma
public class MyClass {
  public void anotherMethod() {
    System.out.println("This is different");
  }
}

The classes have the same full qualified name but they are different.

How can I find all classes in the classpath with a given full qualified name, say com.company.ma.MyClass and print it's location? In this example I'd expect two classes with name com.company.ma.MyClass in two different jars

Upvotes: 1

Views: 693

Answers (2)

user10992464
user10992464

Reputation:

You can't use reflection for that, since you can only iteract with loaded classes, and only one class can be loaded by a class loader with a specified name.

You have to create separate class loaders (like URLClassLoader), and make the firts one parse the first jar, and the second one should look in the second jar. You can use ClassLoader.loadClass() to load the classes from the jars. More info here and here. It would also be better not to include both versions in the classpath, since the second link suggests it might not work if the system class loader can load the class by itself.

Another option is loading one class, doing whatever you want, unloading it and loading your other class. You can unload a class by:

  1. Removing all references to the class and its loader, and triggering garbage collection, as stated here.
  2. Using manipulation tools like ByteBuddy to manipulate the JVM's behaviour.

This would not make it possible to use the classes at the same time, but if you only want to compare or find them it might be sufficient.

If you only want to locate the classes and not use them you can parse the jar files manually and count the appropriate .class files, as explained here.

Short summary: If you have both classes on the classpath, you can only load one of them. If you have neither on the classpath, you can load them both with some manual work. If you only want to find them, parse the jar files.

Upvotes: 1

Thomas
Thomas

Reputation: 182000

I think each (fully qualified) class name can refer to only one class in the JRE; see for example this question. So you can't access them both through reflection at the same time.

Maybe you can write your own ClassLoader to catch and handle conflicts in any way you need.

You can also use java.util.jar.JarFile to open up any .jar file and parse its manifest, which contains a list of all .class files contained in the .jar.

Upvotes: 1

Related Questions