当前位置: 首页 > 知识库问答 >
问题:

接口工具的run()方法在JDK 9中抛出NullPointerException

彭阳荣
2023-03-14

//下面是Hello.java文件。

public class Hello{
    public static void main(String... s){
        System.out.println("hello world");
    }
}

我正在尝试使用Java编译器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);
    }
}

在执行调用Java编译器类(使用 JDK 9)时,它会在运行方法时引发 java.lang.NullPointer 异常。我无法理解为什么当有字符串类型参数时它会引发异常?

这是我在执行它时得到的堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
    at CallingJavaCompiler.main(CallingJavaCompiler.java:5)

另一方面,执行相同的程序,即JDK 8中的CallingJavaCompiler,它在没有任何运行时异常的情况下执行。

请帮助我理解为什么当我使用JDK 9执行它时会抛出空指针异常(NPE)?

注意:我正在使用javac 9.0.4编译上面的代码片段,并使用java版本9.0.4执行它。在使用这些版本编译和执行时,我得到了NPE,但不是JDK 8。

共有2个答案

王才英
2023-03-14

从< code > tool provider # getSystemJavaCompiler 的文档中:

如果jdk.compiler模块可用,则此实现返回该模块提供的编译器,否则返回null。

我怀疑你的jdk。由于某些原因,编译器模块不可用(您可能使用JRE 9而不是JDK 9运行程序),因此您会收到NullPointerException。当然,我建议将其添加到您的模块信息中。java,尽管它似乎不是必需的。

module Hello {
    requires jdk.compiler;
}

无论如何,我能够通过提供Hello.java的完整路径来解决您的问题,如下所示。这适用于视窗;如果您使用任何其他操作系统,则应使用文件分隔符系统.get属性(“文件.分隔符”)而不是 \\

JavaCompiler comp = ToolProvider.getSystemJavaCompiler();

int i = comp.run(System.in, System.out, System.err,"src\\main\\java\\Hello.java");

System.out.println(i);

输出:

0

注意:路径从我的项目的根目录开始(源文件夹< code>src的父文件夹)。记住通过在必要的地方追加目录来包含任何包。

颛孙飞鸾
2023-03-14

将Hello.java替换为Hello.java文件的完整路径(例如C:\Test\Hello.java)。无论如何,即使Hello.java路径错误,我也没有得到NullPointerException。

更新

我能够重现您的 java.lang.空点异常错误。当使用 JRE 而不是 JDK 运行程序时,会出现此错误。这样,找不到编译器,因为编译器仅在 JDK 版本中可用。

更新2

因此,您正在使用命令行来运行程序。

当使用%jdk_home%/bin/java执行时,您使用的是jdk;当使用%jd_home%/jre/bin/java执行时,则使用的是jre。

我看到您使用JDK 9.0.1编译并使用JRE 9.0.4运行。要使其工作,请执行以下操作:

< code>%JDK 9.0.1 home%/bin/java调用JavaCompiler

 类似资料:
  • 最近我遇到了这段代码。 后来,它变成了这个项目的一般惯例。这是否被认为是一种良好的做法?

  • 我读过这段代码,其中接口抛出异常,但实现它的类没有抛出异常或捕获异常,这是为什么?它在java中是合法的还是安全的?

  • 最近我正在学习Java8个特性,所以我从lambda表达式开始,然后我遇到了Java流API,现在我正在尝试围绕流API中的方法,它们是如何工作的? 我对lambda表达式的理解是,如果我们想将lambda表达式传递给该方法,那么我们需要使用单个未实现的方法(Java 8接口可以有默认实现)创建一个与lambda表达式的签名匹配的接口。然后,传递lambda表达式的方法可以通过调用接口方法来执行l

  • 环境安装 python版本的chain3支持python3.5.3及以上的版本。 建议使用虚拟环境进行chain的开发和调用,虚拟环境准备如下 $ which pip || curl https://bootstrap.pypa.io/get-pip.py | python $ which virtualenv || pip install --upgrade virtualenv $ sud

  • 问题内容: 例如,框架/ JDK中的许多方法可能会抛出 但这未在方法签名中指出(因为这是通常保留给检查异常的做法)。我想证明在方法sigs中声明RuntimeExceptions有很多好处(例如类似于静态类型检查)。我喝醉了还是其他? 问题答案: 我不会在签名中声明未经检查的异常,因为它会误导该API的用户。是否必须显式处理该异常不再明显。 在javadoc中声明它是一种更好的方法,因为它允许某人