Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle / Maven difference in treating version range

Tags:

java

maven

gradle

I'm using the QR-Bill library v2.5.3. As one of its dependencies, it specifies PDFBox using the range [2.0.0,3.0):

<dependency>
  <groupId>org.apache.pdfbox</groupId>
  <artifactId>pdfbox</artifactId>
  <version>[2.0.0,3.0)</version>
  <scope>runtime</scope>
</dependency>

With a Gradle project, the dependency resolves to pdfbox-2.0.24. With a Maven project, it resolves to pdfbox-3.0.0-RC1.

Do Maven and Gradle really treat version ranges differently? What would the correct range be for the library so that both Gradle and Maven use the latest 2.x version of PDFBox but do not use version 3.x (as it is incompatible)?

Further debugging details:

Maven Project

https://github.com/manuelbl/SwissQRBill/tree/master/examples/maven_example

% mvn dependency:tree

[INFO] net.codecrete.qrbill:maven-example:jar:1.0-SNAPSHOT
[INFO] \- net.codecrete.qrbill:qrbill-generator:jar:2.5.3:compile
[INFO]    +- io.nayuki:qrcodegen:jar:1.7.0:runtime (version selected from constraint [1.6.0,2.0))
[INFO]    \- org.apache.pdfbox:pdfbox:jar:3.0.0-RC1:runtime (version selected from constraint [2.0.0,3.0))
[INFO]       +- org.apache.pdfbox:fontbox:jar:3.0.0-RC1:runtime
[INFO]       \- commons-logging:commons-logging:jar:1.2:runtime

Gradle project

https://github.com/manuelbl/SwissQRBill/tree/master/examples/gradle_example

% gradle dependencies --configuration runtimeClasspath

runtimeClasspath - Runtime classpath of source set 'main'.
\--- net.codecrete.qrbill:qrbill-generator:2.5.3+ -> 2.5.3
     +--- io.nayuki:qrcodegen:[1.6.0,2.0) -> 1.7.0
     \--- org.apache.pdfbox:pdfbox:[2.0.0,3.0) -> 2.0.24
          +--- org.apache.pdfbox:fontbox:2.0.24
          |    \--- commons-logging:commons-logging:1.2
          \--- commons-logging:commons-logging:1.2

like image 832
Codo Avatar asked Nov 20 '21 16:11

Codo


People also ask

What is difference between Maven and Gradle?

Gradle is based on a graph of task dependencies – in which tasks are the things that do the work – while Maven is based on a fixed and linear model of phases. With Maven, goals are attached to project phases, and goals serve a similar function to Gradle's tasks, being the “things that do the work.”

Which one is better Maven or Gradle?

The biggest differences are Gradle's mechanisms for work avoidance and incrementality. The top 3 features that make Gradle much faster than Maven are: Incrementality — Gradle avoids work by tracking input and output of tasks and only running what is necessary, and only processing files that changed when possible.

What is the advantage of Gradle over Maven?

Gradle is highly customizable; it provides a wide range of IDE support custom builds. Maven has a limited number of parameters and requirements, so customization is a bit complicated. Gradle avoids the compilation of Java. The compilation is mandatory in Maven.

Is Maven faster than Gradle?

Gradle is between 7 and 85 times faster than Maven when building incremental changes; benefits increase with number of subprojects. Gradle builds are 3 to 30 times faster than Maven builds when task outputs can be resolved Gradle's build cache.


Video Answer


2 Answers

Maven's ordering implementation states than alpha, beta, and RC versions are lesser that an actual release. This is why you see this behavior happening.

So, in practice pdfbox-3.0.0-RC1 < pdfbox-3.0.

In order to exclude 3.0 completely you need to exclude the first pre-release. Some ways you can achieve that:

[2.0.,3-alpha)

[2.0.0,3.0.0-alpha2)

Or another option -which is not ideal- is to specify the upper-bound of the range as the latest revision of the 2.x release:

[2.0.0,2.0.24]

This last option is far from great because if Apache releases a revision of 2.x named 2.0.25, Maven wont include it.

like image 184
Diego Avatar answered Oct 21 '22 06:10

Diego


Based upon Diego M.'s answer, here is some additional information:

The version requirement [2.0,3.0) does not seem to ever make sense:

  • The typical intention is to restrict it to all 2.* version. However, Maven also includes all 3.0 pre-release version. I cannot imagine a case where this would be useful.
  • Maven and Gradle interpret it differently. So it is not suitable whenever both tools are used, in particular when publishing to Maven Central.

The better version requirement for restricting to 2.* versions is: [2.0,2.999999].

like image 25
Codo Avatar answered Oct 21 '22 05:10

Codo