2011-12-02 70 views
1

我一直在做关于将Eclipse插件公开为Web服务的研究,但是我感到困惑。如何将Eclipse插件作为Web服务公开?

我的要求基本上是为一组Web服务构建一个Equinox后端。 我将大量使用EMF和相关项目,所以考虑到这一目标,我一直在阅读关于Equinox/OSGI以及构建我所需的选项。

但是,有一些神秘的观点,总体来说还有大量的项目。鉴于下面的调查结果,我想听听你的建议。也许有一个选项我错过了,或者你以前做过。这里是被提名者(鼓点)

在Web容器中托管Equinox。使用bridge.war,插件可以暴露一个servlet。问题是,为了使用像RESTEasy这样的好REST框架(我最喜欢的),REST框架需要是一个生活在Equionox运行时的osgi包。我花了3天时间,并且由于类加载器问题,这不起作用。我现在确信我无法在Equinox中拥有RestEasy。我可以在Web容器中使用RestEasy,并使用XML序列化/反序列化将Web容器中的代码与Equionox中的代码进行对话,但是这样感觉像是浪费了资源。不过,这可能会起作用。

另一种选择似乎是ECF,它是分布式OSGI的实现,它似乎支持SOAP/Rest。但是,我找不到一个将Equinox托管的功能公开为Web服务的清晰教程。所以这仍然迫使我不要使用RestEasy,但至少它似乎给了我一个适合Equinox的框架。我可能仍然需要将其保存在Web收件人的可扩展性中。

然后是Eclipse处女座,它似乎支持托管Web应用程序以及OSGI运行时,显然Web容器托管的代码可以与OSGI运行时代码交谈。不过,我不确定是否可以传递类,因为在Web容器下创建的Jaxb注释类型A可能使用与OSGI运行时插件不同的类加载器。此外,这种设置将我锁定在处女座,我宁愿与JBoss等一起用于生产。

因此,鉴于这些选项以及可能更多我目前不知道的内容,您将如何将EMF和其他基于Eclipse框架的项目公开为Web服务?

编辑: 基于我希望添加更多的好回应。问题的部分细节,部分评论不适合评论部分。

我在问题后的研究让我与接受的答案完全相同:Apache CXF现在是分布式OSGI的实现,这很好。我放弃了RestEasy。我目前的担心是,我已经有一个XSD创建了我的类。 RestEasy使暴露这些变得非常容易,我必须在这里做同样的事情。我的插件将不得不使用这些基于JAXB的类。在最坏的情况下,我可能会尝试使用提供JAXB支持的Eclipse Link项目,以创建XML内容,并通过基本的servlet使用或基于CXF的字符串值传递它。所以这里讨论的解决方案并不完美,但我认为这是目前最好的解决方案。

回答

1

我工作的产品已完成此操作。我们在Web容器内部有Equinox。我们使用Apache CXF公开SOAP和REST Web服务。用一些黑魔法来正确连接一切。我发现CXF文档不太好,尤其是OSGI。

我相信你知道,在Web容器中托管Equinox并不是一个推荐的做法,尽管如果你想使用OSGI是很难避免的。我们也经历了一些类加载问题。实际上,我们从未真正喜欢OSGI(模块化等)的广告效益。现在回到现在为时已晚。 OSGI不应轻易进入。

因此,以下是我们如何使用CXF启用SOAP/REST的快速概述。希望这至少能让你朝着正确的方向发展。

1)安装CXF OSGi bundle了,核心和DOSGI - 我们使用以下: CXF束-最小-2.2.12.jar CXF-dosgi里发现本地-1.1.jar CXF -dosgi-RI-DSW-CXF-1.1.jar 链接: http://cxf.apache.org/download.html

2)安装JAX-RS(REST)和JAX-WS(SOAP)的API -The API定义是在org.apache.servicemix .specs.jsr311-api-1.0-1.3.0.jar和org.apache.servicemix.specs.jaxws-api-2.1-1.1.1.jar(这些是我们的版本) - 这些可能会也可能不会与CXF捆绑在一起。在我们的例子中,只包含了JAX-WS jar。我们不得不搜索JAX-RS软件包。 - 除了在webapp(WEB-INF/eclipse/plugins)中安装bundle之外,我们还必须将它们添加到ECLIPSE/plugins目录进行编译。

3)告诉Equinox加载CXF插件。有可能有其他方法来做到这一点。我们用WEB-INF/eclipse/configuration/config.ini中的条目完成了这项工作。 - 如果此文件存在,请将新罐添加到osgi.bundles属性中: osgi.bundles = ... [email protected],org。 [email protected][email protected],\ cxf-dosgi-ri- [email protected]:start,\ [email protected]:start,\ [email protected]:start

4)就是这样。您现在应该能够开始编写SOAP和REST服务。这是一个Java优先的方法(首先与XML模式相反)。这意味着你: - 定义一个Java接口 - 配置CXF将接口发布为REST或SOAP端点。

这是REST的一个非常简单的例子。它带有标准的免责声明,它是特定于我们的环境的。因人而异。

一)我们用声明式服务,所以首先我们定义在我们包的清单 服务组件的DS文件:META-INF/DS/helloworld.xml B)下面是DS文件:META-INF/DS /helloworld.xml。 DS文件定义OSGI包中的服务及其依赖关系。为简洁起见,这些条目已被省略。

<?xml version="1.0"?> 
<components xmlns="http://www.osgi.org/xmlns/scr/v1.0.0"> 

<component name="hello_world_service" xmlns="http://www.osgi.org/xmlns/scr/v1.0.0"> 

    <!-- Defines this as a REST service ---> 
    <property name="service.exported.configs" value="org.apache.cxf.rs"/> 
    <!-- This is the URI of your REST resource. 
    It is realtive to the Equinox bridge servlet in your webapp --> 
    <property name="org.apache.cxf.rs.httpservice.context" value="/helloworld" /> 
    <!-- This is the java interace that will be exposed . You 
    will use JAX-RS annotations to map these java methods to HTTP verbs. --> 
    <property name="service.exported.interfaces" value="com.foo.IHelloWorldService"/>   
... 

</components> 

C)下面是接口类:

package com.foo; 

@Path("/greeting") 
public Interface IHelloWorldService { 

    @GET 
    @Produces("application/xml") 
    public Greeting getGreeting(); 

} 

public class HelloWorldService implements IHelloWorldService { 
    @override 
    public Greeting getGreeting() { 
     Greeting g = new Greeting(); 
     g.message = "Hello World"; 
     return g; 
    } 
} 

d)因此,一旦这是所有的地方,你应该能够得到以下网址:

/<web-app-name>/bridge/helloworld/greeting 

并收到以下回应:

<Greeting> 
     <message>Hello World</message> 
    </Greeting> 

祝你好运。希望这可以帮助。

+0

非常好的答案,非常感谢您的详细回复。请参阅我的“原始问题”的补充,该问题在“编辑:”之后开始。 – mahonya

+0

另一个关键问题是:那么建议如何公开OSGI?如果不在网络servlet中运行Equionox? – mahonya

+0

推荐的方法是将Web/servlet容器嵌入到OSGI容器中。这并不总是可能的,但是并不是所有的web容器都有OSGI实现。 – EJK

1

不幸的是我认为RESTeasy是这里的问题。根据您对另一个问题的评论,RESTeasy使用Java ServiceLoader API动态查找类,但不幸的是,在任何非平坦(即模块化)类加载体系结构中,都会假设类加载是不真实的。

我鼓励你在RESTeasy论坛上询问关于查找这些类的ServiceLoader方法的替代方法。例如,可能显式注册这些类。

但是,如果您的解决方案无法继续使用RESTeasy,那么您可以在OSGi中使用其他REST API。 Restlet例如有明确的OSGi支持。我也成功地使用了泽西岛。

+0

谢谢,会同时检查。 – mahonya