Garrett Smith
Garrett Smith

Reputation: 696

Is there a way to programmatically tell a Java class's source?

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

Answers (2)

Rafael Winterhalter
Rafael Winterhalter

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

Joop Eggen
Joop Eggen

Reputation: 109547

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

Upvotes: 3

Related Questions