Метод 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). Не забудьте включить любые пакеты, добавив в каталог, где это необходимо.

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