【问题标题】:How to know if a class is from the JRE or from an external Jar?如何知道一个类是来自 JRE 还是来自外部 Jar?
【发布时间】:2012-06-06 15:28:57
【问题描述】:

有谁知道是否有可能(是否有库)知道 Class<?> 变量是否包含在 JRE 中?

这是我想要的:

Class<String> stringClass = String.class;
System.out.println(TheMagickLibrary.isJREClass(stringClass)); // should display true

Class<AnyClass> anotherClass = AnyClass.class;
System.out.println(TheMagickLibrary.isJREClass(anotherClass)); // should display false

【问题讨论】:

  • 为什么需要在运行时知道这一点?
  • 尝试 String isJREClass(Class cl) {return cl.getClassloader().toString();}
  • 我需要它来进行 Arquillian 测试:我想自动发现一个类使用的所有类,以便将它们添加到测试 Archive&lt;?&gt;。但是如果是JRE的话就没有必要了,所以我想检测一下……

标签: java introspection


【解决方案1】:

我可以为您提供 2 个解决方案。

  1. 获取类包,查看是否以java.sun.com.sun.开头
  2. 获取类的类加载器:
Returns the class loader for the class.  Some implementations may use
null to represent the bootstrap class loader. This method will return
null in such implementations if this class was loaded by the bootstrap
class loader.

正如您所见,他们说“某些实现可能返回 null”。这意味着对于这些实现,clazz.getClassLoader() == null 意味着该类由引导类加载器加载,因此属于 JRE。顺便说一句,这适用于我的系统(Java(TM) SE 运行时环境(构建 1.6.0_30-b12))。

如果不检查ClassLoader#getParent()的文档:

 Returns the parent class loader for delegation. Some implementations may
 use <tt>null</tt> to represent the bootstrap class loader. This method
 will return <tt>null</tt> in such implementations if this class loader's
 parent is the bootstrap class loader.

同样,如果当前类加载器是引导程序,某些实现将返回 null。

最后我推荐以下策略:

public static boolean isJreClass(Class<?> clazz) {
    ClassLoader cl = clazz.getClassLoader();
    if (cl == null || cl.getParent() == null) {
        return true;
    }
    String pkg = clazz.getPackage().getName();
    return pkg.startsWith("java.") || pkg.startsWith("com.sun") || pkg.startsWith("sun."); 
}

我相信这对于 99% 的情况来说已经足够了。

【讨论】:

  • 我首先测试了第一个解决方案,但后来我意识到一些外部 jar 在sun.java. 中有类,而在javax. 中的其他类(尤其是javax.swing)是JRE ...好吧,这不是一个可靠的解决方案。我会试试getClassLoader() 一个。
  • 好的,它似乎工作了,谢谢!我还按照here 的指示尝试了clazz.getProtectionDomain().getCodeSource(),并且似乎也可以工作(但文档上不太清楚)
  • 我认为 getProtectionDomain() 是正确的解决方案。感谢您的评论。
  • 你为什么这么认为@AlexR? getCodeSource() 的 Javadoc 只是“Returns the CodeSource of this domain which may be null”,与父引导加载程序无关......
猜你喜欢
  • 2023-03-30
  • 2022-01-07
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 2013-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多