我正在尝试做一些可能违反J2EE规范的事情。 我有不同的jar分别包含cxf端点。
我使用CXFServlet创建了一个Web项目,并将其部署在JBoss 7服务器上。 当我部署其他jar时,他们无法在CXFServlet中注册他们的CXF端点,因为它们无法访问它们。
我想以某种方式将CXFServlet配置为服务,以便在部署时为其他jar加载路由时,CXF端点应该能够自动注册到此CXFServlet。
我了解crossContext,RequestDispatcher概念,但是当我们触发这些项目的servlet时,它们由各个项目驱动。但在我的情况下,一旦部署项目,CXF路由就会被加载,端点会搜索任何CXFServlet,如果没有找到,它就不会被注册。
答案 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中,则当前的类加载器无法找到它。