简体   繁体   中英

How to handle the runtime error: java.lang.NoSuchMethodError

I have an application with a lot of dependencies. One dependency is on ActiveMQ Artemis. In the pom.xml of a Maven module I updated the version from 2.4.0 to 2.10.0

<dependency>
   <groupId>org.apache.activemq</groupId>
   <artifactId>artemis-server</artifactId>
   <version>2.10.0</version>
</dependency>
<dependency>
   <groupId>org.apache.activemq</groupId>
   <artifactId>artemis-commons</artifactId>
   <version>2.10.0</version>
</dependency>
<dependency>
   <groupId>org.apache.activemq</groupId>
   <artifactId>artemis-jms-client-all</artifactId>
   <version>2.10.0</version>
</dependency>

The code I'm using to start an Artemis broker is as follows:

EmbeddedActiveMQ broker = new EmbeddedActiveMQ();
String fileConfig = "file:///" + brokerFile.getAbsolutePath();
broker.setConfigResourcePath(fileConfig);

A broker client is connected through sjms component from Camel:

org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory cf = new ActiveMQJMSConnectionFactory(url);
SjmsComponent component = new SjmsComponent();
component.setConnectionFactory(cf);
context.addComponent("sjms", component);

I use this Maven module in another application which is build/compiled with Gradle 5.6.2. This application also contains libraries for Apache Camel 2.24.2 and Apache ActiveMQ 5.5.10.

The application compiles normal, but in runtime I get a "NoSuchMethodError":

Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: org.apache.activemq.artemis.utils.ClassloadingUtil.loadProperty(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

From the logging:

2019-09-21 03:03:00.883 WARN 4984 --- [ XNIO-2 task-14] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by handler execution: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoSuchMethodError: org.apache.activemq.artemis.utils.ClassloadingUtil.loadProperty(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
java.lang.NullPointerException
   at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.finalize(ActiveMQConnectionFactory.java:961)
   at java.lang.System$2.invokeFinalize(System.java:1270)
   at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:102)
   at java.lang.ref.Finalizer.access$100(Finalizer.java:34)
   at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:217)

Based on the article 3 Steps to Fix NoSuchMethodErrors and NoSuchMethodExceptions I ran "gradlew dependencies".

|    +--- org.apache.activemq:artemis-server:2.10.0 -> 2.4.0
|    |    +--- org.jboss.logging:jboss-logging:3.3.0.Final -> 3.3.2.Final
|    |    +--- org.apache.activemq:artemis-commons:2.4.0
|    |    |    +--- org.jboss.logging:jboss-logging:3.3.0.Final -> 3.3.2.Final
|    |    |    +--- io.netty:netty-buffer:4.1.16.Final -> 4.1.31.Final (*)
|    |    |    +--- io.netty:netty-transport:4.1.16.Final -> 4.1.31.Final (*)
|    |    |    +--- io.netty:netty-handler:4.1.16.Final -> 4.1.31.Final (*)
|    |    |    +--- commons-beanutils:commons-beanutils:1.9.3
|    |    |    |    +--- commons-logging:commons-logging:1.2
|    |    |    |    \--- commons-collections:commons-collections:3.2.2
|    |    |    \--- com.google.guava:guava:19.0 -> 25.1-jre (*)
|    |    +--- org.apache.activemq:artemis-selector:2.4.0
|    |    +--- org.apache.activemq:artemis-journal:2.4.0
|    |    |    +--- org.jboss.logging:jboss-logging:3.3.0.Final -> 3.3.2.Final
|    |    |    +--- org.apache.activemq:artemis-commons:2.4.0 (*)
|    |    |    \--- org.apache.activemq:artemis-native:2.4.0
|    |    |         \--- org.jboss.logging:jboss-logging:3.3.0.Final -> 3.3.2.Final
|    |    +--- org.apache.activemq:artemis-jdbc-store:2.4.0
|    |    |    +--- org.jboss.logging:jboss-logging:3.3.0.Final -> 3.3.2.Final
|    |    |    +--- org.apache.activemq:artemis-journal:2.4.0 (*)
|    |    |    \--- org.apache.activemq:artemis-core-client:2.4.0
|    |    |         +--- org.jgroups:jgroups:3.6.13.Final -> 3.6.7.Final
|    |    |         +--- org.apache.activemq:artemis-commons:2.4.0 (*)
|    |    |         +--- org.apache.johnzon:johnzon-core:0.9.5 -> 1.1.10
|    |    |         +--- io.netty:netty-transport-native-epoll:4.1.16.Final -> 4.1.31.Final (*)
|    |    |         +--- io.netty:netty-transport-native-kqueue:4.1.16.Final -> 4.1.31.Final (*)
|    |    |         \--- io.netty:netty-codec-http:4.1.16.Final -> 4.1.31.Final (*)
|    |    +--- org.apache.activemq:artemis-core-client:2.4.0 (*)
|    |    \--- io.netty:netty-all:4.1.16.Final -> 4.1.9.Final
|    +--- org.apache.activemq:artemis-commons:2.10.0 -> 2.4.0 (*)
|    +--- org.apache.activemq:artemis-jms-client-all:2.10.0

So the Artemis broker is actually running under 2.4.0 version, while the client runs under 2.10.0 (Making them incompatible).

I the article it states:

"Finally, we need to decide which of the two versions we actually need to satisfy both dependencies. Usually, this is the newer version since most frameworks are backwards compatible to some point. However, it can be the other way around or we might even not be able to resolve the conflict at all."

To force both running on 2.10.0 I explicitly state in the build.gradle file:

configurations.all {
  resolutionStrategy {  
    force 'org.apache.activemq:artemis-core-client:2.10.0', 'org.apache.activemq:artemis-broker:2.10.0','org.apache.activemq:artemis-commons:2.10.0','org.apache.activemq:artemis-selector:2.10.0','org.apache.activemq:artemis-journal:2.10.0'
  }
}

compile group: 'org.apache.activemq', name: 'artemis-core-client', version: '2.10.0'
compile group: 'org.apache.activemq', name: 'artemis-commons', version: '2.10.0'
compile group: 'org.apache.activemq', name: 'artemis-server', version: '2.10.0'
compile group: 'org.apache.activemq', name: 'artemis-selector', version: '2.10.0'
compile group: 'org.apache.activemq', name: 'artemis-journal', version: '2.10.0'

After this "gradlew dependencies":

|    +--- org.apache.activemq:artemis-server:2.10.0
|    |    +--- org.jboss.logging:jboss-logging:3.4.0.Final -> 3.3.2.Final
|    |    +--- org.jboss.logmanager:jboss-logmanager:2.1.10.Final
|    |    |    \--- org.wildfly.common:wildfly-common:1.5.1.Final
|    |    +--- org.apache.activemq:artemis-commons:2.10.0
|    |    |    +--- org.jboss.logging:jboss-logging:3.4.0.Final -> 3.3.2.Final
|    |    |    +--- io.netty:netty-buffer:4.1.34.Final -> 4.1.31.Final (*)
|    |    |    +--- io.netty:netty-transport:4.1.34.Final -> 4.1.31.Final (*)
|    |    |    +--- io.netty:netty-handler:4.1.34.Final -> 4.1.31.Final (*)
|    |    |    \--- commons-beanutils:commons-beanutils:1.9.3
|    |    |         +--- commons-logging:commons-logging:1.2
|    |    |         \--- commons-collections:commons-collections:3.2.2
|    |    +--- org.apache.activemq:artemis-selector:2.10.0
|    |    |    \--- org.apache.activemq:artemis-commons:2.10.0 (*)
|    |    +--- org.apache.activemq:artemis-journal:2.10.0
|    |    |    +--- org.jboss.logging:jboss-logging:3.4.0.Final -> 3.3.2.Final
|    |    |    +--- org.apache.activemq:artemis-commons:2.10.0 (*)
|    |    |    +--- org.apache.activemq:activemq-artemis-native:1.0.0
|    |    |    |    +--- org.jboss.logging:jboss-logging:3.3.1.Final -> 3.3.2.Final
|    |    |    |    \--- org.jboss.logmanager:jboss-logmanager:2.0.3.Final -> 2.1.10.Final (*)
|    |    |    +--- io.netty:netty-buffer:4.1.34.Final -> 4.1.31.Final (*)
|    |    |    \--- io.netty:netty-common:4.1.34.Final -> 4.1.31.Final
|    |    +--- org.apache.activemq:artemis-jdbc-store:2.10.0
|    |    |    +--- org.jboss.logging:jboss-logging:3.4.0.Final -> 3.3.2.Final
|    |    |    +--- org.apache.activemq:artemis-commons:2.10.0 (*)
|    |    |    +--- org.apache.activemq:artemis-journal:2.10.0 (*)
|    |    |    \--- org.apache.activemq:artemis-core-client:2.10.0
|    |    |         +--- org.jgroups:jgroups:3.6.13.Final -> 3.6.7.Final
|    |    |         +--- org.apache.activemq:artemis-commons:2.10.0 (*)
|    |    |         +--- org.apache.johnzon:johnzon-core:0.9.5 -> 1.1.10
|    |    |         +--- io.netty:netty-transport-native-epoll:4.1.34.Final -> 4.1.31.Final (*)
|    |    |         +--- io.netty:netty-transport-native-kqueue:4.1.34.Final -> 4.1.31.Final (*)
|    |    |         +--- io.netty:netty-codec-http:4.1.34.Final -> 4.1.31.Final (*)
|    |    |         +--- io.netty:netty-buffer:4.1.34.Final -> 4.1.31.Final (*)
|    |    |         +--- io.netty:netty-transport:4.1.34.Final -> 4.1.31.Final (*)
|    |    |         +--- io.netty:netty-handler:4.1.34.Final -> 4.1.31.Final (*)
|    |    |         +--- io.netty:netty-codec:4.1.34.Final -> 4.1.31.Final (*)
|    |    |         \--- io.netty:netty-common:4.1.34.Final -> 4.1.31.Final
|    |    +--- org.apache.activemq:artemis-core-client:2.10.0 (*)
|    |    +--- org.apache.activemq:activemq-artemis-native:1.0.0 (*)

Both the broker and client libraries are on the same version and the application seems to work normal. It leaves me however uneasy:

  1. How is it possible with automatically dependency resolving to write in the release notes of the application that the libraries are updated while in fact a two year old version is used? How should I know as a developer that this is really not the case?
  2. How to read the gradlew dependencies output? What is really the root cause libary that forces to use the old '2.4.0' version.
  3. Is forcing to use the new version really a good solution or are there expected issues when overriding automatically dependency resolving?
  1. Downgrade of versions in Gradle, before 6.0, is only possible through force , a configuration level force or a substitution rule. There is something in your build that uses one of these techniques to force down the version.
  2. To investigate a specific library's version, use the dependencyInsight task to get a more detailed report about why the specific version of a module was selected. Something like ./gradlew dependencyInsight --configuration <relevantConfiguration> --dependency artemis-server where <relevantConfiguration> can be compileClasspath or runtimeClasspath or something more specific to your project.
  3. Once you figure out why 2.10.0 was downgraded to 2.4.0 you may be able to use a different solution than force to obtain the version you expect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM