【问题标题】:Duplicate ServletName detected in Apache Camel blueprint based OSGi bundles在基于 Apache Camel 蓝图的 OSGi 包中检测到重复的 ServletName
【发布时间】:2017-03-09 08:26:37
【问题描述】:

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

【问题讨论】:

  • 你可以为两个包添加完整的 blueprint.xml 吗?
  • 我认为您可能已经在两个 servlet 定义中声明了端口。最好使用 pax web servlet(在 cxfservlet 上您只需删除端口,但我不确定如何使用其余配置组件执行此操作)
  • @stringy05 谢谢,我会调查的。顺便说一句,它没有抱怨任何端口绑定问题。
  • 不,它从不这样做(对于我使用过的版本),其他 servlet 组件发生的情况是它尝试绑定,如果成功则记录它,然后如果第二次绑定失败则不记录任何内容。如果您将第二个端口更改为 8182,这样可以吗?

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


【解决方案1】:

OsgiServletRegisterer 在注册 CamelHttpTransportServlet 时使用“CamelServlet”作为默认 servlet 名称。

在这两个包中,它都尝试使用默认名称注册。这就是您收到上述错误的原因。

尝试在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>

【讨论】:

  • 我使用名称属性作为helloServlet 然后我得到了这个问题org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to find property descriptor helloServlet on class org.apache.camel.component.servlet.osgi.OsgiServletRegisterer 这似乎很明显,因为source of OsgiServletRegisterer。有什么想法吗?
  • 在 OsgiServletRegistere‌​r 中没有名为“helloServlet”的属性/变量。
  • 我已经更新了代码,它不再给出错误了。但是端点不起作用。我得到了 404,日志中也没有任何线索。
  • 你还在面对这个问题吗?
  • @RuwankaMadhushan,是否解决了 404 错误的最终问题?我正在尝试做完全相同的事情,但是一旦我在 OsgiServletRegisterer bean 上设置属性名称,我就会收到 404 错误。
【解决方案2】:

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

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

不过,还有更多。在camel rest配置中应该声明额外的端点属性,以向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

【讨论】:

  • 感谢您的回答,我会试用您的解决方案。
猜你喜欢
  • 2012-09-05
  • 2014-08-16
  • 2015-10-03
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
  • 2013-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多