2012-10-08 16 views
5

當我在Eclipse中使用JDK7或JDK6編譯和運行項目時,一切都很順利。然而,當我使用ANT構建它然後嘗試使用系統JDK7運行它時,出現以下錯誤:Java 7 - 不一致的堆棧映射框架 - 需要幫助理解解決方案的工作原理

方法myClass.myMethod()中的分支目標25處的不一致堆棧映射幀[[Ljava/lang/Object;在偏移14

我到處找,發現在計算器上一對夫婦在這裏很好的問題:

基本上都建議加上-XX:-UseSplitVerifier作爲JVM選項確實解決了這個問題。我仍然不完全明白爲什麼,但顯然this bug report是應該幫助。不幸的是,我仍然沒有得到它...

我注意到有人使用面向方面編程的問題之一,這讓我覺得我使用Guice(谷歌的DI框架),可能會導致問題但我看不到如何。假設支持JDK7。

我也在使用Proguard,但是這也是假設可以使用JDK7。

反正在這一點上,我不知道爲什麼這個解決方法工作,而不是基本上回落到以前的JDK(在這種情況下是JDK6)版本,當部分代碼試圖播放字節碼時這就是爲什麼我認爲它與DI)代碼有關。但我仍然無法建立適當的聯繫。我也可以離開!

如果有人能解釋發生了什麼或爲什麼發生這種情況,我會非常感激。此外,我真的很討厭使用解決方法,因爲這不是我認爲的長期解決方案。

+0

*「這是假設支持JDK7。」* - 也許它的支持是越野車。您是否搜索過Guice問題跟蹤器/組/列表? –

+0

在他們的問題跟蹤器中找不到任何錯誤 –

+0

我的猜測是,在java7中,他們添加了更積極的字節碼驗證檢查,無論guice用字節代碼做它的依賴注入沒有與這些檢查工作 –

回答

3

從Java 7開始,編譯的字節碼必須包含額外的StackMapTable屬性。這些有助於JVM內部的驗證器在類加載時檢查類是否構建得很好。早期版本的Java更加寬鬆,無需使用屬性就可以減慢驗證速度。

修改原始編譯字節碼的工具(編譯後的ProGuard,即將執行之前的AOP框架...)需要使用修改的代碼一致地更新屬性。如果他們不這樣做,你會得到錯誤消息「不一致的堆棧映射幀」。

ProGuard應該很好地執行此預驗證;我沒有意識到它有任何問題。如果在未應用ProGuard的情況下仍看到錯誤,則問題必須出在DI或AOP上。