5

我正在将应用程序迁移到 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.JavacTooljdk.compiler模块中,它仍然是 JDK 的一部分,但不是 JRE。

jdk.compiler启动 JRE 时有什么方法可以加载模块吗?根据这个答案,我怀疑不是,我尝试使用--add-module的结果是: java.lang.module.FindException: JMOD format not supported at execution time

我还缺少另一个解决方案吗?

4

1 回答 1

4

IMO 对您的问题最简单的解决方案是保持简单,并要求用户下载 JDK 而不是 JRE:

...但我们允许用户编译他们自己的自定义代码

用户下载 JDK 应该不会感到惊讶,因为他们正在使用 JDK 功能:编译代码。

如果这不可能,那么您可能想尝试jlink@nullpointer 在评论中建议的解决方案。

于 2018-05-31T20:46:11.953 回答