Inter Project Dependencies in Maven - maven-2

I have two maven projects:
project-api
project-impl
project-impl's POM specifies a dependency on project-api. The top level aggregation pom lists modules project-api and project-impl.
If I run compile at top level, the dependencies resolves correctly. If I run compile at project-impl, then it can't find dependency project-api. How can I set up maven such that when project-impl compiles, it first compiles and collects its dependencies on other projects?

you can only do that from the root project
mvn -pl child -am
this will build your sub project and also all dependencies in the same tree. in general, when you have a multi module project, you should always build from the parent, never from the child. And if you only want to build one or two child projects, do this:
mvn -pl child
OR
mvn -pl child2,child3
(projects child2 and child3 are build, but child1 and child4 aren't)

You need a dependency on api in the POM of the impl module.
When you compile on the toplevel project the reactor will figure out the right order to build things.
To separately build the project-impl you must first 'mvn install' the the project-api module or it will not find the right dependencies.
If you work in a team, an automated build server which pushes artifacts to a central repository can help to ease the pain here because this can drive you nuts.
This all works very well, however ot works the "maven" way, which is not always as we humans would do things.

Related

maven release:perform and parent pom

I have a library which I "mavenized" recently and put into a local git repository.
In order to lock some plugin versions I created a simple parent pom which defines the plugin versions via pluginManagement (the parent pom file is not checked into any SCM repository). I specify the parent pom in my libraries pom file:
<parent>
<groupId>org.my.company</groupId>
<artifactId>superpom</artifactId>
<version>1</version>
</parent>
I use default directory structure.
When I try to perform a release using the release plugin I run into a problem.
mvn release:prepare runs fine however when I run mvn release:perform maven checks out the corresponding tag from my local git repository into the target/checkout folder and tries to run the deploy goal.
However the build fails with the error message that it can't find the parent pom file defined in my library pom file.
I assume that's related to the fact that maven tries to find the parent pom file in the target folder and it is not available there.
Is there an easy way how to solve this problem?
Update:
I have multiple unrelated GWT libraries which should share the common company parent pom file in order to specify plugin versions.
The parent pom is just used for defining some default versions and won't contain any module definitions because all GWT libraries are unrelated.
The GWT library are really simple and have no real dependencies to any other libraries apart from the default ones (gwt, junit)
Update2:
I solved the problem by installing the superpom into my local repository by running mvn install in the folder of my superpom.
The first fail you did is not to versionise the parent pom where you defined the pluginManagement area. This is the first step you must do put the pom.xml which you like to use a parent. Secondly you have to put the information about the VCS into the scm area of that pom. After you cleaned up everything you must do a mvn release:prepare release:perform of the parent pom. After that you are able to use it as a parent in your other projects. Furthermore you should define the distributionManagement area in your parent pom.

Maven 2 - 'mvn test' does not find internal project plugin dependency

I have a multi-module maven project (maven 2.2.1).
One of the module is a maven plugin.
This plugin is bound to the compile phase of another module, and added as a direct dependency to trigger correct reactor ordering of module's building.
If I run 'mvn clean install' on the root module, with a fresh local repository, everything goes fine (build, test, install). (I precise that my project's artifacts are not deployed anywhere, only installed locally in my machine's local repo).
BUT if I delete my local repository, and perform 'mvn test', the plugin module is reported as missing ? Whereas, the build order is correct, the plugin module is built succesfully before the module using it ???
Is there any special treatment of maven module with 'maven-plugin' packaging ?
I don't understand why other project inter modules dependencies are resolved correctly and not this specific one !
The problem is that a Maven Plugin must be installed into the local repository first before you can use a plugin as a dependency (or better be part of the life-cycle).

Building Products with Maven

I'm fairly new to Maven and I'd like to use it to build a multi-module project.
Lets assume I have the following svn repository structure:
- /trunk/common-services/login-service
(.jar) [re-usable components]
- /trunk/services/mybusiness-service
(.jar)
- /trunk/webservices/mybusiness-rest
(.war)
- /trunk/products/myproduct
(pom) [issue mvn command here]
What I'd like to be able to do is to checkout and build the entire "product" from a single pom using a single mvn command (from a developers pov as well as a CI pov). It's safe to assume that I have the trunk checked out.
How do I do this using Maven? I've looked at the Maven reactor plugin, but I can't figure out how to use it correctly (if it is the correct plugin to use).
The reactor plugin assumes each module has its pom.xml.
For your use case, you would want to create a pom.xml for each module (login-service, mybusiness-service and mybusiness-rest). You would specify the dependencies in each of the modules. For instance, if your mybusiness-rest depends on login-service and mybusiness-service, you would specify these projects as dependencies.
You would have a pom.xml in /trunk which specifies each of the modules to be built. You can use the reactor features in this pom.xml to determine, when to build (or not build) specific modules.
Your developers and CI can build using this single pom.

how to run only parent pom.xml in maven multi-module project

I have maven multi-modules project. At the parent level, i have some java files. And in the parent pom.xml, at the package phase i do some stuff.
Usually, when i run mvn package at parent level, the package phase of parent pom will be run and all the modules will be packaged as well.
I am looking for a way that allow me to do these (when i run mvn package):
allow me to run only paren pom.xml (the script at the package phase), not the modules. This is the 1st priority.
allow me to run paren pom.xml and some particular modules (like module 1, module 2 BUT not module 3 , module 4).
Can i use profile for those issue?
Thanks.
While I agree with the fact that you may not have optimal project structure, the answer is that Maven 2.2.1 has an option "--non-recursive" which satisfies your first requirement:
-N,--non-recursive Do not recurse into sub-projects
So something like this:
mvn --non-recursive clean compile
Why do you want to have java code on the top level? In my opinion this is not a very good idea. Have your code in the subprojects and let the top-level project be responsible for holding the general information and configuration of the entire project.
If you have some base-library code in the top-level project now, you can put it in a sub-project and set up dependencies between the projects.
Take a look at Maven parent pom vs modules pom
The nature of your question indicates that your project structure may not be optimal.

Version propagation in Maven

I have a multi module maven project and I would like to use versions in such a way that the developer has to touch only the root project pom to change the version of all modules.
For example
ProjA contains
Module1
Module2
Module3
All the modules contain their own Poms and have ProjA's pom as their parent. Once I run the build I get a jar created for each module. Now For building a newer version of ProjA, I just have to change the version of the ProjA's pom and all the poms of the modules should pick up this new version from the parent. This works if I harcode the parent version in all the module's pom. But this will also force me to update the poms of all modules for every version change in the parent pom which defeats it purpose.
Is there a way to avoid this and still achieve the stated behaviour?
Use the Maven Versions Plugin and its versions:update-child-modules goal:
versions:update-child-modules updates the parent section of the child modules of a project so the version matches the version of the current project. For example, if you have an aggregator pom that is also the parent for the projects that it aggregates and the children and parent versions get out of sync, this mojo can help fix the versions of the child modules. (Note you may need to invoke Maven with the -N option in order to run this goal if your project is broken so badly that it cannot build because of the version mis-match).