解決Java執行過程當中拋簽名異常的問題

最近某Java工程啓動中拋出了一個詭異的問題, 堆棧比較長, 主要緣由是:java

java.lang.SecurityException: class "javax.servlet.AsyncListener"'s signer information does not match signer information of other classes in the same package

經Google, 發現是因爲javax.servlet這個包中的衆多類, 在多個Jar包中均有實現(好比X和Y都有實現), 若是該Java進程加載時, 使用了X.jar中的javax.servlet.A, 又加載了Y.jar中的javax.servlet.B, 同時X.jar和Y.jar的簽名不一致, 這樣會致使以上報錯.api

在IDE中查找類javax.servlet.AsyncListener, 發如今多個帶javaee或者servlet名字的jar包中均有實現, 能夠經過如下命令獲取工程的全部依賴:tomcat

mvn dependency:tree

爲了定位是哪一個Jar包致使的該問題, 咱們在實現了這個類的Jar包中, 進行簽名檢查:eclipse

jarsigner -verify xxx.jar

經過這個命令能夠看到該Jar是否有簽名. ide

最後發現, 這些Jar包中, 只有一個有簽名, 而其餘都沒有:code

org.eclipse.jetty.orbit:javax.servlet:jar:3.0.0.v201112011016:compile

因此能夠推斷應該是這個eclipse對servlet的實現的Jar包使用了簽名, 致使和其餘相關Jar包不兼容. (是有多喜歡造輪子)orm

而這個Jar包, 經過依賴樹, 咱們發現是hive-jdbc 2.3.2依賴引入的(看着hive依賴真混亂..., 記得hbase也是), 經過升級到 3.1.0, 再次檢查依賴, 咱們發現這個Jar包已經不在依賴樹中了. 而啓動錯誤也消失了.進程

或者還有另一個方法, 把這個有問題的包從hive-jdbc 2.3.2 中exlucde掉, 讓hive使用其餘包中的javax.servlet實現. 其實即使沒有其餘包有javax.servlet的實現, 或者其scope爲provided, 只要這個工程在tomcat中啓動, 都是能夠的. 由於tomcat自帶servlet-api實現.ip

相關文章
相關標籤/搜索