0 Replies Latest reply on Sep 27, 2006 10:54 AM by mskonda

    NPE on SecurityActions.getContextClassLoader (Bug?)

    mskonda Apprentice

      Let me explain what I'm trying to do:

      I have a resource adapter which does EIS specific stuff (it creates an Object, registers callbacks with a EIS written in C++ client using JNI, awaits for callbacks from the C++ EIS).

      When the message arrrives, the C++ client invokes the callback on the same object. The object then submits the message to MessageEndpoint (MDB) fetched from the MessageEndpointFactory.

      Currently (for testing purposes), the MDB's listener callback doesn't have any implementation except printing out that the message is received.

      Now, when a message is arrived(that is, a callback is invoked from the C++ client), the enpoint is created (if not already created) and the listener message is invoked:

       endpointListener.onMessage(event);
      

      I get a NullPointerException:
      2006-09-27 12:54:23,643 TRACE [org.jboss.invocation.local.LocalInvoker] Failed to invoke on mbean: jboss.j2ee:jndiName=MyLocalFlowMDB,service=EJB
      java.lang.NullPointerException
       at org.jboss.ejb.Container.invoke(Container.java:825)
       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:585)
       at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:141)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:72)
       at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:245)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
       at org.jboss.invocation.local.LocalInvoker$MBeanServerAction.run(LocalInvoker.java:144)
       at java.security.AccessController.doPrivileged(Native Method)
       at org.jboss.invocation.local.LocalInvoker$MBeanServerAction.invoke(LocalInvoker.java:163)
       at org.jboss.invocation.local.LocalInvoker.invoke(LocalInvoker.java:104)
       at org.jboss.invocation.InvokerInterceptor.invokeLocal(InvokerInterceptor.java:179)
       at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:165)
       at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
       at org.jboss.ejb.plugins.inflow.MessageEndpointInterceptor.delivery(MessageEndpointInterceptor.java:237)
       at org.jboss.ejb.plugins.inflow.MessageEndpointInterceptor.invoke(MessageEndpointInterceptor.java:117)
       at org.jboss.proxy.ClientMethodInterceptor.invoke(ClientMethodInterceptor.java:59)
       at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:86)
       at $Proxy61.onMessage(Unknown Source)
       at com.cmi2.pats.source.connector.PatsJNIWorker.patsPushEvent(PatsJNIWorker.java:303)
       at com.cmi2.pats.source.connector.PatsJNIWorker.testEvent(PatsJNIWorker.java:485)
       at com.cmi2.pats.source.connector.PatsJNIWorker.javaHandleEODEvent(PatsJNIWorker.java:412)
      2006-09-27 12:54:23,643 TRACE [org.jboss.ejb.plugins.inflow.MessageEndpointInterceptor] MessageEndpoint MyLocalFlowMDB@1 delivery error
      


      When I dig the code, it seems that a method (invoke) in the org.jboss.ejb.Container.java is throwing this exception(see line decorated in red):

      public Object invoke(Invocation mi)
       throws Exception
       {
       ClassLoader callerClassLoader = SecurityActions.getContextClassLoader();
       long start = System.currentTimeMillis();
       Method m = null;
      
       boolean setCl = false;
       Object type = null;
       String contextID = getJaccContextID();
       try
       {
       if (!callerClassLoader.equals(classLoader))
       {
       setCl = true;
       SecurityActions.setContextClassLoader(this.classLoader);
       }
      


      When I debug the session, the callerClassLoader is null hence NPE when compared with the existing DelegatingClassLoader.

      Interesting scenario is - when I send a test message(before the callback occurs on the Obejct from c++ client), it all works perfect (I found that the callerClassLoader is UCL3 during my debug session). However, when the message is obtained via callback, the callerClassLoader is null. (and hence falling flat over the equal block).

      What is that I am doing wrong? I have tried using the java 2 securtiy manager and security.policy, but couldn't succeed.

      However, when I did the following hack, it all went fine:

      // check whether the caller's cl is null to avoid NPE
      if (callerClassLoader != null)
      {
       if (!callerClassLoader.equals(classLoader))
       {
       setCl = true;
       SecurityActions.setContextClassLoader(this.classLoader);
       }
      }
      else
      {
       // caller's cl is null, hence set the delegating cl loader of this class
       setCl = true;
       SecurityActions.setContextClassLoader(this.classLoader);
      }
      ..
      }
      

      I'll appreciate if anyone can throw somelight on this subject.

      PS: I was not quite sure where to post this message to. Let me know if it's wrong forum.

      Thanks
      Madhu