如何让 org.objectweb.asm.util.CheckClassAdapter 抛出异常而不是将错误打印到 stderr?

问题描述 投票:0回答:1

我目前正在我的 Java 项目中使用

org.objectweb.asm.util.CheckClassAdapter
进行字节码验证。但是,我观察到此类将错误打印到 stderr 而不是抛出异常,这使得以编程方式处理验证失败变得具有挑战性。

这是现有代码片段的示例:

final byte[] bytes = …; // class bytes are generated previously  
CheckClassAdapter.verify(
    new ClassReader(bytes),
    false,
    new PrintWriter(System.err)
);

看来潜在的解决方法可能是:

final byte[] bytes = …; // class bytes are generated previously  
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
CheckClassAdapter.verify(
    new ClassReader(bytes),
    false,
    pw
);
if (sw.toString().contains("AnalyzerException")) {
  System.err.println(sw.toString());
  fail();
}

但是,这个解决方案对我来说就像一个“拐杖”。有没有办法修改或扩展

CheckClassAdapter
以使其在字节码验证失败时抛出异常,而不是将错误打印到 stderr?我的目标是捕获并处理代码中的验证错误。任何指导或示例将不胜感激。


ASM版本:

org.ow2.asm:asm:9.6

java bytecode java-bytecode-asm
1个回答
0
投票

由于我还没有找到如何使用

CheckClassAdapter
来验证字节码并抛出
AnalyzerException
异常,因此我决定按照Holger的建议修改验证方法的源代码。以下是验证字节码的方法:

/**
 * Verify the bytecode.
 * @param bytes The bytecode to verify.
 */
private void verify(final byte[] bytes) throws AnalyzerException {
    final ClassNode clazz = new ClassNode();
    new ClassReader(bytes)
        .accept(new CheckClassAdapter(clazz, false), ClassReader.SKIP_DEBUG);
    final Optional<Type> syper = Optional.ofNullable(clazz.superName).map(Type::getObjectType);
    final List<Type> interfaces = clazz.interfaces.stream().map(Type::getObjectType)
        .collect(Collectors.toList());
    for (final MethodNode method : clazz.methods) {
        final SimpleVerifier verifier =
            new SimpleVerifier(
                Type.getObjectType(clazz.name),
                syper.orElse(null),
                interfaces,
                (clazz.access & Opcodes.ACC_INTERFACE) != 0
            );
        // You might need to set your own ClassLoader here.
        // verifier.setClassLoader(Thread.currentThread().getContextClassLoader());
        new Analyzer<>(verifier).analyze(clazz.name, method);
    }
}

进口:

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.analysis.Analyzer;
import org.objectweb.asm.tree.analysis.AnalyzerException;
import org.objectweb.asm.tree.analysis.SimpleVerifier;
import org.objectweb.asm.util.CheckClassAdapter;

另外,值得一提的是,这种方法并不完美,因为您生成字节码然后再次解析它。最有可能的是,您可以通过使用

CheckClassAdapter
CheckMethodAdapter

将字节码验证直接集成到生成过程中来简化此过程
© www.soinside.com 2019 - 2024. All rights reserved.