Find where java class is loaded from

Viewed 195204

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 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?

11 Answers

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

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

getClass().getProtectionDomain().getCodeSource().getLocation();

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()

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();

Take a look at this similar question. Tool to discover same class..

I think the most relevant obstacle is if you have a custom classloader ( loading from a db or ldap )

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

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.

Related