Recently I wrote a project with maven, but I have a question about the version in maven pom.xml.
If I write such a dependency
<dependency>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<!--No version here-->
</dependency>
what will the version be
in a simple project, no subproject
as a dependency in another project and that project use foo-bar-1.0.0
Part 1. of your question: If you don't specify a version there are various different outcomes:
a) you will get an error...
[ERROR] The project org.example:myproject:0.5-SNAPSHOT (D:\src\myproject\pom.xml) has 1 error
[ERROR] 'dependencies.dependency.version' for foo:bar:jar is missing. # line 39, column 14
b) if you have defined the version in the dependency management of the project's parent's pom, then that version is taken. The parent of the project doesn't have to be an enclosing superproject. It can simply be a collection of appropriate definitions.
c) if another dependency of your project also depends on foo:bar, and specifies a version, then that version is taken. Maven 2 has a mechanism called transitive dependencies. If the version of a dependency is not explicitly specified for an artifact, it searches the dependency tree and uses the nearest definition in the tree. If there are two nearest definitions, then the first declaration wins (since maven 2.0.9).
Part 2.: I am not sure, but maybe the transitive dependency mechanism also works that way. But the documentation (as far as I understood it) doesn't mention that case.
But somehow I feel that the second part of your question doesn't make sense: I guess that in order to use an artifact as a dependency, you would have to build it first. So you'd have to know the version of the dependencies well before it is used as a dependency itself.
Related
I want to update this package's version, but I didn't find this package in my pom file under root directory
How can I update this package's version? Do I need to do it directly in the pom file under the Maven package?
This is my dependency tree, and I want to upgrade to 1.31
If you don’t use it directly, then it is coming from one of your dependencies. You can check which one using
mvn dependency:tree
With IntelliJ IDEA, you can also open the Maven view, then right-click the project and select “Analyze Dependencies…” to get the same information.
Ideally, you should keep it as a transitive dependency, otherwise you will have to take care of its upgrade every time you upgrade the library that actually depends on it. Moreover, there can be issues if you upgrade only the transitive dependency and not the intermediate one (e.g. for Spring).
The best solution would thus be to upgrade that intermediate dependency, assuming that they have released a new version of it (SnakeYAML 1.29 being affected by CVE-2022-25857, there are good chances).
Only if you can’t do that, you should add the dependency in the <dependencyManagement> section of your pom.xml, but don’t forget tot maintain it from now on (and remove it once the intermediate dependency is upgraded).
If you can't find it in your pom then it means it's a transitive dependency pulled in by one of your other dependencies. You can just redefine this as a normal dependency in your pom and it will override the version to be whatever you like.
I have a project with numerous submodules.
In each submodule pom.xml file, I repeat exactly the same version number that was defined in parent pom.xml file.
Is it possible:
to define version number in smart way, in only one place, in only one pom.xml file?
to add some verification during build phase that all of the pom.xml files have exactly the same version defined?
For 1: This might be of help
Maven project version inheritance - do I have to specify the parent version?
For 2: You may think of writing your own maven plugin and injecting it with the maven lifecycle.
Please refer to: https://www.mojohaus.org/versions-maven-plugin/
I am looking for a way to test whether or not any of my explicit dependencies in my pom.xml reference/include any of the same transitive dependencies. For example, if dependency-A includes junit.jupiter and dependency-B also includes junit.jupiter, I want a way to see this so that I can exclude it from one of them to prevent conflicts.
I saw through this link that you can use mvn dependency:tree to essentially show all dependencies and their transitive dependencies, but it prints in a fairly unreadable format and it isn't clear through that output what the source of each transitive dependency is.
Note that if dependency-A uses junit.jupiter and dependency-B uses junit.jupiter, then only one of these dependencies will be included. Maven will not include the same dependency twice.
What can be tricky, though, is the resulting version. Maven takes the "nearest" element, not the highest version. If you want to notice if you have conflicting versions, I recommend the "dependency convergence" rule of the maven enforcer rules.
If you want to choose one version for junit.jupiter, add an entry to <dependencyManagement> in your POM.
I wonder when I did not specify a plugin version in some module's pom.xml like in:
<build>
...
<plugin>
<groudId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
...
</build>
What is the default plugin version used when I run "mvn compile"?
I have tried it and see actually it is using maven-compiler-plugin version 3.1 with above plugin element commented, my Maven version is 3.6.3.
I have spent 1 hour to google through Maven's documentation and related posts, but not find exact answer. I really like to know how that version is being decided?
The magic is not happening in the super pom, but in the so called bindings descriptor as available at https://github.com/apache/maven/blob/master/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml.
However, they are moving to the matching packaging plugin, for example for the maven-jar-plugin it is located at https://github.com/apache/maven-jar-plugin/blob/master/src/main/filtered-resources/META-INF/plexus/components.xml
These versions haven't been updated, because it would be weird if 2 users with different Maven versions have different results (e.g. one has a broken build, the other not). Hence it is better to specify the plugin versions in the pom, don't rely of the defaults provided by Maven.
In the end it is all described at https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
It is impossible for maven to work without defining versions of the
artifacts , so somewhere it must be mentioned, lets dig in part by
part.
All pom.xmls are logically inherit from the super POM. You can always see what your "real" pom.xml looks like by typing:
mvn help:effective-pom
The resulting pom.xml that is printed is a combination of the super POM, your pom.xml, and any parent POMs in the mix as well.
Note from Maven 3 the super POM does not contain any of the (default lifecycle) plugins versions but earlier till Maven 2 it used to have.
The Maven 3 super POM is provided by the org.apache.maven.model.superpom.DefaultSuperPomProvider class https://github.com/apache/maven/blob/bce33aa2662a51d18cb00347cf2fb174dc195fb1/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java#L56-L85
The resource it loads can be found here: https://github.com/apache/maven/blob/bce33aa2662a51d18cb00347cf2fb174dc195fb1/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.0.0.xml#L23-L149
Edit:
As per Maven Coordinates
groupId:artifactId:version are all required fields (although,
groupId and version need not be explicitly defined if they are
inherited from a parent - more on inheritance later). The three fields
act much like an address and timestamp in one. This marks a specific
place in a repository, acting like a coordinate system for Maven
projects:
version: This is the last piece of the naming puzzle. groupId:artifactId denotes a single project but they cannot delineate which incarnation of that project we are talking about. Do we want the junit:junit of 2018 (version 4.12), or of 2007 (version 3.8.2)? In short: code changes, those changes should be versioned, and this element keeps those versions in line. It is also used within an artifact's repository to separate versions from each other. my-project version 1.0 files live in the directory structure $M2_REPO/org/codehaus/mojo/my-project/1.0.
Recently I wrote a project with maven, but I have a question about the version in maven pom.xml.
If I write such a dependency
<dependency>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<!--No version here-->
</dependency>
what will the version be
in a simple project, no subproject
as a dependency in another project and that project use foo-bar-1.0.0
Part 1. of your question: If you don't specify a version there are various different outcomes:
a) you will get an error...
[ERROR] The project org.example:myproject:0.5-SNAPSHOT (D:\src\myproject\pom.xml) has 1 error
[ERROR] 'dependencies.dependency.version' for foo:bar:jar is missing. # line 39, column 14
b) if you have defined the version in the dependency management of the project's parent's pom, then that version is taken. The parent of the project doesn't have to be an enclosing superproject. It can simply be a collection of appropriate definitions.
c) if another dependency of your project also depends on foo:bar, and specifies a version, then that version is taken. Maven 2 has a mechanism called transitive dependencies. If the version of a dependency is not explicitly specified for an artifact, it searches the dependency tree and uses the nearest definition in the tree. If there are two nearest definitions, then the first declaration wins (since maven 2.0.9).
Part 2.: I am not sure, but maybe the transitive dependency mechanism also works that way. But the documentation (as far as I understood it) doesn't mention that case.
But somehow I feel that the second part of your question doesn't make sense: I guess that in order to use an artifact as a dependency, you would have to build it first. So you'd have to know the version of the dependencies well before it is used as a dependency itself.