異常:InvocationTargetException && NoSuchMethodError

使用框架代碼常常會發生反射異常,並且很差定位。屢次遇到過InvocationTargetException和NoSuchMethodError錯誤,恰巧今天同事遇到這個問題,決定記錄一下。這次遇到這兩個異常同時發生,其實二者沒有關聯,只是後面的是根本緣由,而前面的是大的包裝異常。java

##InvocationTargetException## 先看jdk1.6中的描述:spring

public class InvocationTargetException extends Exception

「InvocationTargetException is a checked exception that wraps an exception thrown by an invoked method or constructor.」編程

InvocationTargetException 是一種包裝由調用方法或構造方法所拋出異常的受檢查異常。 從版本 1.4 開始,此異常已經更新,符合通用異常鏈機制。「目標異常」是在構造的時候提供的,能夠經過 getTargetException() 方法訪問,這類對象目前被認爲是致使異常的緣由,能夠經過 Throwable.getCause() 方法訪問它。瀏覽器

一般發生在採用反射的方式調用方法的時候,好比顯式的反射或使用框架。此異常會吞掉其餘全部異常,要想看到進一步具體緣由,就須要查看打出來的異常下面的「Caused By:」或使用getCause()獲取緩存

##NoSuchMethodError## 一樣先看下jdk1.6中的描述:tomcat

public class NoSuchMethodError extends IncompatibleClassChangeError

當應用程序試圖調用類(靜態或實例)的指定方法,而該類已再也不具備該方法的定義時,拋出該異常。一般由編譯器捕獲該錯誤;僅當類定義發生不相容的更改時,在運行時纔會發生該錯誤。編譯器捕獲很容易解決,其實咱們一般遇到的是運行時錯誤。好比,使用泛型編程(框架代碼裏一般有大量泛型)時方法參數會被編譯器擦除,而反射調用時使用了具體類型致使方法簽名不匹配。app

一般發生此錯誤的緣由大概有(也是定位問題的優先步驟): (1)本身顯示使用反射或使用框架調用一個類的確不包含的方法。但反射使用時編譯器不會報錯。 (2)被調用的方法的確存在。此時有多是: 2.1 應用環境中存在同全路徑名的類,但類裏方法不一樣,一個有此方法一個沒有此方法,但jvm調用了沒有此方法的類。或應用環境中包含了同一個框架的不一樣版本的jar包,有方法不兼容,好比spring,hibernate的包均可能。 解決辦法:若是是框架類報錯,通常刪除衝突的低版本框架包;若是是本身的類,則查看是否能夠重命名類。框架

2.2 不存在同名的類,並且報錯的類是本身的類而不是框架的類,多是本身修改了本身的類簽名(好比參數類型),環境裏沒有更換最新的class。 解決辦法:clean工程再從新打包。jvm

##本人遇到異常信息##hibernate

java.lang.reflect.InvocationTargetException
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:601)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:450)
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActio
…
…
java.lang.NoSuchMethodError: com.**.framework.appsp.service.UsersService.saveOrUpdate(Lcom/**/framework/appsp/bean/UsersEntity;)Ljava/lang/String;
    com.**.framework.appsp.action.UsersAction.addUser(UsersAction.java:73)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:601)

看到InvocationTargetException後直接找下面的Caused By:,(若是沒有詳細異常就本身再修改下代碼用getCause()捕獲一下),java.lang.NoSuchMethodError: com.**.framework.appsp.service.UsersService.saveOrUpdate(Lcom/**/framework/appsp/bean/UsersEntity;)Ljava/lang/String;(備註:這裏是提示的方法簽名,方法名稱(方法參數)返回值,經過這裏也能夠看下jvm實際調用的方法是否爲本身想調用的方法)根據提示saveOrUpdate找不到,但實際是存在的,並且這個是本身實現的類。在系統環境中沒有找到衝突的同名類,應該是編譯過程有問題。從新clean 打包,刪除瀏覽器緩存,tomcat緩存,啓動,一切正常了。這裏說的挺輕鬆,其實定位過程很糾結。

InvocationTargetException異常的緣由各類各樣,仍是具體問題具體看待,必定要找到這個異常後面的真正異常再去分析。我這裏分析的緣由是我的遇到的和在網上看到的其餘人解決的,應該還只是一個子集,後面遇到再繼續補充。

相關文章
相關標籤/搜索