Understanding eclipse maven dependency hierarchy - eclipse

I want to understand the dependencies for a multi-module maven project and for that referred to eclipse dependency hierarchy.
I did understand fairly, however some of the things I am not able to understand at all.
Below is the screen shot.
The things which I didn't understand are:
--> managed from 1.0.2 [Compile}
--> managed from 1.0.2 (omitted for conflict with 1.0.0) [Compile]
I did search online but I got information in traces. Can anyone help me understand what they mean in easy to understand?
Thanks.

Maven builds a flat classpath from the dependency tree each for compiling ([compile]), for testing, and for running.
In a flat classpath, unlike OSGi, a dependency can only exist in one version. In your cropped screenshot, there is on the second level among other things:
kafka-streams 1.0.2 and
kafka-clients 1.0.0.
kafka-streams 1.0.2 requires kafka-clients 1.0.2 which conflicts to kafka-clients 1.0.0. Therefore kafka-streams 1.0.2 is omitted for conflicts with 1.0.0 even if the version 1.0.2 is required here ("managed from 1.0.2").
More detailed:The classpath which is used to compile or run a plain Java application is flat: all required libraries are globally specified as an ordered list. It is not possible to use a library of a specific version for one package and for another package the same library in a different version.In Maven dependencies builds a tree: each dependency might have its own dependencies. Maven maps the tree of dependencies to the classpath, an ordered list of libraries. If in the Maven dependencies tree the same library exists in different versions, it is not possible to create a flat classpath. This is a conflict.This conflict is resolved by picking one version and omitting all other versions. At the place where the picked version is used instead of the required version, (managed from <required but not picked version>) and (omitted for conflict with <picked version to use instead>) is displayed.In addition, Maven can create different classpaths to compile, to test or to run a Java application via so-called scopes. The [compile] scope is the default scope for using a library in all tasks: compiling, testing and running.
Make sure that the versions specified in the pom.xml file are compatible with each other (which is not yet the case in your screenshot): you have to upgrade kafka-clients from 1.0.0 to 1.0.2 (or downgrade the other libraries).

Related

Dependency upgrade along with transitive dependencies

I have quite a big Play/Akka project on Scala 2.11 with literally dozens of dependencies, for which we need to migrate to all new stack: newest Play, Akka, Scala etc.
But along the upgrade way, our team constantly facing unexpected issues after certain lib update that another lib has transitive dependency on it, which was evicted and suddenly starting to crash in runtime somewhere in internals. E.g. play-pac4j has transitive dependency on Play, which we forgot to upgrade properly after Play upgrade from 2.5 to 2.7.
Question: is there any sbt plugin, which can say in advance which dependencies I need to change to which version version, if I want to update dependency group % name from version-x to version-y?
I'm aware of sbt-dependency-graph plugin and we are using, but I want some automation. Meaning: sbt-dependency-graph has whatDependsOn command, but I don't want to manually verify which version is compatible with transitive dependency i want to go to.
Thank you.

azure-eventhub jar upgrade required inside storm-eventhub jar

I use storm-eventhub jar for my project using maven artifact as follows
<groupId>org.apache.storm</groupId>
<artifactId>storm-eventhubs</artifactId>
<version>2.0.0</version>
storm-eventhub internally uses azure-eventhub version 0.13.1 which is old one.
Hence we are forced to use the same version of azure-eventhub jar in our project as well.
Now the requirement is that we have to upgrade to azure-eventhub version 2.3.2 but storm-eventhub classes fail with NoClassDef errors since many classes refer to 0.13.1 version of azure-eventhub.
Should I customize the classes myself OR can I raise a request to apache community to upgrade the azure-eventhub version inside storm-eventhub library. If so, what would be the ETA approximately.
There is a PR open to upgrade the client version for storm-eventhubs at https://github.com/apache/storm/pull/3004. Unfortunately it looks like the author didn't have time to finish it. You are welcome to pick it up.

Why does Eclipse turn a maven runtime dependency into a compile dependency?

I have a maven project imported into Eclipse Oxygen. Eclipse reports no compile issues (Alt + F5). When I run maven from the command line I get
[ERROR] /home/dean/src/TAP3UIs/TAP3Desktop/src/main/java/com/ms/tap3/controller/RequestAccessController.java:[8,30] package com.google.common.base does not exist
That package does exist in my .m2/repository in guava-15.0.jar. I can also see it in Eclipse mvn dependencies. When I check the mvn dependency:tree for the project I see
[INFO] | | | +- com.google.guava:guava:jar:15.0:runtime
It is a runtime transitive dependency on the command line, which explains why it doesn't compile on the command line. Somehow Eclipse has turned a transitive dependency from runtime to compile.
Does anyone know why this happens and how I make Eclispe m2e respect the scope of the transitive dependencies?
Currently, neither JDT nor m2e support multiple classpaths per project which is required to support different scopes.
See: Eclipse bug 486035 - Different classpath containers for different scopes
Update:
Since Eclipse Photon (4.8) which was released in June 2018 this is now supported. See Eclipse bug 526858 and my video showing this in action.
The main point is this: If you import external classes in your source code, you must set them as compile dependencies, and never trust the fact that they might already be transitive dependencies (because, since they are transitive, you have not direct control over them, so in a future version they might diseappear as well).
What is happening is this:
You need some classes from com.google.common.base package, so you need to set com.google.guava:guava:jar:15.0 as a dependency.
Instead, you didn't because you realised it was already a transitive dependency, but you missed the fact that is a runtime dependency.
Eclipse M2 does not distinguish the different Maven's standard classpaths, so it treats all dependencies as if they were of "compile" scope. So Eclipse includes guava-15.0.jar in the compilation and the project is compiled OK.
Maven, instead, won't include a runtime dependency in the compilation phase, so a compile error is raised.
In brief: You should include guava-15.0 (as well as any other artifact your code needs) as a direct dependency (with compile scope) in your pom file.

How to use lower version of dependency on conflict in maven project

I am working on a multi-module maven project, which have the module with different versions of the scala, the reason being the new module say B was added which required the higher scala version i.e 2.11 and rest of the project is build around scala 2.10.
Now I have a use case where I need to call a method from the class of B to the one with lower version.
which results in the dependency conflict.
Is there any way for which I can define the version of dependencies i.e to use lower version to compile.

Is there a way to define the required sbt version in build.sbt?

In the build.sbt definition of a Scala project, is it possible to define the minimum version of sbt that is required to build the project?
project/build.properties allows you to force sbt to use particular version. If current version of installed sbt is different - sbt itself will download (if needed) the version you've specified there:
sbt.version=0.12.0
See, Hello for instance. So actually you may have installed several versions of sbt in your system - it's just jars, that placed in .sbt/boot/scala-{scala.version required by this sbt}/org.scala-sbt/sbt/{sbt.version} folder. Sbt executable actually looks for version specified in project/build.properties or (if it's not specified) highest version installed in the system.
P.S. From sbt-launcher perspective, sbt is only one dependency with small non-intersecting others like ansi.jar, so specifying the range of versions like [0.13.1, 0.13.8] have no much sense as it would be efective only for conflicting transitive deps. Otherwise it's enough to specify higher possible version (which would compile) - you may even choose some version that you already have (and update project's sbt that way).