Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inherit from a multimodule Maven project with all its goodies?

The problem to which I cannot find a nice, scalable solution:

I have a project that delivers multiple flavours of the given artifact. This has been set up as a multimodule project, currently with 3 modules:

  • /flavour1_module
  • /flavour2_module
  • /flavour3_module

The thing is that I have another 50 projects that need to be setup in the same way, i.e. delivering the 3 flavours.

Solutions considered:

  1. turning the already created multimodule project into a parent for all other 50 projects
    • Cons: It just doesn't work. The instructions kept withing parent's modules are not inherited, thus they are not executed.
  2. using maven-archetype-plugin to create a multi-module project template, and then creating all 50 projects based on the template
    • Cons: if I would need flavour4, I need to manually update all 50 projects to add flavour4_module (and duplicate its content). Not scalable.
  3. embedding the configuration of all flavours into a single pom and enable or disable them based on profiles (i.e. using composition by profiles instead of inheritance via modules). Then pointing the 50 projects to it, as their parent. This would create "inline" modules
    • Cons: I would need to implement on my own mechanisms which are provided by modules out of the box. (e.g. building every flavour in a separate directory). I would also lose the clear seperation that modules provide.

Any ideas how to do it nicely? Is there any other option?

Thanks, Lukasz

Edit:

Another option would be extending the maven-reactor-plugin with reactor:inject-modules goal, which would download module definition from an external artifact, and attach its definition as a normal module. This would create a new module on the fly. Then all 50 projects could make this pom.xml their parent.

The configuration would look like this (a draft):

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-reactor-plugin</artifactId>
  <version>1.0</version>
  <executions>
    <execution>
      <id>inject</id>
      <phase>initialize</phase>
      <goals>
        <goal>inject-modules</goal>
      </goals>
      <configuration>
        <modules>
          <module>
            <artifactId>flavour1_module</artifactId>
            <groupId>[ groupId ]</groupId>
            <version>[ version ]</version>
          </module>
          <module>
            <artifactId>flavour2_module</artifactId>
            <groupId>[ groupId ]</groupId>
            <version>[ version ]</version>
          </module>
          <module>
            <artifactId>flavour3_module</artifactId>
            <groupId>[ groupId ]</groupId>
            <version>[ version ]</version>
          </module>
        </modules>
      </configuration>
    </execution>
  </executions>
</plugin>

Would going this way make sense?

Update:

Writing a plugin that manipulates the list of modules to execute (the idea of module injection that I described above) doesn't seem to be possible to implement, because modules are processed by maven core, and the mechanism was not designed to be extended with a plugin. This is confirmed by the fact that both plugins that do a similar job i.e. manipulating the list of projects to execute:

  • maven-reactor-plugin
  • maven-invoker-plugin

do the trick by executing a system call to create maven child process. For me it is not the way to go, because it's a very unstable solution. Indeed maven-reactor-plugin became incompatible with Maven3.

maven-invoker-plugin still looks promising. The plugin was originally designed to run integration tests, but it would be possible to use it to extend e.g. the compilation phase. But it requires the child pom.xml-s to be treated as resources and modified on the fly. For the problem that I described here the solution would be too complicated and unstable. I would prefer something lighter that could operate in memory while building maven model.

So for now I use profiles, trying to make them as compact as possible. Probably in a while I will need again to think about the problem.

like image 474
Lukasz Guminski Avatar asked Apr 20 '12 11:04

Lukasz Guminski


1 Answers

Now you can use the maven-tiles plugin to get the desired behaviour.

With maven-tiles you can define build behaviours in different poms and import them wherever you like.

There's a working sample attached to MNG-5102 --> daddy3.zip

Maven's inheritance-only strait jacket is now officially removed.

like image 52
Tony Lâmpada Avatar answered Oct 14 '22 00:10

Tony Lâmpada