16

I am developing a spring boot application

I want to override some properties in src/main/resources/application.properties with an external file (e.g. /etc/projectName/application.properties).

I tried several methods:

  1. @PropertySource("file:/etc/projectName/application.properties") as annotation at ApplicationConfig.java

  2. spring.config.location=/etc/projectName/application.properties in my application.properties in resources

I tested it with spring.port. The first method only added properties but didn't override them.

skaffman
  • 398,947
  • 96
  • 818
  • 769
greenhalos
  • 188
  • 1
  • 3
  • 9
  • 4
    Drop the `application.properties` in the same directory as the jar file, it will be picked up automatically. – M. Deinum Jan 05 '15 at 07:51
  • I am using a war file, building with maven in Intellij and deploying into a Tomcat, so no jar-file – greenhalos Jan 05 '15 at 10:56
  • Add to your question as that influences the answer. Regardless you should use option 2 as the properties loaded by Spring Boot are ordered specifically, adding a `@PropertySource` will add your loaded properties to the end of the chain of `PropertySource`s that are consulted. – M. Deinum Jan 05 '15 at 11:13
  • greenhalos, did you ever find a resolution to this problem? I have the same issue with my war file. I'd rather not add arguments/parameters to the tomcat startup config, but I will if I have to. – bwfrieds May 25 '16 at 19:39
  • mainly I needed this due to different developers who hab different database setups. I resolved the problem by placing the default application properties in the resource directory and the custom properties to override the default once wehre placed in a new directory config inside the resource directory. The properties in the config directory override the properties in the resource directory. In production I set the properties in the tomcat script. I hope this is what you were looking for. – greenhalos May 26 '16 at 07:00
  • 1
    @M.Deinum - actually, I found that application.properties needs to be in the current working directory to get picked up. – Janik Zikovsky May 28 '18 at 14:49

7 Answers7

26

I always use --spring.config.location= in the command line as specified in the documentation, and you can put various files in this, one with default values and another with the overridden ones.

Edit:
Alternatively, you could also use something like :

@PropertySources({
    @PropertySource("classpath:default.properties")
    , @PropertySource(value = "file:${external.config}", ignoreResourceNotFound = true)
})

and specify a external.config in your application.properties.
This would provide a default path for overridding config, that is still overriddable itself by specifying a --external.config in the command line.
I use this with ${external.config} being defined as a system env variable, but it should work with a application.properties variable too.

JR Utily
  • 1,792
  • 1
  • 23
  • 38
  • but i wanted to do it without specifying it in the command line but in application properties or ass annotations – greenhalos Jan 05 '15 at 12:14
  • 4
    I would really suggest not to do it that way : it means you are linking your source code with the external environment, and so that your source code would potentially not work anymore on another machine (not speaking of the root privilege needed to write your config file). IMHO, things that are specific of the external env should remain outside of the source. – JR Utily Jan 05 '15 at 13:40
  • command-line is not something which is allowed in deployments. Admin will not modify any scripts. – signonsridhar Sep 04 '20 at 21:24
4

I had the same requirement like yours( war package instead of a fat jar) and I manged to externalize the configuration file: In my main class I made this configuration:

@SpringBootApplication
@PropertySource("file:D:\\Projets\\XXXXX\\Config\\application.properties")
public class WyApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(WyApplication.class, args);
    }

}   

Hope this will help you. Good luck.

2

Notes

1) Tomcat allows you to define context parameters 2) Spring Boot will read the properties defined in Tomcat context parameters as if you are defining them as -Dsomething=some_value

Options

Option 1: Hence a possible way is for you to define spring.config.location at the Tomcat context paramter:

<Context>
    <Parameter name="spring.config.location" value="/path/to/application.properties" />
</Context>

Option 2: define a system property at the Tomcat's setenv.sh file

Dspring.config.location=/path/to/application.properties

Option 3: define an environment variable: SPRING_CONFIG_LOCATION

Ian Lim
  • 4,164
  • 3
  • 29
  • 43
2

If you do not want to use any solution from above, you could do the following in the start of your main(String args[]) method (before the usage of SpringApplication.run(MyClass.class, args):

//Specifies a custom location for application.properties file.
System.setProperty("spring.config.location", "target/config/application.properties");
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
George Z.
  • 6,643
  • 4
  • 27
  • 47
0

Note: The following solution will replace the old application.properties entirely

You can place your application.properties in one of the following locations:

  • Under /config sub-directory of the current directory
  • The current directory
  • A classpath /config package
  • The classpath root

And then exclude the default one under resources directory, like:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>**/application.properties</exclude>
            </excludes>
        </resource>
    </resources>
</build>

Find more details in this link

mhsallam
  • 235
  • 3
  • 5
0

Based on @JR Utily response this "format" work for me when use email config and multiple properties (I tried to use a PropertySourcesPlaceholderConfigurer Bean but for any reason don't take the email config):

@SpringBootApplication
@PropertySources({
    @PropertySource("classpath:application.properties"),
    @PropertySource(value = "file:/path/to/config1.properties", ignoreResourceNotFound = true),
    @PropertySource(value = "file:/path/to/config2.properties", ignoreResourceNotFound = true),
    @PropertySource(value = "file:/path/to/config3.properties", ignoreResourceNotFound = true)
})
public class ExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(ExampleApplication.class, args);
    }
}
sebasdev
  • 309
  • 3
  • 8
0

Yes we can add application.properties file from external folder. The simplest way is

@SpringBootApplication
public class ExternalAppPropertiesTest{

    public static void main(String[] args) {
        System.setProperties("spring.config.location","D:\\yourfoldername where application.properties added");
        SpringApplication.run(ExternalAppPropertiesTest.class, args);
    }
}

N.B. - In case of externally application.properties access please don't use @PropertySources annotation and file path. It will not access your logging properties e.g. logging.file.name=yourlogfilename.log

Here is one more suggestion, for code maintenance you can put your applcation.properties by renaming the file name in your src folder of spring boot application and maintain the changes which is done in external file.

Laurel
  • 5,965
  • 14
  • 31
  • 57