Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java 9+;中使用JRE运行时,我是否可以提供运行时编译器访问;?_Java_Java 9_Java Platform Module System_Java 10_Jmod - Fatal编程技术网

在Java 9+;中使用JRE运行时,我是否可以提供运行时编译器访问;?

在Java 9+;中使用JRE运行时,我是否可以提供运行时编译器访问;?,java,java-9,java-platform-module-system,java-10,jmod,Java,Java 9,Java Platform Module System,Java 10,Jmod,我正在将一个应用程序迁移到Java10。我们的应用程序通常使用JRE运行,但我们允许用户通过捆绑tools.jar并使用反射按需加载JavacTool实例来编译他们自己的自定义代码。我们的方法如下所示: public static JavaCompiler getJavaCompiler() { String toolJarName = "tools.jar"; File file = getResourceForClass("tools.jar"); try {

我正在将一个应用程序迁移到Java10。我们的应用程序通常使用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());
    }
}
这是必要的,因为从JRE运行时,
javax.tools.ToolProvider.getSystemJavaCompiler()
返回null。我们的方法在Java8中运行得很好,但是在Java9中删除了
tools.jar
,我需要的类
com.sun.tools.javac.api.JavacTool
位于
jdk.compiler
模块中,它仍然是jdk的一部分,而不是JRE

启动JRE时,有没有办法加载
jdk.compiler
模块?我怀疑不是,基于,并且我尝试使用
--add module
导致:
java.lang.module.FindException:执行时不支持JMOD格式


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

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

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

用户下载JDK并不奇怪,因为他们使用的是JDK特性:编译代码


如果不可能,那么您可能希望尝试@nullpointer在注释中建议的
jlink
解决方案。

尝试创建一个和
jmod
?另外,考虑一下您的用例?@manouti根据我的建议,我的意思是创建一个自定义运行时映像,至于其中的实现,使用
ToolProvider
而不是
tools.jar
这真是个奇怪的问题。如果应用程序运行在JRE 8上,那么用户也需要在系统上安装JDK 8。也许问题中的代码与JRE无关,而与tools无关。jar默认情况下不在类路径上?如果是这样的话,那么JDK 9和更新版本中就不需要这些代码了,因为java.compiler和JDK.compiler模块是默认解决的。如果您使用的是JRE 8,那么它在哪里找到tools.jar?系统上必须有JDK,您是如何检查它是否与您正在运行的JRE版本相同的。如果你真的想在JRE上运行,那么我认为你必须创建一个新的VM来运行编译器。与JDK 9和更新版本相当的是运行
jlink
来创建一个包含JDK.compiler模块的运行时映像。当我说“他们自己的代码”。。。开发人员不是我们的目标客户,所以他们使用的大多数自定义代码片段都是由第三方(他们自己的IT支持、我们的产品论坛等)编写的。事实上,我们捆绑了JRE,因此用JDK替换它会增加我们的应用程序,但这肯定是我们认为最糟糕的解决方案,这个解决方案变得非常简单,因为不再有JRE了。那些知道如何创建较小的运行时环境的人应该知道如何包含编译器。