Read properties file outside JAR file
So, you want to treat your .properties
file on the same folder as the main/runnable jar as a file rather than as a resource of the main/runnable jar. In that case, my own solution is as follows:
First thing first: your program file architecture shall be like this (assuming your main program is main.jar and its main properties file is main.properties):
./ - the root of your program
|__ main.jar
|__ main.properties
With this architecture, you can modify any property in the main.properties file using any text editor before or while your main.jar is running (depending on the current state of the program) since it is just a text-based file. For example, your main.properties file may contain:
app.version=1.0.0.0
app.name=Hello
So, when you run your main program from its root/base folder, normally you will run it like this:
java -jar ./main.jar
or, straight away:
java -jar main.jar
In your main.jar, you need to create a few utility methods for every property found in your main.properties file; let say the app.version
property will have getAppVersion()
method as follows:
/**
* Gets the app.version property value from
* the ./main.properties file of the base folder
*
* @return app.version string
* @throws IOException
*/
import java.util.Properties;
public static String getAppVersion() throws IOException{
String versionString = null;
//to load application's properties, we use this class
Properties mainProperties = new Properties();
FileInputStream file;
//the base folder is ./, the root of the main.properties file
String path = "./main.properties";
//load the file handle for main.properties
file = new FileInputStream(path);
//load all the properties from this file
mainProperties.load(file);
//we have loaded the properties, so close the file handle
file.close();
//retrieve the property we are intrested, the app.version
versionString = mainProperties.getProperty("app.version");
return versionString;
}
In any part of the main program that needs the app.version
value, we call its method as follows:
String version = null;
try{
version = getAppVersion();
}
catch (IOException ioe){
ioe.printStackTrace();
}
How a JAR file can read an external properties file
http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html
multiple approaches are available, the article above provides more details
ClassLoader.getResourceAsStream ("some/pkg/resource.properties");
Class.getResourceAsStream ("/some/pkg/resource.properties");
ResourceBundle.getBundle ("some.pkg.resource");
Spring boot how to read properties file outside jar
I'm a bit confused by the title of the question and the description. Hopefully I won't confuse you even more with my comments.
In general, Spring Boot is VERY opiniated about project structure as well as the binary created. The recomended way (Spring Boot opinion) is to build a jar with all dependencies inside (fat jar). If you need configuration properties defined outside your fat jar (or war if that's what you built), Spring Boot offers many options (see reference 1). I like my apps to point to an external file using the flag (spring.config.location) which can be set with a system property:
java -jar -Dspring.config.location=<path-to-file> myBootProject.jar
Notice that you can do something similar by using an environment variable to define where your external file lives.
I hope this helps!
References:
1. https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
External properties file for an executable jar
You can add an external properties file next to the .jar provided that you call it application.properties
.
If you cannot rename the properties file, you can also give the path of the external properties file as an option :
java -jar myproject.jar --spring.config.location=/path/to/batch.properties
#Or for executable jars
./myproject.jar --spring.config.location=/path/to/batch.properties
You can also create a symlink application.properties
-> batch.properties
.
See Externalized configuration.
EDIT
This is my maven config :
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.3.3.RELEASE</version>
<configuration>
<executable>true</executable>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
After mvn clean install, I get 2 jars :
backend/target [ ll
total 53M
-rwxr--r-- 1 adenoyelle adenoyelle 53M avril 22 10:56 backend-1.0-SNAPSHOT.jar
-rw-r--r-- 1 adenoyelle adenoyelle 353K avril 22 10:56 backend-1.0-SNAPSHOT.jar.original
Then, I copy the first jar to the destination folder and place a configuration.properties
next to it :
backend@[...]:~/backend$ ll
total 53900
drwxrwxr-x 2 backend backend 4096 Apr 21 13:56 ./
drwxr-xr-x 6 backend backend 4096 Apr 21 13:56 ../
-rw-rw-r-- 1 backend backend 511 Apr 20 16:13 application.properties
-rwxr--r-- 1 backend backend 55175294 Apr 20 19:06 backend-1.0-SNAPSHOT.jar*
lrwxrwxrwx 1 backend backend 24 Apr 20 19:20 backend -> backend-1.0-SNAPSHOT.jar*
-rw-r--r-- 1 backend backend 179 Apr 20 19:26 backend.service
You can see that I also created a file called backend.service
in order to install the jar as a service via systemd
.
Here is the content of the file :
[Unit]
Description=backend
After=syslog.target
[Service]
User=backend
ExecStart=/home/backend/backend
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
And there is a symlink to this file in /etc/systemd/system
:
backend@[...]:/etc/systemd/system$ ll | grep backend
lrwxrwxrwx 1 root root 37 Apr 20 19:23 backend.service -> /home/backend/backend.service
External Jar file import with property
Add the property file to the class path, and keep it externally. Many libraries use property files to configure themselves. For example, logback and log4j do.
java -cp propertyfile
Use the -cp parameter when launching the program. Refer to the documentation of the external library you are using for more information.
How to read properties file from external jar in maven project
There are numerous ways to do this.
Assuming your xyz.properties
file looks like this:
a=b
y=z
mykey=myvalue
Using java.util.ResourceBundle
If you don't need to pass around the read data as a Properties
object, this is the easiest way.
ResourceBundle rb = ResourceBundle.getBundle("xyz");
System.out.println("a=" + rb.getString("a"));
Using java.util.Properties
A bit more work and some boiler-plate, but accomplishes the same thing.
Properties p = new Properties();
try (InputStream is = getClass().getClassLoader().getResourceAsStream("xyz.properties")) {
p.load(is);
}
catch (IOException e) {
// Handle as appropriately.
}
System.out.println("mykey=" + p.getProperty("mykey"));
Related Topics
Printing a Statement Only Once in a While Loop
Java Coding Converted to Pseudo Code
Field Required a Bean Which Could Not Be Found in Springboot
Javax.Validation - Allow Null But Validate If the Value Is Not
How to Mock a Generic Parameter for a Unit Test in Java
Admob No Fill from Ad Server - Failed to Load Ad: 3
Counting Unique Characters in a String
Launch New Activity from Fragment in Android Studio
Largest and Smallest Integer - Exercise from Deitel'S Java Book
Passing Multiple Variables in @Requestbody to a Spring MVC Controller Using Ajax
How to Create Unique Column With Jpa
Could Not Extract Resultset in Hibernate
Checking If a String Contains Only Digits (Isdigitmethod Required)
Junit 5 - No Parameterresolver Registered for Parameter
How to View Apache Parquet File in Windows
Include Comma in a Field Value of CSV (Delimeter as Comma) in Java