ToolProvider.getSystemJavaCompiler() с jre + tools.jar

Примечание. Это повторяющийся вопрос с форумов оракулов, поскольку там никто на него не ответил.

Наши приложения поставляются с JRE, а не с JDK, и в пути к классам у нас также есть tools.jar.

Из нашего приложения мы компилируем abc.java командой: com.sun.tools.javac.Main.compile(file);

Затем следующим шагом является обработка аннотаций с помощью инструмента apt, например.

args[0] = "-nocompile";
args[1]=abc.java
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int aptReturnCode = com.sun.tools.apt.Main.process(processor, new PrintWriter(baos), fl); //where processor is the custom annotation processor.

С java-8 мы обнаружили, что оракул сделал инструмент apt несуществующим, поэтому вместо использования инструмента apt мы должны использовать компилятор java для той же задачи. (Я получил этот совет от этого форума в прошлом). Итак, я пришел с кодом ниже, который нуждался в некоторой доработке процессора аннотаций, но проблема в том, что ToolProvider.getSystemJavaCompiler( ) всегда возвращает null. Есть ли способ, которым я мог бы выполнить эту обработку аннотаций или загрузить компилятор java только с tools.jar в пути к классу без использования jdk?

ArrayList<String> customClasses = new ArrayList<String>();
ArrayList<String> arguments = new ArrayList<String>();//arguments for the java compiler
arguments.add( "-proc:only" ); // only do annotations processing and do not compile the source code.
customClasses.add("full path/abc.java");

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); // always returns null

ByteArrayOutputStream baos = new ByteArrayOutputStream();

DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
  StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
  Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromStrings(customClasses);

  JavaCompiler.CompilationTask task =
  compiler.getTask(new PrintWriter(baos), fileManager, diagnostics, arguments, null, compilationUnits);

  ArrayList<Processor> processors = new ArrayList<Processor>();
  processors.add( new MyCustomProcessor() );
  task.setProcessors( processors );

  boolean success = task.call();

Огромное спасибо


person ali90    schedule 18.03.2015    source источник
comment
Вам нужна версия tools.jar для Java 8 в вашем пути к классам, чтобы она работала. Но имейте в виду, что это снова сломается, как только вы переключитесь на Java 9, так как тогда tools.jar больше не будет (если все развернуто, как планировалось). Итак, суть в том, что если вам нужен компилятор, вам нужен JDK (если только у вас нет собственного собственного компилятора).   -  person Holger    schedule 18.03.2015
comment
У нас есть java8 tools.jar в пути к классам приложения, но ToolProvider.getSystemJavaCompiler(); все еще возвращает ноль   -  person ali90    schedule 18.03.2015
comment
Попробуйте добавить его в путь к классу начальной загрузки, например -Xbootclasspath/a:path/to/tools.jar   -  person Holger    schedule 18.03.2015
comment
Добавление его в путь к классу начальной загрузки, кажется, помогает, но без добавления его в начальную загрузку кажется, что я также могу использовать com.sun.tools.javac.api.JavacTool javac = com.sun.tools.javac.api.JavacTool.create (); Спасибо :)   -  person ali90    schedule 19.03.2015
comment
Что ж, оба решения не переносимы и, вероятно, сломаются в будущей версии…   -  person Holger    schedule 19.03.2015
comment
Под «не переносимым» вы подразумеваете не переносимый на разные платформы, и если да, то как? Благодарю.   -  person ali90    schedule 19.03.2015
comment
Не переносим между различными реализациями JRE/JDK.   -  person Holger    schedule 19.03.2015


Ответы (1)


Настраивая eclipse на windows, у меня есть проект, который использует mapstruct. Я просто хочу отметить, что если вы видите эту ошибку в журналах консоли maven

[ОШИБКА] JVM не подходит для обработки аннотаций! ToolProvider.getSystemJavaCompiler() имеет значение null.

Одно исправление будет

Установите java jdk, откройте eclipse.ini и добавьте следующие строки над -vmargs

-vm 
C:\Program Files\Java\jdk1.8.0_111\bin\javaw.exe
-vmargs
person Begui    schedule 23.12.2016