在基于Apache Camel蓝图的OSGi包中检测到重复的ServletName

时间:2016-10-26 20:09:11

标签: java apache-camel apache-karaf apache-servicemix

我正在尝试创建两个基于Camel servlet的API(两个OSGi包)。我在this example中使用蓝图XML。

这是两个蓝图XML,

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
           http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <reference id="httpService" interface="org.osgi.service.http.HttpService"/>

  <bean class="org.apache.camel.component.servlet.osgi.OsgiServletRegisterer"
        init-method="register"
        destroy-method="unregister">
    <property name="alias" value="/digital"/>
    <property name="httpService" ref="httpService"/>
    <property name="servlet" ref="teamCamelServlet"/>
  </bean>

  <bean id="teamCamelServlet" class="org.apache.camel.component.servlet.CamelHttpTransportServlet"/>

  <bean id="teamService" class="com.test.TeamService"/>

  <camelContext xmlns="http://camel.apache.org/schema/blueprint">

    <restConfiguration component="servlet" bindingMode="json" contextPath="/digital"
                       port="8181">
      <dataFormatProperty key="prettyPrint" value="true"/>
    </restConfiguration>

    <rest path="/team" consumes="application/json" produces="application/json">
    ..content omitted
    </rest>

  </camelContext>

</blueprint>

其他blueprint.xml

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
           http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">

  <reference id="httpService" interface="org.osgi.service.http.HttpService"/>

  <bean class="org.apache.camel.component.servlet.osgi.OsgiServletRegisterer"
        init-method="register"
        destroy-method="unregister">
    <property name="alias" value="/api"/>
    <property name="httpService" ref="httpService"/>
    <property name="servlet" ref="camelServlet"/>
  </bean>

  <bean id="camelServlet" class="org.apache.camel.component.servlet.CamelHttpTransportServlet"/>

  <bean id="helloService" class="com.test.HelloService"/>

  <camelContext xmlns="http://camel.apache.org/schema/blueprint">

    <restConfiguration component="servlet" bindingMode="json" contextPath="/api"
                       port="8181">
      <dataFormatProperty key="prettyPrint" value="true"/>
    </restConfiguration>

    <!-- defines the rest services using the context-path /user -->
    <rest path="/hello" consumes="application/json" produces="application/json">
    ..content omitted
    </rest>

  </camelContext>

</blueprint>

但我收到此错误消息:

javax.servlet.ServletException: Duplicate ServletName detected: CamelServlet. Existing: CamelHttpTransportServlet[name=CamelServlet] This: CamelHttpTransportServlet[name=CamelServlet]. Its advised to use unique ServletName per Camel application.

我在这里做错了什么?我正在尝试在Apache ServiceMix中运行这两个OSGi包。如果其中一个部署,那么它工作正常。如果两者都已部署,则只有第一个正在运行。我是Apache Camel的新手,任何帮助都会很棒。我试过重启ServiceMix,但没有运气。还尝试了清除捆绑缓存。

2 个答案:

答案 0 :(得分:2)

当CamelHttpTransportServlet发现两个使用相同名称注册的servlet时,它会抛出异常“检测到Duplicate ServletName ...”。

在示例中,未设置OsgiServletRegisterer的属性“servletName”,因此注册器类使用默认值“CamelServlet”。

不过,还有更多。在camel rest配置中应声明额外的endpoint属性,以便为camel提供有关要使用的servlet的信息(默认情况下它使用“CamelServlet”)。

因此,要启动两个单独的servlet,您的配置应该是:

Registerer bean配置:

<bean class="org.apache.camel.component.servlet.osgi.OsgiServletRegisterer"
      init-method="register"
      destroy-method="unregister">
    <property name="alias" value="/digital"/>
    <property name="httpService" ref="httpService"/>
    <property name="servlet" ref="teamCamelServlet"/>
    <property name="servletName" value="teamCamelServlet"/>
</bean>

骆驼休息配置:

<restConfiguration component="servlet" bindingMode="json" contextPath="/digital" port="8181">
  <endpointProperty key="servletName" value="teamCamelServlet"/>
  <dataFormatProperty key="prettyPrint" value="true"/>
</restConfiguration>

此解决方案适用于camel 2.14.1及更高版本

版本2.14.0包含一个错误,因为该解决方案不起作用 https://issues.apache.org/jira/browse/CAMEL-7971

答案 1 :(得分:0)

OsgiServletRegisterer在注册CamelHttpTransportServlet时使用“CamelServlet”作为默认的servlet-name。

在两个捆绑包中,它都尝试使用默认名称注册。这就是你说错误的原因。

尝试在OsgiServletRegisterer bean中设置不同的servletName,如下所示

<property name="servletName" value="helloCamelServlet"/>

编辑:试试这样的事情

<bean class="org.apache.camel.component.servlet.osgi.OsgiServletRegisterer"
        init-method="register"
        destroy-method="unregister">
    <property name="alias" value="/digital"/>
    <property name="httpService" ref="httpService"/>
    <property name="servlet" ref="teamCamelServlet"/>
    <property name="servletName" value="teamCamelServlet"/>
  </bean>