Enhanced Java util. Cglib will throw illegalargumentexception when using the date class
I tried to use cglib to enhance Java util. Date. It's useless. I have no experience with cglib, so I want to know what's wrong
For example, the following code enhances how ArrayList works:
@Test public void enhance_ArrayList() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(ArrayList.class); enhancer.setCallback(new FixedValue() { @Override public Object loadObject() throws Exception { return "Hello cglib!"; } }); ArrayList enhanced = (ArrayList)enhancer.create(); }
The following codes:
@Test public void enhance_Date() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Date.class); enhancer.setCallback(new FixedValue() { @Override public Object loadObject() throws Exception { return "Hello cglib!"; } }); Date enhanced = (Date)enhancer.create(); }
Cause this exception:
java.lang.IllegalArgumentException at org.objectweb.asm.ClassReader.<init>(UnkNown Source) at org.objectweb.asm.ClassReader.<init>(UnkNown Source) at org.objectweb.asm.ClassReader.<init>(UnkNown Source) at net.sf.cglib.proxy.BridgeMethodResolver.resolveAll(BridgeMethodResolver.java:61) at net.sf.cglib.proxy.Enhancer.emitMethods(Enhancer.java:911) at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:498) at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
Solution
You seem to be using the JDK in version 8, which contains the class files in version 8 Cglib does not support these class files because this library relies on outdated ASM versions
To debug this, we must note that ASM does not contain any debugging information and does not provide all information in its stack trace All we know is that an illegalargumentexception was thrown from its classreader constructor (named < init >) Looking at the source code, you can see that there is only one possibility of this exception From the source code (used by the latest version of cglib) of ASM 4.2, we can see that if the class file is an unknown version of ASM, only such exceptions will be thrown:
// checks the class version if (readShort(off + 6) > Opcodes.V1_7) { throw new IllegalArgumentException(); }
Unfortunately, there is no text message for this error. There is no real reason why this is not the case, but we must put up with it To fix this error, you need a cglib version that relies on ASM 5 that supports Java 8
As of today, there is no compatible version of cglib available because cglib is not really maintained anymore You may want to try alternative library such as byte buddy Enhancements can be:
new ByteBuddy().subclass(Date.class) .method(named("toString")) .intercept(FixedValue.value("Hello World!")) .make() .load(getClass().getClassLoader(),ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .newInstance();
This overrides the toString method because byte buddy does not allow you to define classes with illegal return values