skyscreamer / nevado

A JMS driver for Amazon SQS.
http://nevado.skyscreamer.org/
Apache License 2.0
51 stars 48 forks source link

NevadoReferencableFactory does not work for NevadoTopics in tomcat #109

Open paulpach opened 8 years ago

paulpach commented 8 years ago

Hi, I tried to configure a Resource in tomcat like this:

<Resource
            name="xxxxxxx"
            type="org.skyscreamer.nevado.jms.destination.NevadoTopic"
            factory="org.skyscreamer.nevado.jms.resource.NevadoReferencableFactory"/>

and I get the following exception:

WARNING: Unexpected exception resolving reference
java.lang.NullPointerException
        at org.skyscreamer.nevado.jms.destination.NevadoTopic.<init>(NevadoTopic.java:21)
        at org.skyscreamer.nevado.jms.resource.NevadoReferencableFactory.getObjectInstance(NevadoReferencableFactory.java:84)
        at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:141)
        at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:842)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
        at org.apache.naming.NamingContextBindingsEnumeration.nextElementInternal(NamingContextBindingsEnumeration.java:117)
        at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:71)
        at org.apache.naming.NamingContextBindingsEnumeration.next(NamingContextBindingsEnumeration.java:34)
        at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:138)
        at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:145)
        at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:110)
        at org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.lifecycleEvent(GlobalResourcesLifecycleListener.java:82)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
        at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:402)
        at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:347)
        at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:689)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:321)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:455)

Digging through the code, I found that that NevadoReferencableFactory is expecting a name="xxxxx" attribute, which I did specify. The problem is that tomcat treats the "name" attribute differently, and does not make it available in the Reference object that is passed to the Factory, thus it is null when NevadoReferencableFactory tries to read it. Reading tomcat's code, it is clear that it is simply not possible to pass the value of the attribute "name" down to the Factory.

A simple solution would be to look for "name", and if null, look for a fallback attribute like "destinationName", that would not break existing uses, and it would make it work under tomcat.

I would argue this is more of a tomcat issue than a Nevado issue, but it would be harder to get them to change the behavior and it is simple to work around in Nevado.

paulpach commented 8 years ago

Another simple workaround is to use the name parameter that is passed to the getObjectInstance method. That contains the value of the name attribute.