My program read configuration data by reading xml file fro current directory:
File fXmlFile = new File("configFile.xml");
It works fine in NetBeans IDE. I have build project and got jar file. It runs fine if I double click on it in Windows 10. In case I open file by using right click on jar and Open with -> Java program can't find configuration file. In this case I got exception:
java.io.FileNotFoundException: C:\Windows\System32\configFile.xml (The system cannot find the file specified)
Why it looks just to system path and not in current directory? How to ask program to load file in current directory when running in Open with -> Java case?
Jar's manifest file:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.10.4
Created-By: 12.0.1+12 (Oracle Corporation)
Class-Path: lib/log4j-api-2.11.2.jar lib/log4j-core-2.11.2.jar lib/met
ouia.jar lib/swt.jar
X-COMMENT: Main-Class will be added automatically by build
Main-Class: com.aaa.myprog.runMe
The current directory is, as Victor already pointed out, dependent on the command that is used to launch the JVM and therefore dynamic at runtime. You instead need a locator that is dependent on the location on the jar file itself, meaning it is dynamic at compile time but static at runtime.
There are different approaches here, so let me shortly introduce two:
Use a launcher script
This way you simply take control of the command line yourself, but you have to do it for every operating system where you plan to use your program. On Windows it could look like this:
app.bat:
cd %~dp0
java -jar app.jar
More information on the first line here.
Use System ClassLoader
This works, because the System ClassLoader's sources are dynamic at compile time but static at runtime, so exactly what you need. However, it comes with the downside that you cannot write to the configuration file, as you only get an InputStream.
app.jar
try (InputStream fXml = ClassLoader.getSystemClassLoader().getResourceAsStream("configFile.xml")) {
...
}
And a full MCVE.
ConfigFile.java:
public class ConfigFile {
public static void main(String[] args) {
try (final BufferedReader configFile = new BufferedReader(
new InputStreamReader(ClassLoader.getSystemClassLoader()
.getResourceAsStream("configFile.txt")))) {
System.out.println(configFile.readLine());
} catch (final IOException exc) {
exc.printStackTrace();
}
}
}
ConfigFile.txt
Hello World
MANIFEST.MF
Manifest-Version: 1.0
Class-Path: .
Main-Class: prv.izruo.test.ConfigFile
command line
P:\workspace\ConfigFile>dir deploy
...
02.05.2019 20:43 1.434 configFile.jar
02.05.2019 20:43 11 configFile.txt
P:\workspace\ConfigFile>java -jar deploy\configFile.jar
Hello World
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With