ASM Objectweb访客没有转换

时间:2014-11-12 10:34:49

标签: javaagents java-bytecode-asm

我想使用ASM来验证某些方法的调用频率以及它们的参数和结果。但是,在运行时它以java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader): attempted duplicate class definition for name: "com/foo/bar/DefaultType"结束。

出于这个原因,我想确保它不是ASM(Objectweb)问题,所以它试图只使用以下代码传递字节而不做任何修改:

@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;
}

但即使经过这次修改,我也会得到同样的错误。有什么提示我应该改变以使这段代码有效吗?

1 个答案:

答案 0 :(得分:0)

对一个老问题的最新答案。

发生这些错误的一种方法是由于如何实现COMPUTE_FRAMES的{​​{1}}选项。特别是,帧计算有时需要找出两个给定类的公共超类。为此,它将使用ClassWriter加载其感兴趣的类。如果您的代码库使用了非平凡的类加载设置,则可能会发生这种情况,即以这种方式将类加载到未受污染的类加载器中(我不记得确切的条件,但是我曾经遇到过这种情况)。解决方案是重写Class.forName的{​​{1}}方法,以更安全的方式执行相同的计算。