6

我需要将 REST 客户端集成到使用 Apache Felix 实现的现有 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);

在这种情况下我得到的错误很奇怪:

[java] java.lang.RuntimeException: java.lang.ClassCastException:
org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor cannot be cast to 
org.jboss.resteasy.client.ClientExecutor

我确信 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 具有相同的来源。

有什么方法可以让 RESTeasy 在 OSGi 中工作?

PS:关于 RESTeasy 的类似问题的讨论,但在 OSGi 之外:java.lang.LinkageError: ClassCastException

更新: 这些是包含在 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.4.jar jaxrs-api-2.3.2。 Final.jar jcip-annotations-1.0.jar jettison-1.3.1.jar jsr250-api-1.0.jar junit-4.10.jar log4j-1.2.14.jar resteasy-jaxb-provider-2.3.2.Final.jar resteasy -jaxrs-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.3.jar my-service-client-0.1.0.3-SNAPSHOT.jar stax-api-1.0-2.jar xmlpull-1.1.3.1.jar xpp3_min-1.1.4c.jar xstream-1.4.2.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

4

4 回答 4

0

看看SpringSource Bundle Repo,它有一些非常有用的预构建的通用库包,包括我们正在使用(与gson一起)进行 RESTful 通信的Apache HTTP 客户端。

于 2013-03-15T11:16:49.747 回答
0

这个问题不仅限于 RESTeasy。它也发生在泽西岛。

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

[java] java.lang.LinkageError: ClassCastException: 试图投射 jar:file:/D:/Development/Eclipses/eclipse_4.2_j2ee_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

即一份来自:

D:/Development/Eclipses/eclipse_4.2_j2ee_x64/lib/jaxrs-api-2.3.2.Final.jar

另一个来自 OSGI 包。

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

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

有几个解决方法:

于 2019-06-12T02:04:21.613 回答
0

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

当我需要 OSGify 依赖项时,我现在首选的解决方案是使用出色的Apache Ops4j Pax Tipi 项目来包装它。

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

您可以从与您的项目设置(依赖项等)最匹配的现有 Tipi 子项目开始,并调整任何缺少的 OSGi 导入/导出(大多数情况下,这些都是由 maven-bundle-plugin 自动创建的)。

只要原始项目不包含太多外来或格式错误的依赖项,这对我来说效果很好。

但是,根据我目前的经验,您可能会遇到使用 root 包的传递依赖等问题,这可能是一个真正的阻碍(找出哪个库是一个真正的噩梦)。

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

默认包“。” Import-Package 语法不允许。

将 maven-bundle-plugin 升级到最新版本 3.0.1 会产生不同的错误(甚至不太有用):

[错误] 捆绑 org.ops4j.pax.tipi:org.ops4j.pax.tipi.resteasy-jaxrs:bundle:3.0.16.Final.1:无法从捆绑本机代码头解析名称:[错误] 错误(s ) 在捆绑配置中找到

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

于 2016-05-10T15:10:29.603 回答
0

RESTEasy 是强制性的吗?我个人在 OSGi 中使用jersey,它作为客户端和服务器都运行良好。

于 2016-05-11T16:43:22.187 回答