Могу ли я предоставить доступ к компилятору времени выполнения при работе с JRE в Java 9+?

Я перевожу приложение на 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. Наш метод хорошо работал с Java 8, но tools.jar был удален в Java 9, и класс мне нужен com.sun.tools.javac.api.JavacTool находится в jdk.compiler модуль, который остается частью JDK, но не JRE.

Есть ли способ загрузить jdk.compiler модуль при запуске JRE? Я подозреваю, что это не так, основываясь на этом ответе, и мои попытки использовать --add-module результат в:java.lang.module.FindException: JMOD format not supported at execution time

Есть ли другое решение, которое я пропускаю?

1 ответ

IMO самое простое решение вашей проблемы - сохранить ее простотой и требовать, чтобы пользователи загружали JDK вместо JRE:

... но мы позволяем пользователям компилировать биты своего собственного кода

Пользователям не стоит удивляться, что они загружают JDK, поскольку они используют функцию JDK: компиляцию кода.

Если это невозможно, вы можете попробовать jlink решение, которое @nullpointer предлагает в комментариях.

Другие вопросы по тегам