Как обработать ошибку времени выполнения: java.lang.NoSuchMethodError - PullRequest
1 голос
/ 21 сентября 2019

У меня есть приложение с большим количеством зависимостей.Одна зависимость от ActiveMQ Artemis.В pom.xml модуля Maven я обновил версию с 2.4.0 до 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>

Код, который я использую для запуска брокера Artemis, выглядит следующим образом:

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

Клиент-брокер подключен через компонент sjms от Camel:

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

Я использую этот модуль Maven в другом приложении, которое компилируется / компилируется с помощью Gradle 5.6.2.Это приложение также содержит библиотеки для Apache Camel 2.24.2 и Apache ActiveMQ 5.5.10.

Приложение компилируется нормально, но во время выполнения я получаю "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;

Изведение журнала:

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)

По статье 3 шага, чтобы исправить NoSuchMethodErrors и NoSuchMethodExceptions Я запустил «gradlew зависимости».

|    +--- 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

Так что брокер Artemis на самом делеработает под версией 2.4.0, в то время как клиент работает под версией 2.10.0 (что делает их несовместимыми).

В статье говорится:

"Наконец, нам нужно решить, какая из двух версий нам действительно нужна для удовлетворения обеих зависимостей. Как правило, это более новая версия, поскольку большинство фреймворков работают в обратном направлении.совместим с какой-то точкой. Однако это может быть наоборот, или мы вообще не сможем разрешить конфликт. "

Чтобы принудительно запустить обе версии на 2.10.0, я явно заявляю в сборке.файл gradle:

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'

После этого "зависимости gradlew":

|    +--- 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 (*)

Вопросы

Библиотеки брокера и клиента находятся ната же версия и приложение вроде работает нормально.Однако мне это непросто:

  1. Как с автоматическим разрешением зависимостей можно записать в примечаниях к выпуску приложения, что библиотеки обновляются, хотя на самом деле используется двухлетняя версия?Откуда мне знать как разработчику, что на самом деле это не так?
  2. Как прочитать вывод зависимостей gradlew?Что на самом деле является основной библиотекой причин, заставляющей использовать старую версию 2.4.0.
  3. Принудительное использование новой версии - действительно хорошее решение, или есть ожидаемые проблемы при переопределении автоматического разрешения зависимостей?

1 Ответ

0 голосов
/ 23 сентября 2019
  1. Понижение версии в Gradle до 6.0 возможно только через force, уровень конфигурации force или правило подстановки.В вашей сборке есть что-то, что использует один из этих методов для сброса версии.
  2. Чтобы исследовать версию конкретной библиотеки, используйте задачу dependencyInsight, чтобы получить более подробный отчет о том, почему конкретная версиямодуль был выбран.Что-то вроде ./gradlew dependencyInsight --configuration <relevantConfiguration> --dependency artemis-server, где <relevantConfiguration> может быть compileClasspath или runtimeClasspath или что-то более специфичное для вашего проекта.
  3. Как только вы поймете, почему 2.10.0 был понижен до 2.4.0, вы можетеиспользовать решение, отличное от force, чтобы получить ожидаемую версию.
...