使用Scanner从打包的jar中读取大文件作为资源时的NullPointer

时间:2018-01-29 05:04:51

标签: java jar

我使用的是Mac OSX 10.12.6

该程序侦听网络上的Tcp请求,读取XML请求并使用XML进行响应。

当我通过命令行运行该程序时:

  

java -classpath target / classes / com.mycompany.ocip.server.OCIServer

运行正常并响应所有XML请求。

但是,当我将其作为jar文件运行时:

  

java -jar target / ocip-server-jar-with-dependencies.jar

我得到一个例外:

  

java.lang.NullPointerException:source       at java.util.Objects.requireNonNull(Objects.java:228)       在java.util.Scanner。(Scanner.java:578)       在com.mycompany.ocip.server.OCIProtocol.readFile(OCIProtocol.java:56)       在com.mycompany.ocip.server.OCIProtocol.processInput(OCIProtocol.java:31)       在com.mycompany.ocip.server.OCIServer.main(OCIServer.java:85)

需要发送大量响应时。

异常所涉及的行是在代码中读取要在响应中发送的XML文件:(来自OCIProtocol.java,如果相关的话)

public String readFile(String filename) throws IOException {
    InputStream inputStream = this.getClass().getResourceAsStream(filename);
    Scanner scanner = new Scanner(inputStream, "UTF-8"); // <-- exception
    scanner.useDelimiter("\\A");
    String text = scanner.hasNext() ? scanner.next() : "";
    scanner.close();
    return text;
}

奇怪的是这个例外:

  1. 仅在作为jar文件运行时发生
  2. 仅在从类路径中读取“大”xml文件时发生,例如25MB(几个较小的文件成功)
  3. 我已经尝试过几十次了。

    运行程序并将类路径设置为目标// classes文件夹

    时,不会发生异常

    什么可能导致这种行为?

    编辑: 按要求:tar输出: 请注意,服务器发送的所有其他XML文件没有问题,除了examples/ServiceProviderDnGetSummaryListResponse-Client1.xml,(可能相关:此文件为25MB,其他文件为较小文件)

    user$ tar -tf target/ocip-server-jar-with-dependencies.jar
    META-INF/
    META-INF/MANIFEST.MF
    com/
    com/mycompany/
    com/mycompany/ocip/
    com/mycompany/ocip/server/
    examples/
    META-INF/maven/
    META-INF/maven/bw-ocip-server/
    META-INF/maven/bw-ocip-server/bw-ocip-server/
    META-INF/maven/com.mycompany/
    META-INF/maven/com.mycompany/bw-ocip-server/
    com/mycompany/ocip/server/OCIProtocol.class
    com/mycompany/ocip/server/OCIServer.class
    examples/AuthenticationResponse.xml
    examples/GroupDnGetActivationListResponse.xml
    examples/LoginResponse.xml
    examples/LogoutResponse.xml
    examples/ServiceProviderCommunicationBarringCriteriaAssignListRequest.xml
    examples/ServiceProviderCommunicationBarringCriteriaAssignListResponse.xml
    examples/ServiceProviderCommunicationBarringCriteriaGetAssignedListRequest.xml
    examples/ServiceProviderCommunicationBarringCriteriaGetAssignedListResponse.xml
    examples/ServiceProviderCommunicationBarringProfileGetResponse-NoSMP.xml
    examples/ServiceProviderCommunicationBarringProfileGetResponse.xml
    examples/ServiceProviderDnGetSummaryListResponse-Client1.xml
    examples/ServiceProviderDnGetSummaryListResponse-NoSP.xml
    examples/ServiceProviderDnGetSummaryListResponse.xml
    examples/ServiceProviderDnGetSummaryListResponse2.xml
    examples/ServiceProviderDnGetSummaryListResponse3.xml
    examples/ServiceProviderDnGetSummaryListResponse4.xml
    examples/ServiceProviderDnGetSummaryListResponse5.xml
    examples/ServiceProviderGetListResponse.xml
    examples/SystemCommunicationBarringCriteriaGetListRequest.xml    
    examples/SystemCommunicationBarringCriteriaGetListResponse.xml
    examples/UserGetListInGroupResponse.xml
    META-INF/maven/bw-ocip-server/bw-ocip-server/pom.properties
    META-INF/maven/bw-ocip-server/bw-ocip-server/pom.xml
    META-INF/maven/com.mycompany/bw-ocip-server/pom.properties
    META-INF/maven/com.mycompany/bw-ocip-server/pom.xml
    

    对readFile的调用如下:

    public String processInput(String theInput) throws IOException {
    
       String theOutput = "";
    
      if (theInput.contains("LoginRequest")) {
        theOutput = this.readFile("/examples/LoginResponse.xml");
      } else if (theInput.contains("LogoutRequest")) {
        theOutput = this.readFile("/examples/LogoutResponse.xml");
      } else if (theInput.contains("ServiceProviderDnGetSummaryList")) {
        theOutput = this.readFile("/examples/ServiceProviderDNGetSummaryListResponse-Client1.xml");
      } else if (theInput.contains("UserGetListInGroupRequest")) {
        theOutput = this.readFile("/examples/UserGetListInGroupResponse.xml");
      } else if (theInput.contains("ServiceProviderCommunicationBarringProfileGetRequest")) {
        theOutput = this.readFile("/examples/ServiceProviderCommunicationBarringProfileGetResponse.xml");
      } else if (theInput.contains("ServiceProviderCommunicationBarringCriteriaAssignListRequest")) {
        theOutput = this.readFile("/examples/ServiceProviderCommunicationBarringCriteriaAssignListResponse.xml");
      } else if (theInput.contains("ServiceProviderCommunicationBarringCriteriaGetAssignedListRequest")) {
        theOutput = this.readFile("/examples/ServiceProviderCommunicationBarringCriteriaGetAssignedListResponse.xml");
      } else if (theInput.contains("SystemCommunicationBarringCriteriaGetListRequest")) {
        theOutput = this.readFile("/examples/SystemCommunicationBarringCriteriaGetListResponse.xml");
      } else
        theOutput = this.readFile("/examples/AuthenticationResponse.xml");
    
       return theOutput;
    }
    

1 个答案:

答案 0 :(得分:1)

现在您已经提供了足够的详细信息,这里的问题是JAR文件中的资源区分大小写,而文件系统显然不是。

  

该文件存在于jar文件中,其名称与文件系统

完全相同

不,不是。资源字符串名称和文件名之间存在大小写差异(DN/Dn