Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override an application property to undefined/unset

I am not sure if this is a valid question, but I was wondering if this was possible.

A Spring boot project has an application.properties and several profile specific properties. The profile specific properties overrides the defined application.properties with whatever has been defined in the application-profile.properties, and also adds those properties belonging exclusively in the profile specific properties. Illustration below:

application.properties

key1=value1
key2=value2

application-profile.properties

key1=valueProfile1
key3=valueProfile3

When the application starts with this profile, the final properties that it sees are as follows:

key1=valueProfile1
key2=value2
key3=valueProfile3

In short, you have a union of both the common and profile properties, with the profile property values appending and overriding the common.

But what if, in a god-knows-what scenario, i need a property to be defined in the common application.properties but i need it to be "undefined" when the application starts in one particular profile. Illustration below:

application.properties

keySpecial=specialValue
key1=value1
key2=value2

application-special.properties

key1=valueSpecial1
//unset or undefine keySpecial
keyAlternateSpecial=specialAlternateValue
key3=valueSpecial3

Now, when the application starts with this "special" profile, I want it to see the final properties as follows:

keyAlternateSpecial=specialAlternateValue
key1=valueSpecial1
key2=value2
key3=valueSpecial3

Note that keySpecial is not defined, doesnt even exist, when the application runs in this special profile.

Is this possible?

Note: I know that I can refrain from defining "keySpecial" in the common application.properties, and define them in all other profile specific properties. And specify "keyAlternateSpecial" only in "special" profile properties.

More Info:

The scenario that made me wonder about this is the spring boot datasource jndi property. From the docs

spring.datasource.jndi-name= # JNDI location of the datasource. Class, url, username & password are ignored when set.

The mere existence of this property makes the application ignore the other datasource properties (class,url,username,password) even if they are set.

I am not allowed to remove the jndi property from the "application.properties". But instead I wanted to unset/undefine it and add the other datasource properties (class,url,username,password) in a "special" profile properties.

like image 338
ameenhere Avatar asked Sep 26 '16 12:09

ameenhere


3 Answers

You can fake removing spring.datasource.jndi-name from application.property by setting spring.datasource.jndi-name=false. This way @ConditionalOnProperty(prefix = "spring.datasource", name = "jndi-name") won't enable autoconfiguration class. For details look at ConditionalOnProperty javadoc.

like image 163
Michal Balicki Avatar answered Oct 16 '22 15:10

Michal Balicki


I solved in my use case with by defining the JNDI property in default profile which is activated when no other profiles are defined, in this way during development I can use a different datasources without JNDI.

Here's an excerpt of my application.yml file, don't know if this works for you.

spring:
  jpa:
    database: POSTGRESQL
    hibernate:
      ddl-auto: none
# Default profile, active by default on JBoss since no spring profiles are activated
---
spring:
  profiles: default
  datasource:
    jndi-name: java:jboss/datasources/anagraficaDS
# Development configuration
---
spring:
  profiles: development
  datasource:
    platform: postgres
    url: jdbc:postgresql://localhost:5432/my-db
    username: root
    password: secret
    driverClassName: org.postgresql.Driver
like image 2
Fabio Avatar answered Oct 16 '22 15:10

Fabio


Late to the party, but:

Since SpringBoot 2.4 a good option would be profile groups.

Put keySpecial=specialValue (and other related config) in its own profile - let's call it special.
Then add it to the profiles it needs to be in. So if you have profiles a, b, and c, and you only need special to be in a and b, then:

spring.profiles.group.profilea[0]=special
spring.profiles.group.profileb[0]=special
like image 1
gz90 Avatar answered Oct 16 '22 13:10

gz90