Find where java class is loaded from

JavaClasspathClassloader

Java 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionlukeView Question on Stackoverflow
Solution 1 - JavaJon SkeetView Answer on Stackoverflow
Solution 2 - JavajirikiView Answer on Stackoverflow
Solution 3 - JavaDave DiFrancoView Answer on Stackoverflow
Solution 4 - JavaJevgeni KabanovView Answer on Stackoverflow
Solution 5 - JavaOldCurmudgeonView Answer on Stackoverflow
Solution 6 - JavaecererView Answer on Stackoverflow
Solution 7 - JavaHongyangView Answer on Stackoverflow
Solution 8 - JavaOscarRyzView Answer on Stackoverflow
Solution 9 - JavaseduardoView Answer on Stackoverflow
Solution 10 - JavaAdamView Answer on Stackoverflow
Solution 11 - JavaDaniel SpiewakView Answer on Stackoverflow