ASM Objectweb visitors without transformation

169 views Asked by At

I want to use ASM to verify how often certain methods are called and what their arguments and result is. However, at runtime it ends with a java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader): attempted duplicate class definition for name: "com/foo/bar/DefaultType".

For that reason I want to ensure that it is not an ASM (Objectweb) problem, so it tried to just pass the bytes without any modification with the following code:

@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
  ProtectionDomain protectionDomain, byte[] classfileBuffer)
  throws IllegalClassFormatException {

byte[] result;

if(className.startsWith("com/foo/bar"))
{
    ClassReader reader = new ClassReader(classfileBuffer);

    try 
    {
      ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

      reader.accept(writer, 0);

      result = writer.toByteArray();
    }
    catch(Exception e)
    {
      result = null;
    }
  }
  else
  {
    // do nothing
    result = null;
  }
  return result;
}

But even after this modification I get the same Error. Any hints what I should change to get this code working?

1

There are 1 answers

0
Johannes Kloos On

Late answer to an old question.

One way these errors can occur is due to how the COMPUTE_FRAMES option of ClassWriter is implemented. In particular, the frame computation will sometimes need to figure out a common superclass for two given classes; to do this, it will load the classes it is interested in using Class.forName. If your codebase uses a non-trivial class loading setup, it may happen that a class gets loaded in an unpexected class loader this way (I can't recall the precise conditions, but I have had this happen to me). The solution is to override the getCommonSuperclass method of ClassWriter to perform the same computation in a safer way.