Reputation: 696
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.
Upvotes: 4
Views: 151
Reputation: 43997
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.
Upvotes: 1
Reputation: 109547
getClass().getProtectionDomain().getCodeSource().getLocation()
- may have a null for JRE classes.
Upvotes: 3