Maven Aggregate POM with Goal? - java

I have a Maven POM that aggregates several modules.
<project [stuff]>
<modelVersion>4.0.0</modelVersion>
<groupId>com.fuhu.osg</groupId>
<artifactId>UserManagement</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<name>UserManagement</name>
<modules>
<module>core</module>
<module>war</module>
<module>ejbs</module>
<module>ear</module>
</modules>
</project>
I want to execute a goal that doesn't apply to the modules against the top-level POM. Something like mvn db-migrate:create. As is, it seems like this attempts to run said command against the sub-projects, which is correct for every OTHER goal, but not for this one.
Is there a way to make a Maven POM that is both an Aggregate for some goals and an ordinary project for others?

You might be helped by Maven build profiles. It's easy to configure one submodule to be invoked when using a certain profile.
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
...
<profiles>
<profile>
<id>db</id>
<modules>
<module>core</module>
</modules>
</profile>
<profile>
<id>all</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>core</module>
<module>war</module>
<module>ejbs</module>
<module>ear</module>
</modules>
</profile>
...
Start your db task with the db profile with something like:
$ mvn -Pdb db-migrate:create
Auto activation of profiles is possible using system environment etc. Sadly I can't find a maven property for the command line goal, which would enable auto activation of a profile when that specific goal is run.

Related

Maven: How to activate child profile using parent's activation criteria

I have a parent/root POM that (1) aggregates child modules, and (2) declares a profile that is conditionally activated based on a property value. So:
<packaging>pom</packaging>
<modules>
<module>moduleA</module>
<module>moduleB</module>
<module>moduleC</module>
</modules>
<profiles>
<profile>
<id>myProfile</id>
<activation>
<property>
<name>animal</name>
<value>cat</value>
</property>
</activation>
</profile>
</profiles>
And in moduleA, I declare the same profile as the parent, and would like it to be activated when I build moduleA using the activation criteria from the parent (animal == cat). But that isn't working. So if this is moduleA's POM:
<properties>
<shape>circle</shape>
</properties>
<profiles>
<profile>
<id>myProfile</id>
<properties>
<shape>square</shape>
</properties>
</profile>
</profiles>
And I build moduleA using mvn help:evaluate -Danimal=cat, evaluating ${shape} says its value is circle, not square as I'd expect. So it seems like the child profile is not activating when building using its parent's activation criteria.
Is there a way to do this? Do I really have to copy and paste the <activation> block from the parent into all its children modules, just so I can get the same behavior?
Try repeating the activation criteria in moduleA. You shouldn't have to repeat other profile content from the parent, but the activation criteria need to match.
<profile>
<id>myProfile</id>
<activation>
<property>
<name>animal</name>
<value>cat</value>
</property>
</activation>
</profile>
Generally trying to share profile config from one module to another is tricky. There are other questions:
Activating a Child Profile from a Parent Profile
Why can't I activate a Maven2 profile from another profile?

How can i add a module to a maven multi-project for sonar?

i have a Maven multi project with several modules in the pom.xml.
But for the sonar-Scan i want to use other modules (includes and excludes)!
The property-file (sonar-project.properties) is not used in Maven-Projects, so the properties sonar.modules and xxx.sonar.projectBaseDir are not working.
How can i configure it with Maven?
You can use Maven profiles to include only specific modules: http://maven.apache.org/guides/introduction/introduction-to-profiles.html
Example:
<profiles>
<profile>
<id>all</id>
<modules>
<module>module-A</module>
<module>module-B</module>
<module>module-C</module>
</modules>
</profile>
<profile>
<id>sonar</id>
<modules>
<module>module-A</module>
<module>module-C</module>
<module>module-D</module>
</modules>
</profile>
</profiles>
Execute mvn -Psonar clean package sonar:sonar

How to use maven profile and overlays to build and package with specified project from multiple?

I have one web project called MyWebProject which having sub modules also and packaging as POM, I have other two simple java project called SimpleJavaProject1 and SimpleJavaProject2 which having packaging as JAR.
I am having dependency for both in web peoject. So I have to use Maven Profile and Overlays such way, that when I will build and package my web project with profile JavaProject1 then web project includes SimpleJavaProject1 in its war and when I said JavaProject2 then it should include SimpleJavaProject2. And it should use Overlays only for specified java project.
Can I use Overlays in Profile?
Please suggest some idea if any...
I'm not familiar with overlays, but hopefully this approach will work for them too.
Typically one solves this sort of problem by defining a property in your parent POM, based on the profile:
<profiles>
<profile>
<id>JavaProject1</id>
<properties>
<java.project>SimpleJavaProject1</java.project>
<java.project.version>1.1</java.project.version>
</properties>
</profile>
<profile>
<id>JavaProject2</id>
<properties>
<java.project>SimpleJavaProject2</java.project>
<java.project.version>1.2</java.project.version>
</properties>
</profile>
</profiles>
Then use this property when you define your dependency (and hopefully your overlays too):
<dependency>
<groupId>com.foo</groupId>
<artifactId>${java.project}</artifactId>
<version>${java.project.version}</version>
</dependency>
Got it...referring #Duncan answer I have tried following and its worked. :-)
Following are my Profiles,
<profile>
<id>JavaProject1</id>
<properties>
<roject.groupId>mygroupId</project.groupId>
<roject.artifactId>myartifactId</project.artifactId>
<roject.version>${myversion}</project.version>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>JavaProject2</id>
<properties>
<roject.groupId>mygroupId</project.groupId>
<roject.artifactId>myartifactId</project.artifactId>
<roject.version>${myversion}</project.version>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
And I have added Overlays in war plugin as follows,
<overlays>
<overlay>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<type>jar</type>
<targetPath>WEB-INF/classes</targetPath>
</overlay>
</overlays>
It worked successfully. :-)

maven - disable dedicated goals for modules in multi-module build

I use a multi module build file to trigger the build of a rather complex java project. Now I want to create the eclipse project files - but not for all modules. Is it possible to define on a pom, that it shall ignore the eclipse:eclipse goal?
The modules definition of the multi-module pom, that I call with mvn eclipse:eclipse looks like that:
<modules>
<module>../project1/generate/pom.xml</module>
<module>../project1/pom.xml</module>
<module>../project2/generate/pom.xml</module>
<module>../project2/pom.xml</module>
<!-- and many more projects with or without generate sub modules -->
</modules>
Of course the pom is not only needed for creating eclipse projects so I can't just remove the modules that cause trouble with that goal.
The reason for asking: eclipse:eclipse executed on the generate modules will change some attributes in manifest files with the effect that the next build breaks. And I'm tired of correcting them manually all the time ;)
You can use Maven Profiles for this.
Remove your defined modules and add something like this:
<profiles>
<profile>
<id>full</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>../project1/generate/pom.xml</module>
<module>../project1/pom.xml</module>
<module>../project2/generate/pom.xml</module>
<module>../project2/pom.xml</module>
</modules>
</profile>
<profile>
<id>eclipse</id>
<modules>
<module>../project1/pom.xml</module>
<module>../project2/pom.xml</module>
</modules>
</profile>
</profiles>
Then when you want to generate eclipse settings:
mvn -Peclipse eclipse:eclipse
You can use Maven Advanced Reactor Options (since Maven 2.1):
For instance, to target only project1 and project2:
mvn --projects project1, project2 eclipse:eclipse
to target project1 and all its dependencies:
mvn --projects project1 --also-make eclipse:eclipse
This provides a standardised way for reactoring multi-mudule projects and does not requires modification in pom.xml.

Maven profile for single module

I have a multi module maven project, which builds successfully, I'd like to build just one of the modules I have. How would I do that with profiles ? I could do it from console in two ways, one way is go to the child module and mvn package or I could use reactor to build just one module.
Can I do the same thing with profiles? By modifying POM? Thank you
EDIT
If is impossible from POM, can I do it from settings.xml ?
To implement this with profiles, you could use two profiles, one <activeByDefault> with all modules and another one with the wanted module only. Something like this:
<profiles>
<profile>
<id>all</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>module-1</module>
...
<module>module-n</module>
</modules>
</profile>
<profile>
<id>module-2</id>
<modules>
<module>module-2</module>
</modules>
</profile>
<profiles>
And then call it like this:
mvn -Pmodule-2 package
Two things to note here:
You need to move the <modules> from the POM in a "default" profile (because <modules> from a profile are only additive, they do not hide the modules declared in the POM).
By marking it as <activeByDefault>, the "default" profile will be picked if nothing else is active but deactivated if something else is.
One could even parametrize the name of the module and pass it as property:
<profiles>
...
<profile>
<id>module-x</id>
<activation>
<property>
<name>module-name</name>
</property>
</activation>
<modules>
<module>${module-name}</module>
</modules>
</profile>
<profiles>
And invoke maven like this:
mvn -Dmodule-name=module-2 package
But this is a poor implementation IMHO, I prefer the -pl "advanced" reactor options (less xml, much more power and flexibility):
mvn -pl module-2 package
To overcome additivity nature of maven default <modules> working with <profiles>, you can use reactor with particular profile, e.g.:
mvn -pl module-2 -Pprofile-name package
This will package module-2 defined in profile-name and not in default profile.

Categories

Resources