Find where java class is loaded from
JavaClasspathClassloaderJava Problem Overview
Does anyone know how to programmaticly find out where the java classloader actually loads the class from?
I often work on large projects where the classpath gets very long and manual searching is not really an option. I recently had a [problem][1] where the classloader was loading an incorrect version of a class because it was on the classpath in two different places.
So how can I get the classloader to tell me where on disk the actual class file is coming from?
Edit: What about if the classloader actually fails to load the class due to a version mismatch (or something else), is there anyway we could find out what file its trying to read before it reads it?
[1]: https://stackoverflow.com/questions/226280/eclipse-class-version-bug "problem"
Java Solutions
Solution 1 - Java
Here's an example:
package foo;
public class Test
{
public static void main(String[] args)
{
ClassLoader loader = Test.class.getClassLoader();
System.out.println(loader.getResource("foo/Test.class"));
}
}
This printed out:
file:/C:/Users/Jon/Test/foo/Test.class
Solution 2 - Java
Another way to find out where a class is loaded from (without manipulating the source) is to start the Java VM with the option: -verbose:class
Solution 3 - Java
getClass().getProtectionDomain().getCodeSource().getLocation();
Solution 4 - Java
This is what we use:
public static String getClassResource(Class<?> klass) {
return klass.getClassLoader().getResource(
klass.getName().replace('.', '/') + ".class").toString();
}
This will work depending on the ClassLoader implementation:
getClass().getProtectionDomain().getCodeSource().getLocation()
Solution 5 - Java
Jon's version fails when the object's ClassLoader
is registered as null
which seems to imply that it was loaded by the Boot ClassLoader
.
This method deals with that issue:
public static String whereFrom(Object o) {
if ( o == null ) {
return null;
}
Class<?> c = o.getClass();
ClassLoader loader = c.getClassLoader();
if ( loader == null ) {
// Try the bootstrap classloader - obtained from the ultimate parent of the System Class Loader.
loader = ClassLoader.getSystemClassLoader();
while ( loader != null && loader.getParent() != null ) {
loader = loader.getParent();
}
}
if (loader != null) {
String name = c.getCanonicalName();
URL resource = loader.getResource(name.replace(".", "/") + ".class");
if ( resource != null ) {
return resource.toString();
}
}
return "Unknown";
}
Solution 6 - Java
Edit just 1st line: Main
.class
Class<?> c = Main.class;
String path = c.getResource(c.getSimpleName() + ".class").getPath().replace(c.getSimpleName() + ".class", "");
System.out.println(path);
Output:
/C:/Users/Test/bin/
Maybe bad style but works fine!
Solution 7 - Java
Typically, we don't what to use hardcoding. We can get className first, and then use ClassLoader to get the class URL.
String className = MyClass.class.getName().replace(".", "/")+".class";
URL classUrl = MyClass.class.getClassLoader().getResource(className);
String fullPath = classUrl==null ? null : classUrl.getPath();
Solution 8 - Java
Take a look at this similar question. https://stackoverflow.com/questions/135971/is-there-a-tool-to-discover-if-the-same-class-exists-in-multiple-jars-in-the-cl#136292"> Tool to discover same class..
I think the most relevant obstacle is if you have a custom classloader ( loading from a db or ldap )
Solution 9 - Java
Simple way:
> System.out.println(java.lang.String.class.getResource(String.class.getSimpleName()+".class"));
Out Example:
> jar:file:/D:/Java/jdk1.8/jre/lib/rt.jar!/java/lang/String.class
Or > String obj = "simple test"; > System.out.println(obj.getClass().getResource(obj.getClass().getSimpleName()+".class"));
Out Example: > jar:file:/D:/Java/jdk1.8/jre/lib/rt.jar!/java/lang/String.class
Solution 10 - Java
This approach works for both files and jars:
Class clazz = Class.forName(nameOfClassYouWant);
URL resourceUrl = clazz.getResource("/" + clazz.getCanonicalName().replace(".", "/") + ".class");
InputStream classStream = resourceUrl.openStream(); // load the bytecode, if you wish
Solution 11 - Java
Assuming that you're working with a class named MyClass
, the following should work:
MyClass.class.getClassLoader();
Whether or not you can get the on-disk location of the .class file is dependent on the classloader itself. For example, if you're using something like BCEL, a certain class may not even have an on-disk representation.