当动态代理遇到ioc (三)cglib与asm jar包冲突
1 目的:当动态代理遇到ioc (二)cglib 将事务中控迁移到cglib
2 现象:
Exception: 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
and
java.lang.RuntimeException: java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.proxy.Enhancer
3 根本原因:
cglib与asm版本不一致,根据不断一个一个cglib尝试,得出
[?[1;34mINFO?[m] +- cglib:cglib:jar:2.2.2:compile
[?[1;34mINFO?[m] | \- asm:asm:jar:3.3.1:compile
[?[1;34mINFO?[m] +- cglib:cglib:jar:3.2.2:compile
[?[1;34mINFO?[m] | \- org.ow2.asm:asm:jar:5.0.4:compile
4 分析背景:
common包用
<dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> <version>5.0.4</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>${cglibVersion}</version> <exclusions> <exclusion> <groupId>asm</groupId> <artifactId>asm</artifactId> </exclusion> </exclusions> </dependency> <cglibVersion>2.2.2</cglibVersion>
5 我们借助一次maven构建类冲突解决方法论 2020.10.18的结论,在war一级pom依赖cglib3.2.2,覆盖掉common的cglib 2.2.2
6 虽然xx-war可以启动访问,然后testcase是在xx项目中的,因此要在xx项目也加上cglib3.2.2覆盖
xx-war
common
cglib 2.2.2
asm1 3.3.1(exclude)
asm 5.0.4 红色的是需要强力协调的
xx
common
cglib 2.2.2
asm1 3.3.1(exclude)
asm 5.0.4
cglib 3.2.2
asm 5.0.4
cglib 3.2.2
asm 5.0.4
7
有个小问题,将来如果common的asm版本变了,则又会出现不一致,故建议:
xx-war
common
cglib 2.2.2
asm 3.3.1
asm 5.0.4
xx
common
cglib 2.2.2
asm 3.3.1
asm 5.0.4
cglib 3.2.2
asm 5.0.4
asm 5.0.4
cglib 3.2.2
asm 5.0.4
asm 5.0.4
8 反证法——我们将war包的asm追加为:
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.ow2.asm/asm --> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> <version>4.0</version> </dependency>
报错,Caused by: java.lang.NoSuchMethodError: org.objectweb.asm.MethodVisitor.visitMethodInsn(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V,证明第7点的方案可行,war层的asm可以覆盖common下的asm
不过如果是7.3.1居然是可以的
9
值得注意的是,
<!-- https://mvnrepository.com/artifact/asm/asm --> <dependency> <groupId>asm</groupId> <artifactId>asm</artifactId> <version>3.3.1</version> </dependency>
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm --> <dependency> <groupId>org.ow2.asm</groupId> <artifactId>asm</artifactId> <version>5.0.4</version> </dependency>
两者groupId不同,意味着无法在编译期即利用 一次maven构建类冲突解决方法论 的结论在最外层覆盖,还得瞄着有无另一个groupId的asm包,否则很容易出现冲突。