有谁知道如何以编程方式找出java类加载器实际从何处加载类?
我经常在大型项目中使用类路径,并且手动搜索并不是一个好的选择。我最近遇到了一个问题,其中类加载器正在加载不正确的类版本,因为它位于两个不同位置的类路径上。
那么,如何让类加载器告诉我实际的类文件来自磁盘上的什么地方?
编辑:如果类加载器由于版本不匹配(或其他原因)而实际上无法加载该类,该如何在读取它之前找出我们要读取的文件呢?
有谁知道如何以编程方式找出java类加载器实际从何处加载类?
我经常在大型项目中使用类路径,并且手动搜索并不是一个好的选择。我最近遇到了一个问题,其中类加载器正在加载不正确的类版本,因为它位于两个不同位置的类路径上。
那么,如何让类加载器告诉我实际的类文件来自磁盘上的什么地方?
编辑:如果类加载器由于版本不匹配(或其他原因)而实际上无法加载该类,该如何在读取它之前找出我们要读取的文件呢?
Answers:
这是一个例子:
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
Test.class.getResource("Test.class")
,它不会重复软件包名称。
Test.class.getResource(Test.class.getSimpleName() + ".class")
BouncyCastleProvider
完整的包名但是是必需的。
查找从何处加载类的另一种方法(不处理源代码)是使用以下选项启动Java VM: -verbose:class
这是我们使用的:
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";
}
通常,我们不使用硬编码。我们可以先获取className,然后使用ClassLoader获取类URL。
String className = MyClass.class.getName().replace(".", "/")+".class";
URL classUrl = MyClass.class.getClassLoader().getResource(className);
String fullPath = classUrl==null ? null : classUrl.getPath();
看看这个类似的问题。 发现同一个类的工具
我认为最相关的障碍是,如果您有一个自定义的类加载器(从db或ldap加载)
简单方法:
System.out.println(java.lang.String.class.getResource(String.class.getSimpleName()+“。class”)));
输出示例:
jar:文件:/ D:/Java/jdk1.8/jre/lib/rt.jar!/java/lang/String.class
要么
字符串obj =“简单测试”; System.out.println(obj.getClass()。getResource(obj.getClass()。getSimpleName()+“。class”)));
输出示例:
jar:文件:/ D:/Java/jdk1.8/jre/lib/rt.jar!/java/lang/String.class
假设您正在使用名为的类MyClass
,则应该可以进行以下操作:
MyClass.class.getClassLoader();
是否可以获取.class文件在磁盘上的位置取决于类加载器本身。例如,如果您使用的是BCEL之类的东西,则某个类甚至可能没有磁盘上的表示形式。