依賴外部jar包問題記錄

一、jar包信息

其他地區的同事開發的模塊,依賴該jar包用於cli-name轉換,暫且叫它A.jar。

該模塊基於dropwizard框架,內部依賴比較複雜。

依賴A.jar後,調試過程中產生了不少問題,做個記錄,有些解決方案比較蠢。

 

二、springboot依賴該jar包,問題記錄

1. IDEA中運行junit單元測試,報錯:command line is too long

        一般情況下可採用的解決方案 : https://blog.csdn.net/kzadmxz/article/details/80322687    

        但是依賴的這個jar包中,cli-name轉換流程,有獲取classpath,掃描jar包中的xml文件這個邏輯

String javaClassPath = System.getProperty("java.class.path");

        dynamic classpath造成獲取到的classpath不正確,掃描不到xml文件,產生的問題類似這個:https://blog.csdn.net/moneyshi/article/details/82459039

        最終解決“command line is too long”的方法還是要使本地存儲庫的路徑儘可能短,參考  http://www.it1352.com/535521.html

 

2. Application Run failed

image.png

        A.jar基於dropwizard框架,應用啓動失敗可能是dropwizard的一些註解的影響或者引入了衝突的jar包,具體原因沒有深究。

        對A.jar做了依賴分析,排除掉其中的xxx-xx-rest,應用可正常啓動

<dependency>
    <groupId>com.xxx.xxx.xxx.platform</groupId>
    <artifactId>xx-xx-xxconverthelper</artifactId>
    <version>xxxxx</version>
    <exclusions>
        <exclusion>
            <groupId>com.xxx.xxx.xx.platform</groupId>
            <artifactId>xxx-xx-rest</artifactId>
        </exclusion>
    </exclusions>
</dependency>

 

3. 框架不兼容

        前面提到依賴的這個jar,它是基於dropwizard框架下的一個module,默認的IOC容器爲hk2,其中有個類中存在這樣的代碼:

serviceLocator = ServiceLocatorHolder.getLocator();
inventoryLtpService = (InventoryLtpService)serviceLocator.getService(InventoryLtpService.class, new Annotation[0]);

      我們是springboot框架,用的是springboot的IOC,hk2的serviceLocator必然是獲取不到的,上面的代碼會報空指針異常。

        沒有想到什麼更好的方案,採用的解決方法是覆蓋jar包中的這個類,重新實現代碼邏輯。可參考:https://blog.csdn.net/u013062329/article/details/86592385

 

三、osgi依賴該jar包,問題記錄

1. jar包衝突

        運行UT,報錯,查找到log4j-over-slf4j是由umben-em-rest間接引入的,直接全部排除掉umben-em-rest,同2.2

image.png

 

2. osgi依賴第三方非bundle的jar包

        umebn-em-rosngconverthelper是一個普通的jar包,非bundle。參考https://blog.csdn.net/sunquan291/article/details/89189318

        採用的解決方案是第三方依賴作成JAR,嵌入到當前bundle中。存在的問題是A.jar提供的cli-name轉換功能,裏面依賴了比較多其他jar包,需要一起嵌入進來,依賴傳遞問題比較嚴重,調試起來複雜,還有import-package的處理需要比較仔細。

        對於依賴傳遞問題,一開始是做了依賴分析,想盡量把依賴都嵌入進來,避免調試時一遍遍出現ClassDefNotFound。但是一些錯誤引入會造成一些麻煩,比如我把jdom錯誤地作爲依賴寫在了pom裏,造成

 bundle安裝時報錯,直到看到 https://stackoverflow.com/questions/33395100/the-default-package-is-not-permitted-by-the-import-package-syntax   最後一個回答,才意識到錯誤所在。儘量還是隻嵌入代碼邏輯需要用到的jar包,一來避免類似這樣的低級錯誤,二來儘量減小bundle的體積。

 

3. classpath問題

        上面提到cli-name轉換流程,有獲取classpath,掃描jar包中的xml文件這個邏輯。當運行karaf時,debug到 System.getProperty("java.class.path") 這一步,無法獲取到JDK目錄下的lib jar包,因此無法找到xml文件。https://stackoverflow.com/questions/3906222/printing-osgi-bundle-classpath 這個Answer描述的是類似的問題。

        目前對OSGI的底層原理和類加載器瞭解比較少,針對這個問題,採用的方法還是覆蓋jar包中的類,將xml文件放在指定位置,不掃描jar,去指定位置讀取。

 

4. bundle的文件讀取問題

        將xml文件放在src/resources文件夾下,採用的文件加載方式爲:

URL url = this.getClass().getClassLoader().getResource(directory);

        運行karaf之後,獲取到的url爲 bundleresource://214.fwk1205445235/converclass/,並不是常規的file://  開頭的協議,因此還是會報找不到文件錯誤。網絡上的一種解決方法爲https://blog.csdn.net/windrui/article/details/40581219 

 

5. xml文件解析異常

javax.xml.parsers.FactoryConfigurationError: Provider com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl could not be instantiated: java.lang.ClassCastException: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl cannot be cast to javax.xml.parsers.SAXParserFactory

相似問題記錄:

https://stackoverflow.com/questions/2619880/unbelievable-cannot-cast-from-class-x-to-its-super-class

http://www.voidcn.com/article/p-annolfiy-btt.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章