Reputation: 346
I'm building my jar-file with maven, they include all dependencies, so i can run the jars via
java -jar
Inside the jar I have a config.json which is the the app-configuration. I verified that config.json is really inside the jar:
/> jar tf cloudimport-0.1-jar-with-dependencies.jar | grep config.json
config.json
But when I run the application it won't find the config.json:
ClassLoader classLoader = getClass().getClassLoader();
System.out.println(classLoader.getResource("config.json"));
File configFile = new File(classLoader.getResource(fileName).getFile());
(Exception thrown here ->) FileReader fileReader = new FileReader(configFile);
BufferedReader br = new BufferedReader(fileReader);
produces:
java -jar cloudimport-0.1-jar-with-dependencies.jar
jar:file:/home/ubuntu/cloudimport-0.1-jar-with-dependencies.jar!/config.json
java.io.FileNotFoundException: file:/home/ubuntu/cloudimport-0.1-jar-with-dependencies.jar!/config.json (No such file or directory)
The Class that runs the above code is located in the jar at:
com.test.cloudsync.config.AppConfig.class
If I run the app from intelliJ in windows, it works properly, but execution from intelliJ means that the Main Class is executed not the jar.
I have already searched for this but answers like: What is the difference between Class.getResource() and ClassLoader.getResource()?
didn't help...
// EDIT The suggestion was that the Excpetion wasn't throwed by the ClassLoader - this is true. I removed some stuff so I could limit the scope, now it seems like the problem is that I try to open a FileINputStream but this is not possible I guess if the file is withing a jar?
The Full Stack Trace:
/> java -jar java_cloudsync/com/tsg/cloudimport/cloudimport/0.1/cloudimport-0.1-jar-with-dependencies.jar
jar:file:/home/ubuntu/java_cloudsync/com/tsg/cloudimport/cloudimport/0.1/cloudimport-0.1-jar-with-dependencies.jar!/config.json
java.io.FileNotFoundException: file:/home/ubuntu/java_cloudsync/com/tsg/cloudimport/cloudimport/0.1/cloudimport-0.1-jar-with-dependencies.jar!/config.json (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileReader.<init>(FileReader.java:72)
at com.tsg.cloudsync.config.AppConfig.readConfigFile(AppConfig.java:33)
at com.tsg.cloudsync.config.AppConfig.<init>(AppConfig.java:23)
at com.tsg.cloudsync.awsutils.SQSSocket.<init>(SQSSocket.java:34)
at com.tsg.cloudsync.awsutils.SQSSocket.<clinit>(SQSSocket.java:19)
at com.tsg.cloudsync.NewFileWatchDog.main(NewFileWatchDog.java:24)
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.tsg.cloudsync.NewFileWatchDog.main(NewFileWatchDog.java:24)
Caused by: java.lang.NullPointerException
at com.tsg.cloudsync.config.AppConfig.getAWSCredentials(AppConfig.java:50)
at com.tsg.cloudsync.awsutils.SQSSocket.<init>(SQSSocket.java:35)
at com.tsg.cloudsync.awsutils.SQSSocket.<clinit>(SQSSocket.java:19)
... 1 more
Upvotes: 2
Views: 2822
Reputation: 346
So it turned out that I was trying to define a
ClassLoader classLoader = getClass().getClassLoader();
File f = new File(classLoader.getResource(fileName).getFile())
FileReader fileReader = new FileReader(configFile);
BufferedReader br = new BufferedReader(fileReader);
Which is not possible, since the jar itself is a File. So instead to get the Contents of a file do:
ClassLoader classLoader = getClass().getClassLoader();
InputStream in = classLoader.getResourceAsStream(fileName);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
Also refer to here: Reading a resource file from within jar
Notice the difference getResourceAsStream(fileName)
and getResource(fileName).getFile()
Thanks for pointing me to the right direction!
Upvotes: 1
Reputation: 22973
Assume following simple structure
bin/
src/AppConfig.java
src/config.json
src/manifest.mf
AppConfig.java
package com.test.cloudsync;
public class AppConfig {
void check() {
ClassLoader classLoader = getClass().getClassLoader();
System.out.println(classLoader.getResource("config.json"));
}
public static void main(String[] args) {
new AppConfig().check();
}
}
manifest.mf
Main-Class: com.test.cloudsync.AppConfig
compile and build the Jar file
javac -d bin/ src/*.java
cp src/config.json bin/config.json
jar cfm test.jar src/manifest.mf -C bin/ .
run the Jar
java -jar test.jar
output
jar:file:/tmp/foobar/test.jar!/config.json
This demonstrates that the exception is not raised by the line ClassLoader classLoader = getClass().getClassLoader()
Upvotes: 0