Cglib throws an IllegalArgumentException when raising the java.util.Date class

I am trying to improve java.util.Date using cglib. This does not work, and I do not experience cglib, so I am wondering what is going wrong.

For example, the code that improves ArrayList below 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(); } 

and the following code:

 @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(); } 

leads to 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) 
+5
source share
2 answers

It seems that you are using the JDK in version 8, which includes class files in version 8. These class files are not supported by cglib, as this library depends on an older version of ASM .

To debug this, we should note that ASM does not contain any debugging information and does not provide all the information in its stack trace. All we know is that there is an IllegalArgumentException from the constructor (called <init> ) of its ClassReader . An analysis of the source code shows that there is only one possibility for such an exception. From the source code of ASM 4.2, which is the latest version of cglib , we see that such an exception is thrown only if the class file has a version unknown to the ASM version:

 // checks the class version if (readShort(off + 6) > Opcodes.V1_7) { throw new IllegalArgumentException(); } 

Unfortunately, there was no text message for this error, there is no real reason why this is not so, but we have to live with it. To fix this error, you will need a version of cglib, which depends on ASM 5+, which supports Java 8.

To date, a compatible version of cglib exists , since cglib is no longer supported . You might want to try an alternative library such as Byte Buddy (note that I wrote this library, a shameless insert). The enhancement will work something like this:

 new ByteBuddy().subclass(Date.class) .method(named("toString")) .intercept(FixedValue.value("Hello world!")) .make() .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded() .newInstance(); 

which will override the toString method since Byte Buddy does not allow you to define classes with invalid return values.

+5
source

Issue was pointed out in cglib, as Rafael Winterhalter pointed out, which prevented cglib from working out winth java 8 classes. It has been fixed in cglib 3.2.0 . Updating to the latest version ( 3.2.4 ) solves the problem.

+3
source

Source: https://habr.com/ru/post/1207538/


All Articles