在 OpenEJB 中部署具有多个队列名称的 MDB 时出错
升级到 OpenEJB 3.1.3 后,Tomcat/OpenEJB 启动时出现以下错误:
ERROR - Unable to register MBean
java.lang.IllegalStateException: javax.management.MalformedObjectNameException: Invalid character ',' in key part of property
at org.apache.openejb.monitoring.ObjectNameBuilder.build(ObjectNameBuilder.java:59)
at org.apache.openejb.core.mdb.MdbContainer.deploy(MdbContainer.java:169)
at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:599)
at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:450)
at org.apache.openejb.assembler.classic.Assembler.buildContainerSystem(Assembler.java:368)
at org.apache.openejb.assembler.classic.Assembler.build(Assembler.java:280)
at org.apache.openejb.OpenEJB$Instance.<init>(OpenEJB.java:125)
at org.apache.openejb.OpenEJB$Instance.<init>(OpenEJB.java:60)
at org.apache.openejb.OpenEJB.init(OpenEJB.java:271)
at org.apache.openejb.OpenEJB.init(OpenEJB.java:250)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.openejb.loader.OpenEJBInstance.init(OpenEJBInstance.java:36)
at org.apache.openejb.client.LocalInitialContextFactory.init(LocalInitialContextFactory.java:71)
at org.apache.openejb.client.LocalInitialContextFactory.init(LocalInitialContextFactory.java:53)
at org.apache.openejb.client.LocalInitialContextFactory.getInitialContext(LocalInitialContextFactory.java:42)
...
<proprietary stack trace skipped>
...
Caused by: javax.management.MalformedObjectNameException: Invalid character ',' in key part of property
at javax.management.ObjectName.construct(ObjectName.java:535)
at javax.management.ObjectName.<init>(ObjectName.java:1403)
at org.apache.openejb.monitoring.ObjectNameBuilder.build(ObjectNameBuilder.java:57)
... 70 more
INFO - Created Ejb(deployment-id=InboundXMLQueueHandlerST,InboundXMLQueueHandlerMT, ejb-name=InboundXMLQueueHandlerST,InboundXMLQueueHandlerMT, container=My MDB Container )
以下 MDB 导致此错误:
@MessageDriven(name="InboundXMLQueueHandlerST,InboundXMLQueueHandlerMT")
public class InboundXMLQueueHandler implements MessageListener {
...
因为更改为错误后就
@MessageDriven(name="InboundXMLQueueHandlerST")
public class InboundXMLQueueHandler implements MessageListener {
...
消失了。
正如您所看到的,我们在注释中使用单个类和逗号分隔的队列名称定义了两个侦听器。这在 3.1.2 中工作得很好(至少看起来是这样),但现在它给了我们上面的错误(尽管该错误似乎并没有阻止 MDB 的部署,但 JMX 监控对我们来说至关重要)。
我也无法找到任何使用 @MessageDriven
注释与多个队列(单个 MDB 类,多个逗号分隔的队列名称)的示例。这是一个错误的做法吗?它是已记录的功能吗? 3.1.3 中发生了什么变化导致 JMX 无法再注册 MDB?
The following error appeared at Tomcat/OpenEJB startup after upgrading to OpenEJB 3.1.3:
ERROR - Unable to register MBean
java.lang.IllegalStateException: javax.management.MalformedObjectNameException: Invalid character ',' in key part of property
at org.apache.openejb.monitoring.ObjectNameBuilder.build(ObjectNameBuilder.java:59)
at org.apache.openejb.core.mdb.MdbContainer.deploy(MdbContainer.java:169)
at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:599)
at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:450)
at org.apache.openejb.assembler.classic.Assembler.buildContainerSystem(Assembler.java:368)
at org.apache.openejb.assembler.classic.Assembler.build(Assembler.java:280)
at org.apache.openejb.OpenEJB$Instance.<init>(OpenEJB.java:125)
at org.apache.openejb.OpenEJB$Instance.<init>(OpenEJB.java:60)
at org.apache.openejb.OpenEJB.init(OpenEJB.java:271)
at org.apache.openejb.OpenEJB.init(OpenEJB.java:250)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.openejb.loader.OpenEJBInstance.init(OpenEJBInstance.java:36)
at org.apache.openejb.client.LocalInitialContextFactory.init(LocalInitialContextFactory.java:71)
at org.apache.openejb.client.LocalInitialContextFactory.init(LocalInitialContextFactory.java:53)
at org.apache.openejb.client.LocalInitialContextFactory.getInitialContext(LocalInitialContextFactory.java:42)
...
<proprietary stack trace skipped>
...
Caused by: javax.management.MalformedObjectNameException: Invalid character ',' in key part of property
at javax.management.ObjectName.construct(ObjectName.java:535)
at javax.management.ObjectName.<init>(ObjectName.java:1403)
at org.apache.openejb.monitoring.ObjectNameBuilder.build(ObjectNameBuilder.java:57)
... 70 more
INFO - Created Ejb(deployment-id=InboundXMLQueueHandlerST,InboundXMLQueueHandlerMT, ejb-name=InboundXMLQueueHandlerST,InboundXMLQueueHandlerMT, container=My MDB Container )
The following MDB causes this error:
@MessageDriven(name="InboundXMLQueueHandlerST,InboundXMLQueueHandlerMT")
public class InboundXMLQueueHandler implements MessageListener {
...
because after changing to
@MessageDriven(name="InboundXMLQueueHandlerST")
public class InboundXMLQueueHandler implements MessageListener {
...
error is gone.
As you can see we define two listeners using single class and comma-separated queue names in annotations. This worked flawlessly with 3.1.2 (at least it seemed) but now it gives us the error above (though the error doesn't seem to prevent the deployment of MDBs but JMX monitoring is critical to us).
I am unable to find any example of usage @MessageDriven
annotation with multiple queues (single MDB class, multiple comma-separated queue names) anymore either. Is this a wrong way do it? Is it a documented feature? What changed in 3.1.3 so that JMX can't register MDB anymore?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯,我们在 3.1.2 中没有 JMX 支持。我个人从未尝试过将 MDB 连接到两个队列 - 有点惊讶它竟然有效。 ActiveMQ 负责实际的“队列连接”(JMS 连接器的标准工作),我们只是传递元数据。
在 OpenEJB 方面,我们所做的唯一魔法是尝试通过
@ActivationConfigProperty
填写您的destination
和destinationType
设置(如果您还没有)这样做了。如果未填写,我们会将destination
设置为您的 Bean 名称;如果未填写,我们会将destinationType
设置为javax.jms.Queue
未填写。因此,如果所有内容均已显式设置,那么上面的 bean 基本上将如下所示。
假设 ActiveMQ 实际上为您提供了两个队列,这就是激活配置。
也许最简单的尝试就是显式设置目标名称并删除 bean 名称。
Hmm, we didn't have JMX support in 3.1.2. I've personally never tried hooking an MDB up to two queues -- sort of surprised that worked. It's ActiveMQ that does the actual "queue hooking up" (standards job of the JMS connector), we just pass the meta-data over.
On the OpenEJB side, the only magic that we do is attempt to fill in your
destination
anddestinationType
settings via@ActivationConfigProperty
if you haven't done so. We'll setdestination
to your bean name if that isn't filled in and we will setdestinationType
tojavax.jms.Queue
if that isn't filled in.So your bean above would essentially look like this if all was set explicitly.
Assuming ActiveMQ actually was giving you both queues, this is the activationConfig that would do it.
Probably the simplest thing to try is to explicitly set the destination name and just delete the bean name.