Null Pointer Exceptions during cache initialization phase
vsevel Apr 23, 2010 12:04 PMHi,
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