管理maven不同的cglib / asm版本

时间:2014-01-23 07:49:53

标签: java maven dependencies sandbox cglib

我在maven中有一个多模块项目,它使用(其中包括)glassfish-jerseyjersey-moxywicket-ioclucenelamdbaj这些全部来自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>

1 个答案:

答案 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版本,但这不是那么值得推荐,因为这些影响是不可预测的,并且还会导致性能下降。