views:

18

answers:

1

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?

+1  A: 

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 and destinationType settings via @ActivationConfigProperty if you haven't done so. We'll set destination to your bean name if that isn't filled in and we will set destinationType to javax.jms.Queue if that isn't filled in.

So your bean above would essentially look like this if all was set explicitly.

@MessageDriven(
    name="InboundXMLQueueHandlerST,InboundXMLQueueHandlerMT",
    activationConfig = {
        @ActivationConfigProperty(
           propertyName = "destinationType", 
           propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(
           propertyName = "destination", 
           propertyValue = "InboundXMLQueueHandlerST,InboundXMLQueueHandlerMT")})
public class InboundXMLQueueHandler implements MessageListener {
...

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.

@MessageDriven(
    activationConfig = {
        @ActivationConfigProperty(
           propertyName = "destination", 
           propertyValue = "InboundXMLQueueHandlerST,InboundXMLQueueHandlerMT")})
public class InboundXMLQueueHandler implements MessageListener {
...
David Blevins
You are right - no JMX support in 3.1.2 - we use ActiveMQ support in both.
grigory
Great. That will still work fine. In addition there are some good invocation stats for you in the 3.1.3 codebase. Mainly count and duration of your onMessage times. We're likely to roll a 3.1.4 next week, so definitely let me know if there's anything we can add for you.
David Blevins