In my project, I have a custom profile custom-profile-name.
A simplified structure of my POM looks like this:
<artifactId>parent</artifactId>
<modules>
<module>child</module>
</modules>
When I run
mvn help:active-profiles -P custom-profile-name
I get:
Active Profiles for Project 'org.sample:parent:pom':
The following profiles are active:
custom-profile-name
Active Profiles for Project 'org.sample:child':
The following profiles are active:
custom-profile-name
I've been reading about profile inheritance and If I understand correctly, profiles should not be inherited. Can anyone explain why the custom-profile-name is active in the child module.
My ultimate goal is to execute the parent with one configuration of a custom plugin and all child modules with another configuration of the same plugin.
Not sure why both parent and child modules are getting activated for custom-profile-name. But to get whats needed for you can be done by defining properties inside the profile.
Example:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>parent</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>parent-app</name>
<url>http://maven.apache.org</url>
<modules>
<module>child</module>
</modules>
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>child</module>
</modules>
<properties>
<parentProp>foo</parentProp>
<childProp>foo</childProp>
</properties>
</profile>
<profile>
<id>custom-profile-name</id>
<modules>
<module>child</module>
</modules>
<properties>
<parentProp>xyz</parentProp>
<childProp>abc</childProp>
</properties>
</profile>
</profiles>
The 'parentProp' is a configuration used by the parent pom and 'childProp' is the configuration used by the child pom. From the configuration it can be seen that the default profile and the 'custom-profile-name' profile behaves differently as the values for the properties is different.
Related
The application landscape consists of several domains with dozens of projects (Maven modules) which can be turned on or off via simple mouse clicks in IntelliJ IDEA.
This is how these modules are defined via profiles in Maven:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>at.wrwks.pipe</groupId>
<artifactId>pipe.reactor.blue</artifactId>
<version>0.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<profiles>
<profile>
<id>modules-blueops</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<modules>
<module>../../blueops/blueops.reactor</module>
</modules>
</profile>
...
How can this be achieved with Gradle also in IDEA? I haven't found a profile-equivalent in Gradle yet, using if/else in the build script is cumbersome and there is no UI support for such custom steps.
Using maven 3.1.1
In my parent pom I have:
<groupId>com.samples</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Parent</name>
<modules>
<module>a</module>
<module>b</module>
<module>c</module>
</modules>
<profiles>
<profile>
<id>skip-c</id>
<modules>
<module>a</module>
<module>b</module>
</modules>
</profile>
...
But module c is still build with I build with:
mvn clean package -Pskip-c
How do I skip a submodule when building my parent project?
Your problem is that your complete module list is always active. You could use a default profile instead.
<groupId>com.samples</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Parent</name>
<profiles>
<profile>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>a</module>
<module>b</module>
<module>c</module>
</modules>
</profile>
<profile>
<id>skip-c</id>
<modules>
<module>a</module>
<module>b</module>
</modules>
</profile>
</profiles>
In addition to julschis comment some details:
Profiles do not replace the normal non profile content of the pom. Therefore, when using your profile, you get a, b and c from the normal pom, and a and b from the profile, therefore your profile is useless.
You need to remove your conditional modules from the main part and put it only into profiles (usually an activeByDefault Profile).
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>a</module>
<module>b</module>
</modules>
</profile>
<profile>
<id>add-c</id>
<modules>
<module>a</module>
<module>b</module>
<module>c</module>
</modules>
</profile>
So it is the other way around, profiles cannot remove anything, but only add or override content.
This technique is called reactor pruning and described here: http://www.blackbuild.com/how-to-really-use-maven-profiles-without-endangering-your-karma/
Your could also use the new functionality from https://jira.codehaus.org/browse/MNG-5230, and simply call (this requires Maven 3.2.1+)
mvn clean package -pl !c
Deactivation of profiles can be done using Maven 2.0.10 + .
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
Deactivating a profile
Starting with Maven 2.0.10, one or more profiles can be deactivated using the command line by prefixing their identifier with either the character '!' or '-' as shown below:
mvn groupId:artifactId:goal -P !profile-1,!profile-2
This can be used to deactivate profiles marked as activeByDefault or profiles that would otherwise be activated through their activation config.
Agregate Project 1:
<groupId>com.mycompany</groupId>
<artifactId>builder</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>../module-1</module>
<module>../module-2</module>
</modules>
<properties>
<project.parent.pom>../builder-v1/pom.xml</project.parent.pom>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lib.version>2.5.1</lib.version>
</properties>
Agregate Project 2:
<groupId>com.mycompany</groupId>
<artifactId>builder</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>../module-1</module>
<module>../module-4</module>
<module>../module-6</module>
</modules>
<properties>
<project.parent.pom>../builder-v2/pom.xml</project.parent.pom>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lib.version>2.6.0</lib.version>
</properties>
Module 1:
<parent>
<groupId>com.mycompany</groupId>
<artifactId>builder</artifactId>
<version>1.0.0</version>
<relativePath>../builder-v1/pom.xml</relativePath>
<!--<relativePath>${project.parent.pom}</relativePath> not work-->
</parent>
<groupId>com.mycompany</groupId>
<artifactId>module-1</artifactId>
Section relativePath with variable from aggregate pom not work
<relativePath>../builder-v1/pom.xml</relativePath>
<!--<relativePath>${project.parent.pom}</relativePath> not work-->
But I need diffrent ${lib.version} in aggregate projects. If I delete inheritance part from
Module 1:
<!--<parent>
<groupId>com.mycompany</groupId>
<artifactId>builder</artifactId>
<version>1.0.0</version>
<relativePath>../builder-v1/pom.xml</relativePath>
</parent>-->
<groupId>com.mycompany</groupId>
<artifactId>module-1</artifactId>
Variables are not passed to the child modules and i got error:
'dependencies.dependency.version' for com.somelib:some-lib:jar must be a valid version but is '${lib.version}'.
How can I configure aggregate project and transfer variables into modules?
UPDATE with #Gab comments
Parent pom:
<groupId>com.mycompany</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<profiles>
<profile>
<id>v1</id>
<activation>
<property>
<name>project.type</name>
<value>v1</value>
</property>
</activation>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lib.version>2.5.1</lib.version>
</properties>
</profile>
...
</profiles>
Module 1:
<parent>
<groupId>com.mycompany</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
</parent>
<groupId>com.mycompany</groupId>
<artifactId>module-1</artifactId>
Agregate Project 1:
<groupId>com.mycompany</groupId>
<artifactId>builder-v1</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>../module-1</module>
<module>../module-2</module>
</modules>
When execute builder-v1 goals activate profile project.type=v1:
mvn clean package --file=pom_v1.xml -Dproject.type=v1 -Dproject.main.module=module-1
maybe define a common parent with 2 profile defining different values for ${lib.version} and automatically activate one profile in your "aggregates" poms. All your module will inherit from the parent one
parent-pom (defining 2 different profiles)
|
+ aggregate 1 (inherit from parent-pom - activate profile 1)
| |
| + module 1 (inherit from parent-pom)
|
| + module 2 (inherit from parent-pom)
+ aggregate 2 (inherit from parent-pom - activate profile 2)
|
+ module 1 (inherit from parent-pom)
|
+ module 3 (inherit from parent-pom)
[edit]
Seems the only trick to automatically activate one profile in your "aggregates" poms to avoid to specify a property in the maven command is
<activation>
<file>
<exists>relative_path_of_file_specific_to_project</exists>
</file>
</activation>
because the property based activation works only with system properties (not the one defined in pom) and you can't override inherited profile configuration (active by default).
If I understand your question right, you want your module to have multiple parents. This is not possible. See this discussion.
You could try suggestion of #Gab. Essentially define two profiles - one for builder-v1 and another for builder-v2. You can do pretty much anything inside a profile, including specifying different set of modules and different properties/versions.
I have parent maven pom.xml like this:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>mygroup-sharing</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<profiles>
<profile>
<id>linux-i386</id>
<activation>
<os>
<family>linux</family>
<arch>x86</arch>
</os>
<property>
<name>platform.suffix</name>
<value>linux-i386</value>
</property>
</activation>
</profile>
<profile>
<id>solaris-i386</id>
<activation>
<os>
<family>solaris</family>
<arch>x86</arch>
</os>
<property>
<name>platform.suffix</name>
<value>solaris-i386</value>
</property>
</activation>
</profile>
...
</profiles>
<properties>
<depr.version>3.6.1-${platform.suffix}</depr.version>
</properties>
</project>
and I have child (and I will have more) pom in subdirectory:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>mygroup-submodule</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>mygroup</groupId>
<artifactId>mygroup-sharing</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
...
<dependencies>
...
<dependency>
<groupId>mygroup</groupId>
<artifactId>depr</artifactId>
<version>${depr.version}</version>
</dependency>
...
</dependencies>
</project>
The problem is, that the version is badly used when trying to compile the child project:
Downloading: http://myserver/nexus/content/groups/public//mygroup/depr/3.6.1-${platform.suffix}/depr-3.6.1-${platform.suffix}.pom
...
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.
Missing:
----------
1) mygroup:depr:jar:3.6.1-${platform.suffix}
Try downloading the file manually from the project website.
Then, install it using the command:
mvn install:install-file -DgroupId=mygroup -DartifactId=depr -Dversion=3.6.1-${platform.suffix} -Dpackaging=jar -Dfile=/path/to/file
Alternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=mygroup -DartifactId=depr -Dversion=3.6.1-${platform.suffix} -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
Path to dependency:
1) mygroup:mygroup-submodule:jar:1.0-SNAPSHOT
2) mygroup:depr:jar:3.6.1-${platform.suffix}
----------
....
... so as you can see, the property platform.suffix is badly applied when using the parent pom.
Also there's warning when running mvn -X install
[WARNING] Overriding profile: 'linux-i386' (source: pom) with new instance from source: pom
but there's no definition of profiles in the child pom file.
If I use this in each pom.xml file, it works properly. But I don't want to have copy-pasted this long part of pom.xml as it also can be extended (with more platforms).
Is there any other way how to share this type (platform suffix) configuration across other modules ?
I have a maven module project that has following modules:
Parent pom
- core
- web-commons
- admin
- web
Both web and admin have dependency on core and web-commons, and each module has its own profile.xml.
Until now, both our admin and web shared the same datasource name and web server, so all the way from core to web-commons we had a reference to this datasource name. (Actually a datasource macro placeholder that gets replaced from profiles.xml during build time).
However, we have to separate the datasources and now I am trying to figure out best way to do this.
Here is the code snippets for clarity.
Parent pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my.groupId</groupId>
<artifactId>parentArtifact</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
...
<modules>
<<module>core</module>
<module>web-commons</module>
<module>admin</module>
<module>web</module>
</modules>
<project>
Core pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my.groupId</groupId>
<artifactId>core</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
...
<project>
core Profiles.xml
<profilesXml xmlns="http://maven.apache.org/PROFILES/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
<profiles>
<profile>
<id>DEV</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<datasource.name>web_datasource</datasource.name>
...
</properties>
</profile>
</profiles>
</profilesXml>
web-commons pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.my.groupId</groupId>
<artifactId>web-commons</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
...
<dependencies>
<dependency>
<groupId>com.my.groupId</groupId>
<artifactId>core</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<project>
web-commons Profiles.xml
<profilesXml xmlns="http://maven.apache.org/PROFILES/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
<profiles>
<profile>
<id>DEV</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<datasource.name>web_datasource</datasource.name>
...
</properties>
</profile>
</profiles>
</profilesXml>
web pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parentArtifactId</artifactId>
<groupId>com.my.groupId</groupId>
<version>1.0</version>
</parent>
<groupId>com.my.groupId</groupId>
<artifactId>web</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.my.groupId</groupId>
<artifactId>core</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.my.groupId</groupId>
<artifactId>web-commons</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
....
</project>
web profiles.xml
<profilesXml xmlns="http://maven.apache.org/PROFILES/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
<profiles>
<profile>
<id>DEV</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<timeout>90</timeout>
...
</properties>
</profile>
</profiles>
</profilesXml>
admin pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parentArtifactId</artifactId>
<groupId>com.my.groupId</groupId>
<version>1.0</version>
</parent>
<groupId>com.my.groupId</groupId>
<artifactId>admin</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.my.groupId</groupId>
<artifactId>core</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.my.groupId</groupId>
<artifactId>web-commons</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
....
</project>
admin profiles.xml
<profilesXml xmlns="http://maven.apache.org/PROFILES/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
<profiles>
<profile>
<id>DEV</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<timeout>120</timeout>
...
</properties>
</profile>
</profiles>
</profilesXml>
Possible solutions:
Change the core profiles.xml and all subsequent profiles.xml, and then run the
mvn clean package -PDEV_WEB and then again
mvn clean package -PDEV_ADMIN
core Profiles.xml
<profilesXml xmlns="http://maven.apache.org/PROFILES/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
<profiles>
<profile>
<id>DEV_WEB</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<datasource.name>web_datasource</datasource.name>
...
</properties>
</profile>
<profile>
<id>DEV_ADMIN</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<datasource.name>admin_datasource</datasource.name>
...
</properties>
</profile>
</profiles>
</profilesXml>
Keep all the pom.xml and profiles.xml as-is and find a maven lifecycle point where we can generate web.war (that has core.jar and web-commons.jar that has web_datasource) and then generate admin.war (that has core.jar and web-commons.jar that has admin_datasource) Not sure how, but will have to investigate this further.
Separate web and admin deployment and keep the datasource name, but have two different web servers that have different datasource settings. [Least likely option]
I'd suggest you make your artifacts environment-agnostic and make them read their configurations from e. g. system properties and/or config files that live outside the artifacts on the file system.
The kind of profile abundance you suggest seems to be a maintainance nightmare to me. What if you cut a release with the release plugin? Which profile would you activate then? Also, note that support for profile.xml was removed in Maven 3.
I ended up refactoring the code so that core and web commons do not have any direct reference to data source profile. All the data source entries have been removed from profiles.xml in core/web commons and new entries made in relevant modules (web/admin). [I know this is not a ideal solution]
Web now has its own entry for datasource-name in profiles.xml, similarly admin has its own datasource-name entry in profiles.xml. Also, core defined a jndi lookup data source spring bean, this is moved to relevant modules that have dependencies (web/admin).
Web profiles.xml
<profilesXmlmlns="http://maven.apache.org/PROFILES/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
<profiles>
<profile>
<id>DEV</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<timeout>90</timeout>
<datasource-name>dev_web</datasource-name>
...
</properties>
</profile>
</profiles>
</profilesXml>
Admin profiles.xml
<profilesXmlmlns="http://maven.apache.org/PROFILES/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
<profiles>
<profile>
<id>DEV</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<timeout>120</timeout>
<datasource-name>dev_admin</datasource-name>
...
</properties>
</profile>
</profiles>
</profilesXml>