一个CXF Servlet,用于不同战争中的多个CXF端点

时间:2015-04-18 05:45:01

标签: servlets cxf

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

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

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

我了解crossContext,RequestDispatcher概念,但是当我们触发这些项目的servlet时,它们由各个项目驱动。但在我的情况下,一旦部署项目,CXF路由就会被加载,端点会搜索任何CXFServlet,如果没有找到,它就不会被注册。

1 个答案:

答案 0 :(得分:0)

我认为您的意思是单独部署或在不同的EAR中部署的单独WAR。

请记住,CXF内置于JBoss中,因此您可能不需要这样的动态注册 - 如果它只是配置。

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

首先,为了使这项工作,必须从JBoss库加载CXF库,而不是从web-app的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,还需要在JBoss安装中添加spring jar并将它们定义为模块,如下所述: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“加强”,因此您将无法检索共享的Bus对象,但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。您可以安装bundle,它们会发布一些端点。可以在here找到对JBoss上的OSGi的一些介绍。 here提示如何从JBoss上的CXF和OSGi开始。但同样,这不是非常流行的使用JBoss的方式,所以不要期待太多支持。


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