How is an artifact's final dependency scope in a project determined? - maven

With reference to https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
Each of the scopes (except for import) affects transitive dependencies in different ways, as is demonstrated in the table below. If a dependency is set to the scope in the left column, transitive dependencies of that dependency with the scope across the top row will result in a dependency in the main project with the scope listed at the intersection. If no scope is listed, it means the dependency will be omitted.
I can't visualise the above. Please clarify for me on the following points:
First question: Assume A depends on B which in turn depends on C. Which does "a dependency is set to the scope in the left column", "transitive dependencies of that dependency with the scope across the top row" and "result in a dependency in the main project" each refer to in the above example?
Question 2: I have a lib folder which contains compile and provided subfolders. A has a compile dependency on B and a provided dependency on C. B has no dependency. C has a provided dependency on B. Which folder should B be located in?

Transitive dependency can be inferred as
will result in

Related

How to handle dependency in maven project?

I have a project A which has B as parent in it's pom.xml and I am getting all the dependencies. Now I need a class P which has been defined in project X and I can use that only if I include Y as a parent (so I think it is case of transitive dependency, though I am not sure if this is a correct understanding).
Now as my project A already has a parent defined so I cannot define Y in the same pom.xml and hence I am not able to get the class P in project A. I tried adding X as normal dependency but I am getting cannot resolve dependency while building project.
How can I handle this ?
If you want to use a class of X, you need to declare X as dependency, not as parent.

How to show which parent pom contains a plugin?

If my pom is a child a hierarchy of other poms, is there a way to show exactly which parent pom contains the definition of a plugin?
Short answer is most probably: No.
According to the way Maven builds its model before executing a certain build, the Maven Builder Model:
In phase 1 the hierarchy of poms is resolved
In phase 2 model normalization and plugins configurations are further resolved
But only at the end of phase 2 the effective model validation is performed, which is done on the final effective pom.xml file, as a result of merges, overriding, profiling, injections (of properties) and so on.
To have a look at the full pom, the effective-pom goal of the maven-help-plugin is definitely the right tool. It will show (or write to a given file) the final effective pom a build is gonna use.
The full definition of a plugin (its executions, its global configuration and so on) can only be created once we have the effective pom, because:
the pluginManagement section in any point in the hierarchy can influence a certain plugin
The plugin section in any point in the hierarchy can also influnce it
profiles declared in any point in the hierarchy can also influence it
properties, if used as placeholders, can also play an important role
Having a look at the official Maven POM reference, we can see many entry point to influence a certain plugin definition, which will only be effective to our build once merged through the whole pom hierarchy. A definition per se would not help much since it can then be overriden/influenced further on on the hierarchy chain.
Think about the inherited element of a plugin:
true or false, whether or not this plugin configuration should apply to POMs which inherit from this one. Default value is true.
Or merging of plugin configuration sections:
The default behavior is to merge the content of the configuration element according to element name. If the child POM has a particular element, that value becomes the effective value. if the child POM does not have an element, but the parent does, the parent value becomes the effective value.
You can control how child POMs inherit configuration from parent POMs by adding attributes to the children of the configuration element. The attributes are combine.children and combine.self. Use these attributes in a child POM to control how Maven combines plugin configuration from the parent with the explicit configuration in the child.
Or further down per execution of a plugin:
inherited: Like the inherited element above, setting this false will supress Maven from passing this execution onto its children. This element is only meaningful to parent POMs.
The overall management can then be influenced by pluginManagement:
Plugin Management contains plugin elements in much the same way, except that rather than configuring plugin information for this particular project build, it is intended to configure project builds that inherit from this one. However, this only configures plugins that are actually referenced within the plugins element in the children. The children have every right to override pluginManagement definitions.
As such, the plugin definition at a certain point of the pom hierarchy may not be meaningful to the final effective build.

When are two artifacts considered equal?

Are two artifacts considered the same for dependency resolution if they have two different values for their respective groups? For example, will
com.example:artifact
and
org.example:artifact
resolve to the same version of artifact on my classpath (where gradle by default will choose the latest)? Or will I get two copies of artifact (because Gradle considers the artifacts different and puts both on the classpath)?
Gradle considers dependencies unique if they have matching group, name and version. In your example, those two dependencies would not be considered the same since they have different groups, and would therefore be duplicated. If you know in advance that such a duplication exists, you can declare a module replacement.
dependencies {
modules {
module("com.example:artifact") {
replacedBy("org.example:artifact")
}
}
}

Maven inherited attributes from parent POM

I am trying to find an authoritative list of which elements get inherited from a parent POM. Based on this page
When you inherit a POM, you can choose to live with the inherited POM information or to selectively override it. The following is a list of items a Maven POM inherits from its parent POM:
identifiers (at least one of groupId or artifactId must be overridden.)
dependencies
developers and contributors
plugin lists
reports lists
plugin executions (executions with matching ids are merged)
plugin configuration
But when I see the effective POM in one of my projects I see it also inherits inceptionYear, description (which is a problem, this should be a description of the POM that contains it, not of its children. What's the point of all children having a description like "The root of all POMs")
So is there an actual list or does it just inherit everything from the parent pom? i use some of these properties in the artifact's manifest so I want to add meaningful values
The child pom inherits everything from the parent pom. If you need to set meaningful values in the child pom then you will need to override the values in the parent pom.
From the Docs:
When a project specifies a parent project, Maven uses that parent POM
as a starting point before it reads the current project’s POM. It
inherits everything, including the groupId and version number.
Most elements from the parent POM are inherited by its children. Two elements that aren't inherited are artifactId & name. (Also, any plugins which explicitly set <inherited>false)

Maven runtime scope and cyclic dependency

I have two module A and B. Actualy B is plugin to A.
B depends on A in compile time. A NOT depend on B.
On A runtime I want to add B to classpath, so in A's pom.xml I add the following dependency
pom.xml
<dependency>
<groupId>my_group</groupId>
<artifactId>my_Plugin</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
Maven process fail with cyclic dependency error
[ERROR] The projects in the reactor contain a cyclic reference: Edge between 'Vertex{label='A'}' and 'Vertex{label='B'}' introduces to cycle in the graph B-->A-->B -> [Help 1]
[ERROR]
Why runtime dependency impact compile time ?
As suggested by Conan and if possible extract your common code into a separate module in order to resolve the cyclicity. Normally, in such cases one would extract common interfaces and the core classes into a separate module which is extended by both modules which cause the cyclic dependency. You would then remove the direct dependencies on the modules which were initially in a cyclic state. Sometimes this is very hard to solve, but modularizing the code helps you figure out how to refactor your code so that it is easily re-usable.

Resources