有谁知道如何以编程方式找出java类加载器实际加载类的位置?
我经常在大型项目上工作,其中类路径变得非常长并且手动搜索不是真正的选项.我最近遇到了一个问题,类加载器加载了一个不正确的类版本,因为它位于两个不同位置的类路径中.
那么我怎样才能让类加载器告诉我实际的类文件来自磁盘的哪个位置?
编辑:如果由于版本不匹配(或其他东西),类加载器实际上无法加载类,那么我们是否可以找到它在读取之前尝试读取的文件?
这是一个例子:
package foo; public class Test { public static void main(String[] args) { ClassLoader loader = Test.class.getClassLoader(); System.out.println(loader.getResource("foo/Test.class")); } }
打印出来的:
file:/C:/Users/Jon/Test/foo/Test.class
找出加载类的位置(不需要操作源)的另一种方法是使用以下选项启动Java VM: -verbose:class
getClass().getProtectionDomain().getCodeSource().getLocation();
这就是我们使用的:
public static String getClassResource(Class> klass) { return klass.getClassLoader().getResource( klass.getName().replace('.', '/') + ".class").toString(); }
这将取决于ClassLoader实现:
getClass().getProtectionDomain().getCodeSource().getLocation()
当对象ClassLoader
被注册时,Jon的版本失败,null
这似乎暗示它是由Boot加载的ClassLoader
.
此方法处理该问题:
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"; }