我想使用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;
}但即使在此修改之后,我也会得到相同的错误。为了让这段代码正常工作,我应该做些什么?
发布于 2020-10-25 17:29:20
对一个老问题的迟来的回答。
发生这些错误的一种方式是由于ClassWriter的COMPUTE_FRAMES选项的实现方式。特别是,帧计算有时需要为两个给定的类找出一个公共超类;为此,它将使用Class.forName加载它感兴趣的类。如果您的代码库使用非平凡的类加载设置,则可能会发生这样的情况:类被加载到未被检查的类加载器中(我记不起确切的情况,但我曾经遇到过这种情况)。解决方案是覆盖ClassWriter的getCommonSuperclass方法,以更安全的方式执行相同的计算。
https://stackoverflow.com/questions/26884810
复制相似问题