I'm working on a project that uses Maven for dependency / building / whatever (project life cycle management or sth), and I'm using Eclipse to develop and test.
The project uses Vert.x (latest) and I'm trying to use Hazelcast for some cluster management, but I encountered a bug with the Hazelcast version that Vert.x declares as a dependency (3.6.3) and the solution apparently is to upgrade to a more recent version.
I've added an updated Hazelcast dependency in my pom.xml
as such:
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>[3.7,)</version>
</dependency>
And maven indeed updates the dependency (actually Eclipse called maven to update as soon as I save the pom.xml
file - pretty neat), and so I get the dependency tree:
$ mvn dependency:tree
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building project 3.8.4
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for jfree:jfreechart:jar:1.0.8 is missing, no dependency information available
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ project ---
[INFO] my.group:project:jar:3.8.4
[INFO] +- some.private.dep ...
[INFO] | +- org.junit:junit4-engine:jar:5.0.0-ALPHA:compile (version selected from constraint [4,))
[INFO] | | \- org.junit:junit-engine-api:jar:5.0.0-ALPHA:compile
[INFO] | | +- org.junit:junit-commons:jar:5.0.0-ALPHA:compile
[INFO] | | \- org.opentest4j:opentest4j:jar:1.0.0-ALPHA:compile
[INFO] | +- io.vertx:vertx-hazelcast:jar:3.3.3:compile (version selected from constraint [3.0.0,))
[INFO] | \- io.vertx:vertx-web:jar:3.4.0.Beta1:compile (version selected from constraint [3.0.0,))
[INFO] | \- io.vertx:vertx-auth-common:jar:3.4.0.Beta1:compile
[INFO] +- io.vertx:vertx-core:jar:3.4.0.Beta1:compile
[INFO] | +- io.netty:netty-common:jar:4.1.8.Final:compile
[INFO] | +- io.netty:netty-buffer:jar:4.1.8.Final:compile
[INFO] | +- io.netty:netty-transport:jar:4.1.8.Final:compile
[INFO] | +- io.netty:netty-handler:jar:4.1.8.Final:compile
[INFO] | | \- io.netty:netty-codec:jar:4.1.8.Final:compile
[INFO] | +- io.netty:netty-handler-proxy:jar:4.1.8.Final:compile
[INFO] | | \- io.netty:netty-codec-socks:jar:4.1.8.Final:compile
[INFO] | +- io.netty:netty-codec-http:jar:4.1.8.Final:compile
[INFO] | +- io.netty:netty-codec-http2:jar:4.1.8.Final:compile
[INFO] | +- io.netty:netty-resolver:jar:4.1.8.Final:compile
[INFO] | \- io.netty:netty-resolver-dns:jar:4.1.8.Final:compile
[INFO] | \- io.netty:netty-codec-dns:jar:4.1.8.Final:compile
[INFO] +- junit:junit:jar:4.12:test
...
[INFO] +- com.hazelcast:hazelcast:jar:3.8-EA:compile
[INFO] \- org.slf4j:slf4j-jdk14:jar:1.7.22:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.785 s
[INFO] Finished at: 2017-02-06T09:52:46+02:00
[INFO] Final Memory: 25M/435M
[INFO] ------------------------------------------------------------------------
When I run mvn package
to create the shaded Jar, I get the correct version of Hazelcast.
The problem is that if I create an Eclipse launch configuration for running the project or its unit tests, it inserts both the old version of Hazelcast as well as the new version of Hazelcase into the classpath - here's an example command line from a unit test being run:
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:33123 -ea -Dfile.encoding=UTF-8
-classpath ...:
$HOME/.m2/repository/io/vertx/vertx-hazelcast/3.3.3/vertx-hazelcast-3.3.3.jar:
$HOME/.m2/repository/com/hazelcast/hazelcast/3.6.3/hazelcast-3.6.3.jar:
...
$HOME/.m2/repository/com/hazelcast/hazelcast/3.8-EA/hazelcast-3.8-EA.jar:
...
-version 3 -port 38387 -testLoaderClass org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader
-loaderpluginname org.eclipse.jdt.junit4.runtime
-classNames my.group.project.SomeTest
Now because both versions are loaded into the classpath, the first one (the older) "wins" and I get the bug instead of getting the newer fixed version.
The launch configuration "Classpath" tab looks very standard:
+ Bootstrap Entries
\- JRE System Library
+ User Enties
\- project
\- Maven Dependencies
And the "Maven Dependencies" "folder" in the "Project Explorer" view shows only the newer Hazelcast version.
What is going on?
Update:
As per the discussion in the comments, I added exclusions to the pom.xml
file to prevent vertx-hazelcast
from adding the old hazelcast
dependency. Because vertx-hazelcast
is loaded from yet another (private) dependency, the new setup is a bit more involved and looks like this:
<dependency>
<groupId>some.private</groupId>
<artifactId>dependency</artifactId>
<version>[1.3,)</version>
<exclusions>
<exclusion>
<groupId>io.vertx</groupId>
<artifactId>vertx-hazelcast</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>[3.0.0,)</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>[3.7,)</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-hazelcast</artifactId>
<version>[3.0.0,)</version>
<exclusions>
<exclusion>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
</exclusion>
</exclusions>
</dependency>
I then removed the old launch configuration and recreated it (by right clicking the JUnit test case and choosing "Debug as Junit") - But that does not change the Eclipse behavior - some jars in the classpath have moved around a bit, but the result is still that vertx-hazelcast
and its hazelcast-3.6.3.jar
dependency are loaded before hazelcast-3.8.jar
.