【问题标题】:NullPointerException when reading a properties file in Java在 Java 中读取属性文件时出现 NullPointerException
【发布时间】:2020-04-11 20:18:12
【问题描述】:

我正在使用以下代码来读取属性文件:

Properties pro = new Properties();
InputStream is = Thread.currentThread().getContextClassLoader().
    getResourceAsStream("resources.properties");

pro.load(is);

当我执行代码时,出现以下错误:

Exception in thread "main" java.lang.NullPointerException
  at java.util.Properties$LineReader.readLine(Properties.java:418)
  at java.util.Properties.load0(Properties.java:337)
  at java.util.Properties.load(Properties.java:325)
  at com.ibm.rqm.integration.RQMUrlUtility.RQMRestClient.getResource(RQMRestClient.java:66)
  at com.ibm.rqm.integration.RQMUrlUtility.RQMRestClient.main(RQMRestClient.java:50)

为什么我会收到NullPointerException?我应该将resources.properties 文件保存在哪里?

【问题讨论】:

    标签: java nullpointerexception inputstream


    【解决方案1】:

    看起来ClassLoader.getResourceAsStream(String name) 返回null,然后导致Properties.load 抛出NullPointerException

    这是文档的摘录:

    URL getResource(String name):查找具有给定名称的资源。资源是可以通过类代码以独立于代码位置的方式访问的一些数据(图像、音频、文本等)。

    资源的名称是一个以'/' 分隔的路径名,用于标识该资源。

    返回: 用于读取资源的URL 对象,或null 如果:

    • 找不到资源,或者
    • 调用者没有足够的权限来获取资源。

    另见

    【讨论】:

    • 我应该把属性文件放在哪里?
    • 是的,我检查过了,那么属性文件应该在哪里?它现在在同一个项目中。
    • @udy:你能先通过简单的检查/调试会话确认isnull 吗?
    • 是的,它为空,我已经检查过了,但没有找到放置属性文件的位置。 ?
    • @udy:您能否编辑问题并添加有关您正在使用的 IDE、当前放置属性文件的位置以及如何运行项目等的更多信息?
    【解决方案2】:

    如果您编写更多行,则更容易修复错误,例如:

    Properties properties = new Properties();
    Thread currentThread = Thread.currentThread();
    ClassLoader contextClassLoader = currentThread.getContextClassLoader();
    InputStream propertiesStream = contextClassLoader.getResourceAsStream("resource.properties");
    if (propertiesStream != null) {
      properties.load(propertiesStream);
      // TODO close the stream
    } else {
      // Properties file not found!
    }
    

    【讨论】:

    • 好的,我明白了。感谢您的回复。
    • 哦,谢谢,谢谢,这终于对我有用了!我之前尝试了许多非常相似的代码(用于在 jar 中运行),我已经完全绝望了。
    【解决方案3】:

    我遇到了同样的问题,并且很困惑,因为我以前在 Sturts 应用程序中使用它。但问题是我不明白 Struts 返回的 ClassLoader 类型与 Spring 返回的不同。我想出来的方法是我打印出返回到系统控制台的对象,如下所示:

    System.out.println(Thread.currentThread().getContextClassLoader());
    

    [
    WebappClassLoader
    上下文:/MyProject
    委托:假
    存储库:
    /WEB-INF/类/
    ----------> 父类加载器:
    org.apache.catalina.loader.StandardClassLoader@1004901
    ]

    它给了我对象的详细信息,我发现它的类型是 WebAppClassLoader,它会在构建完成后开始在 WEB-INF/classes/ 文件夹中查找文件.所以我进入那个文件夹并寻找我的文件所在的位置,所以我给出了相应的路径。

    在我的例子中,它位于 /WEB-INF/classes/META-INF/spring/filename.extension

    InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/spring/filename.extension");
    

    瞧!

    这一切都解决了。

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题,我已经通过执行以下操作解决了

      1. File file = new File("resources.properties");
      2. System.out.println(file.getAbsolutePath());

      然后将“resources.properties”文件放在该路径下。

      【讨论】:

        【解决方案5】:

        如果它在 eclipse 中清理项目,如果它是 intellij 重建项目,它应该开始工作

        【讨论】:

        • 谢谢。我正在使用 intellij 并右键单击顶层 -> 重建工作。
        【解决方案6】:

        这取决于;根据 javadoc ... 上下文 ClassLoader 由线程的创建者提供,供在该线程中运行的代码在加载类和资源时使用。如果未设置,则默认为父线程的 ClassLoader 上下文。原始线程的上下文 ClassLoader 通常设置为用于加载应用程序的类加载器...

        因此,如果Thread.currentThread().getContextClassLoader() 在 main() 函数中并且您还没有创建任何线程,那么它应该与包含方法 main 的类具有相同的包。否则它应该出现在创建线程的类中......

        【讨论】:

        • 它应该具有与main()相同的类加载器
        【解决方案7】:

        我在使用第三方程序时遇到了这个问题,结果我需要在类路径中包含.,以便程序可以读取当前工作目录中的本地属性文件。

        【讨论】:

          【解决方案8】:

          很多人似乎有这个问题,像我一样,他们在一段时间后放弃了。这是我必须让这个工作。此处使用相对路径进行文件查找的技巧是确保您的 classes 文件夹包含资源文件 以及 src 文件。这就是我最终要做的。

          1) 如果您使用 Eclipse,请确保您存在正确的 .classpath 设置并执行 PROJECT CLEAN 以查看在 /classes 下生成的资源文件。注意下面的资源文件的类路径条目放在 src/main/resource 下

          <?xml version="1.0" encoding="UTF-8"?>
          <classpath>
              <classpathentry including="**/*.java" kind="src" output="target/test-classes" path="src/test/java"/>
              <classpathentry including="**/*.java" kind="src" path="src/main/java"/>
              <classpathentry kind="var" path="M2_REPO/javax/mail/mail/1.4.4/mail-1.4.4.jar"/>
              <classpathentry kind="var" path="M2_REPO/javax/activation/activation/1.1/activation-1.1.jar"/>
              <classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
              <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
              <classpathentry kind="output" path="target/classes"/>
          </classpath>
          

          2) 如果您也使用 maven,请确保按照 https://maven.apache.org/guides/introduction/introduction-to-the-pom.html 配置 pom.xml 并执行 mvn clean install 以查看目标/类下的文件

          3) 一旦你在 /classes 下获得了资源文件,接下来在 java 中要做的事情如下。不要忘记使用正斜杠。

          try {
                      properties.load(getClass().getResourceAsStream("/mail-config.properties"));
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
          

          我可以添加一些图像,但没有积分。 :)

          【讨论】:

            【解决方案9】:

            也许,我已经把所有的头发都拔掉了,然后我找到了这个解决方案:

            Properties dbParamProperties = new Properties();
                     InputStream input = null;
                    try {
            
                        String pathOfAbsolute = this.getClass().getProtectionDomain().getCodeSource().getLocation().toString();
                        String propertiesFilePath = pathOfAbsolute+"/properties/conf.properties";
                        propertiesFilePath = propertiesFilePath.replace("file:/", "").replace("/", "\\");
                       System.out.println(pathOfAbsolute);
                       System.out.println(propertiesFilePath);
                       Paths.get(new URI(pathOfAbsolute));
                         input =  ClassLoader.getSystemResourceAsStream(propertiesFilePath);
                       input = new FileInputStream(propertiesFilePath);
                       dbParamProperties.load( input );
                       dbUID =  dbParamProperties.getProperty("userName");
                       dbURL =  dbParamProperties.getProperty("hosturl");
                       dbPWD =  dbParamProperties.getProperty("password");
                       dbPort = dbParamProperties.getProperty("port");
                       dbSID =  dbParamProperties.getProperty("servicenameorsid");
            
            
                    } catch (IOException e) {
            
                        e.printStackTrace();
                    }
                    catch(Exception ex){
                        ex.printStackTrace();
                    }
            

            【讨论】:

              【解决方案10】:

              我遇到了同样的问题,这对我有帮助:

              InputStream is;
              try {
              
                  is = this.getClass().getClassLoader().getResourceAsStream("config.properties");
              
                  prop.load(is);
              
                  String url = prop.getProperty("url");
                  String user = prop.getProperty("user");
                  String pass = prop.getProperty("password");
                  is.close();
                  // opening database connection to MySQL server
                  con = DriverManager.getConnection(url, user, pass);
              
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              } catch (IOException e) {
                  e.printStackTrace();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
              

              【讨论】:

              • 它对你有什么帮助?
              【解决方案11】:

              在我的情况下,我在这段代码中得到 NullPointerException

              LogManager.getLogManager()
                    .readConfiguration(MyClass.class.getResourceAsStream("config/logging.properties"));
              

              我变了

              LogManager.getLogManager().readConfiguration(AzLotteryTerm.class.getClassLoader().getResourceAsStream("config/logging.properties"));
              

              现在可以正常工作了!

              【讨论】:

              • 您的第一个示例不起作用,因为 MyClass 的包名称将自动添加到资源路径之前,除非您确保它以 / 开头。看here
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-05-04
              • 2013-04-11
              • 2018-05-31
              • 2019-03-27
              • 1970-01-01
              相关资源
              最近更新 更多