I have a parent project with around 20 child modules:
<project>
<modules>
<module>module-1</module>
<module>...</module>
<module>module-20</module>
</modules>
</project>
I would like to use this project as one single entity, with all 20 modules included, in other projects. What is the convenient way to do this in Maven?
Should I make a new child module which imports the other 20 modules and refer to this project? Should this be a JAR or a POM project?
<project>
<packaging>jar</packaging>
<dependencies>
<dependency>... module-1 ...</dependency>
<dependency>...</dependency>
<dependency>... module-20 ...</dependency>
</dependencies>
</project>
I think the way you mentioned in your question is a good idea. It is actually mentioned as a best practice in the Maven book, quoting:
If you have a set of dependencies which are logically grouped together. You can create a project with pom packaging that groups dependencies together.
You can create a new module called module-all, which would be of pom packaging, that simply has a dependency on each of the modules. The packaging should be pom because the primary artifact of this module will only be the pom.xml (there will be no sources to compile, no JAR...). Then, in your external projects, you can simply add a dependency to this new module (as <type>pom</type>) and every module-i dependencies will be included transitively.
There would be a cave-at if all of your modules did not share the same version: there would need to be a reference to a specific version of a specific module and you would have to update the module-all version each time a module's version changes. However, if they all share the same version, module-all release cycle would be in line with module-i's.
Related
If I have a POM that contains a dependency of type=POM, e.g.
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>mysql-starter</artifactId>
<version>1.0</version>
<type>pom</type>
</dependency>
I see that the included POM can contain other dependencies, thus providing a way to package together a set of related dependencies.
Can the reference POM also contain build steps?
For example: Use the resource plugin to copy certain files that are needed when using the specific JAR mentioned in its dependencies.
Dependencies of type pom may contain some build configuration information (such as resources, plugins or pluginManagement) but any of them will be executed for the current project but if you configure the pom of the current project to invoke them.
In fact, only the current pom and the parent pom of the current project define in the build element the build information/taks of the current project.
I have a project with a couple of dozen Eclipse plugins, all inter-related and living in different subfolders. The build was converted to a multi-module manifest-first Tycho build a couple of years ago and it works quite well.
One of the plugins is rather key, and can also be built as a standalone Java app, which doesn't use an Eclipse runtime. Currently it has its own POM file (pom-standalone.xml) so that Jenkins can build the standalone app separately and the Tycho build knows nothing about it - the pom-standalone just lists the previously-built plugin jars (thanks Tycho!) and Eclipse libraries that it needs as dependencies. Couple problems with this approach though:
I cannot easily use IntelliJ to work on the standalone project with Maven dependency management, because it doesn't recognize the custom pom-standalone.xml filename as a POM.
The many jars that this project relies on are checked in to the project for the sake of Tycho and the Eclipse Manifest file, but they're also managed by Maven for the standalone build. So any dependencies have to be added to the pom-standalone.xml file AND entered into the OSGi manifest AND checked in to the source control for Eclipse purposes.
It seems like a straightforward workaround would be to tell Tycho/modules to use something other than pom.xml for the submodule's POM, or perhaps all the multimodule POM files, since Eclipse doesn't use those anyway - then the pom-standalone.xml can be converted to pom.xml and then IntelliJ will be fine with it.
I know you can specify the -f attribute to Maven builds, but will that really apply to all submodules? Can you specify the POM filename for just ONE submodule?
Are there alternative solutions? Eclipse/Tycho/p2 builds seem somewhat of a headache requiring manual library management and checking in libraries to source control, but maybe there have been changes I'm not aware of in the Eclipse build world the last few years.
Found a Similar Question that didn't help much.
You can include projects in an aggregator POM by specifying the full name to the POM file with custom name. Example:
<modules>
<module>org.example.bundle1</module>
<module>org.example.bundle2</module>
<module>org.example.keybundle/pom-tycho.xml</module>
</modules>
This both works in a pure Maven and Maven/Tycho build.
To extend #oberlies answer a little bit:
SCENARIO: top aggregation POM comes in multiple flavors, so any style can be built from the top.
<!-- in file pom.xml -->
<modules>
<module>org.example.bundle1</module>
<module>org.example.bundle2</module>
<module>org.example.keybundle</module>
</modules>
All submodules will be built using their standard pom.xml
and
<!-- in file pom-tycho.xml -->
<modules>
<module>org.example.bundle1/pom.xml</module>
<module>org.example.bundle2/pom.xml</module>
<module>org.example.keybundle/pom-tycho.xml</module>
</modules>
Submodules will be built using the specifically named POM file.
and, likewise:
<!-- in file pom-special.xml -->
<modules>
<module>org.example.bundle1/pom.xml</module>
<module>org.example.bundle2/pom-special.xml</module>
<module>org.example.keybundle/pom-tycho.xml</module>
</modules>
Submodules that have custom POM files use them, and others state they still want the normal POM file, all independent of the name of the top aggregation POM file.
Because mvn -f pom-tycho.xml assumes that file name in all submodules. So if you do want pom.xml in any submodule when the top file isn't named pom.xml you need to fully specify for each submodule.
I would like to import properties from a project X pom file into my project Y pom such as library versions. I do not want to make the project X my project's parent.
I have tried to include project Xs pom in the dependency management section as an import.
<dependency>
<groupId>abc</groupId>
<artifactId>def</artifactId>
<version>1.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Please advise.
Thanks.
I think, today, the answer is NO. You can't read properties from external dependency without inheritance.
However a hack can be done with the codehaus Properties Maven Plugin. In fact, it can load maven properties from an external file. It can even use classpath: URLs to load files from. So you might try to load those from another dependency (which should have an appropriate scope since you probably do not want that dependency's JAR to hang around at runtime).
The usual approach to share dependency versions without using parent POMs are BOMs.
These are separate projects that only contain a pom.xml which consists of <dependencyManagement>. This can then be imported in several other projects with <scope>import</scope>.
These other projects then import the dependencyManagement inside the BOM.
Basically, you need to create a parent pom which is imported by both projects.
The parent has a <dependencyManagement> section which lists groupId, artifactId and version
The child pom's only need to list groupId and artifactId since the version is inherited from the parent's <dependencyManagement> section
eg:
root/pom.xml - Builds all modules, a simple pom with a `<modules>` section which includes parent, project1 and project2
root/parent/pom.xml - This has a `<dependencyManagement>` section
root/project1/pom.xml - parent=../parent/pom.xml
root/project2/pom.xml - parent=../parent/pom.xml
More info here
In a multi module project structure as
myApp
|-moduleA
|---pom.xml
|-moduleB
|---pom.xml
|-pom.xml
If i have the following properties in the parent.pom
<properties>
<moduleA.version>4.67</moduleA.version>
<moduleB.version>4.68</moduleB.version>
</properties>
How can i access the properties in the parent pom from any of the child poms? I tried this on the child pom but it didnt work.
<groupId>com.test</groupId>
<artifactId>moduleA</artifactId>
<version>${moduleA.version}</version>
If you have a real multi-module build you should never define the modules to have different versions. They should have the same version which make releasing possible and other things as well. Otherwise you should not use the multi-module setup than use simple single modules which are separated.
This should work. One possible reason I can think of is that perhaps you don't actually inherit the pom where these properties are defined (i.e. it's not defined as your <parent> directly or indirectly), but you only have a main pom that aggregates your projects. It's a guess, though.
I have a multi module project like this:
gwt-app
model
webapp (depends on gwt-app and model)
when I try to execute any goals in webapps, for example, launch jetty, build fails because maven can't find its dependencies (I didn't install modules into a local repo). Is there a possible way to reference the parent pom so that when I run any goals in a submodule, all its dependencies will be compiled (recompiled)?
An example of your pom files would be great but in multi module projects I always declare the dependencies in the parent pom in the dependencyManagement tag:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
</dependency>
...
In the module pom I just delcare the dependency without the version:
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
</dependency>
...
That way were are sure each module uses the same version.
The thing to remember is that modules in maven do not inherit dependencies from the parent. You must declare the dependencies used in the module itself.
Another thing is, I believe that when you are running outside of an IDE (which searches the workspace for dependencies) you need to have each module installed in your local repo. I do not think maven will search for un-installed dependencies within a multi module project if you are not executing on the parent pom.
If you make your parent pom just have regular setup like
<plugins>
</plugins>
<dependencies>
</dependencies>
Then anything in those groups are inherited automatically into the child pom. Child pom just needs the parent section in it:
<parent>
</parent>
You don't even need to declare the same plugins or dependencies in the child pom in this manner. You only need to list the plugins or dependencies in the child pom IF you use or in the parent pom OR you want to override something in the parent pom. I actually just went through all of this week and have my builds working nicely now (small child poms with more things in the parent pom like plugin configurations).
I asked a question about this that might help you:
Maven - Parent Pom - Child Inheritance