172

We have a need to be able to skip a submodule in certain environments.

The module in question contains integration tests and takes half an hour to run. So we want to include it when building on the CI server, but when developers build locally (and tests get run), we want to skip that module.

Is there a way to do this with a profile setting? I've done some googling and looked at the other questions/answers here and haven't found a good solution.

I suppose one option is to remove that submodule from the parent pom.xml entirely, and just add another project on our CI server to just build that module.

Suggestions?

Lii
  • 9,906
  • 6
  • 53
  • 73
denishaskin
  • 2,855
  • 3
  • 19
  • 33
  • Why not Maven Way? It's a perfectly valid claim to me. – MaDa Nov 29 '11 at 13:39
  • Hmm. Now I can't find the places where people seemed to be arguing against this... so I've updated my original question to remove my claim that this doesn't seem to be "The Maven Way". – denishaskin Dec 02 '11 at 14:03

5 Answers5

258

Maven version 3.2.1 added this feature, you can use the -pl switch (shortcut for --projects list) with ! or - (source) to exclude certain submodules.

mvn -pl '!submodule-to-exclude' install
mvn -pl -submodule-to-exclude install

Be careful in bash the character ! is a special character, so you either have to single quote it (like I did) or escape it with the backslash character.

The syntax to exclude multiple module is the same as the inclusion

mvn -pl '!submodule1,!submodule2' install
mvn -pl -submodule1,-submodule2 install

EDIT Windows does not seem to like the single quotes, but it is necessary in bash ; in Windows, use double quotes (thanks @awilkinson)

mvn -pl "!submodule1,!submodule2" install
Alexandre DuBreuil
  • 4,653
  • 1
  • 17
  • 16
  • 32
    Important: if you want to exclude a nested submodule you need to use the qualified version `mvn -pl !com.acme:nestedmodule1` – Leonard Brünings Dec 01 '15 at 15:26
  • 3
    The -pl option need '[groupId]:' before artifactId , so we should use mvn -pl '!:submodule-to-exclude' install – Honsen Mar 15 '18 at 13:27
  • 5
    You can also use `mvn -pl '!path/to/submodule/directory'`, without using groupId and artifactId. My answer works if `submodule1` and `submodule2` are located in the current directory. – Alexandre DuBreuil Mar 15 '18 at 14:36
  • It's also worth nothing that if you use `-pl` in `mvn install`, you'll likely need to use it for `mvn deploy` as well – chizou Sep 20 '18 at 15:55
154

Sure, this can be done using profiles. You can do something like the following in your parent pom.xml.

  ...
   <modules>
      <module>module1</module>
      <module>module2</module>  
      ...
  </modules>
  ...
  <profiles>
     <profile>
       <id>ci</id>
          <modules>
            <module>module1</module>
            <module>module2</module>
            ...
            <module>module-integration-test</module>
          </modules> 
      </profile>
  </profiles>
 ...

In your CI, you would run maven with the ci profile, i.e. mvn -P ci clean install

Raghuram
  • 49,195
  • 9
  • 101
  • 120
  • 4
    Excellent answer! I don't know why I had so much trouble finding this out of the Maven docs. The one suggestion I would make is that because I prefer the integration tests to be run by default, I added `activeByDefault` to that profile, and then had to add another empty profile (e.g. `skip-integration-tests`) to be able to skip them. – denishaskin Nov 29 '11 at 12:57
  • 7
    is there any way to do this without duplicating all the shared stuff? – JonnyRaa Jun 16 '14 at 16:18
  • 7
    Beware, if you use the maven-release-plugin it would appear that it doesn't update the version number of submodules that are hidden behind a profile switch. You could have sub-modules with different version numbers to the rest of your project... – Ardesco Oct 06 '14 at 09:17
  • 9
    Unfortunately, uing the profile you can't exclude a module earlier mentioned in the main part of the pom. The JIRA https://issues.apache.org/jira/browse/MNG-5230 (and whole pom structure) could have been fully-implemented so much better with a bit more careful thought. – Ed Randall Jan 09 '18 at 10:38
  • 3
    does this solution really work? At least I can not get it to work. Seems like I have the same issue like @EdRandall – Gerros Sep 28 '18 at 13:08
39

It's possible to decide which reactor projects to build by specifying the -pl command line argument:

$ mvn --help
[...]
 -pl,--projects <arg>                   Build specified reactor projects
                                        instead of all projects
[...]

It accepts a comma separated list of parameters in one of the following forms:

  • relative path of the folder containing the POM
  • [groupId]:artifactId

Thus, given the following structure:

project-root [com.mycorp:parent]
  |
  + --- server [com.mycorp:server]
  |       |
  |       + --- orm [com.mycorp.server:orm]
  |
  + --- client [com.mycorp:client]

You can specify the following command line:

mvn -pl .,server,:client,com.mycorp.server:orm clean install

to build everything. Remove elements in the list to build only the modules you please.


EDIT: as blackbuild pointed out, as of Maven 3.2.1 you have a new -el flag that excludes projects from the reactor, similarly to what -pl does:

Community
  • 1
  • 1
skuro
  • 13,094
  • 1
  • 43
  • 65
  • 2
    Thanks. This worked well for me. Also note that you can add the "-am" (AKA "--also-make") to also build projects that are required by the modules you have specified. – GaZ Feb 20 '13 at 14:15
  • 1
    Great! I used `mvn install -pl .` in order to install parent pom only in local repo without building modules. – Marcin Feb 27 '13 at 09:38
  • Also, take a look at https://jira.codehaus.org/browse/MNG-5230. You can now exclude projects from the reactor. – blackbuild Mar 20 '14 at 13:33
  • 1
    MNG-5230 link since codehaus.org closed: https://issues.apache.org/jira/browse/MNG-5230 – Ed Randall Jan 09 '18 at 10:33
  • Unfortunately, it doesn't work transitively, ie, if I have top/mod1/mod2, and build from top, -pl '!mod2' raises an error. – zakmck Dec 13 '19 at 18:31
4

The notion of multi-module projects is there to service the needs of codependent segments of a project. Such a client depends on the services which in turn depends on say EJBs or data-access routines. You could group your continuous integration (CI) tests in this manner. I would rationalize that by saying that the CI tests need to be in lock-step with application logic changes.

Suppose your project is structured as:

project-root
  |
  + --- ci
  |
  + --- client
  |
  + --- server

The project-root/pom.xml defines modules

<modules>
  <module>ci</module>
  <module>client</module>
  <module>server</module>
</modules>

The ci/pom.xml defines profiles such as:

... 
<profiles>
  <profile>
    <id>default</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <plugin>
       <artifactId>maven-surefire-plugin</artifactId>
       <configuration>
         <skip>true</skip>
       </configuration>
     </plugin>
  </profile>
  <profile>
    <id>CI</id>
    <plugin>
       <artifactId>maven-surefire-plugin</artifactId>
       <configuration>
         <skip>false</skip>
       </configuration>
     </plugin>
  </profile>
</profiles>

This will result in Maven skipping tests in this module except when the profile named CI is active. Your CI server must be instructed to execute mvn clean package -P CI. The Maven web site has an in-depth explanation of the profiling mechanism.

Sri Sankaran
  • 7,494
  • 4
  • 35
  • 46
2

there is now (from 1.1.1 version) a 'skip' flag in pit.

So you can do things like :

    <profile>
        <id>pit</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.pitest</groupId>
                    <artifactId>pitest-maven</artifactId>
                    <configuration>
                        <skip>true</skip>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>

in your module, and pit will skip

[INFO] --- pitest-maven:1.1.3:mutationCoverage (default-cli) @ module-selenium --- [INFO] Skipping project

twillouer
  • 1,109
  • 9
  • 14