OSGI 中的多个 CXF 包绑定到同一地址

Multiple CXF bundles in OSGI binding to same address

我有多个公开 CXF JAXRS 端点的 WAR。他们有相似的web.xml

<web-app id="app1">
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:META-INF/spring/*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>app1</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>app1</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

它们共享共同的 Spring 配置(名为 common-rest.xml

<beans>
    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <context:annotation-config />  

    <bean id="httpDestinationRegistry"
    class="org.apache.cxf.transport.http.DestinationRegistryImpl" />

    <bean id="baseJaxRSServer"
        abstract="true"
        lazy-init="false"
        class="org.apache.cxf.jaxrs.spring.JAXRSServerFactoryBeanDefinitionParser.SpringJAXRSServerFactoryBean"
        init-method="create"
        p:address="${http.server}/" />
</beans>

而且每个bean都有相似的配置

<beans>
    <import resource="classpath:META-INF/app/common-rest.xml" />

    <bean id="app1JaxRSServer"
        parent="baseJaxRSServer"
        p:serviceBeans-ref="app1ServiceBeans" />
</beans>

确切路径在每个包的 MANIFEST 中定义

Web-ContextPath: app1

问题是我无法让多个包一起工作。对于单个包,它工作正常,但如果我尝试 运行 另一个包,我会得到创建 app1JaxRSServer bean

的异常
org.apache.cxf.service.factory.ServiceConstructionException: There is an endpoint already running on /.

使用 Karaf 4.0.9、CXF 3.1.13、Spring3.2.18

原因是

 <url-pattern>/*</url-pattern> 

如果您有多个使用此设置的捆绑包,它们的端点将会发生冲突。

尝试为每个包使用不同的前缀。

我找到了解决方案,DestionationRegistry 存在问题,它由 CXF HTTP Transport OSGI Bundle(注册默认 /cxf/* 端点的那个)默认创建。我必须通过设置

来禁用这个包

org.apache.cxf.osgi.http.transport.disable = true

在 Karaf 属性中