]
Dan Berindei updated ISPN-9305:
-------------------------------
Status: Pull Request Sent (was: Open)
Git Pull Request:
NullPointerException in cache.size() after cache.containsKey()
--------------------------------------------------------------
Key: ISPN-9305
URL:
https://issues.jboss.org/browse/ISPN-9305
Project: Infinispan
Issue Type: Bug
Components: Core
Affects Versions: 9.3.0.CR1
Reporter: Dan Berindei
Fix For: 9.3.0.Final
{{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}}:
{noformat}
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/:?]
{noformat}
{{CacheAPIOptimisticTest.testSizeInExplicitTxWithNonExistent}} tests this scenario, but
only with a local cache.