运行() 接口工具的方法在 JDK 9 中抛出 NullPointerException
run() method of interface tool throws NullPointerException in JDK 9
//以下是Hello.java文件.
public class Hello{
public static void main(String... s){
System.out.println("hello world");
}
}
我正在尝试使用 Java 编译器 API 编译上面的 class,如下所示:
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);
}
}
在执行调用Java编译器class时(使用JDK 9),它在[=48处抛出java.lang.NullPointerException =] 方法。我无法理解为什么它在有字符串类型参数时抛出异常?
这是我在执行它时得到的堆栈跟踪:
Exception in thread "main" java.lang.NullPointerException
at CallingJavaCompiler.main(CallingJavaCompiler.java:5)
另一方面,执行相同的程序,即在 JDK 8 中调用 Java 编译器,它正在执行 而没有任何 运行时间异常.
请帮助我理解为什么当我使用 JDK 9 执行它时会抛出空指针异常 (NPE)?
注意: 我正在使用 javac 9.0.4 编译以上代码,并使用 java 版本 9.0.4 执行它。在使用这些版本编译和执行时,我得到了 NPE,但没有使用 JDK 8.
将 Hello.java 替换为 Hello.java 文件的完整路径(例如 C:\Test\Hello.java)。无论如何,即使 Hello.java 的路径错误,我也没有得到 NullPointerException。
更新
我能够重现您的 java.lang.NullPointerException 错误。它出现在 运行 使用 JRE 而不是 JDK 连接程序时。这样,找不到编译器,因为编译器仅在 JDK 版本中可用。
更新2
所以您正在使用命令行 运行 程序。
使用 %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
的文档:
This implementation returns the compiler provided by the jdk.compiler module if that module is available, and null otherwise.
我怀疑您的 jdk.compiler
模块由于某种原因不可用(您可能 运行 使用 JRE 9 而不是 JDK 9 的程序),因此您会收到一个NullPointerException
。可以肯定的是,我建议将它添加到您的 module-info.java
,即使它似乎不是必需的。
module Hello {
requires jdk.compiler;
}
无论如何,我可以通过提供 Hello.java
的完整路径来解决您的问题,如下所示。这适用于 Windows;如果你使用任何其他 OS,那么你应该使用 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
)。请记住通过在必要时附加到目录来包含任何包。
//以下是Hello.java文件.
public class Hello{
public static void main(String... s){
System.out.println("hello world");
}
}
我正在尝试使用 Java 编译器 API 编译上面的 class,如下所示:
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);
}
}
在执行调用Java编译器class时(使用JDK 9),它在[=48处抛出java.lang.NullPointerException =] 方法。我无法理解为什么它在有字符串类型参数时抛出异常?
这是我在执行它时得到的堆栈跟踪:
Exception in thread "main" java.lang.NullPointerException
at CallingJavaCompiler.main(CallingJavaCompiler.java:5)
另一方面,执行相同的程序,即在 JDK 8 中调用 Java 编译器,它正在执行 而没有任何 运行时间异常.
请帮助我理解为什么当我使用 JDK 9 执行它时会抛出空指针异常 (NPE)?
注意: 我正在使用 javac 9.0.4 编译以上代码,并使用 java 版本 9.0.4 执行它。在使用这些版本编译和执行时,我得到了 NPE,但没有使用 JDK 8.
将 Hello.java 替换为 Hello.java 文件的完整路径(例如 C:\Test\Hello.java)。无论如何,即使 Hello.java 的路径错误,我也没有得到 NullPointerException。
更新
我能够重现您的 java.lang.NullPointerException 错误。它出现在 运行 使用 JRE 而不是 JDK 连接程序时。这样,找不到编译器,因为编译器仅在 JDK 版本中可用。
更新2
所以您正在使用命令行 运行 程序。
使用 %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
的文档:
This implementation returns the compiler provided by the jdk.compiler module if that module is available, and null otherwise.
我怀疑您的 jdk.compiler
模块由于某种原因不可用(您可能 运行 使用 JRE 9 而不是 JDK 9 的程序),因此您会收到一个NullPointerException
。可以肯定的是,我建议将它添加到您的 module-info.java
,即使它似乎不是必需的。
module Hello {
requires jdk.compiler;
}
无论如何,我可以通过提供 Hello.java
的完整路径来解决您的问题,如下所示。这适用于 Windows;如果你使用任何其他 OS,那么你应该使用 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
)。请记住通过在必要时附加到目录来包含任何包。