How to activate maven profile from command line (to build subsystem) - java

I have a Maven project https://github.com/paulvi/MavenMultiModule1
with root pom.xml as
<modules>
<module>MavenModule1</module>
<module>MavenModule2</module>
</modules>
<properties>
</properties>
<profiles>
<profile>
<id>p1</id>
<modules>
<module>MavenModule1</module>
</modules>
</profile>
<profile>
<id>p2</id>
<modules>
<module>MavenModule2</module>
</modules>
</profile>
</profiles>
I would like to be able to build subsystem separately,
e.g. mvn package -P p1and mvn package -P p2
Both profiles are visible but can't be activated with -P switch
mvn help:all-profiles -P p1
That work with other project
What is missing here to activate profile or what is better way to build subsystem?
I have read How to activate a Maven profile in a dependent module?

your problem is that by declaring
<modules>
<module>MavenModule1</module>
<module>MavenModule2</module>
</modules>
Those are always built.
Just delete your first 4 lines and it will work as expected.
Now you can build MavenModule1 by typing:
-P p1
Both by typing:
-P p1,p2
and so forth.

You don't need profiles to build specific module, use -pl flag instead.
http://books.sonatype.com/mvnref-book/reference/_using_advanced_reactor_options.html

You should remove that space and it should work fine.
use
mvn package -Pp1

Related

How to build/run a maven project as both a .war and .jar? [duplicate]

I have a project which I compile with maven. I have different profiles declared in pom.xml.
For some of these profiles, I prefer building a war, and for other profiles I prefer a jar. I use to manually edit the pom.xml file and change packaging variable to either
<packaging>war</packaging>
or
<packaging>jar</packaging>
before doing a
$ mvn clean package -Pchosenprofile
How can I tell mvn the packaging corresponding to each profile so I don't need to edit pom.xml?
If you want to use profile you can use something like:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
..
<packaging>${packaging.type}</packaging>
<profiles>
<profile>
<id>webapp</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<packaging.type>war</packaging.type>
</properties>
</profile>
<profile>
<id>batch</id>
<properties>
<packaging.type>jar</packaging.type>
</properties>
</profile>
</profiles>
</project>
Have you looked at the attachClasses configuration setting of the war plugin? This simple setting would let you build both a war and a jar (by default with the classifier "classes") in a single maven execution.
I don't think you can.
Two alternatives I can think of:
have two separate modules for packaging, and call one of those depending on profile
have your module in war and tweak the lifecycle (include/exclude build steps) depending on profile to produce your jar or your war
I like the second approach better - a build server would probably build both, and a developer would use the proper profiles/settings to skip the unwanted type.

Maven project depends on Maven projects two levels down [duplicate]

We have a Maven 2 project with lots of modules in it. Example:
<modules>
<module>common</module>
<module>foo</module>
<module>data</module>
<module>bar</module>
... more ...
</module>
Let's say the "data" module is time consuming to build and we want to exclude it when the project is build by a CI server. Currently we use two pom.xml files to achieve this. One has all modules in it and the other one has all modules except the ones which can be left out for CI. But that's pretty annoying because sometimes we forget to put a new module into both files.
Is there a solution which doesn't need two separate module lists?
With Maven 3.2.1, you can now use -pl !<module_name>,!<module_name> to exclude certain modules from the reactor build.
See this feature request: https://issues.apache.org/jira/browse/MNG-5230
The easiest might be to use profiles like this:
<project>
...
<modules>
<module>common</module>
<module>foo</module>
<module>bar</module>
<modules>
...
<profiles>
<profile>
<id>expensive-modules-to-build</id>
<modules>
<module>data</module>
</modules>
</profile>
</profiles>
</project>
You should then check out ways you can activate profiles
The projects to build can also be specified on the mvn command line. This would remove the need for a separate pom, but instead you would have to change the CI configuration everytime there is a new module.
-pl,--projects <arg> Comma-delimited list of specified
reactor projects to build instead
of all projects. A project can be
specified by [groupId]:artifactId
or by its relative path.
Maybe a combination of this flag and --also-make-dependents or --also-make would reduce this maintenance burden again.
-am,--also-make If project list is specified, also
build projects required by the
list
-amd,--also-make-dependents If project list is specified, also
build projects that depend on
projects on the list
I assume you want the default build to always build everything, regardless of speed, so that new developers can get started quickly without having to understand lots about the POM. You can use profiles like this:
<modules>
<module>common</module>
<module>foo</module>
<module>bar</module>
</modules>
...
<profiles>
<profile>
<id>expensive-modules-to-build</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>data</module>
</modules>
</profile>
</profiles>
</project>
The problem with this is that if a developer specifies another profile on the command line, then the expensive-modules-to-build isn't included (unless the developer also specifies it). This makes it complicated to remember which profiles need to be included.
Here is a hacky way around that. Both profiles are always included, because the pom.xml file always exists. So to exclude the expensive modules, you can use -P!full-build on the command line.
<profiles>
<profile>
<id>full-build</id>
<activation>
<file>
<exists>pom.xml</exists>
</file>
</activation>
<modules>
<module>data</module>
</modules>
</profile>
<profile>
<id>short-build</id>
<activation>
<file>
<exists>pom.xml</exists>
</file>
</activation>
<modules>
<module>common</module>
<module>foo</module>
<module>bar</module>
</modules>
</profile>
</profiles>
Another idea: Reactor modules can be nested, so it should be possible to group your fast and slow-building modules into separate poms and then add another aggregator pom containing these two as modules. Your CI Server could then only reference the pom containing the fast building modules.
<artifactId>fast</artifactId>
<modules>
<module>fast-a</module>
<module>fast-b</module>
<module>fast-c</module>
</module>
<artifactId>all</artifactId>
<modules>
<module>fast</module>
<module>slow</module>
</module>
You could be to use maven profiles. In our build environment, we created a profile quick that disables many plugins and test execution.
This is done by
<profile>
<id>quick</id>
<properties>
<skipTests>true</skipTests>
<!-- others... -->
</properties>
<build>
<plugins>
<!-- configuration... -->
</plugins>
</build>
</profile>
And then we invoke maven the following way
mvn groupId:artifactId:goal -P quick
You could maybe disable compilation and other standard plugins in the pom of your module to speed it up.
Not exactly the answer these folks were asking for. My situation was I wanted to deploy only the parent pom. I'm using the spring-boot-thin-layout in a child module. This requires the parent module be deployed into artifactory. I added the following into my project. It enables skipping of install and/or deploy phase.
In my parent pom:
<properties>
<disable.install>true</disable.install>
<disable.deploy>true</disable.deploy>
<enable.deployAtEnd>true</enable.deployAtEnd>
</properties>
<profiles>
<profile>
<id>deploy-parent</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<disable.install>true</disable.install>
<disable.deploy>true</disable.deploy>
<deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
</properties>
<build>
<finalName>${project.version}</finalName>
</build>
</profile>
</profiles>
And the in my child pom(s) or any module you don't want deployed with parent:
<properties>
<maven.install.skip>${disable.install}</maven.install.skip>
<maven.deploy.skip>${disable.deploy}</maven.deploy.skip>
<deployAtEnd>${enable.deployAtEnd}</deployAtEnd>
</properties>
So effectively when I run mvn deploy on the parent pom, it will compile all the modules, not run install on anything, and then at the end deploy any module not having <maven.deploy.skip>${disable.deploy}</maven.deploy.skip> in it's properties. So in my case only deploying the parent.

Maven project with "war" packaging: how to create JAR with maven-jar-plugin? [duplicate]

I have a project which I compile with maven. I have different profiles declared in pom.xml.
For some of these profiles, I prefer building a war, and for other profiles I prefer a jar. I use to manually edit the pom.xml file and change packaging variable to either
<packaging>war</packaging>
or
<packaging>jar</packaging>
before doing a
$ mvn clean package -Pchosenprofile
How can I tell mvn the packaging corresponding to each profile so I don't need to edit pom.xml?
If you want to use profile you can use something like:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
..
<packaging>${packaging.type}</packaging>
<profiles>
<profile>
<id>webapp</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<packaging.type>war</packaging.type>
</properties>
</profile>
<profile>
<id>batch</id>
<properties>
<packaging.type>jar</packaging.type>
</properties>
</profile>
</profiles>
</project>
Have you looked at the attachClasses configuration setting of the war plugin? This simple setting would let you build both a war and a jar (by default with the classifier "classes") in a single maven execution.
I don't think you can.
Two alternatives I can think of:
have two separate modules for packaging, and call one of those depending on profile
have your module in war and tweak the lifecycle (include/exclude build steps) depending on profile to produce your jar or your war
I like the second approach better - a build server would probably build both, and a developer would use the proper profiles/settings to skip the unwanted type.

Maven profiles - build without child projects

I have a maven project with multiple child projects. I also have a maven dbunit plugin which I invoke from command line like this:
mvn dbunit:operation -P test -pl .
-P is a profile switch where all necessary properties are stored (like db url, etc.)
I.e.:
<profile>
<id>test</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<driver>org.postgresql.Driver</driver>
<url>jdbc:postgresql://localhost:5432/db</url>
<username>ers</username>
<password>ers</password>
<useQualifiedTableNames>true</useQualifiedTableNames>
<dataTypeFactoryName>org.dbunit.ext.postgresql.PostgresqlDataTypeFactory</dataTypeFactoryName>
<format>flat</format>
<type>INSERT</type>
<src>${basedir}/some_path/test.xml</src>
</properties>
</profile>
The problem I'm having is that I need to specify -pl . parameter to build only one project (root/parent project) so that the dbunit data is loaded only once. Is it possible to specify some property directly in the profile, so only 1 project is being build? I tried <pl>my_project</pl> and <project>... - but no luck. Thanks!
Yes. The <modules> element can be specified in a profile. So the solution would be to move the DBUnit setup code in a module and then:
<profile>
<id>test</id>
<modules>
<module>db-unit-setup<module>
</modules>
</profile>
If you activate this profile with -P test, only the single module db-unit-setup and the parent POM will be built. But since the parent POM is now an empty project (it's just a POM without any code), that shouldn't hurt.

Maven profile properties are not "overriding"

I have Maven multi-module project with such structure:
parent-pom-project
-- module1
-- module2
At the parent-pom-project I have such pom.xml
<modules>
<module>module1</module>
</modules>
...
<profiles>
<profile>
<id>local</id>
<properties>
<prop>local_prop</prop>
</properties>
</profile>
<profile>
<id>test</id>
<modules>
<module>module2</module>
</modules>
<properties>
<prop>test_prop</prop>
</properties>
</profile>
</profiles>
At all pom.xml files I have such tag:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
At module1 and module2 in resource directory I have properties files with such text:
prop=${prop}
The problem is that after
mvn clean install
or
mvn clean install -Ptest
or even
mvn clean install -P test
I get
prop=local_prop
If I user test profile for build module2 is also builded, but properties are used from local profile.
I use Maven 3.0.3.
Anybody have any ideas?
You could try to use the mvn help:effective-pom -Ptest command to see the paramters used in your build.
See http://maven.apache.org/plugins/maven-help-plugin/plugin-info.html for more details.
Add a ${basedir} in front of your resource directories:
<directory>${basedir}/src/main/resources</directory>
This should fix your problem. My explanation would be that in a multi-module project it's not picking up the path correctly (for within the child module), if you're building from the top-level. Thus when trying to filter, it applies it to a different directory (the actual root-level aggregator), instead of the child.
I hope it helps.
I can't figure out how maven can resolve your property if you do not specify any profile. So, to see what's really there, I tried myself, following exactly the schema you described and... I did not experience the problem you have. In your case, it really behaves like if the property was defined outside the profile -as bugske suggested. What happened if you comment temporarily both profiles ?
I resolve problem uninstalling current maven plugin for eclipse and use another one.
Now I use this ones:
- Maven Integration: http://m2eclipse.sonatype.org/sites/m2e
- Maven Integration for WTP: http://m2eclipse.sonatype.org/sites/m2e-extras/
Early I was using this one http://download.eclipse.org/technology/m2e/releases/. I cannot explain such behavior but may be some configuration was changed by plugin.
Although old I had the same problem and didn't find the solution here. For me the problem was Eclipse which I use parallel to mvn on the command line. Eclipse instantly called process-resources after I did so on the command line.
Thus the solution was to select the profile in Eclipse (Project->Maven->Select Maven Profiles).

Categories