Могу ли я предоставить доступ к компилятору времени выполнения при работе с 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 предлагает в комментариях.