Maven multiple parent-child hierarchy - maven

I have a project that is built in the next manner:
parent module named Production, it holds two modules named apps and libs, each of them holds various projects.
Production
apps
common
utils
libs
api
dev
Production pom
<groupId>com.prod</groupId>
<packaging>pom</packaging>
<modules>
<module>libs</module>
<module>apps</module>
</modules>
Apps pom
<parent>
<groupId>com.prod</groupId>
<artifactId>apps</artifactId>
</parent>
<modules>
<module>common</module>
<module>utild</module>
</modules>
Where packaging of Production, apps and libs is pom.
While the packaging for the rest is war/jar.
When I try to run mvn install on Production (or any other module/project) I get Non-resolvable parent POM: Failure to find
Only when I run mvn install -N on Production, apps and libs, I can finally start working with the projects.
Is there a better way to accomplish successful modules and projects alignment without running mvn install -N? some pom definition or some other solution?

Without seeing your POMs, I am guessing that you are missing <module> elements naming the children in Production, apps and libs POMs.
Once you have that, if everything else is in order, you can build from the Production folder with mvn install and have the reactor figure out what the right order to build the various modules are, subject to inter-module dependencies. Note that the <module> elements are relative paths to the child projects, not anything to do with the GAV of the project.
See http://books.sonatype.com/mvnex-book/reference/multimodule.html for more information about proper setup for multi-module projects.

Related

How to compile specific dependencies using maven

I have a situation where in i need to clean and install couple of dependencies of my maven project. While I am working on this project i am making changes in these dependencies and have to manually clean and install for every small change i am making. I am trying to find a maven command which will make my life easy.
project-bpm-process <-- parent project
project-odata-service - < dependency >
project-core-service - < dependency >
I cannot put them as sub modules as they are not really modules of my this project, they are simply dependencies. So, literally group-id does not match in complete sense (there is a partial match but does not help in any way).
Update 1:
Tried the option 2 suggested by Mark. I see below error which indicates that the sub modules (aggregated projects) are not found under the parent project's folder.
[ERROR] [ERROR] Some problems were encountered while processing the
POMs: [ERROR] Child module
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\project-core-service
of
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\pom.xml
does not exist #
[ERROR] Child module
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\project-odata-service
of
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\pom.xml
does not exist #
[ERROR] Child module
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\project-bpm-process
of
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\pom.xml
does not exist #
I just created a new maven project with packaging "pom" type and added other projects as modules. Now, "project-bpm-process-artificial" has become artificial parent of all the three projects I was talking about.
From maven documentation, i see that the path is relative.
Update 2:
Location of actual pom is located at: *E:\STS-Workspaces\default-workspace\project-bpm-process-artificial*
But other referenced projects are in *C:\Users\ramgo\git* and *E:\git-repos*. These projects are imported into eclipse for development.
The pom.xml is here:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>project-bpm-process-artificial</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>project-bpm-process-artificial</name>
<url>http://maven.apache.org</url>
<modules>
<module>project-core-service</module>
<module>project-odata-service</module>
<module>project-bpm-process</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Solution: For all practical reasons I found option 1 is easy to implement (option 1 provided by Marks). It hardly took 5 minutes to write a batch script. Here is the one for handy reference.
set core=<directory_path_of_core_project>
set module_one=<<directory_path_of_module_one>>
set module_two=<<directory_path_of_module_two>>
cd %core%
call mvn clean install
cd %module_one%
call mvn clean install
cd %module_two%
call mvn clean install
Option 2 seems interesting but not feasible in my case. Links don't work and no way to refer absolute path for sub modules.
.....
The notion of Maven dependency assumes that the artifact is build externally (not even necessarily with maven) and available to your project as a third-party jar.
So, the terminology in the question is misleading to me.
If you have some third-parties (I assume having their own pom.xml) but are external to your project, then obviously in your project you can't manage them. Maven can't build external stuff.
So, based on these assumptions, the choices are:
Option 1
Create a script that will:
enter the dependency directory
run mvn install on that directory
enter your project's directory
run mvn whatever on your project
Option 2
Create an "artificial" pom.xml that will have packaging type "pom" and will list both your project and the dependencies as submodules (your project and dependencies will be peers):
|__some_folder
|__pom.xml
|__dependency1
| |__pom.xml
|__dependency2
| |__pom.xml
|__your-project
|__pom.xml
In this case you will be able to operate with both your project sources like one project and you'll be able to use the following:
cd some_folder
mvn clean install --projects <your-project> --also-make
So that if your project has dependencies in other modules, they'll also be built
I would probably go with the second option, but its your choice really
Update 1
Based on the information you've provided:
Don't really count on eclipse, its not really relevant at this point. You should try to get to the point where running maven from command line should work. The eclipse will follow your poms once you've done everything right.
If you place the "artificial" pom into E:\STS-Workspaces\default-workspace\project-bpm-process-artificial then all the modules should be in sub-folders:
E:\
|_ STS-Workspaces
|_ default-workspace
|_ project-bpm-processes-artificial
|_ project-core-service
| |_pom.xml of that module
| |_.git // it can be a root of git repo
| |_src
|_ project-odata-service
| ...
|_ project-bpm-process
After that you can do the following to check yourself:
cd E:\STS-Workspaces\default-workspace\project-bpm-process-artificial
mvn clean install
It should compile all the libraries and your project
Then if you want to build your project (assuming its called project-bpm-process) then you can do from the same folder:
mvn clean install --projects project-bpm-process --also-make
If it has a dependency on project-core-service but, say, not on project-data-service then only the project-core-service will be rebuilt
Now when the maven if sorted out, you can add eclipse workspace in any other folder. I can't comment much on eclipse since I'm an IntelliJ user. In intelliJ you can just import this artificial pom and it will automatically recognize all the projects. In eclipse I think it should work similarly

Setting subproject pom.xml to be ignored by parent install

My parent pom modules list looks something like this:
<modules>
<module>jarProject1</module>
<module>jarProject2</module>
<module>jarProject2</module>
<module>warProject1</module>
<module>warProject2</module>
</modules>
I would like warProject1 and warProject2 to be ignored when I run mvn clean install on the parent pom. I want install to only build jars and put them in the maven repo but not the war producing projects. Currently I do it using profiles but I have some problems related to that. I would like the parent pom to keep a comprehensive list of modules in its default modules tag and not under profiles. Is there a way to do it and how?

Maven build skips submodules which are dependency in another module

I have nested multi module maven structure like this:
main_aggregator
|- submodule_A
| |- sub_submodule_1
| |- sub_submodule_2
|- submodule_B
|- submodule_C
pom.xml in main_aggregator has this in modules
<modules>
<module>submodule_A</module>
<module>submodule_B</module>
<module>submodule_C</module>
</modules>
pom.xml in submodule_A has this in modules
<modules>
<module>sub_submodule_1</module>
<module>sub_submodule_2</module>
</modules>
parent of main_aggregator's sub modules is something like this:
<parent>
<groupId>my.project</groupId>
<artifactId>main-parent</artifactId>
<version>0.0.1</version>
<relativePath/>
</parent>
parent of submodule_A's sub modules is something like this:
<parent>
<groupId>my.project</groupId>
<artifactId>specific-parent</artifactId>
<version>0.0.1</version>
<relativePath/>
</parent>
The important thing is that submodule_B has dependencies on sub_submodule_1 and sub_submodule_2
When I run build from main_aggregator, it fails and says it could not resolve depenencies for submodule_B - sub_submodule_1 and sub_submodule_2.
In reactor summary I see, that submodule_A was built first and built is success, but it's sub modules - sub_submodule_1 and sub_submodule2 are skipped. So I understand, why it fails on missing dependencies, but what I don't understand is why maven didn't built those dependencies first. Also I don't understand why build of submodule_A is marked as successful when it's sub modules wasn't even built.
Maven version is 3.5.2.
Update:
When I run build in one thread, there is no problem. Problem occurs only when doing parallel build.
Update2:
Running in single thread was only partial success. See my answer...
So I found out what was the problem. The problem was some kind of "copy paste exception". In submodule_A which is an aggregator, I have copied pom from main_aggregator. Of course I changed main things like group id and artifact id, but I didn't change plugins.
Plugin which caused that problems was javadoc. Particularly it's agregate goal. When I deleted it, I could build whole project (but not in parallel).
Problem was, that evidently during parallel builds, aggregators projects are build "out of order" because it has no dependencies (submodule_A start build before it's submodules were build). Now javadoc aggregate comes to play.
Javadoc aggregate forked every submodule build (maybe this is wrong terminology). But this was not ordered by dependencies, so it fails.
There still is problem with parallel builds, because aggregate goal of javadoc in main_aggregator cause the same problem. But that is for another question.
There is one more lesson I learned from that. If I would put content of whole pom.xml of each module in my question, somebody probably would see the problem.
So when you are asking something, don't hide details even when you think they does not matter :)...

Maven - import / group all modules of project

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.

Custom pom.xml filename in Maven multimodule for Tycho

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.

Resources