Reputation: 193
I have a rest server written in java and using gradle as it build system.
In one my class I am using the file src/main/resources/myresource.config as below
public static void main(String[] args) {
String resourcePath = Myapplication.class.getClassLoader().getResource("myresource.config").toURI().getPath();
LOGGER.info(String.format("Loading data from config %s", resourcePath));
BufferedReader br = new BufferedReader(new FileReader(resourcePath));
}
The program works fine when running the class directly from command line or ide.
I am build a jar for my application as below
jar {
manifest {
attributes 'Main-Class': 'com.example.Myapplication',
'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
}
The jar gets build successfully inside build/libs when I try running the jar java -jar myapplication.jar I fails to find the myresource.config resource.
I unzipped the build jar and found that the myresource.config file is present but the jar fails to run.
Things I have tried so far
ClassLoader.getSystemClassLoader().getResource("myresource.config");
Thread.currentThread().getContextClassLoader().getResource("myresource.config")
Can anyone point out what I am doing incorrect?
Stacktrace
INFO: Loading data from config null
Invalid resource: myresource.config
java.lang.NullPointerException
at java.io.FileInputStream.<init>(FileInputStream.java:130)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at java.io.FileReader.<init>(FileReader.java:58)
at com.example.Myapplication.<main>(Myapplication.java:26)
Upvotes: 1
Views: 337
Reputation: 10972
The problem is that, when running the application from the IDE myresource.config
is read directly from the file system. That is you get a regular file URL:
URL configUrl = Myapplication.class.getClassLoader().getResource("myresource.config");
// returns "file:/C:/path/to/project/bin/main/myresource.config"
But when you execute the application from the jar file, the config file is read from the jar and you get a jar based URL:
URL configUrl = Myapplication.class.getClassLoader().getResource("myresource.config");
// returns "jar:file:/C:/path/to/project/build/libs/myapplication.jar!/myresource.config"
This second jar-based URL cannot be converted to a filesystem path and that is why you get null
.
To get the config in both scenarios, you should do something like this
try (final InputStream configInputStream = Myapplication.class.getClassLoader().getResourceAsStream("myresource.config");
final BufferedReader br = new BufferedReader(new InputStreamReader(configInputStream));) {
// do something with br
}
Upvotes: 2
Reputation: 399
I think you must use getResourceAsStream instead.
Myapplication.class.getResourceAsStream("myresource.config")
Upvotes: 0