How does maven resolve a parent pom? - java

I came accross a problem and I want to understand it.
Story
Maven version was 3.2.1. I had a multi-module project structure like this:
mainmoduleA
-pom.xml
-submoduleB
--pom.xml
--submoduleC
---pom.xml
-submoduleD
--pom.xml
--submoduleE
---pom.xml
The submodules are always the child of the module in the parent folder. None of them have relativePath in the parent element in their POM, which means as far as I know ../pom.xml. The problem was, that submoduleC has become a new dependency, and submoduleE was already depending on submoduleC. The version of the new dependency of submoduleC was managed in mainmoduleA. In the local repository and in the company repository was still an old version of mainmoduleA, which did not contain that managed version. The workspace folder structure however contained the correct mainmoduleA POM. If I have built submoduleE alone, I have got a warning that the transitive dependencies of submoduleC will be ignored because of the missing managed version, and the results were compilation errors.
Resolution Priority
What is the order of the possibilities used by maven to look up a parent pom?
Based on my experience above:
maven local repository
maven remote repository
tracking it down in the folder structure based on the relativePath tags of the parent tags.
Am I right with the statements above? Can you prove it somehow? I did not find any relevant documentation.

Related

Use maven local module in Intellij

I currently have the following setup:
parent-pom:
has our common as dependency
service-pom:
is child of parent-pom
contains purge for common, so its always the newest
If I now import the modules in Intellij, the common dependency is used from .m2 folder. The problem is that I cant do refactoring across modules or add something inside a class, I don't have autocomplete.
I tried then changing the project structure. First I've added my local common module as dependency for the service and placed it over the .m2/repository dependency. That worked for autocompletion and refactoring, but can get confusing if I want to use the .m2/repository version.
But compiling and starting spring-boot with it don't works. I added a field to a class from common and referenced it in the service. And when I compiled it, it failed due to this field.
Then I read that I need to configure an artifact (containing common) and added a run configuration and enabled "resolve workspace artifacts". But that also did not work as expected.
Then I've added my local common module to the parent-pom module and added the parent-pom module to the service. In addition I've configured an artifact for the parent-pom.
But that didn't work either.
How can I compile and start my service with the local version of my common (and also be able to use the .m2 if needed)
How do you declare the dependencies between these modules in maven?
Do you have these modules imported into the same IDE project as Maven projects?
For IDE to resolve dependencies to the Maven modules with sources instead of the jars from the local repository, these requirements should be met:
Those Maven modules with sources which you have on your local machine must be added to the same IDE project;
The Maven coordinates (groupId, artifactId, versionId) of these dependencies must match to coordinates of maven modules with sources.
To be able to switch to a local .m2 dependency instead of modules, I think a Maven profile may be used indeed.

Maven dependency tree / hierarchy not showing the truth

I was going to migrate an old Ant project existing of multiple single java projects to a multi-module maven project. All the libraries for have been stored in one local folder.
For building up the dependency management I wanted to go the way to add all dependencies to the parent pom.xml (dependency management section) and also do my best by adding the correct ones to the children (Java Maven projects) until compilation is working.
I then want to streamline the pom.xmls by using "mvn dependency:tree -X" to see if I have added some transitive dependencies to the single Maven projects which aren't not needed to be explicitly added to the pom.xmls
Now when comparing the dependency hierarchy for a Maven project shown in Eclipse with that shown by using "mvn dependency:tree -X", there are some differences:
Maven will not show that "jetty-http" is actually a transitive dependency of jetty-server - mostly because I already added it as direct dependency in the pom.xml before.
While Eclipse does show that relationship and this is the correct result (also checked it manually using Maven central dependency list).
So in the end when using Maven I would have left "jetty-http" as direct dependency in my pom.xml, although I don't have to. This is kind of useless.
Does anyone know why the Maven dependency tree is so limited? I want to understand what is going on here. Is there any alternative using Maven commands?
Or is there even a better way to check for/identify transitive dependencies added to the pom.xml by mistake?
Best practise is to add all dependencies to the POM that are used directly in your source code (and at runtime).
So if X is used in your source code, but is already present as transitive dependency of Y, you should nevertheless add X as direct dependency.
You can check this with mvn dependency:analyze
https://maven.apache.org/plugins/maven-dependency-plugin/analyze-mojo.html

Maven self-contained child artifact

I have a project which has 3 pom files: parent file (very basic one, just declares its children), main pom for building project itself and a pom file for generating swagger client library. The client artifact is getting downloaded into our Nexus.
The problem is that when I want to use a client library in another project as a dependency it also requires a parent artifact. I don't want to download it into Nexus since it's so basic and will only flood the repository. I've tried packing some kind of an uber-jar, but it doesn't work for me - jar is huge and contains all dependencies, yet it still needs parent artifact. Are there any workarounds?
While I generally would not care about having an additional Parent POM in the repository (our repository contains 2000 different self-created artifacts in various versions, it is not "flooded"), you can have a look at the
https://www.mojohaus.org/flatten-maven-plugin/
which allows you to make your pom smaller, and includes the possibility to get away without a Parent POM.

Driver binary downloader maven plugin - across multiple modules

We've got a multi-module Selenium Maven project. Each module represents one application that is tested. We've also got a 'core' module which contains everything necessary for the whole setup (driver initialization, utils classes, etc.).
The problem is that we set the plugins and the repository map in every module's pom.xml - it's basically a copy-paste of the plugins and the repository map (this is it: Lazery)
My question is: is it possible to set the plugins and the repository map in our core pom.xml so that it would be used by all the other modules that have a dependency on that core module? I'm not very well-versed in Maven, so so far I haven't been able to find a solution to this.
EDIT: I have managed to solve the plugin issue by using pluginManagement. However, the issue of the RepositoryMap.xml is still there. I need to have the map in every project's test resources in order for the driver-binary-downloader to start the driver.
Resolved the resources problem by placing the Repository Map into the core module and giving the plugin the path.
As mentioned in my edit in the question: the plugin issue was resolved with the pluginManagement

In Maven, do modules get effected by the repository's updatePolicy?

This is just like this other question I asked, but instead of dependencies, this is about modules. Let me give a scenario. You've got a multi-module project and a continuous integration server that deploys the project. This deploys to a repository that your local settings.xml has an updatePolicy of always. Now imagine you run mvn compile right after the CI deploys the project.
Will you end up compiling against the remote server's modules, or your local modules?
In other words, does the updatePolicy of a repository have any effect on the module tags?
modules tag is an aggregation. It is not treated the same as dependencies. Notice that the value that you specify in dependency and module is different. When you declare a dependency, you specify maven coordinates. Whilst for module, you specify relative directories.
Will you end up compiling against the remote server's modules, or your local modules?
You will always end up compiling against your local module if you run the mvn compile in the aggregator module (NOT in the child module!) and the child module dependency is a sibling dependency. When you mvn compile in an aggregator module, the dependency lookup when it is compiling the child module will be special. It will look from the sibling modules target folder ONLY. I can't find documentation on this, but you can try it out.
Imagine that you have these aggregator pom
...
<modules>
<module>child-a</module>
<module>child-b</module>
</modules>
....
child-b pom is declaring a dependency against child-a. (Make sure you have a real output classes)
Next, when you mvn compile the aggregator pom, child-b will be able to compile even if you have NOT mvn install child-a before. That means, child-a is not even in your local repository. This is possible because maven will look into child-a's target folder for the classes. To confirm this, you can try to run mvn compile clean (yes, clean after compile).
Again, do note that this behavior only applies when you run it from the aggregator pom. If your current working directory is child-b (which is dependent on child-a), it will respect the updatePolicy when it tries to look for child-a.

Categories

Resources