如何解决SpringBoot与ODataJClient版本冲突的问题?

原创 2017年05月22日 20:26:46

我们知道使用SpringBoot可以帮助我们快速建立一个原型;笔者当前使用的SpringBoot的版本是1.4.3.RELESE. 当前使用的ODataJClient的版本是0.9.0. 如果SpringBoot和包含ODataJClient的单元测试分开跑,SpringBoot和ODataJClient都能通过Maven或者Gradle编译,也都能透过测试。 但是如果把SpringBoot和ODataJClient集成起来,就会出现下面的问题。报错的原因如下:

Caused by: java.util.ServiceConfigurationError: javax.xml.stream.XMLEventFactory: Provider com.fasterxml.aalto.stax.EventFactoryImpl not a subtype
at java.util.ServiceLoader.fail(ServiceLoader.java:239)
at java.util.ServiceLoader.access$300(ServiceLoader.java:185)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
at javax.xml.stream.FactoryFinder$1.run(FactoryFinder.java:353)
at java.security.AccessController.doPrivileged(Native Method)
at javax.xml.stream.FactoryFinder.findServiceProvider(FactoryFinder.java:341)
at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:313)
at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:227)
at javax.xml.stream.XMLEventFactory.newInstance(XMLEventFactory.java:64)
at org.hibernate.boot.jaxb.internal.MappingBinder.<init>(MappingBinder.java:40)
at org.hibernate.boot.spi.XmlMappingBinderAccess.<init>(XmlMappingBinderAccess.java:43)
at org.hibernate.boot.MetadataSources.<init>(MetadataSources.java:87)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:179)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:149)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:54)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1648)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1585)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:554)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:111)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)

通过下面的分析,可知

mvn dependency:tree -Dverbose

原来缺少jackson-dataformat-xml的依赖(其实不缺少,只不过是odatajclient-engine也依赖jackson-dataformat-xml(2.2.3),其版本比SpringBoot默认的版本低)

所以odatajclient-engine的覆盖了SpringBoot的jackson-dataformat-xml(2.8.5)的版本,从而报错。所以解决方案是显式的在SpringBoot的项目中加入下面的依赖。

<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>

<dependency>
<groupId>com.msopentech.odatajclient</groupId>
<artifactId>odatajclient-engine</artifactId>
<version>0.9.0</version>
</dependency> 

注意,其必须在加在odatajclient-engine的Maven或者Gradle依赖前面。这样SpringBoot抛出的上面异常就会消除。但是,还有坑。

这个时候SpringBoot的问题解决了,但是odatajclient调用oData V3(比如DSC 5.x的服务)的单元测试就会失败,

调用示范代码:

import java.io.InputStream;
import java.util.List;
import org.junit.Test;
import com.msopentech.odatajclient.engine.communication.request.retrieve.ODataEntitySetRequest;
import com.msopentech.odatajclient.engine.communication.request.retrieve.ODataRetrieveRequestFactory;
import com.msopentech.odatajclient.engine.communication.response.ODataRetrieveResponse;
import com.msopentech.odatajclient.engine.data.ODataEntity;
import com.msopentech.odatajclient.engine.data.ODataEntitySet;
import com.msopentech.odatajclient.engine.format.ODataPubFormat;
import com.msopentech.odatajclient.engine.uri.ODataURIBuilder;

public class ODataTest {
	String testODataServiceRootURL="http://dsc-pull-server:8080/PSDSCPullServer.svc/";
	@Test
	public void testName()  {
		ODataURIBuilder uriBuilder = new ODataURIBuilder(testODataServiceRootURL).appendEntityTypeSegment("Nodes(AgentId='19940477-E202-11E6-80B8-BE117D36B7A4')/Reports");

	    ODataEntitySetRequest req = ODataRetrieveRequestFactory.getEntitySetRequest(uriBuilder.build());
	    req.setFormat(ODataPubFormat.JSON);
	    req.getResponseTemplate();
	    ODataRetrieveResponse<ODataEntitySet> res = req.execute();
	    InputStream input=res.getRawResponse();
	    @SuppressWarnings("rawtypes")
	   // JsonSerializer jsonSerializer= new StdSerializer();
	    
       // System.out.println( res.getStatusCode());
        ODataEntitySet entitySet = res.getBody();
        List<ODataEntity> lsODataEntity=entitySet.getEntities();
        for(ODataEntity odataEntity:lsODataEntity){
        	odataEntity.getProperties();
        	
        }
        System.out.println(entitySet.getCount());
      
	   
	}
}

结果如下:

java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    com/msopentech/odatajclient/engine/data/Deserializer.toODataErrorFromXML(Ljava/io/InputStream;)Lcom/msopentech/odatajclient/engine/data/xml/XMLODataError; @22: invokespecial
  Reason:
    Type 'com/fasterxml/aalto/stax/OutputFactoryImpl' (current frame, stack[5]) is not assignable to 'com/msopentech/javax/xml/stream/XMLOutputFactory'
  Current Frame:
    bci: @22
    flags: { }
    locals: { 'java/io/InputStream' }
    stack: { uninitialized 0, uninitialized 0, uninitialized 4, uninitialized 4, 'com/fasterxml/aalto/stax/InputFactoryImpl', 'com/fasterxml/aalto/stax/OutputFactoryImpl' }
  Bytecode:
    0x0000000: bb00 0259 bb00 0359 bb00 0459 b700 05bb
    0x0000010: 0006 59b7 0007 b700 08bb 0009 59b7 000a
    0x0000020: b700 0b4c 2b2a 1300 5bb6 0010 c000 5bb0
    0x0000030: 4cbb 0012 5912 5c2b b700 14bf          
  Exception Handler Table:
    bci [0, 47] => handler: 48
  Stackmap Table:
    same_locals_1_stack_item_frame(@48,Object[#116])


at com.msopentech.odatajclient.engine.data.ODataReader.readEntitySet(ODataReader.java:63)
at com.msopentech.odatajclient.engine.communication.request.retrieve.ODataEntitySetRequest$ODataEntitySetResponseImpl.getBody(ODataEntitySetRequest.java:89)
at com.msopentech.odatajclient.engine.communication.request.retrieve.ODataEntitySetRequest$ODataEntitySetResponseImpl.getBody(ODataEntitySetRequest.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

很奇怪的输出,原因是新加的jackson-dataformat-xml版本,覆盖了odatajclient-engine中依赖的版本(因为SpringBoot中的jackson-dataformat-xml是高版本,会自动覆盖odatajclient-engine所依赖的低版本)。

那么解决方案是什么?解决方式就是重新编译odatajclient-engine的jar包,把其依赖的jackson-dataformat-xml的版本改成最新的版本,在重新编译。在odatajclient-engine-xml项目中,修改jackson-dataformat-xml的版本为2.8.5,与SpringBoot的1.4.3-RLEASE版本保持一致。

<?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright © Microsoft Open Technologies, Inc.

    All Rights Reserved

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
    OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
    ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
    PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.

    See the Apache License, Version 2.0 for the specific language
    governing permissions and limitations under the License.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.msopentech.odatajclient</groupId>
    <artifactId>odatajclient</artifactId>
    <version>0.9.1-SNAPSHOT</version>
  </parent>

  <name>Client OData library for Java: Engine XML parser</name>
  <description>Java client API for OData 3.0 services: Engine XML parser</description>
  <groupId>com.msopentech.odatajclient</groupId>
  <artifactId>odatajclient-engine-xml</artifactId>
  <packaging>jar</packaging>
  
  <properties>
    <main.basedir>${project.parent.basedir}</main.basedir>
  </properties>

  <dependencies>
    <dependency>
      <groupId>com.fasterxml.jackson.dataformat</groupId>
      <artifactId>jackson-dataformat-xml</artifactId>
      <version>2.8.5</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml</groupId>
      <artifactId>aalto-xml</artifactId>
    </dependency>
  </dependencies>

  <build>
    <plugins>
    
    </plugins>
    
    <resources>
      <resource>
        <directory>..</directory>
        <targetPath>META-INF</targetPath>
        <includes>
          <include>LICENSE</include>
        </includes>
      </resource>
    </resources>
  </build>
  
</project>

然后在SpringBoot中,加入对odatajclient-engine:0.9.1-SNAPSHOT(而不是0.9.0)版本的引用。则所有的问题都缝纫而解.





版权声明:本文为博主原创文章,未经博主允许不得转载。

支持OData协议的Java jar包

开放数据协议(Open Data Protocol,缩写OData)是一种描述如何创建和访问Restful服务的OASIS标准。该标准由微软发起,前三个版本1.0、2.0、3.0都是微软开放标准,遵循...

Android与ReactNative下使用OData进行数据访问

Android与ReactNative下使用OData进行数据访问 1.OData定义 Open Data Protocol (开放数据协议,OData)是用来查询和更新数据的一种Web协...
  • lanye11
  • lanye11
  • 2016年11月22日 15:35
  • 445

行为驱动开发(BDD)你准备好了吗?

最近在研究行为驱动开发(Behavior Drive Development ), 那什么是行为驱动开发呢? 根据BDD in action一书的介绍, Behavior-Driven Devel...

试着用React写项目-利用react-router解决跳转路由等问题(四)

转载请注明出处:王亟亟的大牛之路不知不觉Router部分的内容已经写到第四篇了,这一篇会再点一点histroy以及实现一个提交表单的例子还是老规矩,先安利一下:https://github.com/d...

jstl Jar包 以及版本冲突问题解决

  • 2013年11月21日 17:51
  • 1.06MB
  • 下载

svn update时 版本冲突问题解决

当我们和别人同时修改了文件,别人通过commit提交,我们再去update时,会出现版本冲突,如下所示: 解决方法: 1、  在冲突的文件上(选中文件--右键菜单—Tortoise...
  • framic
  • framic
  • 2016年09月01日 08:46
  • 231

因JDK版本冲突导致问题的一系列解决方案

日常做系统应用时,经常会在服务器上安装各种各样的用到JRE的软件,有些软件还自带虚拟机或者JDK,Windows系统通过注册表来管理当前系统所使用的虚拟机和JDK路径,因此,当安装的软件JDK版本和w...

svn中合并(merge)问题和如何解决版本冲突

1.首先先解释一下合并中的两种方法      合并到

解决ubuntu中多个opencv版本冲突问题

以下内容纯属自己摸索,yy。如有错误,请大家批评指正。在ubuntu中,我们经常会遇到链接库的版本冲突问题。编写的程序在编译时,也往往因为这些问题报错,或虽编译成功,但运行出错。针对这类问题,我以op...

Hadoop运行jar包jdk版本冲突问题解决

前言:今天在eclipse上编译jar包放到hadoop上运行的时候出现了版本冲突的问题.报错内容:在linux机器上执行如下命令:hadoop jar XXXXX.jar com.XXX.XXXXX...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何解决SpringBoot与ODataJClient版本冲突的问题?
举报原因:
原因补充:

(最多只允许输入30个字)