4

The Java classloader loads the first class it can find with a matching name. Is there any way to programmatically tell which one is loaded?

i.e., can I change the main below in a way that tells which ClassLoaderTest is loaded (other than invoking test())?

echo "public class ClassLoaderTest { public static String test() { return \"1\"; } }" > ClassLoaderTest.java
javac ClassLoaderTest.java
mkdir one
mv ClassLoaderTest.class one
echo "public class ClassLoaderTest { public static String test() { return \"2\"; } }" > ClassLoaderTest.java
javac ClassLoaderTest.java
mkdir two
mv ClassLoaderTest.class two
echo "public class Main { public static void main(String[] _) {  System.out.println(ClassLoaderTest.test()); } }" > Main.java
javac Main.java
java -classpath one:two:. Main
java -classpath two:one:. Main

This outputs 1 then 2 based on the classpath order.

Garrett Smith
  • 688
  • 1
  • 7
  • 24

2 Answers2

3

getClass().getProtectionDomain().getCodeSource().getLocation() - may have a null for JRE classes.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
1

You want to analyze a Java class's source code. There are byte code parsers like ASM that are tailored for this purpose. When you look at the code for ASM, it locates a class's source by

getClassLoader()
  .getResourceAsStream(ClassLoaderTest.class.getName().replace('.', '/') + ".class")

which is sufficient if you only need the content of a class file and not its location (which might not even exist).

An alternative is the mentioned method via the ProtectionDomain which requires however additional security rights or ClassLoader::getResource which both might not work for a custom ClassLoader which do not store class files on a storage.

Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192