开发者

if I have a classloader instance, can I find where it looks for the class bytes?

开发者 https://www.devze.com 2023-02-17 00:14 出处:网络
if I have dira,jarb and dirc in the classpath in that order, and I have a java app with 3 classloaders with a parent/child/grandchild relat开发者_JAVA百科ionship, will they all read the same directory

if I have dira,jarb and dirc in the classpath in that order, and I have a java app with 3 classloaders with a parent/child/grandchild relat开发者_JAVA百科ionship, will they all read the same directory ?

I guess I am trying to figure out where each classloader looks... is there a way to find this path given an instance of the classloader ?


In general no, a classloader is permitted to construct bytes however it likes. E.g. the JSP classloader might invoke the JSP compiler dynamically if the JSP file has a recent timestamp.

Running the JVM with the -verbose:class flag will enable a lot of logging which should help you if you're just using the standard bootstrap classloaders.

If there's some custom classloader, you could supply your own URLConnectionFactory and see what URLs are being fetched.


You have actually several questions here.

  • The classes in the classpath directories and jars will usually be loaded by one classloader (the application classloader), not by several ones for each entry.

  • If you have classloaders in a parent-child-relationship, the child one should first ask its parent to load the class and only lookup the bytecode itself when the parent did not find anything. (There are special-purpuse classloaders in some frameworks which do this the other way around. If each class exists only once, then this should not make a difference.)

  • If you have an URLClassLoader, then you can ask its getURLs() method to find out from where it loads. For other classloaders, there may or may not be a way to find this.


Take a look at the ClassLoader API and you will realise there is a method that passes a name and eventually the class loader passes a byte[] to define the class. Because it is a proper class it can grab those bytes from anywhere it wants to. ClassLoader is just another public class anyone can implement their own implementation and do their own thing. ClassLoaders are everywhere, we have the version that reads the classpath system property, in tomcat we have another that reads from a war file, in osgi it reads from a jar file. Each does a few extra things besides simply reading some file and tahts the beauty and flexibility of classloading.

There is no method on ClassLoader that returns a String, because what would it return given the above mentioned CLassLoaders ? A file path, a jar file path ? etc


In general no, but in practice you often want to find out where some class, resource is being loaded from and you can do,

System.out.println(someClassLoader.getResource("someResource.txt"));

Even more useful, if you are looking to find which .class file a Class is from, do

Class c = SomeClass.class;
System.out.println(c.getResource(c.getSimpleName() + ".class"));

The above is not guaranteed to work if the .class file is generated dynamically, but works in most situations.

0

精彩评论

暂无评论...
验证码 换一张
取 消