我有一个Java程序加载第三方类文件(我没写的类)并执行它们。这些类通常使用 java.util.Random ,默认情况下,每次实例化时都会生成随机的起始种子值。出于可重复性的原因,我希望每次都为这些类提供相同的起始种子,只能由我自行决定更改它。

以下是一些明显的解决方案,以及它们不起作用的原因:

  1. 在thirdparty类文件中使用不同的Random类。这里的问题是我只加载类文件,并且无法修改源。

  2. 使用自定义类加载器加载我们自己的Random类而不是JVM的版本。这种方法不起作用,因为Java不允许类加载器覆盖 java 包中的类。

  3. 将我们自己的rt.jar的 java.util.Random 实现交换掉,或者将文件放入JVM的受信任位置。这些方法要求应用程序的用户在他们的机器上搞乱JVM安装,并且不好。

  4. 将自定义 java.util.Random 类添加到bootclasspath。虽然这在技术上可行,但对于此特定应用程序而言,这是不切实际的,因为此应用程序旨在供最终用户从IDE运行。我想让用户方便地运行应用程序,这意味着强制他们设置他们的bootclasspath是一件痛苦的事。我无法在脚本中隐藏它,因为它打算从像Eclipse这样的IDE运行(以便于调试。)

  5. 那我怎么能这样做呢?

有帮助吗?

解决方案

考虑修改第三方库,让他们对随机实例使用see。虽然您没有源代码,但您可以编辑字节码来执行此操作。一个有用的工具包是 ASM

其他提示

您的选项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的一部分,从未出现任何问题。

祝你好运。

您可以使用AOP拦截对Random的调用,并将arg旋转到您想要的位置。

萨姆

虽然您可能不会为“java.x”而轻易更改类加载器。和“sun.x”包,有一种方法可以计算这些类的类加载(并安装一个“后类是字节编码和加载的”监听器),所以你可以在从这些包加载类之后设置类似种子的东西。提示:使用反射。

无论如何,只要我没有进一步的信息你想要达到什么目标,就很难在这里帮助你。

P.S。:请注意“静态{}” - 块可能会阻碍你再次使用种子。

“使用自定义类加载器加载我们自己的Random类而不是JVM的版本。这种方法不起作用,因为Java不允许类加载器覆盖java包中的类。“

如何更改bootclasspath以使用自定义Random类?

BR, 〜A

是选项2正在运行: 为测试目的创建了两个类,名为 ThirdPartyClass.java Random.java

ThirdPartyClass.class

创建jar
jar -cvf tpc.jar ThirdPartyClass.class

Random.class

创建jar
jar -cvf rt123.jar Random.class

之后执行以下命令:

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

输出将是: 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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top