我想使用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;
}
但即使经过这次修改,我也会得到同样的错误。有什么提示我应该改变以使这段代码有效吗?
答案 0 :(得分:0)
对一个老问题的最新答案。
发生这些错误的一种方法是由于如何实现COMPUTE_FRAMES
的{{1}}选项。特别是,帧计算有时需要找出两个给定类的公共超类。为此,它将使用ClassWriter
加载其感兴趣的类。如果您的代码库使用了非平凡的类加载设置,则可能会发生这种情况,即以这种方式将类加载到未受污染的类加载器中(我不记得确切的条件,但是我曾经遇到过这种情况)。解决方案是重写Class.forName
的{{1}}方法,以更安全的方式执行相同的计算。