我正在将应用程序迁移到 Java 10。我们的应用程序通常使用 JRE 运行,但我们允许用户通过捆绑 tools.jar
并使用反射加载来编译他们自己的自定义代码位按需提供的 JavacTool
实例。我们的方法如下所示:
public static JavaCompiler getJavaCompiler() {
String toolJarName = "tools.jar";
File file = getResourceForClass("tools.jar");
try {
file = file.getCanonicalFile();
} catch (IOException ignore) {
}
if (!file.exists())
throw new RuntimeException("Can't find java tools file: '"+file+"'");
try {
URL[] urls = new URL[]{ file.toURI().toURL() };
URLClassLoader cl = URLClassLoader.newInstance(urls);
return Class.forName("com.sun.tools.javac.api.JavacTool", false, cl).asSubclass(JavaCompiler.class).newInstance();
} catch (Exception e) {
throw new RuntimeException("Can't find java compiler from '"+file+"': "+e.getMessage());
}
}
这是必需的,因为 javax.tools.ToolProvider.getSystemJavaCompiler()
从 JRE 运行时返回 null。我们的方法在 Java 8 上运行良好,但是 tools.jar
在 Java 9 中被删除了,我需要的类 com.sun.tools.javac.api.JavacTool
在jdk.compiler
模块仍然是 JDK 的一部分,但不是 JRE。
有什么办法可以在启动JRE时加载jdk.compiler
模块吗?我怀疑不是,基于 this answer ,而我尝试使用 --add-module
的结果是:
java.lang.module.FindException:执行时不支持 JMOD 格式
我还缺少其他解决方案吗?
最佳答案
IMO 解决问题的最简单方法是保持简单并要求用户下载 JDK 而不是 JRE:
... but we allow users to compile bits of their own custom code
用户下载 JDK 应该不足为奇,因为他们正在使用 JDK 的一项功能:编译代码。
如果那不可能,那么您可能想尝试@nullpointer 在评论中建议的 jlink
解决方案。
关于java - 在 Java 9+ 中使用 JRE 运行时,我可以提供运行时编译器访问吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50628270/