Don't work spring.config.additional-location - java

maven:
<profiles>
<profile>
<id>local</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<active.spring.profile>local</active.spring.profile>
</properties>
</profile>
</profiles>
application.properties:
spring.profiles.active=#active.spring.profile#
spring.config.additional-location=classpath:/profile/application-${spring.profiles.active}.properties
and after this I can't get value from src/main/resources/application-local.properties which contains test.prop=123
#Service
public class TestProps {
#Value("${test.prop}")
String testProp;
#PostConstruct
void run() {
System.out.println(testProp);
}
}
Where is the mistake? or it's a bug?

The property: spring.config.additional-location has to be provided as argument for JVM like this: java -Dspring.config.additional-location=classpath:/profile/application-local.properties -jar whatever.jar.
Doesn't make sense to have it in application.properties. From the documentation:
Alternatively, when custom config locations are configured by using
spring.config.additional-location, they are used in addition to the
default locations. Additional locations are searched before the
default locations.
Because the additional locations are searched before the default locations, they have to be provided earlier, so you can't have them in application.properties

additional-location really does not belong to application.properties, because Spring will not interpret it from there. It needs to load the additional config files before the default ones.
On the other hand, it is handy to set the default additional location in maven spring boot plugin. This way one would be able to set security-sensitive information outside of the project sources and it will not appear in the source repository. For example, the client security config could read:
app:
client:
ssl:
keystore: path/to/keystore
keystore-password: the-keystore-password
key-password: the-key-password
Default application.yml in src/main/resources can be skipped, while the additional config could provide the values per active profile and keep them safe on the local machine.

Related

SpringBoot: How to make profile specific resources

I have profiles: dev, prod.
And my homepage located at /src/main/resources/static/index.html
How to make different homepage with different profile?
For example, /src/main/resources/static-dev/index.html and /src/main/resources/static-prod/index.html.
Any advice?
Finally I got a simple solution.
Use different config file application.properties and application-prod.properties.
Each of them I config a different resource location. For example spring.resources.static-locations=classpath:/static-dev/.
If your project supports the Maven dependency manager, Maven's build profiles may be able to help you:
<profile>
<id>live</id>
<properties>
<environment>live</environment>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources/${environment}</directory>
</resource>
</resources>
</build>
</profile>
The code above should be in your pom.xml. In your Spring properties you can specify the active profile in one line:
spring.profiles.active=live
This should be enough to conditionally load any resources.
Both resources should be put under /src/main/resources/static (since this is the default static resource folder IIRC) and then categorized into /prod and /dev. Then in your #GetMapping controller, choose to return /prod/index or /dev/index based on your condition
You can create a Filter that changes the request URL from /index.html to /dev/index.html or /prod/index.html as needed.
The filter can also do the /dev or /prod prefixing for .css and .js files.
Unless all your files are split between dev and prod, you'd probably need an explicit list of which requests should be prefixed.

How to access the values set in profiles (in pom.xml) via java code

I have a maven project with different profiles set in pom.xml with different values. But I don't know how to access those values set in profile via java code.
For example-
My pom.xml:
<profile>
<id>scaler</id>
<properties>
<user>xxxxxxx</user>
<secret>yyyyyyyy</secret>
<proxyHost>172.19.17.13</proxyHost>
<proxyPort>9444</proxyPort>
<environment>SCALER</environment>
</properties>
</profile>
Java code-
String serviceurl = "http://"<proxyhost>":<proxyPort>/";
In the above java code, i want to use proxy host as 172.19.17.13 & port as 9444 as defined in pom.xml but how to access those values from pom??
I will appreciate your help
You should use the maven filtering feature.
http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
Just add a property file in src/main/resources with some placeholders:
key=${myvalue}
then myvalue should be defined as a property in your pom.xml
Be sure to activate the filter on your resources:
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
I'm not sure it depends on maven profile. You can try to use properties-maven-plugin (or other solution) like it described here. Just to write your properties into file and then use it in java code.

How can I get profile specific pom properties in web.xml in Spring?

I am using a service in my spring project.I have following code in my web.xml:-
<init-param>
<param-name>prerenderServiceUrl</param-name>
<param-value>http://10.0.0.45:3000</param-value>
</init-param>
I have 3 profiles in my pom.xml: staging,development & production:
I am looking for the best practices to get <my.service.url> in my web.xml:
<profile>
...
<properties>
...
<my.service.url>http://10.0.0.45:300</my.service.url>
...
</properties>
</profile>
I think the maven resources plugin's filtering function what you need: (http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html)
Maybe you can consider to store environment specific variables in the target environment, not in your build scripts/properties and you can load it from the classpath during the startup. Tight coupling your environment settings with your pom.xml adds some extra effort to you to update your build settings every time when the environment changes or new servers added.
Even though you can use profiles, they shouldn't be used in this case. The idea is that you can distribute the same war over and over again and that the configuration is pulled in. Read How to pass value to maven pom.xml at rum time from java file? for all the options.

Selecting class by Maven build profile

I am quite new to Maven and Java EE programming all-together.
I would like to create a stub class for authentication testing which should be activated in the default Maven build profile.
Currently I have two classes with same name but in different packages. Is it possible to somehow select the correct class to use in the build phase by setting maven build profile parameters? I am also using EJB and JSF2.0 in my project and the authentication object is created in one of the beans:
AuthUtil util = new AuthUtil();
It is possible, with some footwork. You will have to put your class(es) in a dependency and use the profiles in this manner:
<profiles>
<profile>
<id>default</id>
<dependencies>
<dependency>...</dependency>
</dependencies>
</profile>
<profile>
<id>someotherprofile</id>
<dependencies>
<dependency>...</dependency>
</dependencies>
</profile>
</profiles>
Also, the classes will have to be in the same package for this to work.
Cheers,
You can specify the concrete class in a property file, and filter property files by maven build profile, so they would get different values. Property file would then be read by java code and it would be used accordingly.
Is there some reason to do this? It doesn't feel like the right way of doing things...

How do I pull in a private username and password via Maven for testing?

In order to connect to an external system, for which each developer has a personal username and password, I need to pull in a username and password to my JUnit test cases:
String username = System.getProperty("ext.username");
The above line would be called inside any class inside my test folder
How can I best do this via Maven? I think the best scope for the property is inside settings.xml, but I'm not sure about the best way to transfer it from there into my code.
The problem is best solved using a Maven build profile.
In your POM you declare a default value for the properties (To prevent run-time possible errors).
<project>
..
<properties>
<ext.username>XXXXX</ext.username>
<ext.password>YYYYY</ext.password>
</properties>
Each developer can then override these properies in theor local build using a default profile specified in their settings file: $HOME/.m2/settings.xml
<settings>
..
<profiles>
<profile>
<id>dev</dev>
<activeByDefault>true</activeByDefault>
<properties>
<ext.username>XXXXX</ext.username>
<ext.password>YYYYY</ext.password>
</properties>
</profile>
..
</profiles>
..
</settings>
For those worried about security is also possible to encrypt the password.
Finally, it's possible to have multiple profiles configured. These can be chosen at run-time (using profile id) in order to support multiple build environments:
mvn -Pdev ..
mvn -Pprod ..

Categories

Resources