Inexplicably unresolvable IncompatibleClassChangeError in jetty-maven-plugin with Spring - java

I'm working on a Restlet application issue and thought it would be great to set up a Github repository containing a cut-down version of the application to test out. However, it's never that easy...
The repository is here: https://github.com/morungos/restlet-spring-static-files
Basically, the problem is that whenever I try to run it using mvn jetty:run-war (which I actually need to do to test out the restlet issue) I get the following backtrace:
java.lang.IncompatibleClassChangeError: class org.springframework.cglib.core.DebuggingClassWriter has interface org.springframework.asm.ClassVisitor as super class
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:415)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:377)
at org.springframework.cglib.core.DefaultGeneratorStrategy.getClassVisitor(DefaultGeneratorStrategy.java:30)
The part that's interesting is that the original application -- even when I had it use the exact same pom.xml, did not show the same problem for the same command. Both seem to be fine with mvn jetty:run, but the Restlet issue needs a war file to test against.
Now I've seen this issue and it usually an ASM/CGLIB conflict, and when I checked the dependencies, both Jetty and Spring do use different ASM systems, but I figure where or how to set the dependencies right to make this work. And even if I could, I can't figure out why it works in one application and not in a slightly smaller version (which sadly I can't yet show).
Any thoughts on how to resolve this? I've tried adding an exclusion to the Jetty dependency that's causing the issue (jetty-annotations) but then Jetty failed hideously, so it's clearly required.

I took a look at your pom using mvn dependency:tree. You have a mix of Spring 3.2 and 3.1 JARs. The Spring 3.2 JARs are being pulled in by Restlet.
[INFO] +- org.restlet.jee:org.restlet:jar:2.3.1:compile
[INFO] +- org.restlet.jee:org.restlet.ext.servlet:jar:2.3.1:compile
[INFO] +- org.restlet.jee:org.restlet.ext.spring:jar:2.3.1:compile
[INFO] | +- cglib:cglib-nodep:jar:2.2:compile
[INFO] | +- commons-logging:commons-logging:jar:1.1.3:compile
[INFO] | +- org.springframework:spring-beans:jar:3.2.6.RELEASE:compile
[INFO] | +- org.springframework:spring-core:jar:3.2.6.RELEASE:compile
[INFO] | +- org.springframework:spring-expression:jar:3.2.6.RELEASE:compile
[INFO] | +- org.springframework:spring-web:jar:3.2.6.RELEASE:compile
[INFO] | | \- aopalliance:aopalliance:jar:1.0:compile
[INFO] | \- org.springframework:spring-webmvc:jar:3.2.6.RELEASE:compile
[INFO] +- javax.servlet:javax.servlet-api:jar:3.0.1:compile
[INFO] +- org.springframework:spring-context:jar:3.1.4.RELEASE:runtime
[INFO] | +- org.springframework:spring-aop:jar:3.1.4.RELEASE:compile
[INFO] | \- org.springframework:spring-asm:jar:3.1.4.RELEASE:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.7.7:compile
[INFO] +- org.slf4j:slf4j-jdk14:jar:1.7.7:compile
[INFO] \- junit:junit:jar:4.9:test
[INFO] \- org.hamcrest:hamcrest-core:jar:1.1:test

Hmmm, my fault for carelessly letting Spring and Restlets resolve their differences. Explicitly bringing in all the Spring dependencies, rather than just the few I needed, made all the difference. A runtime scope for Spring had also crept in.
All I did was add the following top-level dependencies to the POM:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
When I went back carefully, I could see the app was bringing in versions 3.1.4 and 3.2.6, and mixing them. The surprising thing was that everything seemed to work fine except for Jetty, and only when invoked on a WAR.
Long-range interactions between components are always the harder ones to debug, I guess...

Related

cucumber throwing java.lang.NoClassDefFoundError: io/cucumber/core/gherkin/FeatureParser

I'm learning Cucumber and I'm getting the FeatureParser error
java.lang.NoClassDefFoundError: io/cucumber/core/gherkin/FeatureParser
I have imported below jar files
gherkin-9.2.0.jar
cucumber-core-5.2.0.jar
cucumber-java-5.2.0.jar
cucumber-junit-5.2.0.jar
cucumber-jvm-deps-1.0.6.jar
cucumber-plugin-5.2.0.jar
i have written code like below
LoginTestRunner.java
package cucumberTests;
import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
#RunWith(Cucumber.class)
#CucumberOptions(features="features", glue="stepImplementations")
public class LoginTestRunner {
}
I have written feature file as well.
Getting below error:
java.lang.NoClassDefFoundError: io/cucumber/core/gherkin/FeatureParser
at io.cucumber.core.feature.FeatureParser.parseResource(FeatureParser.java:35)
at io.cucumber.core.runtime.FeaturePathFeatureSupplier.lambda$new$0(FeaturePathFeatureSupplier.java:39)
at java.base/java.util.function.BiFunction.lambda$andThen$0(BiFunction.java:70)
at io.cucumber.core.resource.ResourceScanner.lambda$processResource$2(ResourceScanner.java:126)
at io.cucumber.core.resource.PathScanner$ResourceFileVisitor.visitFile(PathScanner.java:67)
at io.cucumber.core.resource.PathScanner$ResourceFileVisitor.visitFile(PathScanner.java:52)
at java.base/java.nio.file.Files.walkFileTree(Files.java:2724)
at java.base/java.nio.file.Files.walkFileTree(Files.java:2796)
at io.cucumber.core.resource.PathScanner.findResourcesForPath(PathScanner.java:46)
at io.cucumber.core.resource.PathScanner.findResourcesForUri(PathScanner.java:26)
at io.cucumber.core.resource.ResourceScanner.findResourcesForUri(ResourceScanner.java:109)
at io.cucumber.core.resource.ResourceScanner.scanForResourcesUri(ResourceScanner.java:86)
at io.cucumber.core.runtime.FeaturePathFeatureSupplier.loadFeatures(FeaturePathFeatureSupplier.java:62)
at io.cucumber.core.runtime.FeaturePathFeatureSupplier.get(FeaturePathFeatureSupplier.java:46)
at io.cucumber.junit.Cucumber.<init>(Cucumber.java:156)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder$DefensiveAnnotatedBuilder.buildRunner(DefensiveAllDefaultPossibilitiesBuilder.java:113)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder.runnerForClass(DefensiveAllDefaultPossibilitiesBuilder.java:56)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.vintage.engine.discovery.ClassSelectorResolver.resolveTestClass(ClassSelectorResolver.java:66)
at org.junit.vintage.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:47)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:129)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1631)
at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127)
at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:488)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:543)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:174)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:120)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:87)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:80)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:112)
at org.junit.vintage.engine.discovery.VintageDiscoverer.discover(VintageDiscoverer.java:42)
at org.junit.vintage.engine.VintageTestEngine.discover(VintageTestEngine.java:62)
at org.junit.platform.launcher.core.DefaultLauncher.discoverEngineRoot(DefaultLauncher.java:177)
at org.junit.platform.launcher.core.DefaultLauncher.discoverRoot(DefaultLauncher.java:164)
at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:120)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.<init>(JUnit5TestReference.java:45)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.createUnfilteredTest(JUnit5TestLoader.java:76)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.createTest(JUnit5TestLoader.java:66)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestLoader.loadTests(JUnit5TestLoader.java:53)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:526)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.ClassNotFoundException: io.cucumber.core.gherkin.FeatureParser
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 56 more
I'm learning Cucumber and I'm getting the FeatureParser error
If you follow the 10 minute tutorial you'll get an introduction that uses Maven dependency management.
In addition to this tutorial I would strongly urge you to invest time in learning either Maven or Gradle along with Cucumber. Amongst other things these tools will automate your dependency management and this can make your life much easier.
For example:
If you want to use Cucumber with JUnit 4 and annotation based step definitions you would declare this minimal set of dependencies in a Maven pom.xml file.
<properties>
<cucumber.version>5.2.0</cucumber.version>
</properties>
<dependencies>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
By telling Maven what your dependencies are Maven can calculate your transitive dependencies i.e: the dependencies of your dependencies.
This has many advantages. One example would be using the mvn dependency:tree -Dverbose=true command to will list all dependencies. This is much faster and much less error prone then downloading jar files by hand and hoping that you have the right ones.
$ mvn dependency:tree -Dverbose=true
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< cucumber:cucumber-java-skeleton >-------------------
[INFO] Building Cucumber-Java Skeleton 0.0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # cucumber-java-skeleton ---
[INFO] cucumber:cucumber-java-skeleton:jar:0.0.1
[INFO] +- io.cucumber:cucumber-java:jar:5.2.0:test
[INFO] | +- io.cucumber:cucumber-core:jar:5.2.0:test
[INFO] | | +- io.cucumber:cucumber-gherkin:jar:5.2.0:test
[INFO] | | +- io.cucumber:cucumber-gherkin-vintage:jar:5.2.0:test
[INFO] | | +- io.cucumber:tag-expressions:jar:2.0.4:test
[INFO] | | +- io.cucumber:cucumber-expressions:jar:8.3.1:test
[INFO] | | +- io.cucumber:datatable:jar:3.3.0:test
[INFO] | | +- io.cucumber:cucumber-plugin:jar:5.2.0:test
[INFO] | | \- io.cucumber:docstring:jar:5.2.0:test
[INFO] | \- org.apiguardian:apiguardian-api:jar:1.1.0:test
[INFO] +- io.cucumber:cucumber-junit:jar:5.2.0:test
[INFO] \- junit:junit:jar:4.13:test
[INFO] \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.781 s
[INFO] Finished at: 2020-02-10T23:00:14+01:00
[INFO] ------------------------------------------------------------------------
Add the following dependency and rebuild your project:
Note that the scope is set to test --
java.lang.NoClassDefFoundError is thrown when the class is found at compile time, but not at runtime. So you need to ensure this .jar is available at runtime
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>5.1.3</version>
<scope>test</scope>
</dependency>
If you're using Eclipse, make sure that you have the project class path set to include the dependency and that it's built and embedded into the project
In your testrunner.java file , try giving full path of feature file

How to use same lib for compile and run at Eclipse?

I have a maven project that was imported as java project. When I run it, I get
Handling error: NestedServletException, Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: org.apache.commons.lang.time.DateUtils.addDays(Ljava/util/Date;I)Ljava/util/Date;
Using this answer I got this line:
[Loaded org.apache.commons.lang.time.DateUtils from file:/C:/Users/user/.m2/repository/commons-lang/commons-lang/2.0/commons-lang-2.0.jar]
But at pom.xml it's:
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
Considering I have this libs at Java Build Path:
and
How could I resolve this problem? Where can I assured compare my run vs compile libs?
EDIT
this is the output of mvn dependency:tree -Dverbose -Dincludes=commons-lang:
[INFO] com.companyName.gestao.projectName:projectName-webapp:war:1.0.0-SNAPSHOT
[INFO] \- com.companyName.gestao.projectName:projectName-business:jar:1.0.0-SNAPSHOT:compile
[INFO] +- com.companyName.commons.utils:companyName-commons-utils:jar:1.14.5:compile
[INFO] | \- softdes:softdes-all:jar:1.6.23:compile
[INFO] | \- commons-lang:commons-lang:jar:2.6:compile (version managed from 2.0)
[INFO] \- net.sf.jasperreports:jasperreports:jar:companyName-6.4.0.4:compile
[INFO] \- org.codehaus.castor:castor-xml:jar:1.3.3:compile
[INFO] +- org.codehaus.castor:castor-core:jar:1.3.3:compile
[INFO] | \- (commons-lang:commons-lang:jar:2.6:compile - version managed from 2.0; omitted for duplicate)
[INFO] \- (commons-lang:commons-lang:jar:2.6:compile - version managed from 2.0; omitted for duplicate)
Running the same command at business subproject(at same directory level that webapp project):
[INFO] com.companyName.gestao.projectName:projectName-business:jar:1.0.0-SNAPSHOT
[INFO] +- com.companyName.commons.utils:companyName-commons-utils:jar:1.14.5:compile
[INFO] | \- softdes:softdes-all:jar:1.6.23:compile
[INFO] | \- commons-lang:commons-lang:jar:2.0:compile
So webapp depends upon business that depends upon companyName-commons-utils that depends upon softdes-all that depends upon commons-lang version 2. But webapp must use commons-lang version 2.6.
Can I accomplish this by changing dependency order at pom.xml?
SECOND EDIT
After adding <exclusion> to commons-lang at business dependency, I run dependency tree maven as stated above. Now, besides BUILD SUCCESS, maven doesn't have any tree printed, as below:
PS C:\workspace\projectName-dev\webapp> mvn dependency:tree -Dverbose -Dincludes=commons-lang
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Conciliador - webapp 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.10:tree (default-cli) # conciliador-webapp ---
[WARNING] Using Maven 2 dependency tree to get verbose output, which may be inconsistent with actual Maven 3 resolution
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.629s
[INFO] Finished at: Thu May 17 13:21:08 BRT 2018
[INFO] Final Memory: 29M/494M
[INFO] ------------------------------------------------------------------------
PS C:\workspace\projectName-dev\webapp>
I discovered that commons-lang dependency is inside dependencyManagement as stated here and DateUtils is still loaded from 2.0 version Jar. What could be done?
As #LuisMuñoz stated on comments, I added exclusions to all possible libs using older dependencies. Even with this Eclipse insisted in using older versions of it. I went to project Properties > Java Build Path > Order and Export and top prioritized over everything else my newer dependency version 2.6. After this it worked. Sounds like pom definitions doesn't matter at all if is Eclipse configs that have the final word.

Eclipse uses wrong maven dependency in launch configuration

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.
Note This answer is a summary from discussion with the OP
It looks like vertex-hazelcast declares both compile and test scoped dependencies on hazelcast. These scopes are not transitive so it's my understanding that this version will be included in the classpath by design. #Echnalb suggestion to use an exclusion is the recommended way to resolve this.
As that hasn't worked, it could be an ancestor is also declaring a dependency which would also need to be excluded.
After looking through some other dependencies that were declared in vertex-hazelcast, I checked hazelcast-client to see if it also declared a dependency on the earlier version of hazelcast the assumption being that the ancestral dependency was being added to the classpath despite the exclusion from the parent.
It did include such a dependency:
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<scope>test</scope>
<version>${project.parent.version}</version>
<classifier>tests</classifier>
</dependency>
I suggest(ed) adding an exclusion for hazelcast-client which seems to have solved the problem.
#Guss comments
Prior to the exclusion, running dependency:tree, hazelcast-client is
not listed at all
It is interesting that dependency:tree does not detect test scoped dependencies. Is there's a way to force it to switch scopes?

How to know which tomcat version embedded in spring boot

I used spring boot in project. It has inbuild tomcat server. I find out a jar spring-boot-starter-tomcat-1.2.5.RELEASE.jar. I required to do certain tomcat related configuration on linux server.
How can I get to know which tomcat version used in this?
You can also check the version without leaving your IDE by seeing the effective pom.
For example, if you are using IntelliJ you can view effective pom by right clicking pom.xml > Maven > Show effective POM.
...or from the command line by issuing mvn help:effective-pom
Via http://search.maven.org/, in https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/1.2.5.RELEASE/spring-boot-dependencies-1.2.5.RELEASE.pom:
<tomcat.version>8.0.23</tomcat.version>
or For Gradle print the dependepency tree via the console with
./gradlew dependencies
Example snippet from output:
...
| +--- org.springframework.boot:spring-boot-starter-tomcat:2.1.0.RELEASE
| | +--- javax.annotation:javax.annotation-api:1.3.2
| | +--- org.apache.tomcat.embed:tomcat-embed-core:9.0.12
| | +--- org.apache.tomcat.embed:tomcat-embed-el:9.0.12
| | \--- org.apache.tomcat.embed:tomcat-embed-websocket:9.0.12
| | \--- org.apache.tomcat.embed:tomcat-embed-core:9.0.12
...
In my example above it is tomcat version 9.0.12
You can look at http://mvnrepository.com/:
http://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat/1.2.5.RELEASE
Below you have section Compile Dependencies and you can see that it uses Tomcat 8.0.23.
You can check the versions of all the dependencies in the dependency tree.
for that:
go to the directory of pom.xml
run the following command:
$ mvn dependency:tree
[INFO] Scanning for projects...
enter code here
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building {Project Name}
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) # spring-mvc-logback ---
[INFO] com.sj.common:spring-mvc-logback:war:1.0-SNAPSHOT
[INFO] +- org.springframework:spring-core:jar:4.1.6.RELEASE:compile
[INFO] +- org.springframework:spring-webmvc:jar:4.1.6.RELEASE:compile
[INFO] | +- org.springframework:spring-beans:jar:4.1.6.RELEASE:compile
[INFO] | +- org.springframework:spring-context:jar:4.1.6.RELEASE:compile
[INFO] | | \- org.springframework:spring-aop:jar:4.1.6.RELEASE:compile
[INFO] | | \- aopalliance:aopalliance:jar:1.0:compile
[INFO] | +- org.springframework:spring-expression:jar:4.1.6.RELEASE:compile
[INFO] | \- org.springframework:spring-web:jar:4.1.6.RELEASE:compile
[INFO] +- org.slf4j:jcl-over-slf4j:jar:1.7.12:compile
[INFO] | \- org.slf4j:slf4j-api:jar:1.7.12:compile
[INFO] +- ch.qos.logback:logback-classic:jar:1.1.3:compile
[INFO] | \- ch.qos.logback:logback-core:jar:1.1.3:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.937 s
[INFO] Finished at: 2015-06-19T19:17:54+08:00
[INFO] Final Memory: 13M/308M
[INFO] ------------------------------------------------------------------------
And you will be able to watch all the dependencies and versions associated with that dependency.
In Eclipse IDE:
Open your pom.xml
Go to "Effective POM" tab
Search for "tomcat"
Find <tomcat.version> line, for example: <tomcat.version>9.0.27</tomcat.version>
For those who use PCF i.e. cloudfoundry
I generally keep spring boot tomcat dependency as provided
Which means my local tomcat version may be slightly different.
The java buildpack includes the tomcat version
https://github.com/cloudfoundry/java-buildpack/releases
e.g. java buildpack 4.19.1 comes with Openjdk 1.8.0_212 and tomcat 9.0.19
Consider the below snippet of your project's pom.xml wherein default parent is spring-boot-starter-parent
Your project pom.xml
<!--Spring boot parent project -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
Next lookup pom.xml of spring-boot-starter-parent project to see the dependencies, it has the spring-boot-dependencies as its parent. If using modern IDEs like IntelliJ/Vscode can easily traverse within IDE.
spring-boot-starter-parent pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.5</version>
</parent>
One level up again i.e., to spring-boot-dependencies it further doesn't have a parent, under properties all the defaults are listed. Sample snippet below having non exhaustive list showing only tomcat.
spring-boot-dependencies pom.xml
<properties>
<!-- Other dependencies -->
<tomcat.version>9.0.45</tomcat.version>
<!-- Other dependencies -->
</properties>
This way, we can search for all the defaults out of the box.
Print the dependepency tree via the console with
mvn dependency:tree

Maven Dependancy Refereing old Poi Version

I am using Apache Poi version 3.8 in my POM. But it is still downloading poi-3.2 along with poi-3.8 as (may be) due to some internal dependency. The strange behavior for me is My project using poi-3.2 when even I have mentioned 3.8 version in POM. I have Googled a lot for the same, but found myself unlucky.
Here is my POM entry :
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.8</version>
<type>jar</type>
</dependency>
I have checked the poi jar my project using in classpath by the code:
ClassLoader classloader =
org.apache.poi.poifs.filesystem.POIFSFileSystem.class.getClassLoader();
URL res = classloader.getResource(
"org/apache/poi/poifs/filesystem/POIFSFileSystem.class");
String path = res.getPath();
System.out.println("Core POI came from " + path);
This prints :
Core POI came from file:/D:/Software/Softwares/apache-tomcat-6.0.33/webapps/scd-web/WEB-INF/lib/poi-3.2.jar!/org/apache/poi/poifs/filesystem/POIFSFileSystem.class
There is a poi-3.8.jar in same folder but classpath picking up 3.2.
My question is :
What should I do to so that My project uses poi-3.8.jar instead of poi-3.2.jar.
Many Thanks !!
Edited:
Output of mvn dependency:tree
[INFO] Building SCD-common [INFO] task-segment: [dependency:tree]
[INFO]
------------------------------------------------------------------------
[WARNING] While downloading xmlbeans:xmlbeans:2.3.0 This artifact has been relocated to org.apache.xmlbeans:xmlbeans:2.3.0.
[INFO] [dependency:tree] [INFO] com.idc:scd-common:jar:4.2.0.5
[INFO] +- org.springframework:spring-webmvc:jar:2.5.6:compile
[INFO] | +- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] | +- org.springframework:spring-beans:jar:2.5.6:compile
[INFO] | +- org.springframework:spring-context-support:jar:2.5.6:compile
[INFO] | \- org.springframework:spring-web:jar:2.5.6:compile
[INFO] +- com.idc.worldwide.keystones:service-single-signon-dynamo-api:jar:1.0:compile
[INFO] +- com.idc.worldwide.keystones:service-single-signon-dynamo-database-impl:jar:1.0.3:compile
[INFO] | +- org.apache:commons-dbcp:jar:1.2.2:compile
[INFO] | +- org.apache:commons-pool:jar:1.4:compile
[INFO] | \- com.idc.worldwide.webchannel:sage-core:jar:3.2.0.001:compile
[INFO] | +- com.idc.webchannel.legacy.sage-dependencies:aspose-slides:jar:1. 0:compile
[INFO] | +- com.servlets:cos:jar:09May2002:compile
[INFO] | +- com.sun:jai_codec:jar:1.1.3:compile
[INFO] | +- com.sun:jai_core:jar:1.1.3:compile
[INFO] | +- com.verity:k2:jar:5.00.3177.0:compile
[INFO] | +- org.apache:poi:jar:3.2:compile
[INFO] | +- org.apache:poi_contrib:jar:3.2:compile
[INFO] | +- org.apache:poi_scratchpad:jar:3.2:compile
[INFO] | \- org.springframework:spring:jar:2.5.6:compile
[INFO] +- org.springframework:spring-core:jar:3.0.5.RELEASE:compile
[INFO] | \- org.springframework:spring-asm:jar:3.0.5.RELEASE:compile
[INFO] +- org.springframework:spring-aop:jar:3.0.5.RELEASE:compile
There are various mvn command to help solving this issue:
mvn dependency:analyze-dep-mgt
will print details about dependency resolving.
mvn dependency:tree
will print the dependency tree (very helpful to see dependencies of your dependencies)
mvn help:effective-pom
will print the pom resulting from the merge of your pom hierarchy.
If you don't find any references to poi-3.2 with maven, you can take a look at your classpath in your IDE. Do you add any jar by-passing maven ?
Editing your question with the result of those commands can be useful for us to help you.
Looks like
org.apache:poi:jar:3.2
is a compile dependency of
com.idc.worldwide.keystones:service-single-signon-dynamo-database-impl
(although I think you may have cut something)
and
org.apache.poi:poi:jar:3.8
is not a dependency (it's not in the dependency tree).
Make sure your <dependency> entry is within the <dependencies> tag.
Run
mvn dependency:tree
to check which library has a transitive dependency to poi 3.2. You can then exclude it in your pom.
<dependency>
<groupId>sample.group</groupId>
<artifactId>sample-artifactB</artifactId>
<version>1</version>
<exclusions>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
</exclusions>
</dependency>
Maybe you are mixing normal dependency with plugin dependency, see here (not too fitting answer).
Use dependency management in the root POM if you have child projects.

Categories