プロパティファイルを読み取るために次のコードを使用しています。
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
ファイル?
ClassLoader.getResourceAsStream(String name)
はnull
を返し、_Properties.load
_がNullPointerException
をスローするように見えます。
ドキュメントからの抜粋です:
URL getResource(String name)
:指定された名前のリソースを検索します。リソースは、コードの場所に依存しない方法でクラスコードからアクセスできるデータ(画像、オーディオ、テキストなど)です。リソースの名前は、リソースを識別する_
'/'
_で区切られたパス名です。戻り値:リソースを読み取るための
URL
オブジェクト、またはnull
の場合:
- リソースが見つからなかった、または
- 呼び出し側には、リソースを取得するための十分な特権がありません。
getResource
を使用したイメージのロード次のようにより多くの行を書くと、バグ修正が簡単になります。
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!
}
同じ問題があり、以前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");
それですべてが直った。
私は同じ問題を抱えていて、私は次のようにして解決しました
File file = new File("resources.properties");
System.out.println(file.getAbsolutePath());
そして、そのパスの下に「resources.properties」ファイルを置きます。
多くの人がこの問題を抱えているようで、私のように彼らはしばらくしてあきらめます。これが私がこれを機能させるために必要だったものです。ここでファイル検索に相対パスを使用する秘訣は、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();
}
画像を追加することもできましたが、ポイントがありませんでした。 :)
まあそれは依存します。 javadocのとおり... コンテキストClassLoaderは、クラスおよびリソースをロードするときにこのスレッドで実行されるコードが使用するためにスレッドの作成者によって提供されます。設定されていない場合、デフォルトは親スレッドのClassLoaderコンテキストです。原始スレッドのコンテキストClassLoaderは、通常、アプリケーションのロードに使用されるクラスローダーに設定されます...
したがって、Thread.currentThread().getContextClassLoader()
がmain()関数内にあり、スレッドを作成していない場合は、メソッドmainを含むクラスと同じパッケージを持つ必要があります。それ以外の場合は、スレッドを作成したクラスに存在する必要があります。
おそらく、私はすべての髪の毛を抜いて、それからこの解決策を見つけました:
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();
}
サードパーティのプログラムでこの問題があり、プログラムが現在の作業ディレクトリにあるローカルプロパティファイルを読み取ることができるように、クラスパスに.
を含める必要があることがわかりました。
私は同じ問題を抱えていて、これが私を助けました:
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();
}