Buggy code:
@ ThreadSafe public class KeyAffinityServiceImpl implements KeyAffinityService { private final float THRESHOLD = 0.5F ; private static final Log log = LogFactory . getLog ( KeyAffinityServiceImpl . class ) ; private final Set < Address > filter ; @ GuardedBy ( "maxNumberInvariant" ) private final Map < Address , BlockingQueue > address2key = new ConcurrentHashMap < Address , BlockingQueue > ( ) ; private final Executor executor ; private final Cache cache ; private final KeyGenerator keyGenerator ; private final int bufferSize ; private final AtomicInteger maxNumberOfKeys = new AtomicInteger ( ) ; private final AtomicInteger exitingNumberOfKeys = new AtomicInteger ( ) ; private volatile boolean started ; private final ReadWriteLock maxNumberInvariant = new ReentrantReadWriteLock ( ) ; private final ReclosableLatch keyProducerStartLatch = new ReclosableLatch ( ) ; private volatile KeyAffinityServiceImpl . KeyGeneratorWorker keyGenWorker ; private volatile ListenerRegistration listenerRegistration ; public KeyAffinityServiceImpl ( Executor executor , Cache cache , KeyGenerator keyGenerator , int bufferSize , Collection < Address > filter , boolean start ) { } @ Override public Object getCollocatedKey ( Object otherKey ) { } @ Override public Object getKeyForAddress ( Address address ) { } @ Override public void start ( ) { if ( started ) { KeyAffinityServiceImpl . log . debug ( "Service<seq2seq4repair_space>already<seq2seq4repair_space>started,<seq2seq4repair_space>ignoring<seq2seq4repair_space>call<seq2seq4repair_space>to<seq2seq4repair_space>start!" ) ; return ; } List < Address > existingNodes = getExistingNodes ( ) ; maxNumberInvariant . writeLock ( ) . lock ( ) ; try { addQueuesForAddresses ( existingNodes ) ; resetNumberOfKeys ( ) ; } finally { maxNumberInvariant . writeLock ( ) . unlock ( ) ; } keyGenWorker = new KeyAffinityServiceImpl . KeyGeneratorWorker ( ) ; executor . execute ( keyGenWorker ) ; listenerRegistration = new ListenerRegistration ( this ) ; <START_BUG> ( ( EmbeddedCacheManager ) ( cache . getCacheManager ( ) ) ) . addListener ( listenerRegistration ) ; <END_BUG> cache . addListener ( listenerRegistration ) ; keyProducerStartLatch . open ( ) ; started = true ; } @ Override public void stop ( ) { } public void handleViewChange ( ViewChangedEvent vce ) { } public boolean isKeyGeneratorThreadAlive ( ) { } public void handleCacheStopped ( CacheStoppedEvent cse ) { } public class KeyGeneratorWorker implements Runnable { private volatile boolean isActive ; private boolean isAlive ; private volatile Thread runner ; @ Override public void run ( ) { } private void generateKeys ( ) { } private boolean waitToBeWakenUp ( ) { } private void tryAddKey ( Address address , Object key ) { } public boolean isActive ( ) { } public boolean isAlive ( ) { } public void stop ( ) { } } private void resetNumberOfKeys ( ) { } private void addQueuesForAddresses ( Collection < Address > addresses ) { } private boolean interestedInAddress ( Address address ) { } private List < Address > getExistingNodes ( ) { } private Address getAddressForKey ( Object key ) { } private DistributionManager getDistributionManager ( ) { } public Map < Address , BlockingQueue > getAddress2KeysMapping ( ) { } public int getMaxNumberOfKeys ( ) { } public int getExitingNumberOfKeys ( ) { } public boolean isKeyGeneratorThreadActive ( ) { } public boolean isStarted ( ) { } }

Fix:
cache . getCacheManager ( ) . addListener ( listenerRegistration ) ;