2010-01-12 43 views
2

我想啓動一個java子進程,它具有與當前java進程相同的java classpath和動態加載的類。以下是不夠的,因爲它不包含任何動態加載的類:使用父進程啓動Java子進程類路徑

String classpath = System.getProperty("java.class.path"); 

目前我在尋找與下面的代碼所需要的每個類。但是,在某些機器上,某些類/庫會失敗,源變量爲空。是否有更可靠和更簡單的方法來獲取當前jvm進程使用的庫的位置?

String stax  = ClassFinder.classPath("javax.xml.stream.Location"); 

public static String classPath(String qualifiedClassName) throws NotFoundException { 
    try { 
     Class qc = Class.forName(qualifiedClassName); 
     CodeSource source = qc.getProtectionDomain().getCodeSource(); 
     if (source != null) { 
      URL location = source.getLocation();   
      String f = location.getPath(); 
      f = URLDecoder.decode(f, "UTF-8"); // decode URL to avoid spaces being replaced by %20 
      return f.substring(1); 
     } else { 
      throw new ClassFinder().new NotFoundException(qualifiedClassName+" (unknown source, likely rt.jar)"); 
     } 
    } catch (Exception e) { 
     throw new ClassFinder().new NotFoundException(qualifiedClassName); 
    } 
} 
+0

出於好奇:你是怎麼想出這種方法的? – 2010-01-12 16:24:55

+0

我是怎麼想出這種方法的?我發現它在網上的某個地方,不記得現在在哪裏。 我認爲這個問題真的歸結爲,爲什麼ProtectionDomain .getCodeSource()有時返回null。 APIs文檔沒有用,他們只是說該方法可能會返回null。 – 2010-01-12 17:15:40

回答

1

我想啓動一個java子進程,它具有與當前java進程相同的java classpath和動態加載的類。

你的意思是調用一個新的JVM?

鑑於...

  • 有可能在各種代理程序和工具來插入,可以在加載時變換班JVM
  • 有可能採取byte陣列和轉它變成一個類
  • 有可能具有複雜的類裝載程序層次結構具有不同類之間的可見性,並且具有相同的類裝載多次

......沒有一般的,魔術的,萬能的和萬無一失的方式來做到這一點。你應該設計你的應用程序和它的類加載機制來實現這個目標。如果您允許使用第三方插件,則必須記錄其工作原理以及他們如何註冊庫。

+0

最後,我使用上面描述的機制來查找我們的庫。我們的庫引用清單中的所有其他庫,我知道它們將安裝在與庫相同的文件夾中。 – 2010-01-14 22:12:51

2

請參閱我的previous question其中包括獲取類路徑以及如何啓動子流程。

+0

確實 - 這是一個類似的問題。我需要的是額外的動態加載類。我不想用這些文件定義一個額外的文件,或者引入額外的環境變量來定位它們,因爲它們都是由當前環境'知道的'。 – 2010-01-12 17:01:05

0

如果你看一下Class.getClassLoader的javadoc,你會發現「bootstrap」類加載器通常表示爲null。 「String.class.getClassLoader()」將在普通的sun jvm實現上返回null。我認爲這個實現細節會傳遞到CodeSource中。因此,只要您的子進程使用與當前進程相同的jvm impl,我就不會想象您需要擔心來自引導類加載器的任何類。