javassist 处理 Cglib 生成的类时发生 javassist.NotFoundException

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

我的代码如下:

  1. pom.xml
    <dependencies>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.29.2-GA</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.7.7</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
  1. CglibTest.java
public class CglibTest implements MethodInterceptor {
    public void run() {
        System.out.println("hello cglib");
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("before run()");
        methodProxy.invokeSuper(o, objects);
        System.out.println("after run()");
        return null;
    }
}
  1. Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");

        CglibTest cglibTest = new CglibTest();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(CglibTest.class);
        enhancer.setCallback(cglibTest);
        CglibTest testService = (CglibTest) enhancer.create();
        System.out.println("CglibTest : " + testService.getClass().getName());
    }
}
  1. javaagent + javassist
public class Agent {
    public static void premain(String agentArgs, Instrumentation inst) {
        MonitorTransformer transformer = new MonitorTransformer();
        inst.addTransformer(transformer, true);
    }
}

public class MonitorTransformer implements ClassFileTransformer {

    @Override
    public byte[] transform(ClassLoader loader, String originalClsName, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
        String className = originalClsName.replaceAll("/", ".");
        if (className.startsWith("java.") || className.startsWith("sun.")
                || className.startsWith("jdk.") || className.startsWith("javax.")
                || className.startsWith("com.sun.")
        ) {
            return classfileBuffer;
        }

        ClassPool ctPool = ClassPool.getDefault();
        CtClass ctClass;
        try {
            try {
                ctClass = ctPool.get(className);
            } catch (NotFoundException e) {
                ctPool.appendClassPath(new LoaderClassPath(loader));
                try {
                    ctClass = ctPool.get(className);
                } catch (NotFoundException ne) {
                    System.out.println("javassist fail, ctClass not found: " + className + ", origin: " + originalClsName);
                    ne.printStackTrace();
                    return classfileBuffer;
                }
            }
            return ctClass.toBytecode();
        } catch (Error e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return classfileBuffer;
    }

    @Override
    public byte[] transform(Module module, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        ClassLoader cl = module.getClassLoader() == null ? loader : module.getClassLoader();
        return this.transform(cl, className, classBeingRedefined, protectionDomain, classfileBuffer);
    }
}

我运行,然后像这样抛出异常: javassist.NotFoundException:org.example.CglibTest$$EnhancerByCGLIB$$f3005a82

我尝试使用jdk-dynamic-proxy,这种情况是正常的。不知道为什么Javassist在遇到Cglib的时候会抛出这样的异常。有人可以帮我解决吗?

spring javassist javaagents cglib
© www.soinside.com 2019 - 2024. All rights reserved.