Question

I have a multi-module project in maven, that uses (amongst others) glassfish-jersey, jersey-moxy, wicket-ioc, lucene and lamdbaj These all come with asm, but all with different versions.
Lately, I run into a lot of trouble when running my tests. Typical error I get is:

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

I read that this can be caused by different asm versions. Is there a way to 'sandbox' these different asm-versions in their dependencies, so they don't get mixed up?

Edit:

My current solution is to use jarjar, like this:

  <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>
Was it helpful?

Solution

Try explicitly adding some cglib v3.* on your class path which uses a recent version of ASM. The problem that you encounter is that cglib modifies the behavior of the ASM class writer by inheritance rather then by delegation. However, ASM enforced this latter best practice by making its ClassWriter's methods final from any version 4.* while it was still possible to override its methods in version 3. The error you encounter is a result of combining cglib 2.* with ASM 4.*.

Fortunately (for you), cglib has been rather static in its last versions, i.e. there were only minor API changes while the newer versions mostly consisted of updates of ASM. If you are lucky, this explicit use of cglib v3.* therefore solves your problem. This holds as long as none of your project dependencies has a direct dependency on ASM what seems reasonable for the dependencies you named like Jersey or Lucene.

If this does not work, you need to recompile some of your dependencies while using a tool like jarjar in order to repack the direct ASM dependencies into different name spaces in order to resolve these version conflicts. An alternative could be to isolate different ASM versions by some conditional child-first ClassLoader magic but this is not so recommendable since the effects are unpredictable and will also result in a performance penalty.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top