How to manage Environment and Region/location Specific Configuration using Maven - java

We have following 3 [DEV,STAGING,PROD] environment. And multiple regions/location under each environment example [ ASIA,EUROPE,US ]. What is best way we can configure the project using maven so that it can pick correct configuration xml and properties based on the environment and region.
For example: if we want to test/build our application in STAGING on US region, STAGING-US.xml , STAGING-US.properties should be taken during the build.
Our application is Maven based .
It would be great help if you could suggest any other better alternative also, we are trying to use maven profile. But it seems we have to create multiple profiles.

Related

Best Way to Remove Functionality from Java Spring Boot App at Build

I'm looking for a way to conditionally remove functionality from my Spring Boot app during the build. Whether that is a Maven plugin that strips out the actual Java classes or packages, or just is able to set a variable that cannot be later changed environmentally.
My spring boot app has a bunch of reports that can be generated but they shouldn't all be available in every environment they are deployed in. I would like an easy build config file where I can set which reports are enabled and disabled before build. I need them hard set at build, so someone with control of the environment can't just go in and update an associated property value and they become enabled again.
I was looking for some plugin that would remove classes or packages, or that could hardcode the variable value into the compiled class files but couldn't find anything. I figure there must be some way to make configuration stuck at build time. Have been unsuccessful finding a way to set properties at build that cannot be overridden.

Injecting log level to logback.xml with maven

I have a java swing project that will end up in a fat client. There is no JEE background, no application server or servlet container will be involved. Nor any other runtime container then a plain JVM.
I am using the build tool maven to manage dependencies and to build the application.
I am using logback api for logging purposes.
Now I have two build profiles, one for building a developer version and one for building the final version.
Is it possible to set values to the logback.xml file using a maven property? For example, I have the following <root level="${log.level}"> tag in my logback.xml. Now I want to define the value of ${log.level} in my maven build profile. Is it possible?
This question is not related to
It is certainly possible, with maven resource filtering.
https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
I would strongly recommend not to do it this way though. Managing 2 binaries just for the sake of having different properties seems an overkill.
I would recommend some setting on the target host (env variable, parameter to your program) that will allow you to select log level at runtime.
Passing log level, name or path of logging config, or name of target environment (dev/prod) are all acceptable solutions.

Do I have to duplicate plugin configuration in Maven profiles?

I'm using rpm-maven-plugin to create an RPM that installs my java project. I need to build RPMs for both CentOS 5 and CentOS 7. I'm already using profiles to set properties that contain the names of some RPM dependencies that differ between the two, then referencing those properties in the rpm plugin.
I now need to also change what files the RPM puts in place based on the cent5 vs cent7 profiles (cent 5 still uses init scripts, cent 7 has gone to unit files with systemd). I can't think of an easy way to do that by setting properties, I need to include different file mappings in each. Do I need to duplicate my (long) RPM plugin configuration in two profiles to get the changes? That feels dangerous because the plugin configuration is long, and duplication will inevitably lead to developers making future changes in one and missing the other. Is there a way to just add to the plugin configuration with the profile?
What is the best way to manage a small change of a complicated plugin configuration across maven profiles?
Use Maven's aggregation (with sub-modules):
Inheritance and aggregation create a nice dynamic to control builds through a single, high-level POM. You will often see projects that are both parents and aggregators.
and inheritance (with a parent POM):
A parent project is one that passes its values to its children. A multimodule project simply manages a group of other subprojects or modules.
See also this answer to Maven and Profiles: ....

what is the most convenient way to build package for different environments?

I have a maven project, which has quite different settings in the properties files for production and development envs. Is it right, that the most common way is to have different maven profiles (dev by default) which will package different properties during the build process?
Is there maybe another way?
Yes, this is exactly what profiles are designed for.
You don't even need different properties files, you can have one property file that gets filtered with different properties from each profile.
The problem with profiles is that you need to run your build the number of times of your profiles. Which means if have five profiles (dev, pre-test, pre-live, qa, prod) you need to run your build five times. I would suggest to go a different way and produce as a result of a build direct those five artifacts (usually war's etc.) which have been configured appropriately. This can be achieved by using the example i have produced which makes life easiert. The example will produce
There is another approach to put environment dependencies in an environment to have single artifact built from maven project and then provide properties during deployment. In this case maven doesn't know anything about particular environment.
E.g. you could put something -Dmy.config.file=/path/to/env/my.properties in java command line or by using JNDI, or reading properties from database, and so on.
This is more viable approach if you have a lot of different environments or you don't know anything about them (e.g. distributing a .war application to end-users).

How to build multiple configurations of an artifact (e.g. WAR etc.) with Maven?

due to the modular nature of some of our current applications, we have a need to understand how to setup Maven to produces mutliple configurations of the same artifact (in our case a WAR file), combinations of BOTH deployment level (dev, test, production) AND localised (gb, fr, es etc.)? We're looking for something like:
artifact-gb-dev.war
OR
artifact-fr-test.war (etc., etc.)
We've been made aware of Maven 'build profiles', which seem to fit the deployment environment criteria, and the 'maven-assembly-plugin', which might address the country/internationalisation issues BUT is it possible to combine the two (i.e. integrate French-language resources files into a production-level build)?
An example of our current directory structure might be:
..\gb
\dev
\test
\production
..\fr
\dev
\test
\production
..\es
\dev
\test
\production
where a build might require a (one) French development release (fr/dev) OR all production releases (gb-fr-es-etc/prod), for example.
We're new to Maven and have decided to try it due to the quick ramp-up offered by pre-configured Maven archetypes and its dependency management. Until now we've used Ant for our builds.
Thanks
Richard
Have a look at the maven war overlay mechanism. It basically allows you to have a generic pom and put overlays (for each country for example) on top of it to build any number of wars.
I've used this in the past to create a website (platform) for multiple countries with small differences per country.
See: http://maven.apache.org/plugins/maven-war-plugin/examples/war-overlay.html

Categories