Details
-
Bug
-
Resolution: Done
-
Major
-
9.3.0.CR1
-
None
Description
containsKey(missingKey) registers a NullCacheEntry in the transaction context to signal that the entry was already checked and it does not exist.
If the cache is repl/dist, size() uses distributed streams. TxDistributedCacheStream doesn't know about NullCacheEntry and tries to compute the segment of its key, causing a NullPointerException:
14:52:36,645 ERROR (testng-test) [InvocationContextInterceptor] ISPN000136: Error executing command SizeCommand, writing keys [] java.lang.NullPointerException: null at org.infinispan.commons.hash.MurmurHash3.hash(MurmurHash3.java:399) ~[classes/:?] at org.infinispan.distribution.ch.impl.HashFunctionPartitioner.getSegment(HashFunctionPartitioner.java:45) ~[classes/:?] at org.infinispan.stream.impl.AbstractCacheStream.isPrimaryOwner(AbstractCacheStream.java:425) ~[classes/:?] at org.infinispan.stream.impl.tx.TxDistributedCacheStream.lambda$null$0(TxDistributedCacheStream.java:68) ~[classes/:?] at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174) ~[?:1.8.0_171] at java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1625) ~[?:1.8.0_171] at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[?:1.8.0_171] at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[?:1.8.0_171] at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[?:1.8.0_171] at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_171] at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[?:1.8.0_171] at org.infinispan.stream.impl.tx.TxDistributedCacheStream.lambda$supplierForSegments$2(TxDistributedCacheStream.java:70) ~[classes/:?] at org.infinispan.stream.impl.termop.SegmentRetryingOperation.performOperation(SegmentRetryingOperation.java:78) ~[classes/:?] at org.infinispan.stream.impl.AbstractCacheStream.performOperationRehashAware(AbstractCacheStream.java:288) ~[classes/:?] at org.infinispan.stream.impl.AbstractCacheStream.performOperation(AbstractCacheStream.java:232) ~[classes/:?] at org.infinispan.stream.impl.DistributedCacheStream.count(DistributedCacheStream.java:426) ~[classes/:?] at org.infinispan.commands.read.SizeCommand.perform(SizeCommand.java:45) ~[classes/:?] at org.infinispan.commands.read.SizeCommand.perform(SizeCommand.java:20) ~[classes/:?] at org.infinispan.interceptors.impl.CallInterceptor.visitCommand(CallInterceptor.java:29) ~[classes/:?] at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:56) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.visitSizeCommand(DDAsyncInterceptor.java:100) ~[classes/:?] at org.infinispan.interceptors.distribution.BaseDistributionInterceptor.visitSizeCommand(BaseDistributionInterceptor.java:122) ~[classes/:?] at org.infinispan.commands.read.SizeCommand.acceptVisitor(SizeCommand.java:35) ~[classes/:?] at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.visitSizeCommand(DDAsyncInterceptor.java:100) ~[classes/:?] at org.infinispan.commands.read.SizeCommand.acceptVisitor(SizeCommand.java:35) ~[classes/:?] at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.visitSizeCommand(DDAsyncInterceptor.java:100) ~[classes/:?] at org.infinispan.commands.read.SizeCommand.acceptVisitor(SizeCommand.java:35) ~[classes/:?] at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.visitSizeCommand(DDAsyncInterceptor.java:100) ~[classes/:?] at org.infinispan.commands.read.SizeCommand.acceptVisitor(SizeCommand.java:35) ~[classes/:?] at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.impl.TxInterceptor.visitSizeCommand(TxInterceptor.java:270) ~[classes/:?] at org.infinispan.commands.read.SizeCommand.acceptVisitor(SizeCommand.java:35) ~[classes/:?] at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.statetransfer.TransactionSynchronizerInterceptor.visitCommand(TransactionSynchronizerInterceptor.java:41) ~[classes/:?] at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:56) ~[classes/:?] at org.infinispan.statetransfer.StateTransferInterceptor.handleDefault(StateTransferInterceptor.java:352) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.visitSizeCommand(DDAsyncInterceptor.java:100) ~[classes/:?] at org.infinispan.commands.read.SizeCommand.acceptVisitor(SizeCommand.java:35) ~[classes/:?] at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.visitSizeCommand(DDAsyncInterceptor.java:100) ~[classes/:?] at org.infinispan.commands.read.SizeCommand.acceptVisitor(SizeCommand.java:35) ~[classes/:?] at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNextAndExceptionally(BaseAsyncInterceptor.java:123) ~[classes/:?] at org.infinispan.interceptors.impl.InvocationContextInterceptor.visitCommand(InvocationContextInterceptor.java:90) ~[classes/:?] at org.infinispan.interceptors.BaseAsyncInterceptor.invokeNext(BaseAsyncInterceptor.java:56) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.handleDefault(DDAsyncInterceptor.java:54) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.visitSizeCommand(DDAsyncInterceptor.java:100) ~[classes/:?] at org.infinispan.commands.read.SizeCommand.acceptVisitor(SizeCommand.java:35) ~[classes/:?] at org.infinispan.interceptors.DDAsyncInterceptor.visitCommand(DDAsyncInterceptor.java:50) ~[classes/:?] at org.infinispan.interceptors.impl.AsyncInterceptorChainImpl.invoke(AsyncInterceptorChainImpl.java:248) ~[classes/:?] at org.infinispan.cache.impl.CacheImpl.size(CacheImpl.java:443) ~[classes/:?] at org.infinispan.cache.impl.CacheImpl.size(CacheImpl.java:438) ~[classes/:?] at org.infinispan.cache.impl.AbstractDelegatingCache.size(AbstractDelegatingCache.java:313) ~[classes/:?]
CacheAPIOptimisticTest.testSizeInExplicitTxWithNonExistent tests this scenario, but only with a local cache.