Spring Boot: is it possible to use external application.properties files in arbitrary directories using a thick jar?

Is it possible to have multiple application.properties files? ( EDIT : note that this question has evolved with the one on the title.)

I tried to have 2 files.

  • The first is in the root folder in the Jar application.
  • The second is in the directory specified in the class path.

2 files are called "application.properties".

Is it possible to "merge" the contents of both files? (and the second value of the property overrides the first) Or, if I have one file, then the other file is ignored?

UPDATE 1 : content can be merged. Yesterday it seemed that the first was ignored, but it seems that this is because then something was broken. Now it works well.

UPDATE 2 : he is back! Again, only one of the two files applies. This is weird ... It started after I created the jar application file using the Spring Tool Suite. And it seems that the Jar version always ignores the second (in the classpath), while the behavior of the extended version that runs on STS changes. Where can I start the investigation?

UPDATE 3 :

The behavior of the Jar version was actually correct. This is the specification of java.exe. When the -jar parameter is specified, java.exe ignores the -classpath parameter and the CLASSPATH environment variable, and the class path will contain only the jar file. Thus, the second application.properties file in the classpath is ignored.

Now, how can I load the second application.properties file in the classpath?

UPDATE 4 :

I was able to load the application.properties file in the external path when using the -jar option.

The key was PropertiesLauncher.

To use PropertiesLauncher, the pom.xml file must be modified as follows:

<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!-- added --> <layout>ZIP</layout> <!-- to use PropertiesLaunchar --> </configuration> </plugin> </plugins> </build> 

For this, I referred to the following StackOverflow question: spring failed to use the property loading utility . BTW, In Spring Boot Maven boot file ( http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/maven-plugin/repackage-mojo.html ), there is no mention of triggers being set ZIP used by PropertiesLauncher. (Maybe in another document?)

After the jar file was created, I could see that the PropertiesLauncher property was used by checking the Main-Class property in META-INF / MENIFEST.MF in the bank.

Now I can start the jar as follows (on Windows):

 java -Dloader.path=file:///C:/My/External/Dir,MyApp-0.0.1-SNAPSHOT.jar -jar MyApp-0.0.1-SNAPSHOT.jar 

Note that the application jar file is included in loader.path.

The application.properties file is now loaded in the C: \ My \ External \ Dir \ config folder.

As a bonus, any file (for example, a static html file) in this directory can also be accessed by the bank, since it is in the bootloader path.

As for the non-jar (extended) version mentioned in UPDATE 2, there may have been a problem with the order of the classpath.

(By the way, I changed the title of the question to be more specific for this problem.)

+51
spring spring-boot configuration
01 Oct '14 at 11:53 on
source share
11 answers

I was able to load the application.properties file in the external path when using the -jar option.

The key was PropertiesLauncher.

To use PropertiesLauncher, the pom.xml file must be modified as follows:

 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <!-- added --> <layout>ZIP</layout> <!-- to use PropertiesLaunchar --> </configuration> </plugin> </plugins> </build> 

For this, I referred to the following StackOverflow question: the spring boot launcher cannot be used . By the way, in the Spring Boot Maven Plugin document ( http://docs.spring.io/spring-boot/docs/1.1.7.RELEASE/maven-plugin/repackage-mojo.html ) there is no mention of specifying ZIP triggers that PropertiesLauncher is used . (Maybe in another document?)

After the jar file was compiled, I saw that PropertiesLauncher was being used by checking the Main-Class property in META-INF / MENIFEST.MF in the jar.

Now I can run jar as follows (on Windows):

 java -Dloader.path=file:///C:/My/External/Dir,MyApp-0.0.1-SNAPSHOT.jar -jar MyApp-0.0.1-SNAPSHOT.jar 

Note that the application jar file is included in the loader.path file.

The application.properties file is now loaded in C: \ My \ External \ Dir \ config.

As a bonus, jar can access any file (for example, a static html file) in this directory, since it is in the path of the loader.

As for the non-jar (extended) version mentioned in UPDATE 2, there may be a problem with the order of the classpath.

+9
07 Oct '14 at 10:54 on
source share

If you have not changed the default values ​​of Spring Boot (which means that you are using @EnableAutoConfiguration or @SpringBootApplication and have not changed the processing of Property Source), then it will look for properties with the following order (highest overrides are the lowest):

  • A /config subdirectory of the current directory
  • Current directory
  • Classpath /config package
  • Classpath root

The list above is given in this part of the documentation.

This means that if a property is found, for example, application.properties in src/resources , it will be overridden by a property with the same name, which is located in application.properties in the /config directory, which is located next to the packed jar.

This default order used by Spring Boot makes configuration very simple, which in turn makes it easy to configure applications in multiple environments (dev, staging, production, cloud, etc.).

To see the full set of functions provided by Spring Loading for reading properties (hint: there is much more than reading from application.properties ), check out this part of the documentation.

As you can see from my brief description above or from the full documentation, Spring Download applications are very useful for DevOps!

+44
01 Oct '14 at 1:06
source share

Everything is explained here in the docs:

http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

This explains that this is the order of priority:

  • A / config subdirectory of the current directory.
  • Current directory
  • Classpath / config package
  • Classpath root

It also indicates that you can define additional property files for such overrides:

 java -jar myproject.jar --spring.config.location=classpath:/overrides.properties 

If you use spring.config.location then all default locations for application.properties also included. This means that you can set the default values ​​in application.properties and override as required for a particular environment.

+16
01 Oct '14 at 13:05
source share

You could start your spring boot using the path to the external property files as follows:

 java -jar {jar-file-name}.jar --spring.config.location=file:///C:/{file-path}/{file-name}.properties 
+8
Jul 20 '15 at 15:45
source share
 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <layout>ZIP</layout> </configuration> </plugin> </plugins> </build> java -Dloader.path=file:///absolute_path/external.jar -jar example.jar 
+2
Nov 14 '16 at 3:03
source share

This may happen at the end, but I think I found a better way to load external configurations, especially when you start the spring-boot application using java jar myapp.war instead of @PropertySource ("classpath: some. Properties")

The configuration will be loaded from the project root or from the place where the war / jar file is run from

 public class Application implements EnvironmentAware { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } @Override public void setEnvironment(Environment environment) { //Set up Relative path of Configuration directory/folder, should be at the root of the project or the same folder where the jar/war is placed or being run from String configFolder = "config"; //All static property file names here List<String> propertyFiles = Arrays.asList("application.properties","server.properties"); //This is also useful for appending the profile names Arrays.asList(environment.getActiveProfiles()).stream().forEach(environmentName -> propertyFiles.add(String.format("application-%s.properties", environmentName))); for (String configFileName : propertyFiles) { File configFile = new File(configFolder, configFileName); LOGGER.info("\n\n\n\n"); LOGGER.info(String.format("looking for configuration %s from %s", configFileName, configFolder)); FileSystemResource springResource = new FileSystemResource(configFile); LOGGER.log(Level.INFO, "Config file : {0}", (configFile.exists() ? "FOund" : "Not Found")); if (configFile.exists()) { try { LOGGER.info(String.format("Loading configuration file %s", configFileName)); PropertiesFactoryBean pfb = new PropertiesFactoryBean(); pfb.setFileEncoding("UTF-8"); pfb.setLocation(springResource); pfb.afterPropertiesSet(); Properties properties = pfb.getObject(); PropertiesPropertySource externalConfig = new PropertiesPropertySource("externalConfig", properties); ((ConfigurableEnvironment) environment).getPropertySources().addFirst(externalConfig); } catch (IOException ex) { LOGGER.log(Level.SEVERE, null, ex); } } else { LOGGER.info(String.format("Cannot find Configuration file %s... \n\n\n\n", configFileName)); } } } } 

Hope this helps.

0
Jun 17 '16 at 8:08
source share

Another flexible way is to use a class path containing a thick jar file (-cp fat.jar) or all jar files (-cp "$ JARS_DIR / *"), and another user-defined configuration class path or folder containing configuration files, usually in other places and outside the jar. Thus, instead of the limited Java-jar, use the more flexible classpath as follows:

 java \ -cp fat_app.jar \ -Dloader.path=<path_to_your_additional_jars or config folder> \ org.springframework.boot.loader.PropertiesLauncher 

See the Spring-boot jar doc executable and this link

If you have several MainApps, which is common, you can use. How do I tell Spring Boot, which main class to use for the executable jar?

You can add additional locations by setting the environment variable LOADER_PATH or loader.path in loader.properties (a comma-separated list of directories, archives or directories within archives). Basically, loader.path works for both java -jar and java -cp.

And, as always, you can override and precisely specify the application.yml that it should use for debugging.

 --spring.config.location=/some-location/application.yml --debug 
0
Jan 19 '18 at 4:30
source share

Solution for yml file:

1. Copy yml to the same directory as the jar application.

2. Run the command, an example for xxx.yml :

 java -jar app.jar --spring.config.location=xxx.yml 

It works fine, but when you start the logger there is an INFO:

 No active profile set ......... 
0
Mar 19 '18 at 8:16
source share

When you create a spring boot jar using maven install and want all resources, such as the properties file and lib folder, to be created outside of jar ..., add the following code to pom.xml, where I define the output folder where I want to extract and save the necessary resources to the bank.

 <build> <finalName>project_name_Build/project_name</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>prepare-package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/project_name_Build/lib</outputDirectory> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>false</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>write here the qualified or complete path of main class of application</mainClass> </manifest> <manifestEntries> <Class-Path>. resources/</Class-Path> </manifestEntries> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> </plugins> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>application.properties</include> <include>log4j.properties</include> </includes> <targetPath>${project.build.directory}/ConsentGatewayOfflineBuild/resources</targetPath> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>application.properties</include> <include>log4j.properties</include> </includes> </resource> </resources> <pluginManagement> <plugins> <!-- Ignore/Execute plugin execution --> <plugin> <groupId>org.eclipse.m2e</groupId> <artifactId>lifecycle-mapping</artifactId> <version>1.0.0</version> <configuration> <lifecycleMappingMetadata> <pluginExecutions> <!-- copy-dependency plugin --> <pluginExecution> <pluginExecutionFilter> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <versionRange>[1.0.0,)</versionRange> <goals> <goal>copy-dependencies</goal> </goals> </pluginExecutionFilter> <action> <ignore /> </action> </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> </plugin> </plugins> </pluginManagement> </build> 
0
Apr 30 '19 at 10:50
source share

I know this is a pointy question, and the OP wanted to load another properties file.

My answer is: doing custom hacks like this is a terrible idea.

If you use spring boot with a cloud provider such as a cloud foundry, do yourself a favor and use the cloud configuration services.

https://spring.io/projects/spring-cloud-config

It loads and consolidates certain default properties / dev / project-default / project-dev, such as magic

Again, loading Spring already gives you enough ways to do it correctly https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Please do not reinvent the wheel.

0
May 6 '19 at 18:17
source share
 java -jar server-0.0.1-SNAPSHOT.jar --spring.config.location=application-prod.properties 
0
Aug 14 '19 at 12:57
source share



All Articles