How to detect unexpanded or missing value properties in Maven? - maven

I'm configuring a web app to use Maven filtering to expand property placeholders in configuration files for different environments.
Is there a way to detect if any property hasn't been expanded in the filter files, i.e. if I could end up with myprop=${customvalue} at some stage before deployment?

Related

Spring Boot Managing Properties File

I am trying to revamp my microservice to maintain a single application yaml rather maintaining multiple profiles. Initially I was maintaining different profiles and the common configurations were repeated across the helm environment specific values yaml. Now the strategy is to move everything to values.yml and maintain environment specific values in config map. The problem I face is my application yml now looks very generic with placeholders and for the same reason the test runs fails as I cannot give a default value for each of the configurations in application.yml. The reason being, For Eg: mongodb cluster endpoint format is different in local to other environment. I managed to place a local specific yaml file under test/resources, but not sure it's the right approach. I need to anyway maintain a local specific yaml under main/resources for running locally. So essentially I am duplicating it under test resources as well. Is there any better way of pointing test to load the application-local.yml under main resources so that I can avoid the duplication or is there any better way of doing this as a whole?
1. Working with multiple configs in One File
You can add all your configurations in one property file as illustrated below
spring.application.name: test. ## Used for all profiles
---
spring.config.active.on-profile:dev
spring.database.host: localhost
spring.database.name: testing
---
spring.config.active.on-profile:prod. ##You can use spring.profiles:prod
spring.database.host: localhost
spring.database.name: testing
---
--- marks where yml document splits, while #--- marks where properties file splits.
Multi-document property files are often used in conjunction with the following activation properties
spring.config.activate.on-profile
spring.config.activate.on.on-cloud-platform
All property definitions defined without specifying the profile name are used on all profiles. In the above case spring.application.name will be used on all profiles dev or prod.
When running the application you can manually specify profile or you can set in within the yml or properties on properties that are used throughout the application.
spring.application.name: test
spring.profiles.active: prod
2. Testing your application
when running tests that need to access properties in yml(property)file there is
no need to redefine your configurations.Just add #ActiveProfile("profile-name")
on your tests.
for example:
#ActiveProfiles("dev")
#SpringBootTest(webEnvironmentSpringBootTest.WebEnvironment.RANDOM_PORT)

Maven: is it possible to use a conditional properties filtering?

As we know there is a very useful option in Maven Resource plugin: we can use filtering to replace the placeholders in some resources files with some predefined values. The explanation can be found here: http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
A question is: is it possible to use a conditional filtering? I.e. I want to replace some placeholders in my files but I want to do it basing on some conditions, for example:
if the value of myProperty = "DevelopmentSetup" then the replacement
comes from development.properties, otherwise use "ProductionSetup".
Can I do it with Maven?
While you cannot configure Maven's resource plugin to use conditional filtering (at least as far as I know), it is still possible with Maven to select a build profile based on the value of a particular property. As described on Maven - Introduction to build profiles, you can activate a particular profile when some property has a given value (scroll down to 'The profile below will activate the profile when the system property "debug" is specified with any value').
So, the solution to your problem would be to set up two profiles, development and production. In these profiles, you configure your resource filter settings accordingly to either use your development property file or production property file.
There is also some useful information in Maven: The Complete Reference. Especially the tips and tricks section.

Same property defined in multiple active profiles in maven - which one shall win?

What exactly would happen when multiple profiles are activated and they have conflicting definitions of a properties? For example, if there are two profiles both define the properties ${platform-path} but define it as two different values, what would be the final effective value used?
I tried using the help:effective-pom and it seems it is the profile defined later in the settings.xml file who has the last word, but I could not seem to see this behavior documented in either the maven site nor the sonaType book.
I guess it depends on the implementation of the xml parser.
A quick test showed me that the last definition of the variable on the pom file is the one that is considered the correct one.

Maven Variables are not replaced into installed pom file

We are using Maven(3.0.3) as build tool and we need to have different version for different environments (DEV , TEST, QA ) . If we pass version property value during build time based on environment , the installed POM doesn't have the passed property values instead it still has the ${app-version} string.
I saw already there is a bug for this http://jira.codehaus.org/browse/MNG-2971
Is there any other alternative ,because we cannot different POM file for different environments ,which will be hard to maintain..
Thanks
Vijay
Create different artifacts for the environments and use the parameter as a classifier. The pom is the same for all three artifacts but the classifier separates them.
Apparently Maven does not make any variable/property substitution when installing the POM. It is installed as is, that is the principle. You'd better not read any properties from POM (unless this is e.g. version number), bout you should configure your properties in external file (one per stage, e.g. dev.properties, test.properties, ...) and then configure Maven profiles (again, one per stage) and invoke Maven like mvn -Pdev depending on what you want to build. In profile you can package your final application with whatever properties you like (e.g. with the help of build-helper-maven-plugin:add-resource or maven-antrun-plugin + copy rule).
Alternatively you can filter your resources. For example, you can filter your Spring context XML file, which refers the properties file (so you package all property files, but Spring will refer only some specific). Or you can filter another properties file from which you will learn what is the "main" properties file to use (double indirection).
You should create the archives for your different targets within a single build and use as already mentioned the classifier to separate those artifacts from each others.

deploy and running with different configurations in maven

i search a method for Maven that accept different configurations for deploy and debug. I want to choose different web.xml-file. How to get it?
Greetz,
sheepy
You can use resource filtering to substitute values in the web.xml from properties declared in different profiles or in the command line option or you can use property to specify different web.xml in maven-war-plugin configuration.

Resources