Я знаю, что это было задано и много ответа, но у меня все еще нет хорошего решения, и я до сих пор не понимаю некоторых частей. Поэтому у меня есть требование скомпилировать * .java файлы программно.Программно скомпилировать java-файлы
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
является то, что я использую, и (как и ожидалось) компилятор null
. Теперь я знаю, что мне нужно использовать JDK, а не JRE как «runtime», но вот что-то я не понимаю: недостаточно ли просто поместить tools.jar
в путь к классам приложения, а затем иметь доступ к API компилятора Java? Если это так, существует (я думаю, есть) разница между автономным Java-приложением и веб-приложениями. На самом деле, я пытаюсь вызвать JavaCompiler из веб-приложения PlayFramework, поэтому я понял, может быть, эти решения (включая tools.jar
) работают только для автономных приложений?
Я также пытался создать пользовательский ClassLoader и вызывать вышеупомянутый метод с отражением, но все, что я получаю null
для compiler
объекта:
ClassLoader classloader = app.classloader();
File file = new File("lib/tools.jar");
URL url = file.toURI().toURL();
URL[] urls = new URL[]{url};
ClassLoader newCL = new URLClassLoader(urls, classloader) {
};
Class<?> loadClass = newCL.loadClass("javax.tools.ToolProvider");
Method method = loadClass.getMethod("getSystemJavaCompiler", null);
Object object = method.invoke(null);
System.out.println("Object: " + object); // NULL
Объяснение для кода выше:
- Я не включил попытку/уловы ради простоты.
- app.classloader() является Плей-метод, который возвращает ClassLoader в App
tools.jar
входит в мою Lib папку проекта Play (это означает, что он находится на пути к классам проекта - согласно документации Play)
Я уверен, что перед тем,
Параметры, подобные Runtime.exec("javac myFile.java")
и компилятор Eclipse JDT, известны мне, но это не то, что я ищу.
О, и что-то вроде System.setProperty("java.home", "PATH_TO_YOUR_JDK");
, а затем ToolProvider.getSystemJavaCompiler();
работает, но я нахожу это решение таким уродливым.
С наилучшими пожеланиями
EDIT: (для получения дополнительной информации и отражает последнее состояние) Это базовое представление веб-приложения-структуры:
myApp
|-conf\...
|-lib\MyJar.jar
|-lib\tools.jar
|-logs\...
|-...
myJar.jar сейчас META-INF/MANIFEST.MF
файл со следующим содержанием:
Manifest-Version: 1.0
Sealed: true
Main-Class: here.comes.my.main.class
Class-Path: tools.jar
Без, начиная с приложения Play, я пытаюсь (в папке lib
): java -jar MyJar.jar
- мой простой метод main
пытается вызвать компилятор (ToolProvider.getSystemJavaCompiler();
) и возвращает null
. Таким образом, это заставляет меня поверить, что проблема не имеет ничего общего с Play - я даже не могу получить компилятор при нормальной работе Jar!
'JAVA_HOME' установлен на моей машине dev, возвращая путь к JDK по запросу. Но получение свойства '' java.home'' из запущенного приложения Play (с 'System.getProperty (...)') возвращает путь к JRE. Так что, возможно, это единственная проблема. Но не должно быть проблем, когда у меня есть 'tools.jar' в моем пути к классам. И я уверен, что 'tools.jar' находится в моем пути к классам (проверял его во время запуска веб-приложения) и что файл не поврежден. Я собираюсь попробовать вышеупомянутый материал для загрузки. – user2229298
Я запустил игру на своем ubuntu, и я смог получить java-компилятор из scala-action без каких-либо проблем. Может быть, что-то не так с вашей настройкой? –
Просто попробовал 'JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); \t \t \t System.out.println ("Java-компилятор:" + javaCompiler); 'из метода' onStart' в 'app/Global.java' - с' tools.jar' в пути к классам моего приложения - даже это возвращается 'null' – user2229298