web-dev-qa-db-ja.com

Javaでプロパティファイルを読み取るときのNullPointerException

プロパティファイルを読み取るために次のコードを使用しています。

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ファイル?

19
udy

ClassLoader.getResourceAsStream(String name)nullを返し、_Properties.load_がNullPointerExceptionをスローするように見えます。

ドキュメントからの抜粋です:

URL getResource(String name) :指定された名前のリソースを検索します。リソースは、コードの場所に依存しない方法でクラスコードからアクセスできるデータ(画像、オーディオ、テキストなど)です。

リソースの名前は、リソースを識別する_'/'_で区切られたパス名です。

戻り値:リソースを読み取るためのURLオブジェクト、またはnullの場合:

  • リソースが見つからなかった、または
  • 呼び出し側には、リソースを取得するための十分な特権がありません。

こちらもご覧ください

19

次のようにより多くの行を書くと、バグ修正が簡単になります。

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

同じ問題があり、以前Sturtsアプリケーションで使用していたため、かなり混乱しました。しかし、問題はStrutsが返すClassLoaderのタイプがSpringが返すものと異なることを理解していないことでした。そして、私がそれを理解した方法は、次のようにシステムコンソールに返されたオブジェクトを印刷することでした。

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

[
WebappClassLoader
コンテキスト:/ MyProject
代理人:false
リポジトリ:
/WEB-INF/classes /
---------->親クラスローダー:
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");

ほら!

それですべてが直った。

2
mekbib.awoke

私は同じ問題を抱えていて、私は次のようにして解決しました

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

そして、そのパスの下に「resources.properties」ファイルを置きます。

1
user2967084

多くの人がこの問題を抱えているようで、私のように彼らはしばらくしてあきらめます。これが私がこれを機能させるために必要だったものです。ここでファイル検索に相対パスを使用する秘訣は、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も使用している場合は、pom.xmlを https://maven.Apache.org/guides/introduction/introduction-to-the-pom.html のように設定してください。 mvn clean installを実行して、target/classesの下のファイルを確認します

3)/ classesの下にリソースファイルを取得したら、Javaは次のようになります。スラッシュを付けることを忘れないでください。

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

画像を追加することもできましたが、ポイントがありませんでした。 :)

0
Ajay Menon

まあそれは依存します。 javadocのとおり... コンテキストClassLoaderは、クラスおよびリソースをロードするときにこのスレッドで実行されるコードが使用するためにスレッドの作成者によって提供されます。設定されていない場合、デフォルトは親スレッドのClassLoaderコンテキストです。原始スレッドのコンテキストClassLoaderは、通常、アプリケーションのロードに使用されるクラスローダーに設定されます...

したがって、Thread.currentThread().getContextClassLoader()がmain()関数内にあり、スレッドを作成していない場合は、メソッドmainを含むクラスと同じパッケージを持つ必要があります。それ以外の場合は、スレッドを作成したクラスに存在する必要があります。

0
Favonius

おそらく、私はすべての髪の毛を抜いて、それからこの解決策を見つけました:

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

サードパーティのプログラムでこの問題があり、プログラムが現在の作業ディレクトリにあるローカルプロパティファイルを読み取ることができるように、クラスパスに.を含める必要があることがわかりました。

0
Avi Flax

私は同じ問題を抱えていて、これが私を助けました:

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