How a Jar File Can Read an External Properties File

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



Leave a reply



Submit