问题描述
我正在尝试使用cglib增强 java.util.Date
。它不起作用,我对cglib没有经验,所以我想知道出了什么问题。
I am trying to enhance java.util.Date
with cglib. It does not work and I am not experienced with cglib, so I am wondering what is going wrong.
例如,下面的代码增强了 ArrayList
有效:
For example, the below code enhancing an 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();
}
,但以下代码:
@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();
}
导致此异常:
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)
推荐答案
好像你在版本8中使用了JDK,其中包括版本8中的类文件.cglib不支持这些类文件,因为此库依赖于过时版本的,我们可以看到只有在类文件是ASM版本未知的版本时才会抛出此类异常:
To debug this, we have to note that ASM does not include any debugging information and does not provide all information in its stack trace. All we know is that there is a IllegalArgumentException
thrown from a constructor (named <init>
) of its ClassReader
. Looking at the source code reveals that there is only one possibility for such an exception. From the source code of ASM 4.2 which is used by the latest version of cglib, we can see that such an exception is only thrown if the class file is of a version that is unknown to the version of ASM:
// checks the class version
if (readShort(off + 6) > Opcodes.V1_7) {
throw new IllegalArgumentException();
}
不幸的是,没有为此错误提供短信,没有真实的为什么不是这种情况的原因,但我们必须忍受这一点。要修复此错误,您需要一个依赖于支持Java 8的ASM 5+的cglib版本。
Unfortunately, there was not text message provided for this error, there is no real reason for why this is not the case, but we have to live with this. To fix this error, you would need a cglib version which depends on ASM 5+ which supports Java 8.
截至今天,,因为cglib是。您可能想尝试(注意我写了这个库,无耻插件)。增强功能可以是这样的:
As of today, there is no compatible version of cglib available as cglib is not really maintained anymore. You might want to try out an alternative library such as Byte Buddy instead (note that I wrote this library, shameless plug). The enhancement would 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();
将覆盖 toString
方法作为字节Buddy不允许您定义具有非法返回值的类。
which would override the toString
method as Byte Buddy does not allow you to define classes with illegal return values.
这篇关于增强java.util.Date类时,cglib会抛出IllegalArgumentException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!