Accessing executing folder when running a jar file - java

I would like to be able to run a jar file java -jar myapp.jar on different folders and have it load config.properties based on the executing context.
/myapp/myapp.jar
/folder1/config.properties
/folder2/java -jar /myapp/myapp.jar <------ loads /folder1/config.properties
/some/folder2/config.properties
/some/folder2/java -jar /myapp/myapp.jar <------ loads /folder2/config.properties
Once the properties are loaded, I want it to then create some files in the current execution folder.
So:
How do I tell java to load a properties file based on the current executing context?
How do I get access the folder that the jar was executing from?

When you provide a relative path to the constructor of the class File like new File("config.properties"), behind the scene, the absolute path built is
System.getProperty("user.dir") / config.properties
with user.dir that is actually the User working directory which is also the directory from which you launch your command.

Related

How to access outside file from java jar

I have a jar that is reading a file using below code:
Thread.currentThread().getContextClassLoader().getResource(fileName);
I want to run this jar using java -jar .jar command but I want to keep this file outside my jar, so that I can edit the jar file later on without touching the jar. Can anyone help me, how to run this jar so that it will pick up the file from outside.
There are multiple approaches you can do that and it will depend on where would you like to place this external file. For the sake of this answer, I will refer to this file as config file
Not In The Same Directory
The first approach is where you will need to place this file outside the JAR and not necessarily next to the JAR file in the same directory. In that case, you can pass the file location of the config file using either an environment variable (if you are running the JAR in a shell for example) or a Java property.
To use an environment variable, assuming you are using some Linux distro, then you can use the export command to set the value; something like this:
$ export CONFIG_FILE_LOC=/etc/myapp/config.file
You can then read the value in your code using the System class by using the following code:
String fileLocationEnv = System.getenv("CONFIG_FILE_LOC");
Alternatively, you can set this as a property by adding the following segment to your launch command:
$ java -Dconfig.file.location=/etc/myapp/config.file -jar myapp.jar
You can then read the value in your code using the System class for properties using the following code:
String fileLocationProp = System.getProperty("config.file.location");
In The Same Directory
If you need the config file to co-exist in the same directory as your JAR file, then you can use the following code to get the JAR directory and then append the filename to it. Here's the code (assuming a class named MyApp)
try{
new File(MyApp.class.getProtectionDomain().getCodeSource().getLocation().toURI());
} catch(URISyntaxException exception){
System.out.println("Exception");
}
Hope that helps.
To open the file as a resoure, add the folder containing the file(s) you want to use, to your classpath:
java -classpath .;config -jar myjar.jar
This example adds the current directory and the config directory to your classpath.
Multiple folders can be specified by using a separator. On windows use ';' , on unix use ':' .
To open the file as a File, you can just use
new File("configfile")
which will look in the working directory (directory where you launched your java)

How can I dynamically use externalized properties file with Spring jar?

With this setup (from Eclipse using Windows10)
I was able to correctly start my SpringBoot application. This one worked too (same directory pattern):
Now I'm packaging my project as JAR and I want to use an external properties file. I had an teste32.yml file beside my JAR at the same directory (also tried to use it inside /config directory, as show here, but it didn't work either)
I want to dynamically use a properties file beside my JAR file everytime. Doesn't matter at which directory they are, I wanted to dynamically point to a properties file always at the same directory as the JAR is. I want to say to my client: "take this JAR and this file, put them wherever you want and run this command X and everything will be alright". I'm trying to discover command X but before I add some dynamic path, I'm trying with absolutes paths. I'm using this:
java -jar myJar.jar -Dspring.config.name=teste32 -Dspring.config.location=C:\workspace\myProject\target\
I manually copied teste32 inside target\ to test this. But this didn't work. This didn't work either (only spring.config.location variants):
-Dspring.config.location=file:C:\workspace\myProject\target\
-Dspring.config.location=classpath:/
-Dspring.config.location=file:C:/workspace/myProject/target/
I also tried with no spring.config.location, only name
So my questions are:
What does classpath: and file: mean? Until now I got the 2 correct setups by pure luck and I would like to understand when to use them.
When I have my project package as a JAR, what classpath becomes?
Finally, which combination is necessary to dynamically use a properties always at the same directory as the JAR?
UPDATE
Using --debug at the correct example got me this line at the very begging (Spring banner was still visible):
2018-09-25 15:45:14.480 DEBUG 11360 --- [ main] o.s.b.c.c.ConfigFileApplicationListener : Loaded config file 'file:src/main/resources/xirulei/teste32.yml' (file:src/main/resources/xirulei/teste32.yml)
But after moving myJar.jar and teste32.yml to a specific directory and running java -jar myJar.jar -Dspring.config.name=teste32 --debug (without spring.config.location, since teste32 is at the same directory as JAR), I simply didn't get any ConfigFileApplicationListener debug line.
a) java -jar myJar.jar -Dspring.config.name=teste32 -Dspring.config.location=C:\workspace\myProject\target
Did you check content of target dir? I'm pretty sure your cfg file is placed to target\classes\xirulei and it is why Spring cannot find it in target
b) When you place teste32.yml in the same directory as jar file then Spring must be able to find it (given this directory is working directory) without -Dspring.config.location (but you still need to provide -Dspring.config.name=teste32)
c) When you use -jar and do not provide additional class paths then classpath: points to the root of packages inside jar. Spring cannot find your file at classpath:/ because your file is at classpath:/xirulei/
Well, after all it was a simple mistake. As documentation says and as already pointed here, it should be
java -jar myproject.jar --spring.config.name=myproject
and not
java - jar myproject.jar -Dspring.config.name=myproject
As stated on question, only when using Eclipse -D(JVM argument) is necessary. When using bash/cmd, just --(program argument) is the correct option:

Executable Jar with extern properties

I made a java program with a properties file named config.properties.
It works perfectly on Eclipse.
I'm trying to create an executable jar for this programe.
Using the classic method (right click on project, export, executable jar file...) i get a working jar but when i try to edit my config.properties file the changes are not taken in account for the following execution of my jar.
How can I get, on the one hand an executable jar and on the other hand a config.properties file (outside of my Jar) that can be edited by the users to change the parameters of my Jar code ?
Currently my property file is stocked in /src and declared like this :
public static ResourceBundle bundle = ResourceBundle.getBundle("config");
When I need to use one of the properties of this file in my java code I use :
bundle.getString("Car.Color");
Thanks for your help :)
Edit your classpath to include a directory within which your properties file is located. For example:
java -classpath C:\java\MyClasses com.myapp.RunIt

Add external properties file to classpath

My application is packaged into a jar file and is run with the regular "java -jar ..." command.
I have a properties file "myApp.properties" in the directory: /opt/myuser/resources
I want to add the /opt/myuser/resources directory to the classpath. I believe this is advantageous because when the properties files are on the classpath, I can access the properties files in my source code without specifying the full path to the properties files (/opt/myuser/resources/myApp.properties). This way I can keep a properties file with environment-specific properties separate from my application.
I've tried to set the classpath using instructions from Oracle (http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/classpath.html under "Using the JDK tools' -classpath option") like this:
java -cp .:/opt/myuser/resources -jar myApp.jar
but I get an error that the properties file myApp.properties (referenced in the source code) cannot be opened:
Caused by: java.io.FileNotFoundException: class path resource [myApp.properties] cannot be opened because it does not exist
Am I going about this the wrong way? Should I edit the classpath in another way?
Hopefully this will help someone else.
I've used as program arguments for spring boot
--spring.config.location=file:/opt/myuser/resources/myApp.properties
and then it will use that file.
pass this parameter in VM options/environment variables
-Dspring.config.location=/deployments/tomcat/instance-conf/myApp.properties
use gerResource solutions to load file on your Properties Object:
ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
Class.getResourceAsStream ("/some/pkg/resource.properties");
ResourceBundle.getBundle ("some.pkg.resource");

geting error in specifying class path when running program from cmd

I am trying to run program from command prompt
Here is my director structure
In the classes directory i have this structure
In the email folder i have two properties file general-mail-settings.properties and customer-mail-settings.properties
Now when i run the command
D:\vintnes\lasses>java -cp ".;..\dependency-jars\*" com/softech/ls360/integration/BatchImport vintners
Then i get the error that
java.lang.Exception: Email Properties File not found: src\main\resources\email\general-mail-settings.properties (The system cannot find the path specified)
at
...
I tried this to specify path
java -cp ".;..\dependency-jars\*;.\email\*.*" com/softech/ls360/integration/BatchImport customer
But still i am getting the error. I tried ;email\* and \email\*, but still i am getting the error. How can i specify path so program get run?
Thanks
You put a path to src/main/resources in your code somewhere. This is a directory used by Maven builds to hold "resource" files (files that aren't code but that should be copied into the finished artifact, like configuration files or media). The contents of src/main/resources are copied directly into the root of the artifact as-is, so in this case, the email directory is copied straight into your classes directory. Remove the src/main/resources part of the path from your properties lookup.

Categories

Resources