I'm trying to get bytecode of cglib enhanced object this way using BCEL:
package app;
import cglib.MyInterceptor;
import net.sf.cglib.proxy.Enhancer;
import org.apache.bcel.Repository;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import service.Tool;
public class CgLibApp {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
// target object
Tool tool = new Tool();
// proxying
Enhancer e = new Enhancer();
e.setSuperclass(tool.getClass());
e.setCallback(new MyInterceptor(tool));
Tool proxifiedTool = (Tool) e.create();
// trying to get proxy byte code
JavaClass clazz = Repository.lookupClass(proxifiedTool.getClass());
Method method = clazz.getMethod(Tool.class.getMethod("meth"));
System.out.println(method.getCode().toString());
}
}
But I'm getting:
Exception in thread "main" java.lang.ClassNotFoundException: SyntheticRepository could not load service.Tool$$EnhancerByCGLIB$$22a3afcc
at org.apache.bcel.util.SyntheticRepository.loadClass(SyntheticRepository.java:174)
at org.apache.bcel.util.SyntheticRepository.loadClass(SyntheticRepository.java:158)
at org.apache.bcel.Repository.lookupClass(Repository.java:74)
at app.CgLibApp.main(CgLibApp.java:21)
What should I do to get bytecode from Enhanced object?
I've found this question while researching how to save the CGLIB-generated class in spring-boot 3.0 application (e.g. handling @Transactional
or @Configuration
-annotated classes). This simple approach may help:
import org.springframework.cglib.core.ReflectUtils;
...
public class SpringCglibUtils {
public static void initGeneratedClassHandler(String targetPath) {
File dir = new File(targetPath);
dir.mkdirs();
ReflectUtils.setGeneratedClassHandler((String className, byte[] classContent) -> {
try (FileOutputStream out = new FileOutputStream(new File(dir, className + ".class"))) {
out.write(classContent);
} catch (IOException e) {
throw new UncheckedIOException("Error while storing " + className, e);
}
});
}
}
and then define in your main class before creating context:
SpringCglibUtils.initGeneratedClassHandler("cglib");
Spring will store to the targetPath
directory all generated class files.
Note: unfortunately it's not available before spring-boot 3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With