我有一个Java程序加载第三方类文件(我没写的类)并执行它们。这些类通常使用java.util.Random
,默认情况下,每次实例化时都会生成随机的起始种子值。出于可重复性的原因,我希望每次都为这些类提供相同的起始种子,只能由我自行决定更改它。
以下是一些明显的解决方案,以及它们不起作用的原因:
在thirdparty类文件中使用不同的Random类。这里的问题是我只加载类文件,并且无法修改源。
使用自定义类加载器加载我们自己的Random类而不是JVM的版本。这种方法不起作用,因为Java不允许类加载器覆盖java
包中的类。
将我们自己的rt.jar java.util.Random
实现交换掉,或者将文件放入JVM的受信任位置。这些方法要求应用程序的用户在他们的机器上搞乱JVM安装,并且不好。
将自定义java.util.Random
类添加到bootclasspath。虽然这在技术上可行,但对于此特定应用程序而言,这是不切实际的,因为此应用程序旨在供最终用户从IDE运行。我想让用户方便地运行应用程序,这意味着强制他们设置他们的bootclasspath是一件痛苦的事。我无法在脚本中隐藏它,因为它打算从像Eclipse这样的IDE运行(以便于调试。)
那我怎么能这样做呢?
答案 0 :(得分:3)
您的选项2实际上将按以下方向运行。
您需要(如anjab所说)更改引导类路径。
在程序的命令行中,您需要添加以下内容:
java -Xbootclasspath / p:C:\ your \ _ random_impl.jar YourProgram
假设您使用的是Windown机器或任何操作系统中的相关路径。
该选项在加载rt.jar之前添加jar文件中的类。所以你的Random将在rt.jar Random类之前加载。
输入以下内容显示用法:
java -X
它显示了JVM所具有的所有X(tra)功能。它可能没有 在其他VM实现上,例如JRockit或其他,但它存在于Sun JVM上。
-Xbootclasspath / p:在bootstrap类路径前面添加
我在应用程序中使用此方法,其中默认ORB类应替换为其他ORB实现。 ORB类是Java Core的一部分,从未出现任何问题。
祝你好运。答案 1 :(得分:2)
考虑修改第三方库,让他们对随机实例使用see。虽然您没有源代码,但您可以编辑字节码来执行此操作。这样做的一个有用的工具包是ASM。
答案 2 :(得分:1)
您可以使用AOP拦截对Random的调用,并将arg旋转到您想要的位置。
萨姆
答案 3 :(得分:1)
虽然您可能不会为“java.x”和“sun.x”包简单地更改类加载器,但是有一种方法可以计算类加载(并安装这些类的“后类是字节编码和加载的”监听器) ,所以你可以在从这些包中加载类之后设置类似种子的东西。提示:使用反射。
无论如何,只要我没有进一步的信息你想要达到什么目标,就很难在这里帮助你。
P.S。:请注意“静态{}” - 块可能会阻碍你再次使用种子。
答案 4 :(得分:0)
“使用自定义类加载器加载我们自己的Random类而不是JVM的版本。这种方法不起作用,因为Java不允许类加载器覆盖java包中的类。”
如何更改bootclasspath以使用自定义Random类?
BR, 〜A
答案 5 :(得分:0)
是选项2正在运行:
为测试目的创建了两个名为ThirdPartyClass.java
和Random.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