Uploaded image for project: 'Application Server 3  4  5 and 6'
  1. Application Server 3 4 5 and 6
  2. JBAS-5364

UnifiedInvokerHAProxy can throw NullPointerException under load




      Under heavy load and sharing an EJB proxy between different threads, there's a
      chance of NullPointerException like the one below being reported, specially when
      using proxies configured with RoundRobin as load balance policy, such as SLSBs
      or EJB2 home proxies:

      at org.jboss.invocation.unified.interfaces.UnifiedInvokerHAProxy.invoke(UnifiedInvokerHAProxy.java:186)
      at org.jboss.invocation.InvokerInterceptor.invokeInvoker(InvokerInterceptor.java:365)
      at org.jboss.invocation.MarshallingInvokerInterceptor.invoke(MarshallingInvokerInterceptor.java:63)
      at org.jboss.proxy.ejb.RetryInterceptor.invoke(RetryInterceptor.java:176)
      at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:61)
      at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:70)
      at org.jboss.proxy.ejb.HomeInterceptor.invoke(HomeInterceptor.java:184)
      at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:100)
      at $Proxy1.create(Unknown Source)

      Whenever a new target for an invocation is chosen, init(InvokerLocator locator)
      method in UnifiedInvokerProxy is executed:

      protected void init(InvokerLocator locator)
      this.locator = locator;


      { client = createClient(locator, getSubSystem()); client.connect(); }

      catch(Exception e)

      { log.fatal("Could not initialize UnifiedInvokerProxy.", e); }


      This method could be executed in paralell to the following in
      UnifiedInvokerHAProxy.invoke(Invocation invocation):

      Client clientInstance = getClient(invocation);
      log.debug("Making invocation on " + clientInstance.getInvoker().getLocator());

      When the new client instance is created, the invoker is null until client.connect() is
      called, so something like this can happen:

      1.- T1 (Thread 1) executes getClient(invocation); and returns client#1
      2.- T2 (Thread 2) selects a new target for the invocation and calls init(InvokerLocator locator)
      3.- T2 calls createClient() and the instance variable client becomes client#2
      4.- T1 now calls clientInstance.getInvoker().getLocator() which is now client#2 but
      connect() has not been called on this instance, so results on NPE.

      The simplest of all solutions would be to make assignment of client instance thread safe,
      something I already did for JBAS-4815 to get around another thread safety issue.

      I'm gonna take the tests I created for JBAS-4815 and use them to replicate something like
      this and check whether the fix for that fixes this as well.

        Gliffy Diagrams


            Issue Links



                • Assignee:
                  galder.zamarreno Galder ZamarreƱo
                  galder.zamarreno Galder ZamarreƱo
                • Votes:
                  0 Vote for this issue
                  2 Start watching this issue


                  • Created: