【问题标题】:One CXF Servlet for multiple CXF endpoints in different wars一个 CXF Servlet 用于不同战争中的多个 CXF 端点
【发布时间】:2015-04-18 05:45:00
【问题描述】:

我正在尝试做一些可能违反 J2EE 规范的事情。 我有不同的罐子分别包含 cxf 端点。

我使用 CXFServlet 创建了一个 Web 项目并将其部署在 JBoss 7 服务器上。 当我部署其他 jars 时,它们无法在 CXFServlet 中注册其 CXF 端点,因为它们无法访问。

我想以某种方式将 CXFServlet 配置为服务,以便在部署时为其他 jar 加载路由时,CXF 端点应该能够自动注册到此 CXFServlet。

我知道 crossContext、RequestDispatcher 概念,但是当我们触发这些项目的 servlet 时,它们是由各个项目驱动的。但就我而言,一旦项目部署完毕,CXF 路由就会被加载,并且端点会搜索任何 CXFServlet,如果没有找到,则不会注册。

【问题讨论】:

    标签: servlets cxf


    【解决方案1】:

    我假设您的意思是独立部署或在不同 EAR 中部署的单独 WAR。

    请记住,CXF 是内置在 JBoss 中的,所以也许您不需要这种动态注册 - 如果它只是关于配置。

    不幸的是,您无法使用单独的 WAR 轻松进行此类动态注册。我做了一些研究。

    首先,为了完成这项工作,CXF 库必须从 JBoss 库中加载,而不是从您的 web 应用程序的 lib 目录中加载。这是因为 WAR 有单独的类加载器。加载类时,这些类加载器会咨询它们的父类,但不会咨询其他 WAR 类加载器。即使两个 WAR 都嵌入了 CXF jar,生成的类也会不兼容 - 类加载器 A 加载的 CXFServlet 类与类加载器 B 加载的 CXFServlet 类不同,即使这两个类都是从同一个 JAR 加载的。

    要使用 JBoss 嵌入式 CXF,您需要将 jboss-deployment-structure.xml 添加到 WEB-INF,内容如下:

    <jboss-deployment-structure>
     <deployment>
      <dependencies>
       <module name="org.apache.cxf" services="import">
        <imports>
         <include path="**" />
        </imports>
       </module>
      </dependencies>
     </deployment>
    </jboss-deployment-structure>
    

    要运行需要spring框架的CXFServlet,您还需要将spring jars添加到JBoss安装中并将它们定义为模块,如下所述:How can I use the external jars on JBoss 7?。还需要添加 jboss-deployment-structure.xml 中的依赖项。

    如果你让它运行起来(恭喜,我没能做到:/)那么你可以尝试使用org.apache.cxf.BusFactory.getDefaultBus()返回的默认总线。例如,带有 CXFServlet 的主 WAR 可能会设置此默认总线,而其他模块可能能够检索到此总线。但我有 99% 的把握,不是从 CXF 获得 BusFactory,而是得到一些 org.jboss.wsf.stack.cxf.client.configuration.JBossWSBusFactory。这个被 JBoss “加强”了,所以你将无法检索共享总线对象,但 each thread 的另一个对象是不同的。要更改这一点,您应该在每个 WAR 中创建以下文件:META-INF/services/org.apache.cxf.bus.factory,内容为:org.apache.cxf.BusFactory。这应该能够用默认的 CXF 覆盖 JBoss 总线工厂。

    好的,现在我们应该可以检索公共总线了。我还没有测试过,但是使用 Bus 你应该能够添加新服务。没有明显的 API,但也许这样的东西会起作用:bus.getExtension(WSDLManager.class).addDefinition(implementor, definition);

    呃,如您所见,这只是潜在解决方案的草图。有太多事情可能出错。这项任务并不容易,而且肯定很痛苦。

    您也可以尝试使用 JBoss 7 支持的 OSGi。您安装捆绑包,它们会发布一些端点。 JBoss 上对 OSGi 的一些介绍可以在here 找到。 here 是一些提示如何在 JBoss 上使用 CXF 和 OSGi。但同样,这不是很流行的 JBoss 使用方式,所以不要期望得到太多支持。


    编辑: 为什么cxf.xml 文件的自动发现不起作用,您可能也很感兴趣。 CXFServlet 正在使用currentClassloader.getResourceAsStream(..) 来检查cxf.xml 是否存在。如果 cxf.xml 在不同的 WAR 中,则当前的类加载器无法找到它。

    【讨论】:

    • 嗨,大卫,感谢您的详细解释。我正在从 OSGI 迁移到 Java,所以我必须弄清楚如何做到这一点:) 我会尝试你的解决方案。
    • 我希望阻止您尝试 ;)。让我们知道您是否成功 - 这可能对其他人也有帮助。
    • 嗨大卫 :) 到目前为止它对我不起作用。当我得到正确的解决方案时,我会发布。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多