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: ....
Related
This question already has answers here:
How to activate a Maven profile per pom.xml?
(3 answers)
Closed 7 years ago.
I'm not familiar with Maven and am trying to figure out how it works on our existing project.
project and folder structure is basically
A
A\1
A\2
A\3
Inside each folder is a pom file. Each pom contains 1 or more defined profiles.
What I do not understand is with this command
A>mvn install
How do all of the pom get executed and which profiles are being executed?
I don't see any tags marked with activebydefault
Frustrated when I need to spend time learning at step 1 and build some projects but am forced to be at step 50 without anybody on the team that knows the first thing about Maven. Of course solutions are always due yesterday.
Profiles can be specified in your POM, in your parent POM, in your settings. Hence, looking just at your POM file may not be enough.
Running mvn help:active-profiles would give you a list of all active profiles and from which source (pom or settings).
Running mvn help:all-profiles would give you a list of all available profiles, the active ones and from which source (pom or settings).
Running mvn help:effective-pom -Doutput=full-pom.xml would provide you the full POM file (in the full-pom.xml generated file), as a merging of current pom, parent pom and settings. That would be the full source of true.
The structure you describe is for a multi-module maven project, which means A is the aggregator project (having packaging pom, its only delivery is a pom file, its only function is to provide the modules it will build).
However, beware that in Maven aggregation and inheritance are two different concepts, which are often used together: aggregation means I will build as part of my build all of my defined modules; inheritance means I will inherit configuration from my parent pom. As such, A\1 may inherit profiles from project A if in the pom of A\1 you will find A defined as parent (which is often the case, to have an aggregator which is also parent of all the defined modules).
Why to have an aggregator? To have a centralized build and location of correlated sub-projects while still keep a good separation of concerns across sub-modules. Moreover, as Maven best practices, a project should only generate one artefact, hence it might be the case to have a web application having logic in one module, war generation in another module, ear generation in yet another module, for instance.
Why to have inheritance? To have a centralized place where to set shared/common configuration, like profiles but also dependencies and dependencies management.
Lastly, it is a common misunderstanding and hence be also aware that:
If a profile is active by default in Maven, it will be part of the default build. However, if you activate a profile via command line (via the -P option) you will then activate the requested profile but also and automatically deactivate the one which was active by default
the mechanism above doesn't apply to profiles defined in the settings.xml of your maven installation (which are applied by default, if activated, to all the Maven builds on the concerned machine).
Update A further note on this answer leveraged by some comments: a Maven build is specified as part of the build section (a flow of plugins executions), which doesn't necessarily need profiles. Profiles are generally defined to add a further behavior to the build, but it is good practice to have a build building successfully regardless of any activable profile, that is, I don't have to know about the defined profiles to run your build, it's a core concept of maven, harmonization and convention over configuration: given a Maven project, I can always assume that simply mvn clean install would do the required magic.
For a list of common questions about starting with Maven, the official Getting Started Guide already provides a good help.
Also check the Profiles Pitfalls of the official Introduction to Profiles for further guidance on profiles.
No profile is active unless you have one marked as activeByDefault.
my java se project/system consists of multiple components like below where there can be many shared libs and many applications/ running processes. Example the 3 components below make up 'System 1'.
System 1:
1. Common lib - for our shared code
2. App 1 - a app/process with it's own code referencing the common lib.
3. App 2 - a app/process with it's own code referencing the common lib.
My questions how do i setup Maven/Intelij to support this structure ... and is it a good structure to follow?
At present I have the groupId as 'com.MyCompany.System1' and the Mavan modules for the components with artifactIds as 'com-MyCompany-System1-common' etc.
Is this the correct way to go or how should i arrange Maven to support this structure?
Thanks in advance.
It sounds like a typical Maven multi-module setup should serve your needs. As for IntelliJ, just set it up in Maven and then import the maven pom into IntelliJ. It'll just work. You can just open the pom file as a project, and IntelliJ will set everything up for you correctly.
Advice:
Even if it feels like more work up front, the more you can break up your project into cleanly-defined modules, the happier you'll be in the end.
I wouldn't repeat the groupId in the artifactId. The artifactId should definitely be distinct, but not that distinct.
Consider using Gradle instead if it's an option. It's the next logical step in build tools after Maven, and it'll vastly reduce your effort as the number of modules increases. Gradle/IntelliJ interaction is almost as good as Maven/IntelliJ. It's slightly more work, but the tradeoff is worth it.
Source: I have a mix of >100 Maven and Gradle modules spread across >30 source code repos which I've been building and working in with IntelliJ for 3 years.
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).
What are the main possible reasons of breaking down a Maven project to sub-modules?
Are you looking something more than the benefits of Modularization? The sub-modules should ideally be representing a single concept/feature so that they are functionally cohesive.
Pom file inheritence
You can use the and sections of the root poms to keep consistent version numbers and configurations across all child projects. So if I have an aggregator project that lists 300 projects, all that use apache commons-io and I want to upgrade them all the the latest version of commons-io, I can just change the version in the dependencyManagement section of the root pom. None of the child projects need specify a version.
build profiles
In the above example, if I have 300 sub projects, an individual developer is probably not regularly working on all (or even many) of the 300 sub-projects. You can create a build profile that specifies only the modules you work on regularly, and if you have a continuous integration server that deploys artifacts to an artifact repository, you'll get all the changes the developers on your team make too, without having to build all 300 modules.
General organization/clarity
While waiting for an answer to my comment.
A reason to split a Java EE based maven project into sub modules is so you can build the JAR/RAR/WAR/EAR/whatever independently of eachother.
For regular Java apps, you might split out the functionality into separate JARs, again each of these could be a sub-module under the overall project and again you can build them independently, run separate goals/phases/reports etc.
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