2012-06-06 100 views
1

有沒有人知道是否有可能(是否有庫)知道變量是否包含在JRE中?如何知道某個類是來自JRE還是外部Jar?

這是我想要的東西:

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 
+5

爲什麼在運行時需要知道這一點? –

+0

嘗試String isJREClass(Class cl){return cl.getClassloader()。toString();} –

+1

我需要它進行Arquillian測試:我想發現一個類自動使用的所有類,以便將它們添加到Test '檔案'。但是,如果它是一個JRE,沒有必要,所以我想檢測它... –

回答

4

我可以爲您提供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%的不夠好。

+0

我首先測試了第一個解決方案,但後來我意識到一些外部罐子在'sun.'或'java.'中有類,並且'javax.'中的其他人(尤其是''javax.swing')是JRE的一部分......好吧,這不是一個可靠的解決方案。我將嘗試'getClassLoader()'。 –

+1

好吧,它似乎工作,謝謝!我也嘗試過'clazz.getProtectionDomain()。getCodeSource()',如[這裏](http://www.exampledepot.com/egs/java.lang/ClassOrigin.html)所示,並且似乎也有效(但不太清晰文檔) –

+0

我認爲getProtectionDomain()是正確的解決方案。感謝您的評論。 – AlexR

相關問題