Метод run() инструмента интерфейса создает исключение NullPointerException в JDK 9
// Ниже приведен файл Hello.java.
public class Hello{
public static void main(String... s){
System.out.println("hello world");
}
}
Я пытаюсь скомпилировать вышеуказанный класс с помощью Java Compiler API следующим образом:
import javax.tools.*;
public class CallingJavaCompiler{
public static void main(String... s){
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
int i = comp.run(System.in,System.out,System.err,"Hello.java");
System.out.println(i);
}
}
Выполняя класс CallingJavaCompiler (используя JDK 9), он вызывает исключение java.lang.NullPointerException при запуске метода. Я не могу понять, почему это вызывает исключение, когда есть аргумент строкового типа?
Вот трассировка стека, которую я получаю при ее выполнении:
Exception in thread "main" java.lang.NullPointerException
at CallingJavaCompiler.main(CallingJavaCompiler.java:5)
С другой стороны, за исключением той же программы, т.е. CallingJavaCompiler в JDK 8, она выполняется без каких-либо исключений времени выполнения.
Пожалуйста, помогите мне понять, почему выдается исключение нулевого указателя (NPE), когда я выполняю его с использованием JDK 9?
Примечание: я компилирую приведенный выше фрагмент кода с использованием javac 9.0.4 и выполняю его с использованием java версии 9.0.4. При компиляции и выполнении с этой версией я получаю NPE, но не с JDK 8.
2 ответа
Замените Hello.java полным путем к файлу Hello.java (например, C:\Test\Hello.java). В любом случае, я не получил NullPointerException, даже если путь к Hello.java указан неверно.
ОБНОВИТЬ
Я смог воспроизвести вашу ошибку java.lang.NullPointerException. Появляется при запуске программы с JRE вместо JDK. Таким образом, компилятор не найден, так как компилятор доступен только в версии JDK.
UPDATE2
Итак, вы используете командную строку для запуска программы.
При выполнении с %jdk_home%/bin/java
вы используете JDK и при выполнении с %jdk_home%/jre/bin/java
Вы используете JRE.
Я вижу, вы компилируете с JDK 9.0.1 и работаете с JRE 9.0.4. Чтобы заставить его работать, выполните что-то вроде:
%JDK 9.0.1 home%/bin/java CallingJavaCompiler
Из документации ToolProvider#getSystemJavaCompiler
:
Эта реализация возвращает компилятор, предоставленный модулем jdk.compiler, если этот модуль доступен, и ноль в противном случае.
Я подозреваю, что ваш jdk.compiler
модуль по какой-то причине недоступен (возможно, вы запускаете программу с JRE 9, а не с JDK 9), поэтому вы и получаете NullPointerException
, Конечно, я рекомендую добавить его в свой module-info.java
даже если это не требуется.
module Hello {
requires jdk.compiler;
}
В любом случае, я смог решить вашу проблему, указав полный путь к Hello.java
, как показано ниже. Это работает на Windows; если вы используете любую другую ОС, то вы должны использовать File.separator
или же System.getProperty("file.separator")
скорее, чем \\
,
JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
int i = comp.run(System.in, System.out, System.err,"src\\main\\java\\Hello.java");
System.out.println(i);
Выход:
0
Примечание. Путь начинается с корневого каталога моего проекта (родительский каталог исходной папки, src
). Не забудьте включить любые пакеты, добавив в каталог, где это необходимо.