如果我有一个类加载器实例,我可以找到它在哪里寻找类字节吗?
如果我在类路径中按顺序有 dira、jarb 和 dirc,并且我有一个带有 3 个具有父/子/孙关系的类加载器的 java 应用程序,那么它们都会读取相同的目录吗?
我想我正在尝试找出每个类加载器的位置...有没有办法在给定类加载器的实例的情况下找到该路径?
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 relationship, 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 ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一般来说,不可以,类加载器可以随心所欲地构造字节。例如,如果 JSP 文件具有最近的时间戳,则 JSP 类加载器可能会动态调用 JSP 编译器。
使用
-verbose:class
标志运行 JVM 将启用大量日志记录,如果您只是使用标准引导类加载器,这应该会对您有所帮助。如果有一些自定义类加载器,您可以提供自己的
URLConnectionFactory
并查看正在获取哪些 URL。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.您实际上有几个问题。
classpath 目录和 jar 中的类通常由一个类加载器(应用程序类加载器)加载,而不是每个条目由多个类加载器加载。
如果您的类加载器处于父子关系中,则子加载器应首先要求其父加载该类,并且仅在父加载器未找到任何内容时才查找字节码本身。 (某些框架中有特殊用途的类加载器,它们以相反的方式执行此操作。如果每个类仅存在一次,那么这应该不会产生影响。)
如果您有一个
URLClassLoader
,然后你可以询问它的 getURLs() 方法来找出它从哪里加载。对于其他类加载器,可能有也可能没有找到它的方法。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 itsgetURLs()
method to find out from where it loads. For other classloaders, there may or may not be a way to find this.看一下 ClassLoader API,您会发现有一个传递名称的方法,最终类加载器传递一个 byte[] 来定义类。因为它是一个合适的类,所以它可以从任何它想要的地方获取这些字节。 ClassLoader 只是另一个公共类,任何人都可以实现自己的实现并做自己的事情。类加载器无处不在,我们有读取类路径系统属性的版本,在 tomcat 中我们有另一个从 war 文件读取的版本,在 osgi 中它从 jar 文件读取。除了简单地读取一些文件之外,每个都做了一些额外的事情,并且体现了类加载的美观和灵活性。
ClassLoader 上没有返回 String 的方法,因为给定上述 CLassLoaders ,它会返回什么?文件路径、jar 文件路径? ETC
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
一般来说不需要,但在实践中,您经常想找出某个类、资源是从哪里加载的,您可以这样做,
更有用的是,如果您想查找某个类来自哪个 .class 文件,请执行
上面的操作如果 .class 文件是动态生成的,则不保证可以工作,但在大多数情况下都可以工作。
In general no, but in practice you often want to find out where some class, resource is being loaded from and you can do,
Even more useful, if you are looking to find which .class file a Class is from, do
The above is not guaranteed to work if the .class file is generated dynamically, but works in most situations.