Itc*_*chy 7 java java-9 java-module
如何在测试运行时将我的测试添加到我的生产代码中,以便它们都在同一个 Java 9 模块中并且可以使用反射相互访问?
到目前为止我已经尝试过:
module-info.java)→ 它运行良好,但不是我想要的。--patch-module到其他文件夹几乎增加(到一个指定使用--module-path)→将其与“正常”的代码工作,但不与反射,它没有找到指定的类--module-path。
--patch-module→指定我的测试和生产代码,它只会在我首先指定的文件夹中找到类。--add-opens mymodule/mypackge=mymodule或...=ALL-UNNAMED打开它进行反射 → 看起来没有任何效果。所以我的完整测试线是:
java \
--patch-module com.stackoverflow.examplemodule=ModuleInfoTest:ModuleInfoExample \
--module-path ModuleInfoExample \
--add-opens com.stackoverflow.examplemodule/com.stackoverflow.examplepackage=com.stackoverflow.examplemodule \
--add-opens com.stackoverflow.examplemodule/com.stackoverflow.examplepackage=ALL-UNNAMED \
--module com.stackoverflow.examplemodule/com.stackoverflow.examplepackage.Main
Run Code Online (Sandbox Code Playgroud)
我在一个包含以下子目录和文件的目录中:
我正在使用:
openjdk version "13.0.2" 2020-01-14
OpenJDK Runtime Environment (build 13.0.2+8)
OpenJDK 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)
Run Code Online (Sandbox Code Playgroud)
正如我从批准的答案中了解到的那样,我的问题并不是真正的“访问其他课程”,正如我所说的那样。但更像是找到它们(通过扫描类路径/模块路径)。然而,这部分已经在另一个 StackOverflow 问题中得到了回答。
在Oracle 的 Java 13 java 命令中,这些是您尝试使用的两个选项:
--add-opens module/package=target-module(,target-module)*
--patch-module module=file(;file)*
Run Code Online (Sandbox Code Playgroud)
但:
--add-opens对您没有帮助,因为它向其他模块打开了一个模块。您只有一个模块。--patch-module必须指定要修补到模块中的目录(或 jarfile)。我注意到有;一个:不像你用的。在我看来,您一直在告诉 java 修补模块所在目录中的文件:ModuleInfoExample。您只需要将文件添加ModuleInfoTest/到您的模块中。我根据您的问题创建了结构并运行了它:
javac -d target/ModuleInfoExample src/ModuleInfoExample/*.java src/ModuleInfoExample/com/stackoverflow/examplepackage/*.java
javac -cp target/ModuleInfoExample -d target/ModuleInfoTest src/ModuleInfoTest/com/stackoverflow/examplepackage/*.java
Run Code Online (Sandbox Code Playgroud)
java --module-path target/ModuleInfoExample --module com.stackoverflow.examplemodule/com.stackoverflow.examplepackage.Main
prints:
Hello world - I'm private
Run Code Online (Sandbox Code Playgroud)
java --module-path target/ModuleInfoExample --module com.stackoverflow.examplemodule/com.stackoverflow.examplepackage.AnyClass
Error: Could not find or load main class com.stackoverflow.examplepackage.AnyClass in module com.stackoverflow.examplemodule
Run Code Online (Sandbox Code Playgroud)
java --module-path target/ModuleInfoExample --patch-module com.stackoverflow.examplemodule=target/ModuleInfoTest --module com.stackoverflow.examplemodule/com.stackoverflow.examplepackage.AnyClass
prints:
Inside AnyClass - calling Main: Hello world - I'm private
field.get() = I'm private
field.get() = I'm not private anymore
Run Code Online (Sandbox Code Playgroud)
>tree /f
..snip..
C:.
+---src
¦ +---ModuleInfoExample
¦ ¦ ¦ module-info.java
¦ ¦ ¦
¦ ¦ +---com
¦ ¦ +---stackoverflow
¦ ¦ +---examplepackage
¦ ¦ Main.java
¦ ¦
¦ +---ModuleInfoTest
¦ +---com
¦ +---stackoverflow
¦ +---examplepackage
¦ AnyClass.java
¦
+---target
+---ModuleInfoExample
¦ ¦ module-info.class
¦ ¦
¦ +---com
¦ +---stackoverflow
¦ +---examplepackage
¦ Main.class
¦
+---ModuleInfoTest
+---com
+---stackoverflow
+---examplepackage
AnyClass.class
Run Code Online (Sandbox Code Playgroud)
module com.stackoverflow.examplemodule {
// exports com.stackoverflow.examplepackage; // no need to export. Nothing is using this
}
Run Code Online (Sandbox Code Playgroud)
package com.stackoverflow.examplepackage;
public class Main {
private String privateString = "I'm private";
public static void main(String[] args) {
new Main().hello();
}
public void hello(){
System.out.println("Hello world - " + privateString);
}
}
Run Code Online (Sandbox Code Playgroud)
package com.stackoverflow.examplepackage;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class AnyClass {
public static void main(String[] args) {
testhello();
System.out.println();
breakhello();
}
public static void testhello(){
System.out.print("Inside AnyClass - calling Main: ");
Main test = new Main();
test.hello();
}
public static void breakhello(){
try {
// Not necessary - same package, but..
Class<?> mainClass = Class.forName("com.stackoverflow.examplepackage.Main");
Constructor<?> constructor = mainClass.getConstructor();
Object main = constructor.newInstance();
// Getting, printing and changing the field..
Field field = mainClass.getDeclaredField("privateString");
field.setAccessible(true);
System.out.println(" field.get() = " + field.get(main));
field.set(main,"I'm not private anymore");
System.out.println(" field.get() = " + field.get(main));
} catch (Exception e) { // Sorry, all in one big bucket
System.out.println("Error: " + e);
}
}
}
Run Code Online (Sandbox Code Playgroud)