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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在基于Apache Camel蓝图的OSGi包中检测到重复的ServletName相关的知识,希望对你有一定的参考价值。

我正在尝试创建两个基于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,但没有运气。还尝试了清除捆绑缓存。

答案

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

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

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

所以,要启动两个单独的servlet,你的配置应该是这样的:

注册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>

该解决方案适用于骆驼2.14.1及更高版本

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

另一答案

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>

以上是关于在基于Apache Camel蓝图的OSGi包中检测到重复的ServletName的主要内容,如果未能解决你的问题,请参考以下文章

osgi+camel+karaf运行环境搭建

如何在 Scala 的 Felix 中运行 OSGi 蓝图?

OSGi 包中的 Websphere 8.5 + CXF。是不是可以?

找不到AnnotationReader类

osgi + camel + karaf配置日志输出

OSGi:蓝图与 Spring DM