软件开发

java.lang.NoSuchMethodError

记录一个东西,也许有人搜到了这个页面,能得到帮助。

在一个Java项目中使用了ActiveMQ的SDK,导致单元测试出现了java.lang.NoSuchMethodError: org.springframework.core.annotation.AnnotatedElementUtils.getMergedAnnotationAttributes错误。

异常的stacktrace如下:

java.lang.NoSuchMethodError: org.springframework.core.annotation.AnnotatedElementUtils.getMergedAnnotationAttributes(Ljava/lang/reflect/AnnotatedElement;Ljava/lang/Class;)Lorg/springframework/core/annotation/AnnotationAttributes;

at org.springframework.transaction.annotation.SpringTransactionAnnotationParser.parseTransactionAnnotation(SpringTransactionAnnotationParser.java:42)
at org.springframework.transaction.annotation.AnnotationTransactionAttributeSource.determineTransactionAttribute(AnnotationTransactionAttributeSource.java:155)
at org.springframework.transaction.annotation.AnnotationTransactionAttributeSource.findTransactionAttribute(AnnotationTransactionAttributeSource.java:133)
at org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.computeTransactionAttribute(AbstractFallbackTransactionAttributeSource.java:158)
at org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.getTransactionAttribute(AbstractFallbackTransactionAttributeSource.java:105)
at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:179)
at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:249)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:72)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)

感到很奇怪,后来用IDEA一行一行点进去发现,一开始还在Junit包里,但是 at org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.getTransactionAttribute(AbstractFallbackTransactionAttributeSource.java:105)这一行跑到active-mq的jar包里去了,这就很奇怪了,关activemq什么事呢?这说明我用的Spring版本和activemq用的Spring版本不同,所以会出现NoSuchMethod的提示。

解决方法是pom文件中不要引入activemq-all这个jar包,而是单独的引入需要的功能。

原先的是

<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-all</artifactId>
    <version>5.15.9</version>
</dependency>

现在应该改成:

<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-broker</artifactId>
    <version>5.15.9</version>
</dependency>
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-pool</artifactId>
    <version>5.15.9</version>
</dependency>
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-spring</artifactId>
    <version>5.15.9</version>
</dependency>
<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-spring</artifactId>
    <version>5.15.9</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jms</artifactId>
    <version>${spring.version}</version>
</dependency>

由此我们也能感觉到activemq-all这个打包方式太奇怪了,好像是直接把spring-core的源码复制到目录下一样,如果是用pom配置依赖,我们还可以用exclusions排除一下就行了,然而这里是不行的。于是我就看了一下源码https://github.com/apache/activemq/blob/master/activemq-all/pom.xml,发现使用了maven-shade-plugin打包,这种方式应该是把所有的依赖放入一个jar包中,方便单独运行,应该是更适合独立的桌面应用,不适合我们的网站平台,因为容器的类加载会按照包名加载,容易加载到重名的。

6 thoughts on “java.lang.NoSuchMethodError”

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据