2014-11-23 102 views
5

我試圖用cglib增強java.util.Date。它不工作,我沒有經驗與cglib,所以我想知道什麼是錯的。cglib在增強java.util.Date類時拋出IllegalArgumentException

例如,下面的代碼增加一個ArrayList作品:

@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) 

回答

5

好像你正在使用包含版本8中的類文件的版本8中的JDK。這些類文件是n不受cglib支持,因爲此庫取決於ASM的過期版本。

爲了進行調試,我們必須注意ASM不包含任何調試信息,也不提供堆棧跟蹤中的所有信息。我們所知的是,ClassReader的構造函數(名爲<init>)引發了IllegalArgumentException。查看源代碼可以發現,這種例外只有一種可能性。從ASM 4.2是used by the latest version of cglib的源代碼,我們可以看到,這種異常只是拋出如果類文件的版本是未知版本的ASM:

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

不幸的是,沒有爲這個錯誤提供的文本消息,沒有真正的理由爲什麼不是這種情況,但我們必須忍受這一點。要解決此錯誤,您需要一個cglib版本,該版本取決於支持Java 8的ASM 5+。

截至今天,有no compatible version of cglib available,因爲cglib是not really maintained anymore。你可能想嘗試一個alternative library such as Byte Buddy而不是(注意我寫這個庫,無恥的插件)。增強會的工作是這樣的:

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

這將覆蓋toString方法字節好友不允許與非法的返回值定義類。

+0

謝謝。現在切換回java7,它工作正常。需要看看Byte Buddy或其他選項,當需要將應用程序升級到java8時,如果cglib在此時不支持java8。 – Raipe 2014-11-25 19:20:24

3

在cglib中有一個issue,由Rafael Winterhalter在他的回答中指出,它阻止了cglib在java 8類中運行。它被修復在cglib 3.2.0。更新到最新版本(3.2.4)解決了這個問題。

相關問題