Given the following minimal Maven multi-module structure. Module A is released together with the project and the other modules of the project. However, it inherits from some other parent POM (rather than the project POM).
|--------------------|
|-------------| | module A that does |
| project POM |--- module --->| *not* inherit from |
|-------------| | project POM |
|--------------------|
How can I propagate or synchronize properties from project POM to module A?
Project
<project>
<parent>some-parent</parent>
<groupId>some-group</groupId>
<artifactId>my-project</artifactId>
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<modules>
<module>A</module> <!-- NOT inheriting from here -->
<module>B</module> <!-- inheriting from here -->
</modules>
</project>
Module
<project>
<parent>some-OTHER-parent</parent>
<!-- don't want to duplicate this, should be propagated from my-project -->
<!--properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties-->
<groupId>some-group</groupId>
<artifactId>A</artifactId>
</project>
First attempt
I wrote a small Groovy script for the GMavenPlus plugin that updates the module A pom.xml correctly synchronizing the project properties. However, even though the plugin runs in the validate phase (i.e. the earliest possible) it's too late. Maven already initialized the reactor with the old properties.
I want to give developers the convenience of simply running mvn some-task without having to worry about the properties being consistent. Managing those manually would be a pain.
8< ---------------
off-topic: the complete use case
I have a project ("my-project") that contains code other projects will consume: libraries, tools, utilities, etc (modules "B", "B+", "B++"). Furthermore, it contains a POM module (module "A") that said business projects will inherit from. That POM represents an opinionated blue-print that those projects should adhere to unless there are good reasons not to.
I need the project POM "my-project" to build all the modules "B", "B+", "B++".
The POM module "A"
has definitions very different from "my-project" as itself serves as a parent for the business projects.
(amongst others) lists all the modules "B", "B+", "B++", etc. in its dependency management section.
has to be released together with all the "B"s it manages -> that's why it lives in the same code project
shares a few external dependencies "X", "Y", "Z" with the project POM "my-project"
=> I need the versions for "X", "Y", "Z" in both the project POM "my-project" and in the POM module "A"
Related
We are using a parent pom that has a child module where we have 2 pom files - the one named pom.xml and other being images-pom.xml.
This is the situation because we are doing some naming changes and for the time being we want to have them both.
In our parent pom we have the following code
<modules>
<module>child</module>
</modules>
<packaging>pom</packaging>
By default it seems that this is looking and trying to build the pom.xml - but in reality we want to use the images-pom.xml Is there any way to achieve this without creating a new module and using profiles?
I have a single Git repository that contains several Maven modules, using Maven inheritance and Maven aggregation. That is, in the root directory, there is a parent POM, that defines some modules, each of which use that root POM as their parent.
<project>
…
<groupId>io.example</groupId>
<artifactId>parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<packaging>pom</packaging>
…
<scm>
<connection>scm:git:https://bitbucket.org/example/foobar.git</connection>
<developerConnection>scm:git:https://bitbucket.org/example/foobar.git</developerConnection>
<url>https://bitbucket.org/example/foobar</url>
</scm>
…
<modules>
<module>foo</module>
<module>bar</module>
</modules>
…
I recently found out that Maven will append the module path to the <scm><url> value for each module (foo and bar above). For example, the foo submodule would get an SCM URL of https://bitbucket.org/example/foobar/foo.
So should each of my modules redeclare the <scm> section, so that the submodule POMs have the same SCM URL as the parent POM? How does the Nexus Staging Maven Plugin use this SCM information, anyway?
I have also cross-posted this at Sonatype.
Regarding your initial question in the title: It does not use it given the code provided at github. When you search for 'scm' in all .java files you have zero hits. Of course they could do some weird tricks like building the String like "s" + "c" + "m" or it is hidden in some third party dependency or...
Still I think besides an offical answer, this is the best any outsider can tell.
I've a multi-module maven application that we need build through Jenkins.
Project structure is like:
a.xml
<artifactId>parent-1</artifactId>
<modules>
<module>lookup-1</module>
<module>lookup-2</module>
</modules>
lookup-1.xml
<artifactId>lookup-1</artifactId>
<parent>
<groupId>com.lookup</groupId>
<artifactId>parent-1</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>
<name>lookup-1</name>
lookup-2.xml
<artifactId>lookup-2</artifactId>
<parent>
<groupId>com.lookup</groupId>
<artifactId>parent-1</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>
<name>lookup-2</name>
now,
mvn clean install -f a.xml works fine. For this I created one Jenkins job.
Now, same as a.xml, I've another project with b.xml. b.xml has the same code as of a.xml except different Ids. So, I've created another jenkins job for b.xml.
Both jobs work fine. But, now I want to build both these project from single Jenkins job based on which project we commit in Git. For, this I want to have a new project(pom.xml) and where I want to put both a and b under modules tag. Like this:
pom.xml
<name>combined_project</name>
<artifactId>combined_project</artifactId>
<modules>
<module>a</module>
<module>b</module>
</modules>
a.xml
<artifactId>parent-1</artifactId>
<name>a</name>
<parent>
<artifactId>combined_project</artifactId>
</parent>
<modules>
<module>lookup-1</module>
<module>lookup-2</module>
</modules>
But, its not working for me. I'm getting following exception in maven:
Child module D:\....\a of D:\....\pom.xml does not exist
Maven not able to find child module.
I've following project structure:
project
|_ lookup-1
|_ lookup-1.xml
|_ lookup-2
|_ lookup-2.xml
|_ a.xml
|_ b.xml
|_ pom.xml
Any hint?
a.xml has 2 sub modules lookup-1 and lookup-2. By default maven is looking for the sub modules in the nested maps. So you need to have the following directory structure:
<parent>
|
+- a/pom.xml
| |
| +- lookup-1/pom.xml
| |
| +- lookup-2/pom.xml
|
+- b/pom.xml
|
+- pom.xml
Alternative is to change the parent into
<name>combined_project</name>
<artifactId>combined_project</artifactId>
<modules>
<module>a</module>
<module>b</module>
<module>lookup-1</module>
<module>lookup-2</module>
</modules>
Maven follows a project structure and each <module> will contain a pom.xml file. As you have explicitly stated the pom file in command line that file will be selected as the pom.xml for that project. However, for every submodule that is listed maven will search for the exact file named "pom.xml" for each submodule.
From the folder structure provided, it can be inferred that a.xml can act as a pom file when explicitly specified in command-line but it cannot act as a module as it does not have a dedicated folder with pom.xml.
A maven project in general has the following structure:
archetype-id(folder)
pom.xml(packaging: pom)(with one module module-artifact-id)
module-artifact-id(folder)
pom.xml
If you are attempting to build only the module that has been updated then the module that is not checked in recently will not be part of the newly created archive. But if you still would want to do it for some "special" reason. The following method might be the one you are looking for:
(I wouldn't recommend it -- as it is messy and goes against conventions)
Have two sub-modules in a single project and also Have two .xml files (pom files to be specified in commandline). In one xml file lets say "a.xml" "module-1" is to be specified as a module and in "b.xml" "module-2" is to be specified as a module.
Using the currently modified module invoke the build on that pom file. Example, if module-1 is modified specify a.xml in the command line as the pom.xml.
Please note that I have not attempted it but if it is possible this is one of the ways I can think of by which we can accomplish what you are looking for.
Reference for passing parameters : Pass a dynamic parameter in Jenkins build
Two possibilities :
Either you need to fix the path of your submodules in the modules section of the parent pom.
While creating a jenkins job you will have to tell jenkins to clone submodules as well. when I started with jenkins, I faced similar problem. The solution was to enable "Recursively update submodules" checkbox under Advanced scm behaviors in Jenkins UI.
I have a multi-module project built with maven. I need to run the project's integration tests daily. It is not possible to do this during the standard maven build cycle, because on runtime the integration tests defined within the modules have circular dependencies, which are illegal for me to declare on their poms.
Instead, I have created a separate project named Global that lists all modules jars and test-jars as its dependencies. Global has the same parent as all the modules. The idea is that using maven-ant-tasks I will be able to get a classpath of all modules jars and test-jars and go on from there. Global's pom.xml dependency section is as follows:
<dependency>
<groupId>mygroup</groupId>
<artifactId>A</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>A</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>B</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>B</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
...etc
The problem is that I cannot seem to get a classpath that contains all jars and test-jars declared on Global's pom.xml (and their runtime dependencies) using the ant tasks available. I have tried (among other things):
<dependencies pathId="cp1" type="jar" usescope="runtime">
<pom file="${basedir}/pom.xml">
<profile id="DEV" />
</pom>
</dependencies>
[1] This one fetches all runtime dependencies. Nothing wrong with that.
<dependencies pathId="cp2">
<dependency groupId="mygroup" artifactId="Global" version="myVersion" scope="test" type="test-jar"/>
</dependencies>
[2] This one fetches all runtime dependencies along with Global-myversion-tests.jar, but no other test-jar.
<dependencies pathId="cp3" type="test-jar" usescope="test">
<pom file="${basedir}/pom.xml">
<profile id="DEV" />
</pom>
</dependencies>
[3] This one fetches nothing.
Obviously, declaring something like [2] once for each module will do the trick, but I am looking to create a setup that will not need to edit a gazillion files each time a new module is added or removed. BTW I am using maven-ant-task-2.1.3.
Thanks for any input.
---Edits for #yannisf accepted answer---
You should not ever have cyclic dependencies
I assume you mean for maven builds. Having cyclic dependencies on runtime is pretty common, for example:
Module A declares interface: UploadToDocumentManagementSystem
Module B implements it in : UploadToCoolDms (that way in the future, when the DMS system changes to CoolerDms module B can be replaced by a new implementation with no side-effects to the rest of the app).
Module B depends on A compile time (and, by definition, runtime as well)
Module A depends on B on runtime
Maven does not allow to declare this. The reason, that I can sympathize with, is that maven needs to complete build cycles (including tests) of multi-module projects in a specific order. Thing is, it is not really necessary to declare it if you get rid of any runtime dependecy to B for the tests of A (which is good practice and should happen anyway).
You should do things the maven way instead of resorting to ant-tasks
Fair enough, I can see how maven-ant-tasks was not made for this use.
In your global pom you are declaring dual types for the same artifact (jar, test-jar)
Is that a problem in general? For example module A contains some samples for its tests that I would like to use in the tests of module B as well. Is it wrong (by maven best practices standards) to declare that B depends on A jar (compile scope) and on A test-jar (test scope)? Won't an integration tests project justify to depend on a module as well as the same module's samples and resources used for its unit tests?
tl;dr version: I will attempt to rearrange the tests declared on the modules and create separate module(s) for integration tests (assuming I can get 20 developers to play ball). Thanks for the answer and for making me admit defeat and stop trying to make maven work with the project instead of making the project work with maven :).
You are trying to break the maven conventions in many ways. 1. You should not ever have cyclic dependencies, 2. You should do things the maven way instead of resorting to ant-tasks 3. In your global pom you are declaring dual types for the same artifact (jar, test-jar).
Although at first this might not seem to answer your question, you should take a step back and rethink your layout. Integration tests need all the dependencies and are much more demanding than unit tests. So, instead of trying to fit them into the existing projects, create a separate maven project in the same group, that will only host integration tests (under src/java/test, main will be blank) and will have as dependencies all the other projects.
I have my project structure like this.
pro
pro-common
pom.xml
pro-list-history ==> [1] Packaging type pom
pro-list-main
pro-list-entities
pom.xml
pro-list-daos
pom.xml
pro-list-services
pom.xml
pom.xml
pro-search
pom.xml
pro-customers
pom.xml
pom.xml
pro2
pro-list-history
pro-list-main
pro-list-entities
pom.xml
pro-list-daos
pom.xml
pro-list-services
pom.xml ==> Want to use [1]
pom.xml
pom.xml
My question is is okay to use groupId and artifactID from [1] in the second project as shown above?
The referred module packaging type is pom.
Put a dependency section in the project two at the specified module as shown above, and specified as pom. Build is fine, but its not importing the dependencies from that project.
Can anyone help?
First, you can depend on a POM dependency. See: Netbeans: maven dependencies of type pom for an example and discussion.
However, I think you are asking if there is a short-hand way to import all the sub-modules of a "parent" module by specifying its pom.If so, see this question:
Maven - include all submodules of a pom as dependencies in another module
You can just reference the sub-module in another module like you would a file:
<modules>
<module>inside-project-module</module>
<module>inside-project-module</module>
<module>inside-project-module</module>
<module>../OtherProject/outside-project-module</module>
<modules>