java加载classpath_关于classpath:查找从哪里加载java类

有人知道如何编程地找出Java类加载器从何处加载该类吗?

我经常在大型项目中工作,在这些项目中,类路径非常长,手动搜索实际上不是一个选项。我最近遇到了一个问题,类加载器加载了一个不正确的类版本,因为它位于类路径的两个不同位置。

那么,如何让类加载器告诉我实际类文件在磁盘上的来源呢?

编辑:如果由于版本不匹配(或其他原因),类加载器实际上无法加载类,那么我们是否可以在读取之前找到它尝试读取的文件?

"我不认为jarrodroberson of this should be事情考虑到stackoverflow.com /问题/复制/ 11747833 & hellip;因为这是要在2008年的问题,问题是要在2012年

下面是一个例子:

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"),它不重复包名。

如果类是从.groovy文件编译的,会怎么样?

@梅里顿:或者,为了生存重构:Test.class.getResource(Test.class.getSimpleName() +".class")。

但是,对于BouncyCastleProvider完整的包名是必需的。

getClassLoader()可以返回null。有关此方法的扩展,请参见此处。

@meriton Class#getResource(String name)委托给对象的类加载器,即ClassLoader#getResource(String name)方法。

同时,getResource可以返回空值。这个代码不会每次都起作用。

@汤姆和第225;?扎托:如果类可供类加载器使用,它就会工作。我同意如果OP需要处理类不可用的可能性,那么他们需要做一个空检查——这是一个简单的修改。

我用它来加载资源,这就是它失败的地方。具体地说,当我运行maven测试类时,它失败了——当时,我项目中的类试图从/target/test-classes而不是/target/classes加载资源。这个问题是通过使用new MyClass().getClass().getResource("...")或只是this.getClass ...(如果在实例化的上下文中)来解决的。

另一种方法是从(不操纵源)加载一个类的方法是用选项EDCOX1(2)启动Java VM。

这非常有效,并且不存在使用空类加载器处理类的问题。

我认为这应该是公认的答案。它确实为提出的问题提供了适当的解决方案。

@RIES如果不需要通过编程来实现这一点,这绝对是一种方法,它确实解决了我的问题。然而,该组织特别询问了如何通过程序实现这一点。

好吧,那只是把我从一个6小时的火花斯卡拉依赖地狱生活中拉出来。谢谢!

getClass().getProtectionDomain().getCodeSource().getLocation();

是的,尽管它不能在安装了安全管理器并且没有所需权限的情况下工作。

也可能是NPE…

仅供参考,npe=空指针异常。嗯!

只要您有一个实例的引用,这个方法是首选的,因为您可以从两个不同的位置加载同一个类。

当从Java 9 +模块调用(当然在2008中你不可能知道)时也不起作用。

这就是我们使用的:

public static String getClassResource(Class> klass) {

return klass.getClassLoader().getResource(

klass.getName().replace('.', '/') +".class").toString();

}

这将取决于类加载器的实现:getClass().getProtectionDomain().getCodeSource().getLocation()

当对象的ClassLoader注册为null时,jon的版本失败,这似乎意味着它是由启动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";

}

只编辑第一行:Main类。

Class> c = Main.class;

String path = c.getResource(c.getSimpleName() +".class").getPath().replace(c.getSimpleName() +".class","");

System.out.println(path);

输出:

/C:/Users/Test/bin/

也许风格不好,但效果很好!

通常,我们不知道使用什么硬编码。我们可以先获取类名,然后使用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加载)

这种方法适用于文件和JAR:

Class clazz = Class.forName(nameOfClassYouWant);

URL resourceUrl = clazz.getResource("/" + clazz.getCanonicalName().replace(".","/") +".class");

InputStream classStream = resourceUrl.openStream(); // load the bytecode, if you wish

假设您使用的是一个名为MyClass的类,那么下面的内容应该有效:

MyClass.class.getClassLoader();

是否可以获取.class文件的磁盘上位置取决于类加载器本身。例如,如果您使用的是BCEL,那么某个类甚至可能没有磁盘上的表示。

这将返回用于加载类的类加载器,不是吗?它找不到.class文件在哪里?

不,它不是。类加载器实际上可以重新传递到完全不同的类路径-意味着它将完全无法到达实际的类位置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值