Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
479 views
in Technique[技术] by (71.8m points)

configuration - 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:MyExternalDirconfig 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.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...