在 Java 中读取属性文件时出现 NullPointerException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3139532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:47:12  来源:igfitidea点击:

NullPointerException when reading a properties file in Java

javanullpointerexceptioninputstream

提问by udy

I am using the following code to read a properties file:

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

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

pro.load(is);

And when I execute the code I'm getting the following error:

当我执行代码时,我收到以下错误:

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)

Why am I getting a NullPointerException? And where should I save the resources.propertiesfile?

为什么我得到一个NullPointerException?我应该在哪里保存resources.properties文件?

回答by polygenelubricants

It looks like ClassLoader.getResourceAsStream(String name)returns null, which then causes Properties.loadto throw NullPointerException.

它看起来像ClassLoader.getResourceAsStream(String name)return null,然后导致Properties.loadthrow NullPointerException

Here's an excerpt from documentation:

这是文档的摘录:

URL getResource(String name): Finds the resource with the given name. A resource is some data (images, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code.

The name of a resource is a '/'-separated path name that identifies the resource.

Returns:A URLobject for reading the resource, or nullif:

  • the resource could not be found, or
  • the invoker doesn't have adequate privileges to get the resource.

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

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

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

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

See also

也可以看看

回答by Favonius

Well it depends; As per javadoc ... The context ClassLoader is provided by the creator of the thread for use by code running in this thread when loading classes and resources. If not set, the default is the ClassLoader context of the parent Thread. The context ClassLoader of the primordial thread is typically set to the class loader used to load the application...

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

So if Thread.currentThread().getContextClassLoader()is in the main() function and you haven't created any thread then it should have the same package as that of the class containing method main. Otherwise it should be present in the class which has created the thread....

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

回答by Andreas Dolk

Bugfixing is easier if you write more lines, like:

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

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!
}

回答by mekbib.awoke

I had the same problem and was quite confused as I used it previously in a Sturtsapplication. But the problem was that I didn't understand the type of ClassLoader that Strutsreturns is different than what Springreturns. And the way i figured it out was i printed out the object that was returned on to the system console like this:

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

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

[
WebappClassLoader
context: /MyProject
delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
org.apache.catalina.loader.StandardClassLoader@1004901
]

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

It gave me the detail of the object, and in that I found its type to be of WebAppClassLoaderwhich will start looking for files in the WEB-INF/classes/ folder after a build is done. So I went into the that folder and looked for where my file is located so I gave the path accordingly.

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

In my case it was located in /WEB-INF/classes/META-INF/spring/filename.extension

就我而言,它位于 /WEB-INF/classes/META-INF/spring/filename.extension

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

Voilà!

瞧!

That fixed it all.

这一切都解决了。

回答by Black_Zerg

In my situatioan I get NullPointerException in this code

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

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

I changed

我变了

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

and now works ok!

现在工作正常!

回答by user2967084

I had the same problem and I have resolved by doing the following

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

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

and then put "resources.properties" file under that path.

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

回答by Avi Flax

I had this problem with a third-party program and it turned out that I needed to include .in the classpath so that the program could read a local properties file in the current working directory.

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

回答by Ajay Menon

Many seem to have this problem and like me they give up after sometime. Here is what I had to get this working. The trick here to use relative path for file lookup is to make sure your classes folder contains resources filesalong with src files. Here is what I ended up doing.

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

1) If you are using eclipse make sure you proper .classpath setting present and do PROJECT CLEANto see the resources files get generated under /classes. Notice the classpath-entries below for resource files place under src/main/resource

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) If you are using maven as well make sure you configure your pom.xml as per the https://maven.apache.org/guides/introduction/introduction-to-the-pom.htmland do mvn clean install to see the files under target/classes

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

3) Once you have got the resource files under /classes the next thing to do in java is the following. Don't forget to have the forward slash.

3) 在 /classes 下获得资源文件后,接下来在 java 中要做的事情如下。不要忘记有正斜杠。

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

I could have added some images but did not have points. :)

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

回答by Surajit Biswas

Perhaps, I have plucked all my hairs out and going then I have found this solution out:

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

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();
        }

回答by Ruslan Omelchenko

I had the same problem and this helped me:

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

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();
}