2008-09-20 50 views
5

我有一個加載第三方類文件(我沒有寫的類)的Java程序並執行它們。這些類通常使用java.util.Random,默認情況下,每次實例化時都會生成隨機起始種子值。由於可重複性的原因,我希望每次都給這些類別提供相同的起始種子,只能根據我的判斷進行更改。我如何向java.util.Random提供第三方類中的特定種子?

這裏有一些明顯的解決方案,以及爲什麼他們不工作:

  1. 在第三方類文件使用不同的Random類。這裏的問題是我只加載類文件,並且無法修改源文件。

  2. 使用自定義類加載器來加載我們自己的Random類而不是JVM的版本。這種方法將不起作用,因爲Java不允許類加載器覆蓋java包中的類。

  3. 替換掉我們自己的rt.jar的java.util.Random實現,或者將文件放入JVM的可信位置。這些方法要求應用程序的用戶在他們的機器上安裝JVM,並且不好。

  4. 將自定義java.util.Random類添加到bootclasspath。雖然這在技術上是可行的,但對於這個特定的應用程序來說,這是不切實際的,因爲這個應用程序是爲最終用戶從IDE運行而設計的。我想讓用戶運行該應用程序方便,這意味着強制他們設置他們的bootclasspath是一個痛苦。我不能在腳本中隱藏這一點,因爲它打算從像Eclipse的IDE運行(爲了便於調試。)

所以,我該怎麼辦呢?

回答

2

考慮修改第三方庫,讓他們使用他們的隨機實例看到。雖然你沒有源代碼,但你可以編輯字節碼來完成它。一個有用的工具包是ASM

1

您可以使用AOP攔截對Random的調用,並將arg轉換爲您想要的。

山姆

0

「使用自定義類加載器,而不是加載的JVM的版本,我們自己的Random類,這種方法是行不通的,因爲Java不允許類加載器來覆蓋在java包中的類。」

如何更改bootclasspath以使用您的自定義Random類?

BR, 〜一個

+0

Cha修改bootclasspath是有效的,但需要修改Java程序的運行方式。如果你可以控制某人啓動程序的方式,這很好,例如一個啓動腳本,但在我的情況下,用戶通常從IDE內運行,並且必須手動執行,這並不好。 – adum 2008-09-20 01:12:57

1

雖然你可能不會改變的類加載器平凡的「java.x」和「sun.x」套餐,有一個估計類加載(和「課後安裝方式被字節編碼並加載了這些類的「監聽器」,所以你可以在從這些包中加載類之後設置類似於種子的東西。提示:使用反射。

無論如何,只要我沒有進一步的信息,你想達到什麼目的,在這裏很難幫到你。

P.S .:請注意,「靜態{}」 - 塊可能會妨礙您再次混淆種子。

3

您的選擇2將實際工作,並遵循以下指示。

您將需要(如anjab所述)來更改引導類路徑。

在您需要添加以下程序的命令行:

的java -Xbootclasspath/p:C:\你\ random_impl.jar YourProgram

假設你Windown機或上任何操作系統中的這個問題的路徑。

該選項在加載rt.jar之前添加jar文件中的類。所以你的Random將在rt.jar Random類之前加載。

的用量是通過鍵入顯示:

java -X 

它顯示所有的X(TRA)設有德JVM有。在其他VM實現(如JRockit或其他)上可能不支持 ,但它在Sun JVM上存在。

-Xbootclasspath/p:前置自舉類路徑的前面

我已經在默認的ORB類應該與別人取代的應用程序中使用這種方法的ORB實現。 ORB類是Java核心的一部分,從來沒有任何問題。

祝你好運。

0

是選項2的工作: 創建了兩個班的測試目的命名ThirdPartyClass.javaRandom.java

創建罐子從ThirdPartyClass.class

jar -cvf tpc.jar ThirdPartyClass.class 

創建罐子從Random.class

jar -cvf rt123.jar Random.class 

之後執行用以下命令:

java -Xbootclasspath/p:tcp.jar:rt123.jar -cp . -verbose ThirdPartyClass 

的輸出將是:seed value for ThirdPartyClass-> 1

源代碼ThirdPartyClass.java ----->

import java.util.Random; 

public class ThirdPartyClass { 
    ThirdPartyClass(long seed) { 
     System.out.println("seed value for ThirdPartyClass-> "+seed); 
    } 

    public static void main(String [] args) { 
     ThirdPartyClass tpc=new ThirdPartyClass(new Random().nextLong()); 
    } 
} 

源代碼Random.java ------->

package java.util; 

import java.io.Serializable; 

public class Random extends Object implements Serializable 
{ 
    public Random() { 
    } 

    public Random(long seed) { 
    } 

    public long nextLong() { 
     return 1; 
    } 
} 

謝謝 Mahaveer Prasad Mali

相關問題