Integration testing of Maven Plugin submodule - java

I have Maven project with multiple submodules. One of these submodules, let's say submodule X depends on all other submodules, as it is Maven Plugin that integrates everything else.
Now I want to use this Maven Plugin during verify stage in my parent POM to do real run of it over entire project (kind of eating own dogfood).
Unfortunatelly I'm getting error:
The projects in the reactor contain a cyclic reference
So how can I make such dogfood integration test for a Maven Plugin submodule?

I would review aggregation and inheritance: they are indeed two different concepts in Maven often used in combination but which can however be used in a complete separated manner as well.
In this case, your plugin submodule is certainly defined as a module in the aggregator pom (that is, it is a submodule). But I also presume the plugin submodule also has as parent pom the aggregator pom as well (that is, the aggregator pom is also the parent pom, which is a normal approach, but not always required).
Is the latter required? You could keep on having the multi-module/aggregator approach without necessarely having the aggregator as parent of the plugin submodule. As such, the plugin subModule would still be a module of the aggregator pom but it would not have as a parent the aggregator pom, decoupling it from it and as such breaking the cyclic dependencies.
Possible drawback: in the aggregator pom you were also defining common things (dependencies management, properties) required also in the plugin submodule. If the case, you would then need to duplicate/review these common settings only for the concerned submodule.

Small suggestion from my side. Cyclic means you have some transitive dependency in your modules. Can please check the dependency tree of your modules and resolve the circular dependency first.

Related

Using dependency management in a child pom

Is there any reason to use the dependency management section in a child pom? I'm looking at a maven project in my organization that uses inheritance and aggregation, where the parent and child poms both have a dependency management section. Is the child one doing anything?
I found this question really helpful but didn't find the answer to my specific question - Differences between dependencyManagement and dependencies in Maven
It can be used to control the version of transitive dependencies (libraries that your direct dependencies depend on) without adding a direct dependency.
Child POM will add or override dependency management entries of the parent POM.
Keep in mind that you really, really don't want to have different versions of the same dependency in your codebase. So use this feature judiciously. Preferably you should have organization-wide parent POM file with all dependency versions defined and child POMs don't change them.
In a child pom it does not make sense.
In a multi module setup you should control everything for all children in the parent. For example solve version conflicts / excluding transitive dependencies or import BOM files from other frameworks/libraries (for example spring boot/junit 5/etc.) makes handling of those libs including the centralised maintenance location...

How to define common configurations in maven projects

I hope this is the right place and right discussion to start.
What I want
I am looking for a good/the right way to handle multiple maven projects, that share a common configuration, which is in my case
Set the maven-compiler-plugin version with source/target compilation version
Set the maven-source-plugin to attach sources to artifacts
Define local repository server
Define common dependencies (via dependencyManagement and dependencies).
What I did
My first approach was to create a multi module project. But as the modules are actually independant, when it comes to release (so not the same release cycle), it seemed to be more a burden as a gain. I also failed to make it that I can independently work with a submodule in IntelliJ and have for each submodule it's own Jenkins job. For me it was always all or nothgin
The second approach was/is to have seperate projects. This makes coding in IntelliJ simple and Jenkins can have jobs for each project.
But now changes to parent pom, which affects the children, are tedious to delegate as all other projects must adopt to the change to the new parent.
It is doable and might be the way to work with this, but as I am afraid I misuse the parent concept here, I was wondering, whether there is a better way to use common settings in multiple maven projects ?
Thanks for reading and I hope this was understandable
You can re-use dependencies management section from different pom using <scope>import</scope>, described here, but that would work only for dependencies and you cannot do that for properties, repos and etc.
I'm afraid there is no better way to solve you problem then the parent-pom. Actually this is widely adopted approach. Spring boot, for example, uses that for a long time already.
One thing you want to do to is a good release management for that parent pom. Be sure that you are not dependent on SNAPSHOT version to not brake existing projects.
Just create a parent POM with the common settings and keep the rest separate.
Publish that POM to the (local) repository separately as a standalone entity with pom packaging (no submodules at this level).
Have a look at the Spring Boot parent POM as an example.
The only change in your projects would then be to use your new POM as the parent POM.
<project ... >
<parent>
<groupId>my-group</groupId>
<artifactId>my-parent</artifactId>
<version>1</version>
</parent>
...
Note however that it is generally not a good idea to hardcode dependencies in the parent POM (defining versions via dependencyManagement is OK, but let each project specify explicitly which dependency it actually needs).

Transfer a Maven dependency + all transitive + parent POM

My project stores its dependencies in a Maven repository. I would like to be able to move certain dependencies to another Maven repository. The move is the easy part. But it's what to move that is difficult for me to get right.
In order for build tools such as Maven or Gradle to be able to use the moved dependency in a build, I need to also transfer (1) transitive dependencies (recursively) and (2) the project's parent POM file, performing (1) again on the parent until all nodes in the dependency graph are exhausted.
This seems like a very common usecase and I'm hedging my bets on the fact it has been implemented many times over.
Question: Are there common libraries that implement this functionality out-of-the-box?
If not, I'll probably have to implement a custom POM parser. Are my assumptions above about what needs to move correct?
The copy-dependencies goal of the maven-dependency-plugin may help you on this task:
Goal that copies the project dependencies from the repository to a defined location.
It also provides an option, addParentPoms to also copy the parent poms required by the build (hence, the whole hierarchy). This option is not enabled by default though.
Moreover, via the different include/exclude options (by group Id, by artifact Id and so on) you may filter what you actually need to move.
Via its excludeTransitive option you may also check whether transitive dependencies are required or not: by default is set to false, hence transitive dependencies will be copied too.
Via its outputDirectory option you can specify where to copy dependencies, transitive dependencies and hierarchy of pom files, according to any specified filter.
You may also be interested in the combination of the purge-local-repository goal of the maven-dependency-plugin, to delete from your local repository whatever required by the project (including transitive dependencies, hierarchy of pom, plugin dependencies) and the go-offline goal to prepare the project for off-line mode, that is, to resolve (download) whatever required. Again, both goals provide include/exclude mechanisms and transitive dependencies management so that you may refine your strategy and outcome.
mvn dependency:list will give you list of all dependencies of your project, including transitive dependencies and dependencies specified in your parent pom.

Maven dependency grouping via poms

I have a multi-module maven project that uses some dependencies from netflix. The trouble is that those dependencies are built using gradle and use a runtime scope. When I build my project I then have only the direct dependency loaded but not it's own dependencies.
To fix that I added dependencyManagement entries to transform all the runtime scopes to compile scopes. They usually go in pack of 10 to 20 entries so what I want is to be able to make some pom that would only address this issue and be able to load it any time I need a dependency.
I know this can be done as i've read Maven pull dependencies via middle pom file and How to use POMs as a dependency in Maven? but I was wondering how I may carry those poms inside my current multi-module project.
I'd like to have those in my parent module and avoid needing to create one sub-module per pom. Like pom-dep1.xml, pom-dep2.xml... and have those bundled in my build. Is that possible ?
Thanks

Maven inheritance and aggregation

I'm just curious, what happens if there are used both inheritance and aggregation in the same maven application?
This is the application structure:
my-project-app
my-project-jar
my-project-war
Now, in app's pom.xml, I declare jar and war projects as modules, and in the same time the the poms from both modules declare the app pom as their parent. It is create some kind of redundancy here, isn't it?
What is the best solution for this case?
It's not redundant. They both do different things.
If you use aggregation (define <modules>), you just say which projects have to be built, and its package type is pom.
If you inherit (define <parent>), you'll inherit the parent pom's preferences.
See:
Inheritance and aggregation create a nice dynamic to control builds through a single, high-level POM. You will often see projects that are both parents and aggregators. For example, the entire maven core runs through a single base POM org.apache.maven:maven, so building the Maven project can be executed by a single command: mvn compile. However, although both POM projects, an aggregator project and a parent project are not one in the same and should not be confused. A POM project may be inherited from - but does not necessarily have - any modules that it aggregates. Conversely, a POM project may aggregate projects that do not inherit from it.
More infos here.

Categories