Maven - Child Module Profiles
Asked Answered
S

1

13

Problem

I have a maven project that has a similar structure to the following one:
(simplified for explanation purposes)

--parent
    |-- child A (inherits from parent)
    |-- child B (inherits from parent)
          |-- child B1 (inherits from B)
          |-- child B2 (inherits from B)
          |-- child B3 (inherits from B)

Solely the children B1 and B2 have to be built using a certain profile that includes some extra build stuff. By consequence the profile has been specified in module B.

Logically the modules belong to module B and additionally inherit some dependencies etc. (aggreagtion + inheritance).
(imagine something like B = Frontend, B1 = UI, B2 = Themes, B3 = Something else)


Question

  • Is there a possibility to still use a full build from the parent pom and activate the according profile only in the correct children? (would be my favorite solution)
  • Or do I need separate builds using advanced reactor options (-pl, etc.)?
  • Or is there a completely other approach for such scenarios?

Edit

Edit as the question was identified as duplicate: The problem is that the solution mentioned in the according question does not work.

If I activate the sub profile by using a property, it will be activated as well for module B (the parent), and for ALL children.

I only want it to be active for child B1 and B2.

Sukhum answered 11/2, 2016 at 7:54 Comment(4)
Possible duplicate of Activating a Child Profile from a Parent ProfileAlrick
Agree with @A.DiMatteo. The linked question answers this one.Kenya
what are these extra build stuff the profile is adding? Few more plugin executions? Can you at least mention the involved plugins? There is a possible solution, but I need more details : )Alrick
it would explode the question if I add all the details, thats why I tried to abstract it. There are a whole lot of other plugin executions involved that include different additional stuff in the target package, etc.Sukhum
A
22

If you want to have a profile which should be applied to sub-modules (and only some of them), defined in a centralized way in their parent project (pom) and yet not apply the profile to the parent itself, here is a proposed approach:

Define the profile in the parent pom, sample one:

<profiles>
    <profile>
        <id>sample-profile</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <version>1.5</version>
                    <executions>
                        <execution>
                            <id>print-hello</id>
                            <phase>${phase.prop}</phase>
                            <goals>
                                <goal>run</goal>
                            </goals>
                            <configuration>
                                <target>
                                    <echo message="hello there!" />
                                </target>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Note what we are doing:

  • the plugin phase element is parametrized, so the binding of the plugin to a build phase will also be parametrized
  • We can now decide via property to which phase attach this plugin execution
  • We can now decide via property to attach this plugin execution to no phase (or empty phase)

So, in the same parent pom, let's define the property:

<properties>
    <phase.prop>none</phase.prop>
</properties>

As such, the build running on the parent pom will attach the plugin execution to no phase (none is not a keyword or known-value, just a de-fact standard used for a non existing phase, you could leave it empty or put it any value you like, it would have the same effect) and hence skip it. It will also be skipped by default in all the declared modules. The profile will still be active in every module, but would be harmless since it would not execute any plugin by default.

Then, in modules where you want the plugin executions to be active you could re-define only the concerned property and the required phase:

<properties>
    <phase.prop>package</phase.prop>
</properties>

When then activating the profile from the main build (the parent)

mvn clean install -Psample-profile

The parent will apply it to all modules, but the effective profile execution will only occur where the phase.prop value has a maven-meaningful value.

If you need to have different phases for different plugin executions, then you could define more than one property and apply the same pattern.

If you don't have a plugin execution but rather a global plugin configuration for a plugin already executed by Maven (as part of its packaging and default build), you could then re-define its execution overriding the default execution id.

Note that we could have done the same using the skip configuration element, but:

  • not all plugins provide the skip configuration entry
  • using the phase element is not related to any configuration and can be reused for executions attached to the same phase
Alrick answered 16/2, 2016 at 12:25 Comment(2)
I implemented your solution and it seems to work. Only problem is that my profiles plugin executions happen in different phases. Now I need to set 4 properties inside the child pom. I tried to do this using the maven antrun plugin in the validate phase (child sets a property to true and antrun sets all the other properties), but this does not seem to work. Thank you anyway, if I do not find a solution to set multiple properties at once this will still help us out.Sukhum
@Sukhum Perhaps the Properties Maven Plugin helps with setting multiple properties.Polyadelphous

© 2022 - 2024 — McMap. All rights reserved.