java - 管理maven不同的cglib/asm版本

标签 java maven dependencies sandbox cglib

我在 Maven 中有一个多模块项目,它使用(除其他外)glassfish-jerseyjersey-moxywicket-ioc >、lucenelamdbaj 这些都带有 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>

最佳答案

尝试在使用a recent version of ASM的类路径上显式添加一些cglib v3.* 。您遇到的问题是 cglib 通过继承而不是通过委托(delegate)来修改 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 依赖项重新打包到不同的 namespace 中,从而解决这些版本冲突。另一种方法是通过一些有条件的子优先 ClassLoader 魔法来隔离不同的 ASM 版本,但这并不是那么值得推荐,因为效果是不可预测的,而且还会导致性能损失。

关于java - 管理maven不同的cglib/asm版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21302318/

相关文章:

java - Spring测试时如何在上下文初始化之前初始化测试类?

java - 如何关闭此 javadoc 警告 : @return tag has no arguments

android - 此类文件的 Jar 属于容器 'Android Dependencies',该容器不允许修改其条目上的源附件

java - 什么是列出已编译的 Java 类所需的所有导入的可移植方法

java - 在完全离线的环境下开发Spring Boot项目,可能吗?

java - 是否可以同时读取和写入文件?

java - org.testng.TestNGException : An error occurred while instantiating class

grails - 无法将 spring-security-ldap 2.0.1 解析为 Grails 2.4.4

java - 如何编写一个计时器来跟踪 Java 中的多个事件?

java - 是否可以在子目录中(而不是在项目根目录中)定义 pom.xml ?