我在maven中有一个多模块项目,它使用(其中包括)glassfish-jersey
,jersey-moxy
,wicket-ioc
,lucene
和lamdbaj
这些全部来自asm
,但所有版本都不同。
最近,我在运行测试时遇到了很多麻烦。我得到的典型错误是:
java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter overrides final method visit.(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
我读到这可能是由不同的asm
版本引起的。有没有办法在它们的依赖项中“沙箱”这些不同的asm版本,所以它们不会混淆?
编辑:
我目前的解决方案是使用jarjar
,如下所示:
<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>jarjar-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jarjar</goal>
</goals>
<configuration>
<includes>
<include>cglib:cglib-nodep</include>
</includes>
<rules>
<rule>
<pattern>net.sf.cglib.asm.**</pattern>
<result>com.myproject.lambda4j.asm.@1</result>
</rule>
<rule>
<pattern>net.sf.cglib.**</pattern>
<result>com.myproject.lambda4j.cglib.@1</result>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
答案 0 :(得分:2)
尝试在使用a recent version of ASM的类路径上明确添加一些cglib v3。*。您遇到的问题是cglib通过继承而不是委派来修改ASM类编写器的行为。但是,ASM通过制作ClassWriter
的方法final
from any version 4.*来强制执行后一种最佳做法,同时仍可覆盖其方法in version 3。您遇到的错误是将cglib 2. *与ASM 4。*。
幸运的是(对你来说),cglib在其最新版本中一直是静态的,即只有少量的API更改,而较新的版本主要包括ASM的更新。如果你很幸运,这个显式使用cglib v3。*可以解决你的问题。只要您的项目依赖项没有直接依赖于ASM,这对于您命名为Jersey或Lucene的依赖项而言似乎是合理的,就会成立。
如果这不起作用,则需要在使用 jarjar 之类的工具时重新编译一些依赖项,以便将直接ASM依赖项重新打包到不同的名称空间中,以便解决这些版本冲突。另一种方法可能是通过一些有条件的子级优先ClassLoader
魔法来隔离不同的ASM版本,但这不是那么值得推荐,因为这些影响是不可预测的,并且还会导致性能下降。