Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I provide runtime compiler access when running with JRE in Java 9+?

I'm migrating an application to Java 10. Our application normally runs with the JRE, but we allow users to compile bits of their own custom code by bundling tools.jar and using reflection to load a JavacTool instance on demand. Our method looks like:

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());
    }
}

This is necessary because javax.tools.ToolProvider.getSystemJavaCompiler() returns null when running from the JRE. Our method worked well with Java 8, but tools.jar was removed in Java 9, and the class I need com.sun.tools.javac.api.JavacTool is in the jdk.compiler module which remains part of the JDK, but not the JRE.

Is there any way to load the jdk.compiler module when launching the JRE? I suspect it's not, based on this answer, and my attempts to use --add-module result in: java.lang.module.FindException: JMOD format not supported at execution time

Is there another solution I'm missing?

like image 257
rainbowgoblin Avatar asked May 31 '18 15:05

rainbowgoblin


1 Answers

IMO the simplest solution to your problem is to keep it simple and require users to download the JDK instead of the JRE:

... but we allow users to compile bits of their own custom code

It should come to no surprise to the users to download a JDK since, well, they are using a JDK feature: compiling code.

If that's not possible, then you may want to try the jlink solution that @nullpointer suggests in the comments.

like image 197
M A Avatar answered Oct 31 '22 20:10

M A