【发布时间】:2017-12-22 23:03:08
【问题描述】:
就上下文而言,我正在开发一个名为 Randoop 的工具。我需要做的是能够在运行时使用 Java 代理替换某些方法调用。具体来说,我想用 Random(0) 替换对 Random() 的调用。
我的目录结构如下:
test_randoop/
randoop.jar
replacecall.jar
replacement_file.txt
ClassWithRandom.java
ClassWithRandom.class
replace/
java/
util/
Random.java
Random.class // created with "javac Random.java" command
我正在运行 test_randoop 目录中的所有命令。
Random.java的内容是:
package replace.java.util;
public class Random {
/** Default mock for {@code Random()}. Replaces call with {@code Random(0)}. */
public static java.util.Random randomWithSeedZero() {
return new java.util.Random(0);
}
public static int returnZero() {
return 0;
}
}
我想在运行时使用以下行获取 Random 类,其中 classname 定义为 replace.java.util.Random
Class<?> methodClass = Class.forName(classname);
但是,此代码是从 replacecall.jar 文件中调用的,该文件是我用来替换调用的 Java 代理。这似乎是个问题,因为代理似乎不知道 replace.java.util.Random 类。
详细来说,我正在运行的 Java 程序是使用以下命令执行的:
java -ea -classpath .:randoop.jar -Xbootclasspath/a:/home/waylonh/test_randoop/replacecall.jar -javaagent:/home/waylonh/test_randoop/replacecall.jar="--replacement-file=replacement_file.txt --debug=true --verbose=true" randoop.main.Main gentests --testclass=ClassWithRandom --output-limit=10
问题是在类路径中永远找不到replace.java.util.Random 类,并且forName 方法会抛出ClassNotFoundException。
我尝试在运行时使用以下 sn-p 打印出系统类路径:
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
for (URL u : ((URLClassLoader) classLoader).getURLs()) {
System.out.println(u.getFile());
}
结果输出是:
/home/waylonh/test_randoop/
/home/waylonh/randoop/build/libs/randoop-all-3.1.5.jar
/home/waylonh/randoop/build/libs/replacecall-3.1.5.jar
我会在这里遗漏什么?是否必须为 Java 代理参数提供不同的类路径?为什么系统类加载器将test_randoop目录列为classpath的一部分,却找不到replace/java/util中的Random类?
【问题讨论】:
标签: java jvm classpath instrumentation javaagents