依赖外部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

 

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