Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot: Is it possible to use external application.properties files in arbitrary directories with a fat jar?

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

I tried to have 2 files.

  • The first one is on the root folder in the application Jar.
  • The second one is on the directory which is specified in classpath.

2 files are both named 'application.properties'.

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

UPDATE 1: it is possible to 'merge' the contents. Yesterday it seemed that the first one was ignored, but it seems that it's because that something was broken then. Now it works well.

UPDATE 2: It's back again! Again only one of two files is being applied. It's strange... It started after I built the app jar file using Spring Tool Suite. And it seems that the Jar version always ignores the second one (in classpath), while the behavior of the expanded version which runs on STS varies. From where can I start to investigate?

UPDATE 3:

The behavior of the Jar version was in fact correct. It's the specification of java.exe. When -jar option is specified, java.exe ignores both -classpath option and CLASSPATH environment variable, and the classpath will contain only the jar file. So, the second application.properties file on the classpath is ignored.

Now, how can I let the second application.properties on the classpath be loaded?

UPDATE 4:

I managed to load an application.properties file in external path while using -jar option.

The key was PropertiesLauncher.

To use PropertiesLauncher, pom.xml file must be changed like this:

<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 referenced the following StackOverflow question: spring boot properties launcher unable to use . BTW, In 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 that specifying ZIP triggers that PropertiesLauncher is used. (Perhaps in another document?)

After the jar file had been built, I could see that the PropertiesLauncher is used by inspecting Main-Class property in META-INF/MENIFEST.MF in the jar.

Now, I can run the jar as follows(in 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.

Now an application.properties file in C:\My\External\Dir\config is loaded.

As a bonus, any file (for example, static html file) in that directory can also be accessed by the jar since it's in the loader path.

As for the non-jar (expanded) version mentioned in UPDATE 2, maybe there was a classpath order problem.

(BTW, I changed the question's title to be more specific to this issue.)

like image 751
zeodtr Avatar asked Oct 01 '14 11:10

zeodtr


People also ask

What are possible sources of external configuration in spring boot?

Spring Boot allows you to externalize your configuration so you can work with the same application code in different environments. You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration.

How do you call external properties from spring boot?

properties as the configuration file name you can switch to another by specifying a spring.config.name environment property. You can also refer to an explicit location using the spring. config. location environment property (comma-separated list of directory locations, or file paths).

Which property in application properties file will help to run spring boot application?

Properties files are used to keep 'N' number of properties in a single file to run the application in a different environment. In Spring Boot, properties are kept in the application. properties file under the classpath. Note that in the code shown above the Spring Boot application demoservice starts on the port 9090.


1 Answers

If you have not changed the defaults of Spring Boot (meaning you are using @EnableAutoConfiguration or @SpringBootApplication and have not changed any Property Source handling), then it will look for properties with the following order (highest overrides lowest):

  1. A /config subdir of the current directory
  2. The current directory
  3. A classpath /config package
  4. The classpath root

The list above is mentioned in this part of the documentation

What that means is that if a property is found for example application.properties under src/resources is will be overridden by a property with the same name found in application.properties in the /config directory that is "next" to the packaged jar.

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

To see the whole set of features provided by Spring Boot for property reading (hint: there is a lot more available than reading from application.properties) check out this part of the documentation.

As one can see from my short description above or from the full documentation, Spring Boot apps are very DevOps friendly!

like image 160
geoand Avatar answered Oct 13 '22 21:10

geoand