How to share POM fragments between different POMs
I am currently struggling with Maven: I have a complex project made of several nested modules and for some of those modules, I have similar configurations in the POMs.
I would like to make it clean. Actually, I would like to define a "runnable-jar" common configuration and activate it in some modules.
Here is the POM fragment I would like to share between several projects:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<!-- Use a custom descriptor, with suffix "bin" -->
<descriptors>
<descriptor>src/main/assembly/runnable-jar-assembly.xml</descriptor>
</descriptors>
<!-- Add main class to manifest -->
<archive>
<manifest>
<mainClass>${mainClass}</mainClass>
</manifest>
</archive>
</configuration>
<!-- Add build of this package to lifecycle -->
<executions>
<execution>
<id>make-runnable-jar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
In some of the POMS, I would like to be able to do something like:
<!-- Set the main class -->
<properties>
<mainClass>my.main.Class</mainClass>
</properties>
<!-- Activate runnable jar build -->
<import>src/main/pom/runnable-jar-pom.xml</import>
I have searched for a mean to import some XML fragments 开发者_开发知识库into a POM, or to define a whole XML nodeset macro.
For what I have found, the closest solution would be to define a profile in the parent POM and activate it in some sub modules by testing the presence of a file. See this related question. But I am facing the problem of the {basedir}
property not being set correctly inherited / set.
I find it very surprising to need a hack to do something so basic (=usual). How do you usually handle this in Maven ?
I have just discovered something that might solve my problem :
A module does not require to be a sub-module of its parent module.
Parent and sub-module relationships are separate concepts.
You can specify a parent POM module that is not the actual parent folder in your folder structure, by using the relativePath attribute (as explained in the doc)
In my case, I use the following layout:
- main-project
- utils (parent:main-project)
- cli-programs (parent:main-project)
- generic-cli (parent:cli-programs; Dummy & empty POM module)
- cli-1 (parent:generic-cli)
- cli-2 (parent:generic-cli)
Then, in generic-cli/pom.xml
I can declare a configuration that is common to all my cli programs (like custom test suites, runnable-jar packaging, etc).
One way to do this would be to declare your <plugin>
code inside <pluginManagement>
of the parent pom of your multi-module project. The individual modules can then have a <plugin>
section which can use this without redeclaring the contents.
Parent pom:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
... all the details...
</plugin>
...
</plugins>
</pluginManagement>
Child poms:
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugin>
Maven-tiles solves this. It's also on the roadmap for maven 3.x, tracked here.
not a total answer but a solution to the basedir problem is to use a common layout of the modules, e.g. root/modules/moduleA root/modules/moduleB.
You can't build the modules formm their own directory anymore, only through thr parent project. But you can work with the profiles.
精彩评论