2 Replies Latest reply on Apr 27, 2010 10:02 AM by manik

    Null Pointer Exceptions during cache initialization phase

    vsevel

      Hi,

       

      I have created a test to demonstrate infinispan behavior when a new node joins an existing one, and we start using the new node right away.

       

      In my test I have I start 2 RMI servers. Each server exposes a simple get/put API that gives access to a distributed cache. Caches instances in each RMI server run as an infinispan cluster with distributed synchronous mode.

       

      The unit test looks like this:

       

       

      @Test
          public void discoverClusterMT() throws Exception {
              startRemoteStandaloneCacheServer(true);
              // String key = "somekey";
              // getService(LOCAL_SERVER).put(key, 0);
              // Assert.assertEquals(new Integer(0), getService(REMOTE_SERVER).getCurrentValue(key));
              final Map<String, Exception> errors = new ConcurrentHashMap<String, Exception>();
              final Map<String, Integer> done = new ConcurrentHashMap<String, Integer>();
      
              for (int i = 0; i < 10; i++) {
                  final int threadId = i;
      
                  new Thread() {
                      @Override
                      public void run() {
                          try {
                              String key = "mykey." + threadId;
                              getService(LOCAL_SERVER).put(key, 0);
                              long start = System.currentTimeMillis();
      
                              while (getService(REMOTE_SERVER).getCurrentValue(key) == null) {
                                  Thread.sleep(10);
                              }
      
                              log.info("discovered cluster in " + (System.currentTimeMillis() - start) + " ms");
                          } catch (Exception e) {
                              errors.put("" + threadId, e);
                              log.error(e, e);
                          } finally {
                              done.put("" + threadId, threadId);
                          }
                      }
                  }.start();
              }
      
              while (done.size() < 10) {
                  Thread.sleep(1000);
              }
      
              Assert.assertTrue(errors.isEmpty());
          }

       

      We assume at the beginning of the test that the first RMI server is already running. The test does the following:

      • the second RMI server is started. The associated cache instance will be initialized lazily
      • 10 threads are started, each only doing a put on the cache instance of the local RMI server, then calling the remote RMI server and asking its value for the same key, until it gives back the value that was put

       

      The test as it stands fails, as each thread gets the folllowing exception on the put:

       

       

      java.lang.NullPointerException
          at org.infinispan.util.concurrent.locks.LockManagerImpl.lockAndRecord(LockManagerImpl.java:82)
          at org.infinispan.container.EntryFactoryImpl.acquireLock(EntryFactoryImpl.java:205)
          at org.infinispan.container.EntryFactoryImpl.wrapEntryForWriting(EntryFactoryImpl.java:148)
          at org.infinispan.container.EntryFactoryImpl.wrapEntryForWriting(EntryFactoryImpl.java:106)
          at org.infinispan.interceptors.LockingInterceptor.visitPutKeyValueCommand(LockingInterceptor.java:197)
          at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)
          at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:118)
          at org.infinispan.interceptors.base.CommandInterceptor.handleDefault(CommandInterceptor.java:132)
          at org.infinispan.commands.AbstractVisitor.visitPutKeyValueCommand(AbstractVisitor.java:57)
          at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)
          at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:118)
          at org.infinispan.interceptors.TxInterceptor.enlistWriteAndInvokeNext(TxInterceptor.java:183)
          at org.infinispan.interceptors.TxInterceptor.visitPutKeyValueCommand(TxInterceptor.java:132)
          at org.infinispan.interceptors.DistTxInterceptor.visitPutKeyValueCommand(DistTxInterceptor.java:76)
          at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)
          at org.infinispan.interceptors.base.CommandInterceptor.invokeNextInterceptor(CommandInterceptor.java:118)
          at org.infinispan.interceptors.InvocationContextInterceptor.handleAll(InvocationContextInterceptor.java:48)
          at org.infinispan.interceptors.InvocationContextInterceptor.handleDefault(InvocationContextInterceptor.java:34)
          at org.infinispan.commands.AbstractVisitor.visitPutKeyValueCommand(AbstractVisitor.java:57)
          at org.infinispan.commands.write.PutKeyValueCommand.acceptVisitor(PutKeyValueCommand.java:76)
          at org.infinispan.interceptors.InterceptorChain.invoke(InterceptorChain.java:269)
          at org.infinispan.CacheDelegate.put(CacheDelegate.java:413)
          at org.infinispan.CacheSupport.put(CacheSupport.java:30)
          at com.lodh.bank.TestImpl.put(TestImpl.java:26)
      

       

      However if I uncomment the 3 lines at the beginning, it apparently gives time for the second node to initialize and the test succeeds.

       

      Any thoughts?

      Thanks,

       

      Vincent