Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java OSGi应用程序内部的REST客户端_Java_Web Services_Osgi_Resteasy_Apache Felix - Fatal编程技术网

Java OSGi应用程序内部的REST客户端

Java OSGi应用程序内部的REST客户端,java,web-services,osgi,resteasy,apache-felix,Java,Web Services,Osgi,Resteasy,Apache Felix,我需要将REST客户机集成到使用ApacheFelix实现的现有OSGi应用程序中。REST服务基于JAX-RS的RESTeasy实现(版本2.3.2.Final)。我创建了一个带有客户端依赖项的单独包,导出所需的RESTeasy包并将其导入到使用客户端的包中,但不幸的是,我无法在OSGi上下文中使其工作 我尝试了两种不同的方法。第一个使用通用ClientRequest: ClientRequest request = new ClientRequest(MyService.URL_TEST+"

我需要将REST客户机集成到使用ApacheFelix实现的现有OSGi应用程序中。REST服务基于JAX-RS的RESTeasy实现(版本2.3.2.Final)。我创建了一个带有客户端依赖项的单独包,导出所需的RESTeasy包并将其导入到使用客户端的包中,但不幸的是,我无法在OSGi上下文中使其工作

我尝试了两种不同的方法。第一个使用通用ClientRequest:

ClientRequest request = new ClientRequest(MyService.URL_TEST+"/stats");
request.body(javax.ws.rs.core.MediaType.APPLICATION_XML, stats);
ClientResponse<String> response = request.post(String.class);
其中我确信ApacheHttpClient4Executor实现了ClientExecutor接口

当我尝试在RESTeasy周围使用自己的REST客户端包装器时,如下所示:

MyService myService = MyServiceClient.getInstance();
myService.saveStatistics(stats);
我得到一个不同的例外:

[java] java.lang.LinkageError: ClassCastException: attempting to
castjar:file:/D:/Development/Eclipses/eclipse_4.2_j2ee_x64/lib/jaxrs-api-2.3.2.Final.jar
!/javax/ws/rs/ext/RuntimeDelegate.classtobundle:
//78.0:1/javax/ws/rs/ext/RuntimeDelegate.class
据我所知,LinkageError很可能与RESTeasy使用一些类装入器技巧初始化RuntimeDelegate的方式有关,这可能受到OSGi框架的限制。我怀疑首先提到的java.lang.ClassCastException具有相同的源代码

有没有办法让REST在OSGi中轻松工作

PS:关于RESTeasy的类似问题的讨论,但在OSGi之外:

更新: 以下是restclient捆绑包中包含的: activation-1.1.jar commons-codec-1.2.jar commons-httpclient-3.1.jar commons-io-2.1.jar commons-logging-1.0.4.jar flexjson-2.1.jar httpclient-4.1.2.jar httpcore-4.1.2.jar javassist-3.12.1.GA.jar jaxb-api-2.2.3.jar jaxb-impl-2.2.2.2.4.jar jaxrs-api-2.2.2.jar jcip-annotations-1.0.jar jcip-1.1.3.jar-1.1.1.1.3.jar jjst-10.jar junit junit junit junit-10.10log4j-1.2.14.jar resteasy-jaxb-provider-2.3.2.Final.jar resteasy-jettison-provider-2.3.2.Final.jar scannotation-1.0.3.jar slf4j-api-1.6.4.jar slf4j-log4j12-1.6.4.jar myservice-common-0.1.0.0.0.3.jar my-service-client-0.1.0.0.0.0.0.0.0.3-SNAPSHOT.jar.jar-stax-api-1.1.1.1.0-2.jar-1.4c-1.jar

这些是restclient捆绑包中的导出:javax.ws.rs、javax.ws.rs.ext、javax.ws.rs.core、org.jboss.resteasy.client、org.jboss.resteasy.client.cache、org.jboss.resteasy.client.extractors、org.jboss.resteasy.client.marshallers、org.jboss.resteasy.client.core.executors、javax.xml.bind.annotation、,org.jboss.resteasy.plugins.providers、org.jboss.resteasy.plugins.providers.jaxb、org.jboss.resteasy.spi

看看,它有一些非常有用的预构建的公共库包,包括我们用来(与之结合)进行RESTful通信的库。

(不幸的是,我项目的一个遗留模块仍然使用OSGi,但现在使用的是RESTeasy 3.0.16)

当我需要OSGify依赖项时,我现在首选的解决方案是使用优秀的

该项目提供了一个预配置的Maven设置(父POM处理绑定),您只需在Tipi子模块中使用
org.apache.ops4j.pax.Tipi
前缀调整原始项目的GAV坐标,并构建新的绑定项目,该项目将提取原始依赖项,将其解包并包装为OSGi绑定

您可以从最符合您的项目设置(依赖项等)的现有Tipi子项目开始,并调整缺少的任何OSGi导入/导出(通常,这些都是由maven bundle插件自动创建的)

只要原始项目不包含太多异国情调或格式错误的依赖项,这对我来说就非常有效

然而,正如我目前所经历的那样,您可能会遇到这样的障碍,这可能是一个真正的阻碍(找出哪个库是一个真正的噩梦)

不幸的是,RESTeasy似乎受到了这一点的影响,因为我得到了完全相同的错误(默认包,即使在将非测试和非提供的依赖项声明为可选之后:

导入包语法不允许使用默认包“”

将maven bundle插件升级到最新版本3.0.1会产生不同的错误(甚至没有那么有用):

[错误]Bundle org.ops4j.pax.tipi:org.ops4j.pax.tipi.resteasy jaxrs:Bundle:3.0.16.Final.1:无法从Bundle本机代码头解析名称: [错误]在捆绑包配置中发现错误

更新似乎可以通过将POM中的Tipi版本升级到1.4.0来解决,测试…

RESTEasy是强制性的吗?
我个人在OSGi中使用过,无论是作为客户端还是服务器,它都工作得很好。

这个问题不仅限于RESTeasy,Jersey也会出现

这是因为类路径上有两个JAX-RS类的副本。
您可以在LinkageError中看到这一点:

[java]java.lang.LinkageError:ClassCastException:试图将jar:file:/D:/Development/eclipse\u 4.2\u j2ee\u x64/lib/jaxrs-api-2.3.2.Final.jar!/javax/ws/rs/ext/RuntimeDelegate.class强制转换为bundle://78.0:1/javax/ws/rs/ext/RuntimeDelegate.class

i、 e.一份副本来自:

D:/Development/eclipse/eclipse\u 4.2\u j2ee\u x64/lib/jaxrs-api-2.3.2.Final.jar

另一个来自OSGI包

这会导致RuntimeDelegate类出现问题,默认情况下,RuntimeDelegate类使用系统类加载器创建RuntimeDelegate实现(请参见javax.ws.rs.ext.FactoryFinder)

如果通过两个不同的类加载器加载同一个jar,也会出现问题

有两种变通方法:

  • 从系统类路径中删除jaxrs-api-2.3.2.Final.jar
  • 在进行任何JAX-RS调用之前,将线程上下文类加载器设置为包的线程上下文类加载器。
    FactoryFinder将使用它加载RuntimeDelegate。
    为了避免调用Thread.currentThread().setContextClassLoader(myBundleClassLoader)污染代码,可以使用代理包装JAX-RS客户端。例如,请参阅

您的客户端包中包括哪些jar?到目前为止包括:myservice-client-0.1.0.3-SNAPSHOT.jar myservice-common-0
[java] java.lang.LinkageError: ClassCastException: attempting to
castjar:file:/D:/Development/Eclipses/eclipse_4.2_j2ee_x64/lib/jaxrs-api-2.3.2.Final.jar
!/javax/ws/rs/ext/RuntimeDelegate.classtobundle:
//78.0:1/javax/ws/rs/ext/RuntimeDelegate.class