You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bookkeeper.apache.org by eo...@apache.org on 2022/04/01 07:38:02 UTC

[bookkeeper] branch master updated: [build] Fix various spotbugs warnings (#3160)

This is an automated email from the ASF dual-hosted git repository.

eolivelli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git


The following commit(s) were added to refs/heads/master by this push:
     new 62cfc0e  [build] Fix various spotbugs warnings  (#3160)
62cfc0e is described below

commit 62cfc0ec8670cb66ce4bf2b0d707f42cba5e3354
Author: Nicolò Boschi <bo...@gmail.com>
AuthorDate: Fri Apr 1 09:37:57 2022 +0200

    [build] Fix various spotbugs warnings  (#3160)
---
 .github/workflows/compatibility-check-java8.yml    |  2 +-
 .github/workflows/pr-validation.yml                |  2 +-
 .../benchmark/BenchReadThroughputLatency.java      |  2 +
 bookkeeper-http/servlet-http-server/build.gradle   |  1 +
 bookkeeper-http/servlet-http-server/pom.xml        |  1 -
 .../http/servlet/BookieHttpServiceServlet.java     |  2 +
 .../bookkeeper/bookie/GarbageCollectorThread.java  |  2 +
 .../bookie/InterleavedLedgerStorage.java           |  2 +
 .../java/org/apache/bookkeeper/bookie/Journal.java |  2 +-
 .../bookie/UncleanShutdownDetectionImpl.java       |  8 +-
 .../bookie/datainteg/DataIntegrityCheckImpl.java   | 91 +++++++++++-----------
 .../bookie/datainteg/EntryCopierImpl.java          | 10 ++-
 .../bookie/datainteg/MetadataAsyncIterator.java    | 40 +++++-----
 .../bookie/storage/ldb/KeyValueStorageRocksDB.java |  4 +-
 .../bookie/storage/ldb/LedgerMetadataIndex.java    |  5 +-
 .../bookie/storage/ldb/LedgersIndexRebuildOp.java  |  2 +
 .../ldb/SingleDirectoryDbLedgerStorage.java        |  8 +-
 .../apache/bookkeeper/client/BookKeeperAdmin.java  | 61 ++++++++-------
 .../client/LedgerFragmentReplicator.java           | 13 ++--
 .../apache/bookkeeper/meta/MetadataDrivers.java    |  3 +
 .../proto/checksum/DirectMemoryCRC32Digest.java    |  2 +-
 .../bookkeeper/replication/ReplicationWorker.java  |  2 +
 .../http/service/AutoRecoveryStatusService.java    |  2 +
 .../server/http/service/ExpandStorageService.java  |  2 +
 .../server/http/service/GetLastLogMarkService.java |  2 +-
 .../cli/commands/autorecovery/ToggleCommand.java   |  2 +
 .../tools/cli/commands/bookie/LedgerCommand.java   |  3 +-
 .../commands/bookie/ListActiveLedgersCommand.java  |  2 +
 .../cli/commands/bookie/ListLedgersCommand.java    |  2 +
 .../cli/commands/bookie/ReadLedgerCommand.java     |  2 +
 .../commands/bookie/ReadLogMetadataCommand.java    |  2 +
 .../cli/commands/client/LedgerMetaDataCommand.java |  2 +
 .../cli/commands/client/SimpleTestCommand.java     |  2 +
 .../tools/cli/helpers/DiscoveryCommand.java        |  2 +
 .../bookkeeper/verifier/BookkeeperVerifier.java    |  4 +-
 .../common/util/affinity/impl/NativeUtils.java     |  2 +-
 .../apache/bookkeeper/proto/ProtocolBenchmark.java |  9 +--
 pom.xml                                            | 19 -----
 tests/backward-compat/pom.xml                      | 11 +++
 tests/integration-tests-utils/build.gradle         |  1 +
 .../tests/integration/utils/DockerUtils.java       |  3 +-
 .../tests/integration/utils/MavenClassLoader.java  | 12 +--
 tools/perf/build.gradle                            |  1 +
 .../bookkeeper/tools/perf/table/PerfClient.java    |  2 +
 .../cli/commands/cluster/InitClusterCommand.java   |  2 +
 .../stream/cli/commands/table/DelCommand.java      |  2 +
 .../stream/cli/commands/table/GetCommand.java      |  2 +
 .../cli/commands/table/IncrementCommand.java       |  2 +
 .../stream/cli/commands/table/PutCommand.java      |  2 +
 49 files changed, 216 insertions(+), 148 deletions(-)

diff --git a/.github/workflows/compatibility-check-java8.yml b/.github/workflows/compatibility-check-java8.yml
index 3011039..3e18450 100644
--- a/.github/workflows/compatibility-check-java8.yml
+++ b/.github/workflows/compatibility-check-java8.yml
@@ -50,7 +50,7 @@ jobs:
         with:
           java-version: 1.8
       - name: Build with Maven
-        run: mvn clean package -B -nsu -DskipBookKeeperServerTests -Dorg.slf4j.simpleLogger.defaultLogLevel=INFO
+        run: mvn clean package spotbugs:check -B -nsu -DskipBookKeeperServerTests -Dorg.slf4j.simpleLogger.defaultLogLevel=INFO
 
       - name: print JVM thread dumps when cancelled
         if: cancelled()
diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml
index 440edc3..eb5075e 100644
--- a/.github/workflows/pr-validation.yml
+++ b/.github/workflows/pr-validation.yml
@@ -52,7 +52,7 @@ jobs:
           distribution: 'temurin'
           java-version: 11
       - name: Validate pull request
-        run: mvn clean -B -nsu apache-rat:check checkstyle:check package -Ddistributedlog -DskipTests -Dorg.slf4j.simpleLogger.defaultLogLevel=INFO
+        run: mvn clean -B -nsu apache-rat:check checkstyle:check spotbugs:check package -Ddistributedlog -DskipTests -Dorg.slf4j.simpleLogger.defaultLogLevel=INFO
         
       - name: Check license files
         run: dev/check-all-licenses
diff --git a/bookkeeper-benchmark/src/main/java/org/apache/bookkeeper/benchmark/BenchReadThroughputLatency.java b/bookkeeper-benchmark/src/main/java/org/apache/bookkeeper/benchmark/BenchReadThroughputLatency.java
index 50a14f1..15a7db2 100644
--- a/bookkeeper-benchmark/src/main/java/org/apache/bookkeeper/benchmark/BenchReadThroughputLatency.java
+++ b/bookkeeper-benchmark/src/main/java/org/apache/bookkeeper/benchmark/BenchReadThroughputLatency.java
@@ -21,6 +21,7 @@ package org.apache.bookkeeper.benchmark;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.Enumeration;
@@ -147,6 +148,7 @@ public class BenchReadThroughputLatency {
     }
 
     @SuppressWarnings("deprecation")
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     public static void main(String[] args) throws Exception {
         Options options = new Options();
         options.addOption("ledger", true, "Ledger to read. If empty, read all ledgers which come available. "
diff --git a/bookkeeper-http/servlet-http-server/build.gradle b/bookkeeper-http/servlet-http-server/build.gradle
index ea341bf..72f4b2b 100644
--- a/bookkeeper-http/servlet-http-server/build.gradle
+++ b/bookkeeper-http/servlet-http-server/build.gradle
@@ -28,6 +28,7 @@ dependencies {
     implementation depLibs.commonsIO
 
     compileOnly depLibs.lombok
+    compileOnly depLibs.spotbugsAnnotations
     annotationProcessor depLibs.lombok
 
     testImplementation depLibs.junit
diff --git a/bookkeeper-http/servlet-http-server/pom.xml b/bookkeeper-http/servlet-http-server/pom.xml
index 77dfeac..6ea0a35 100644
--- a/bookkeeper-http/servlet-http-server/pom.xml
+++ b/bookkeeper-http/servlet-http-server/pom.xml
@@ -53,5 +53,4 @@
             <scope>test</scope>
         </dependency>
     </dependencies>
-
 </project>
diff --git a/bookkeeper-http/servlet-http-server/src/main/java/org/apache/bookkeeper/http/servlet/BookieHttpServiceServlet.java b/bookkeeper-http/servlet-http-server/src/main/java/org/apache/bookkeeper/http/servlet/BookieHttpServiceServlet.java
index 966eceb..44b7dbd 100644
--- a/bookkeeper-http/servlet-http-server/src/main/java/org/apache/bookkeeper/http/servlet/BookieHttpServiceServlet.java
+++ b/bookkeeper-http/servlet-http-server/src/main/java/org/apache/bookkeeper/http/servlet/BookieHttpServiceServlet.java
@@ -20,6 +20,7 @@
  */
 package org.apache.bookkeeper.http.servlet;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.IOException;
 import java.io.Writer;
 import java.util.Enumeration;
@@ -69,6 +70,7 @@ public class BookieHttpServiceServlet extends HttpServlet {
   }
 
   @Override
+  @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
   protected void service(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException {
     HttpServiceRequest request = new HttpServiceRequest()
                                 .setMethod(httpServerMethod(httpRequest))
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java
index 6195169..600d0f4 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/GarbageCollectorThread.java
@@ -24,6 +24,7 @@ package org.apache.bookkeeper.bookie;
 import static org.apache.bookkeeper.util.BookKeeperConstants.METADATA_CACHE;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Strings;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.util.concurrent.DefaultThreadFactory;
 
 import java.io.IOException;
@@ -594,6 +595,7 @@ public class GarbageCollectorThread extends SafeRunnable {
      *
      * @throws InterruptedException if there is an exception stopping gc thread.
      */
+    @SuppressFBWarnings("SWL_SLEEP_WITH_LOCK_HELD")
     public synchronized void shutdown() throws InterruptedException {
         if (!this.running) {
             return;
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/InterleavedLedgerStorage.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/InterleavedLedgerStorage.java
index 0960c66..5d0b1ef 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/InterleavedLedgerStorage.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/InterleavedLedgerStorage.java
@@ -35,6 +35,7 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.RateLimiter;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
 
@@ -576,6 +577,7 @@ public class InterleavedLedgerStorage implements CompactableLedgerStorage, Entry
     }
 
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     public List<DetectedInconsistency> localConsistencyCheck(Optional<RateLimiter> rateLimiter) throws IOException {
         long checkStart = MathUtils.nowInNano();
         LOG.info("Starting localConsistencyCheck");
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Journal.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Journal.java
index 93e8065..a4c91e9 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Journal.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Journal.java
@@ -588,7 +588,7 @@ public class Journal extends BookieCriticalThread implements CheckpointSource {
         }
     }
 
-    private class CbThreadFactory implements ThreadFactory {
+    private static class CbThreadFactory implements ThreadFactory {
         private int counter = 0;
         private String threadBaseName = "bookie-journal-callback";
 
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/UncleanShutdownDetectionImpl.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/UncleanShutdownDetectionImpl.java
index 879a288..33192c3 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/UncleanShutdownDetectionImpl.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/UncleanShutdownDetectionImpl.java
@@ -48,8 +48,12 @@ public class UncleanShutdownDetectionImpl implements UncleanShutdownDetection {
         for (File ledgerDir : ledgerDirsManager.getAllLedgerDirs()) {
             try {
                 File dirtyFile = new File(ledgerDir, DIRTY_FILENAME);
-                dirtyFile.createNewFile();
-                LOG.info("Created dirty file in ledger dir: {}", ledgerDir.getAbsolutePath());
+                if (dirtyFile.createNewFile()) {
+                    LOG.info("Created dirty file in ledger dir: {}", ledgerDir.getAbsolutePath());
+                } else {
+                    LOG.info("Dirty file already exists in ledger dir: {}", ledgerDir.getAbsolutePath());
+                }
+
             } catch (IOException e) {
                 LOG.error("Unable to register start-up (so an unclean shutdown cannot"
                         + " be detected). Dirty file of ledger dir {} could not be created.",
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/DataIntegrityCheckImpl.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/DataIntegrityCheckImpl.java
index 319ceac..139d07f 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/DataIntegrityCheckImpl.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/DataIntegrityCheckImpl.java
@@ -24,6 +24,7 @@ import io.reactivex.rxjava3.core.Flowable;
 import io.reactivex.rxjava3.core.Maybe;
 import io.reactivex.rxjava3.core.Scheduler;
 import io.reactivex.rxjava3.core.Single;
+import io.reactivex.rxjava3.disposables.Disposable;
 import java.io.IOException;
 import java.util.Comparator;
 import java.util.List;
@@ -39,7 +40,6 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
-
 import lombok.extern.slf4j.Slf4j;
 import org.apache.bookkeeper.bookie.BookieException;
 import org.apache.bookkeeper.bookie.LedgerStorage;
@@ -84,12 +84,10 @@ public class DataIntegrityCheckImpl implements DataIntegrityCheck {
     }
 
     @Override
-    public CompletableFuture<Void> runPreBootCheck(String reason) {
+    public synchronized CompletableFuture<Void> runPreBootCheck(String reason) {
         // we only run this once, it could be kicked off by different checks
-        synchronized (this) {
-            if (preBootFuture == null) {
-                preBootFuture = runPreBootSequence(reason);
-            }
+        if (preBootFuture == null) {
+            preBootFuture = runPreBootSequence(reason);
         }
         return preBootFuture;
 
@@ -355,46 +353,47 @@ public class DataIntegrityCheckImpl implements DataIntegrityCheck {
     CompletableFuture<Set<LedgerResult>> checkAndRecoverLedgers(Map<Long, LedgerMetadata> ledgers,
                                                                 String runId) {
         CompletableFuture<Set<LedgerResult>> promise = new CompletableFuture<>();
-        Flowable.fromIterable(ledgers.entrySet())
-            .subscribeOn(scheduler, false)
-            .flatMapSingle((mapEntry) -> {
-                    long ledgerId = mapEntry.getKey();
-                    LedgerMetadata originalMetadata = mapEntry.getValue();
-                    return recoverLedgerIfInLimbo(ledgerId, mapEntry.getValue(), runId)
-                        .map(newMetadata -> LedgerResult.ok(ledgerId, newMetadata))
-                        .onErrorReturn(t -> LedgerResult.error(ledgerId, originalMetadata, t))
-                        .defaultIfEmpty(LedgerResult.missing(ledgerId))
-                        .flatMap((res) -> {
-                                try {
-                                    if (res.isOK()) {
-                                        this.ledgerStorage.clearLimboState(ledgerId);
-                                    }
-                                    return Single.just(res);
-                                } catch (IOException ioe) {
-                                    return Single.just(LedgerResult.error(res.getLedgerId(),
-                                                                          res.getMetadata(), ioe));
-                                }
-                            });
-                },
-                true /* delayErrors */,
-                MAX_INFLIGHT)
-            .flatMapSingle((res) -> {
-                    if (res.isOK()) {
-                        return checkAndRecoverLedgerEntries(res.getLedgerId(),
-                                                            res.getMetadata(), runId)
-                            .map(ignore -> LedgerResult.ok(res.getLedgerId(),
-                                                           res.getMetadata()))
-                            .onErrorReturn(t -> LedgerResult.error(res.getLedgerId(),
-                                                                   res.getMetadata(), t));
-                    } else {
-                        return Single.just(res);
-                    }
-                },
-                true /* delayErrors */,
-                1 /* copy 1 ledger at a time to keep entries together in entrylog */)
-            .collect(Collectors.toSet())
-            .subscribe(resolved -> promise.complete(resolved),
-                       throwable -> promise.completeExceptionally(throwable));
+        final Disposable disposable = Flowable.fromIterable(ledgers.entrySet())
+                .subscribeOn(scheduler, false)
+                .flatMapSingle((mapEntry) -> {
+                            long ledgerId = mapEntry.getKey();
+                            LedgerMetadata originalMetadata = mapEntry.getValue();
+                            return recoverLedgerIfInLimbo(ledgerId, mapEntry.getValue(), runId)
+                                    .map(newMetadata -> LedgerResult.ok(ledgerId, newMetadata))
+                                    .onErrorReturn(t -> LedgerResult.error(ledgerId, originalMetadata, t))
+                                    .defaultIfEmpty(LedgerResult.missing(ledgerId))
+                                    .flatMap((res) -> {
+                                        try {
+                                            if (res.isOK()) {
+                                                this.ledgerStorage.clearLimboState(ledgerId);
+                                            }
+                                            return Single.just(res);
+                                        } catch (IOException ioe) {
+                                            return Single.just(LedgerResult.error(res.getLedgerId(),
+                                                    res.getMetadata(), ioe));
+                                        }
+                                    });
+                        },
+                        true /* delayErrors */,
+                        MAX_INFLIGHT)
+                .flatMapSingle((res) -> {
+                            if (res.isOK()) {
+                                return checkAndRecoverLedgerEntries(res.getLedgerId(),
+                                        res.getMetadata(), runId)
+                                        .map(ignore -> LedgerResult.ok(res.getLedgerId(),
+                                                res.getMetadata()))
+                                        .onErrorReturn(t -> LedgerResult.error(res.getLedgerId(),
+                                                res.getMetadata(), t));
+                            } else {
+                                return Single.just(res);
+                            }
+                        },
+                        true /* delayErrors */,
+                        1 /* copy 1 ledger at a time to keep entries together in entrylog */)
+                .collect(Collectors.toSet())
+                .subscribe(resolved -> promise.complete(resolved),
+                        throwable -> promise.completeExceptionally(throwable));
+        promise.whenComplete((result, ex) -> disposable.dispose());
         return promise;
     }
 
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/EntryCopierImpl.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/EntryCopierImpl.java
index 8d1df94..85b4adc 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/EntryCopierImpl.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/EntryCopierImpl.java
@@ -154,7 +154,15 @@ public class EntryCopierImpl implements EntryCopier {
         @VisibleForTesting
         CompletableFuture<ByteBuf> fetchEntry(long entryId) {
             List<BookieId> ensemble = metadata.getEnsembleAt(entryId);
-            ImmutableList<Integer> writeSet = writeSets.floorEntry(entryId).getValue().getForEntry(entryId);
+            final Map.Entry<Long, WriteSets> writeSetsForEntryId = this.writeSets
+                    .floorEntry(entryId);
+            if (writeSetsForEntryId == null) {
+                log.error("writeSets for entryId {} not found, writeSets {}", entryId, writeSets);
+                throw new IllegalStateException("writeSets for entryId: " + entryId + " not found");
+            }
+            ImmutableList<Integer> writeSet = writeSetsForEntryId
+                    .getValue()
+                    .getForEntry(entryId);
             int attempt = 0;
             CompletableFuture<ByteBuf> promise = new CompletableFuture<>();
             fetchRetryLoop(entryId, attempt,
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/MetadataAsyncIterator.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/MetadataAsyncIterator.java
index 0a86447..f942b6b 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/MetadataAsyncIterator.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/datainteg/MetadataAsyncIterator.java
@@ -22,6 +22,7 @@ package org.apache.bookkeeper.bookie.datainteg;
 import io.reactivex.rxjava3.core.Completable;
 import io.reactivex.rxjava3.core.Flowable;
 import io.reactivex.rxjava3.core.Scheduler;
+import io.reactivex.rxjava3.disposables.Disposable;
 import java.io.IOException;
 import java.util.Iterator;
 import java.util.concurrent.CompletableFuture;
@@ -76,25 +77,26 @@ public class MetadataAsyncIterator {
 
     public CompletableFuture<Void> forEach(BiFunction<Long, LedgerMetadata, CompletableFuture<Void>> consumer) {
         CompletableFuture<Void> promise = new CompletableFuture<>();
-        Flowable.<Long, FlatIterator>generate(
-                () -> new FlatIterator(ledgerManager.getLedgerRanges(zkTimeoutMs)),
-                (iter, emitter) -> {
-                    try {
-                        if (iter.hasNext()) {
-                            emitter.onNext(iter.next());
-                        } else {
-                            emitter.onComplete();
-                        }
-                    } catch (Exception e) {
-                        emitter.onError(e);
-                    }
-                })
-            .subscribeOn(scheduler)
-            .flatMapCompletable((ledgerId) -> Completable.fromCompletionStage(processOne(ledgerId, consumer)),
-                                false /* delayErrors */,
-                                maxInFlight)
-            .subscribe(() -> promise.complete(null),
-                       t -> promise.completeExceptionally(unwrap(t)));
+        final Disposable disposable = Flowable.<Long, FlatIterator>generate(
+                        () -> new FlatIterator(ledgerManager.getLedgerRanges(zkTimeoutMs)),
+                        (iter, emitter) -> {
+                            try {
+                                if (iter.hasNext()) {
+                                    emitter.onNext(iter.next());
+                                } else {
+                                    emitter.onComplete();
+                                }
+                            } catch (Exception e) {
+                                emitter.onError(e);
+                            }
+                        })
+                .subscribeOn(scheduler)
+                .flatMapCompletable((ledgerId) -> Completable.fromCompletionStage(processOne(ledgerId, consumer)),
+                        false /* delayErrors */,
+                        maxInFlight)
+                .subscribe(() -> promise.complete(null),
+                        t -> promise.completeExceptionally(unwrap(t)));
+        promise.whenComplete((result, ex) -> disposable.dispose());
         return promise;
     }
 
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/KeyValueStorageRocksDB.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/KeyValueStorageRocksDB.java
index 293004c..3571f12 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/KeyValueStorageRocksDB.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/KeyValueStorageRocksDB.java
@@ -22,6 +22,7 @@ package org.apache.bookkeeper.bookie.storage.ldb;
 
 import static com.google.common.base.Preconditions.checkState;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.IOException;
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
@@ -29,7 +30,6 @@ import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map.Entry;
-
 import org.apache.bookkeeper.bookie.storage.ldb.KeyValueStorageFactory.DbConfigType;
 import org.apache.bookkeeper.conf.ServerConfiguration;
 import org.rocksdb.ColumnFamilyDescriptor;
@@ -171,6 +171,7 @@ public class KeyValueStorageRocksDB implements KeyValueStorage {
     }
 
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     public Entry<byte[], byte[]> getFloor(byte[] key) throws IOException {
         try (Slice upperBound = new Slice(key);
                  ReadOptions option = new ReadOptions(optionCache).setIterateUpperBound(upperBound);
@@ -184,6 +185,7 @@ public class KeyValueStorageRocksDB implements KeyValueStorage {
     }
 
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     public Entry<byte[], byte[]> getCeil(byte[] key) throws IOException {
         try (RocksIterator iterator = db.newIterator(optionCache)) {
             // Position the iterator on the record whose key is >= to the supplied key
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/LedgerMetadataIndex.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/LedgerMetadataIndex.java
index f359e03..23ec7aa 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/LedgerMetadataIndex.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/LedgerMetadataIndex.java
@@ -235,7 +235,10 @@ public class LedgerMetadataIndex implements Closeable {
         lock.lock();
         try {
             LedgerData ledgerData = get(ledgerId);
-            boolean oldValue = ledgerData != null ? ledgerData.getLimbo() : false;
+            if (ledgerData == null) {
+                throw new Bookie.NoLedgerException(ledgerId);
+            }
+            final boolean oldValue = ledgerData.getLimbo();
             LedgerData newLedgerData = LedgerData.newBuilder(ledgerData).setLimbo(false).build();
 
             if (ledgers.put(ledgerId, newLedgerData) == null) {
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/LedgersIndexRebuildOp.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/LedgersIndexRebuildOp.java
index 7e10de8..6e481ca 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/LedgersIndexRebuildOp.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/LedgersIndexRebuildOp.java
@@ -22,6 +22,7 @@ package org.apache.bookkeeper.bookie.storage.ldb;
 
 import com.google.common.collect.Lists;
 import com.google.protobuf.ByteString;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.io.File;
@@ -71,6 +72,7 @@ public class LedgersIndexRebuildOp {
         this.verbose = verbose;
     }
 
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     public boolean initiate()  {
         LOG.info("Starting ledger index rebuilding");
 
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/SingleDirectoryDbLedgerStorage.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/SingleDirectoryDbLedgerStorage.java
index ffade42..2697abd 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/SingleDirectoryDbLedgerStorage.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/storage/ldb/SingleDirectoryDbLedgerStorage.java
@@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.protobuf.ByteString;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
 import io.netty.buffer.Unpooled;
@@ -622,7 +623,6 @@ public class SingleDirectoryDbLedgerStorage implements CompactableLedgerStorage
     public ByteBuf getLastEntry(long ledgerId) throws IOException, BookieException {
         throwIfLimbo(ledgerId);
 
-        long startTime = MathUtils.nowInNano();
         long stamp = writeCacheRotationLock.readLock();
         try {
             // First try to read from the write cache of recent entries
@@ -696,11 +696,10 @@ public class SingleDirectoryDbLedgerStorage implements CompactableLedgerStorage
             return;
         }
 
-        // Only a single flush operation can happen at a time
-        flushMutex.lock();
-
         long startTime = MathUtils.nowInNano();
 
+        // Only a single flush operation can happen at a time
+        flushMutex.lock();
         try {
             // Swap the write cache so that writes can continue to happen while the flush is
             // ongoing
@@ -963,6 +962,7 @@ public class SingleDirectoryDbLedgerStorage implements CompactableLedgerStorage
      *            Iterator over index pages from Indexed
      * @return the number of
      */
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     public long addLedgerToIndex(long ledgerId, boolean isFenced, byte[] masterKey,
             LedgerCache.PageEntriesIterable pages) throws Exception {
         LedgerData ledgerData = LedgerData.newBuilder().setExists(true).setFenced(isFenced)
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java
index 1dde401..1df80b1 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java
@@ -27,6 +27,7 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -49,6 +50,7 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.BiConsumer;
+import java.util.function.Function;
 import java.util.function.Predicate;
 import lombok.SneakyThrows;
 import org.apache.bookkeeper.bookie.BookieException;
@@ -71,6 +73,7 @@ import org.apache.bookkeeper.meta.LedgerManager;
 import org.apache.bookkeeper.meta.LedgerManager.LedgerRangeIterator;
 import org.apache.bookkeeper.meta.LedgerManagerFactory;
 import org.apache.bookkeeper.meta.LedgerUnderreplicationManager;
+import org.apache.bookkeeper.meta.MetadataBookieDriver;
 import org.apache.bookkeeper.meta.UnderreplicatedLedger;
 import org.apache.bookkeeper.meta.zk.ZKMetadataDriverBase;
 import org.apache.bookkeeper.net.BookieId;
@@ -1238,38 +1241,42 @@ public class BookKeeperAdmin implements AutoCloseable {
      */
     public static boolean format(ServerConfiguration conf,
             boolean isInteractive, boolean force) throws Exception {
-        return runFunctionWithMetadataBookieDriver(conf, driver -> {
-            try {
-                try (RegistrationManager regManager = driver.createRegistrationManager()) {
-                    boolean ledgerRootExists = regManager.prepareFormat();
-
-                    // If old data was there then confirm with admin.
-                    boolean doFormat = true;
-                    if (ledgerRootExists) {
-                        if (!isInteractive) {
-                            // If non interactive and force is set, then delete old data.
-                            doFormat = force;
-                        } else {
-                            // Confirm with the admin.
-                            doFormat = IOUtils
-                                    .confirmPrompt("Ledger root already exists. "
-                                            + "Are you sure to format bookkeeper metadata? "
-                                            + "This may cause data loss.");
+        return runFunctionWithMetadataBookieDriver(conf, new Function<MetadataBookieDriver, Boolean>() {
+            @Override
+            @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
+            public Boolean apply(MetadataBookieDriver driver) {
+                try {
+                    try (RegistrationManager regManager = driver.createRegistrationManager()) {
+                        boolean ledgerRootExists = regManager.prepareFormat();
+
+                        // If old data was there then confirm with admin.
+                        boolean doFormat = true;
+                        if (ledgerRootExists) {
+                            if (!isInteractive) {
+                                // If non interactive and force is set, then delete old data.
+                                doFormat = force;
+                            } else {
+                                // Confirm with the admin.
+                                doFormat = IOUtils
+                                        .confirmPrompt("Ledger root already exists. "
+                                                + "Are you sure to format bookkeeper metadata? "
+                                                + "This may cause data loss.");
+                            }
                         }
-                    }
 
-                    if (!doFormat) {
-                        return false;
-                    }
+                        if (!doFormat) {
+                            return false;
+                        }
 
-                    driver.getLedgerManagerFactory().format(
-                            conf,
-                            driver.getLayoutManager());
+                        driver.getLedgerManagerFactory().format(
+                                conf,
+                                driver.getLayoutManager());
 
-                    return regManager.format();
+                        return regManager.format();
+                    }
+                } catch (Exception e) {
+                    throw new UncheckedExecutionException(e.getMessage(), e);
                 }
-            } catch (Exception e) {
-                throw new UncheckedExecutionException(e.getMessage(), e);
             }
         });
     }
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerFragmentReplicator.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerFragmentReplicator.java
index 90e2006..d39e32f 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerFragmentReplicator.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerFragmentReplicator.java
@@ -106,7 +106,7 @@ public class LedgerFragmentReplicator {
 
     protected Throttler replicationThrottle = null;
 
-    private int averageEntrySize;
+    private AtomicInteger averageEntrySize;
 
     private static final int INITIAL_AVERAGE_ENTRY_SIZE = 1024;
     private static final double AVERAGE_ENTRY_SIZE_RATIO = 0.8;
@@ -123,7 +123,7 @@ public class LedgerFragmentReplicator {
         if (conf.getReplicationRateByBytes() > 0) {
             this.replicationThrottle = new Throttler(conf.getReplicationRateByBytes());
         }
-        averageEntrySize = INITIAL_AVERAGE_ENTRY_SIZE;
+        averageEntrySize = new AtomicInteger(INITIAL_AVERAGE_ENTRY_SIZE);
     }
 
     public LedgerFragmentReplicator(BookKeeper bkc, ClientConfiguration conf) {
@@ -338,7 +338,7 @@ public class LedgerFragmentReplicator {
         final AtomicBoolean completed = new AtomicBoolean(false);
 
         if (replicationThrottle != null) {
-            replicationThrottle.acquire(averageEntrySize);
+            replicationThrottle.acquire(averageEntrySize.get());
         }
 
         final WriteCallback multiWriteCallback = new WriteCallback() {
@@ -418,10 +418,9 @@ public class LedgerFragmentReplicator {
         }, null);
     }
 
-    /* make sure this update safety when different callback run this updating */
-    private synchronized void updateAverageEntrySize(int toSendSize) {
-        averageEntrySize = (int) (averageEntrySize * AVERAGE_ENTRY_SIZE_RATIO
-                + (1 - AVERAGE_ENTRY_SIZE_RATIO) * toSendSize);
+    private void updateAverageEntrySize(int toSendSize) {
+        averageEntrySize.updateAndGet(value -> (int) (value * AVERAGE_ENTRY_SIZE_RATIO
+                + (1 - AVERAGE_ENTRY_SIZE_RATIO) * toSendSize));
     }
 
     /**
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/MetadataDrivers.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/MetadataDrivers.java
index 83fb439..e71dc12 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/MetadataDrivers.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/MetadataDrivers.java
@@ -24,6 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Sets;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.net.URI;
 import java.util.Collections;
 import java.util.Optional;
@@ -305,6 +306,7 @@ public final class MetadataDrivers {
      * @throws MetadataException when failed to access metadata store
      * @throws ExecutionException exception thrown when processing <tt>function</tt>.
      */
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     public static <T> T runFunctionWithMetadataClientDriver(ClientConfiguration conf,
                                                             Function<MetadataClientDriver, T> function,
                                                             ScheduledExecutorService executorService)
@@ -336,6 +338,7 @@ public final class MetadataDrivers {
      * @throws MetadataException when failed to access metadata store
      * @throws ExecutionException exception thrown when processing <tt>function</tt>.
      */
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     public static <T> T runFunctionWithMetadataBookieDriver(ServerConfiguration conf,
                                                             Function<MetadataBookieDriver, T> function)
             throws MetadataException, ExecutionException {
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/checksum/DirectMemoryCRC32Digest.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/checksum/DirectMemoryCRC32Digest.java
index 4f77531..78870e9 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/checksum/DirectMemoryCRC32Digest.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/checksum/DirectMemoryCRC32Digest.java
@@ -83,7 +83,7 @@ class DirectMemoryCRC32Digest implements CRC32Digest {
             updateBytesMethod = CRC32.class.getDeclaredMethod("updateBytes", int.class, byte[].class, int.class,
                     int.class);
             updateBytesMethod.setAccessible(true);
-        } catch (Exception e) {
+        } catch (Throwable e) {
             updateByteBufferMethod = null;
             updateBytesMethod = null;
         }
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/replication/ReplicationWorker.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/replication/ReplicationWorker.java
index d897e77..f8d6402 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/replication/ReplicationWorker.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/replication/ReplicationWorker.java
@@ -31,6 +31,7 @@ import com.google.common.base.Stopwatch;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.HashMap;
@@ -356,6 +357,7 @@ public class ReplicationWorker implements Runnable {
         return (returnRCValue.get() == BKException.Code.OK);
     }
 
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     private boolean rereplicate(long ledgerIdToReplicate) throws InterruptedException, BKException,
             UnavailableException {
         if (LOG.isDebugEnabled()) {
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/AutoRecoveryStatusService.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/AutoRecoveryStatusService.java
index f9ab650..463d9bc 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/AutoRecoveryStatusService.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/AutoRecoveryStatusService.java
@@ -20,6 +20,7 @@ package org.apache.bookkeeper.server.http.service;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.Collections;
 import java.util.Map;
 import org.apache.bookkeeper.common.util.JsonUtil;
@@ -42,6 +43,7 @@ import org.apache.commons.lang3.ObjectUtils;
  * the same as desired. The output would be the current status after the action.
  *
  */
+@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
 public class AutoRecoveryStatusService implements HttpEndpointService {
     protected final ServerConfiguration conf;
 
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/ExpandStorageService.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/ExpandStorageService.java
index 9f7a0a4..5c8c8ca 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/ExpandStorageService.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/ExpandStorageService.java
@@ -20,6 +20,7 @@ package org.apache.bookkeeper.server.http.service;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import com.google.common.collect.Lists;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.File;
 import java.net.URI;
 import java.util.Arrays;
@@ -61,6 +62,7 @@ public class ExpandStorageService implements HttpEndpointService {
      * Update the directories info in the conf file before running the command.
      */
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     public HttpServiceResponse handle(HttpServiceRequest request) throws Exception {
         HttpServiceResponse response = new HttpServiceResponse();
 
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/GetLastLogMarkService.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/GetLastLogMarkService.java
index 0ffa9bb..3289be5 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/GetLastLogMarkService.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/GetLastLogMarkService.java
@@ -97,7 +97,7 @@ public class GetLastLogMarkService implements HttpEndpointService {
                 response.setBody(jsonResponse);
                 response.setCode(HttpServer.StatusCode.OK);
                 return response;
-            } catch (Exception e) {
+            } catch (Throwable e) {
                 LOG.error("Exception occurred while getting last log mark", e);
                 response.setCode(HttpServer.StatusCode.NOT_FOUND);
                 response.setBody("ERROR handling request: " + e.getMessage());
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/autorecovery/ToggleCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/autorecovery/ToggleCommand.java
index 520bcaa..57c320f 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/autorecovery/ToggleCommand.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/autorecovery/ToggleCommand.java
@@ -20,6 +20,7 @@ package org.apache.bookkeeper.tools.cli.commands.autorecovery;
 
 import com.beust.jcommander.Parameter;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.concurrent.ExecutionException;
 import lombok.Setter;
 import lombok.experimental.Accessors;
@@ -39,6 +40,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Command to enable or disable auto recovery in the cluster.
  */
+@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
 public class ToggleCommand extends BookieCommand<ToggleCommand.AutoRecoveryFlags> {
 
     static final Logger LOG = LoggerFactory.getLogger(ToggleCommand.class);
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/LedgerCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/LedgerCommand.java
index d9cf8d7..fa753e9 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/LedgerCommand.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/LedgerCommand.java
@@ -20,9 +20,9 @@ package org.apache.bookkeeper.tools.cli.commands.bookie;
 
 import com.beust.jcommander.Parameter;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.IOException;
 import java.util.function.Consumer;
-
 import lombok.Setter;
 import lombok.experimental.Accessors;
 import org.apache.bookkeeper.bookie.BookieImpl;
@@ -164,6 +164,7 @@ public class LedgerCommand extends BookieCommand<LedgerCommand.LedgerFlags> {
         }
     }
 
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     private boolean printPageEntries(LedgerCache.PageEntries page) {
         final MutableLong curEntry = new MutableLong(page.getFirstEntry());
         try (LedgerEntryPage lep = page.getLEP()) {
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommand.java
index ccdd05b..d27abca 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommand.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListActiveLedgersCommand.java
@@ -22,6 +22,7 @@ import static org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithLedgerMa
 
 import com.beust.jcommander.Parameter;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -54,6 +55,7 @@ import org.slf4j.LoggerFactory;
  *  List active(exist in metadata storage) ledgers in a entry log file.
  *
  **/
+@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
 public class ListActiveLedgersCommand extends BookieCommand<ActiveLedgerFlags>{
     private static final Logger LOG = LoggerFactory.getLogger(ListActiveLedgersCommand.class);
     private static final String NAME = "active ledger";
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListLedgersCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListLedgersCommand.java
index 3224bce..8016109 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListLedgersCommand.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ListLedgersCommand.java
@@ -22,6 +22,7 @@ import static org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithLedgerMa
 
 import com.beust.jcommander.Parameter;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.net.UnknownHostException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
@@ -48,6 +49,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Command for list all ledgers on the cluster.
  */
+@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
 public class ListLedgersCommand extends BookieCommand<ListLedgersFlags> {
 
     private static final Logger LOG = LoggerFactory.getLogger(ListLedgersCommand.class);
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommand.java
index b2dff8f..7f3fbdf 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommand.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLedgerCommand.java
@@ -20,6 +20,7 @@ package org.apache.bookkeeper.tools.cli.commands.bookie;
 
 import com.beust.jcommander.Parameter;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.buffer.ByteBufUtil;
 import io.netty.buffer.UnpooledByteBufAllocator;
 import io.netty.channel.EventLoopGroup;
@@ -138,6 +139,7 @@ public class ReadLedgerCommand extends BookieCommand<ReadLedgerCommand.ReadLedge
         }
     }
 
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     private boolean readledger(ServerConfiguration serverConf, ReadLedgerFlags flags)
         throws InterruptedException, BKException, IOException {
 
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLogMetadataCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLogMetadataCommand.java
index b22338d..987015c 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLogMetadataCommand.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/ReadLogMetadataCommand.java
@@ -20,6 +20,7 @@ package org.apache.bookkeeper.tools.cli.commands.bookie;
 
 import com.beust.jcommander.Parameter;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.File;
 import java.io.IOException;
 import lombok.Setter;
@@ -139,6 +140,7 @@ public class ReadLogMetadataCommand extends BookieCommand<ReadLogMetadataFlags>
         });
     }
 
+    @SuppressFBWarnings("IS2_INCONSISTENT_SYNC")
     private synchronized void initEntryLogger(ServerConfiguration conf) throws IOException {
         // provide read only entry logger
         if (null == entryLogger) {
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/LedgerMetaDataCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/LedgerMetaDataCommand.java
index 3c9a394..21ff540 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/LedgerMetaDataCommand.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/LedgerMetaDataCommand.java
@@ -22,6 +22,7 @@ import static org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithLedgerMa
 
 import com.beust.jcommander.Parameter;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.util.Optional;
@@ -44,6 +45,7 @@ import org.slf4j.LoggerFactory;
 /**
  * Print the metadata for a ledger.
  */
+@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
 public class LedgerMetaDataCommand extends BookieCommand<LedgerMetaDataCommand.LedgerMetadataFlag> {
 
     private static final String NAME = "show";
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommand.java
index 6b2eda0..d83fb50 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommand.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/client/SimpleTestCommand.java
@@ -21,6 +21,7 @@ package org.apache.bookkeeper.tools.cli.commands.client;
 import static org.apache.bookkeeper.common.concurrent.FutureUtils.result;
 
 import com.beust.jcommander.Parameter;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.concurrent.TimeUnit;
 import lombok.Setter;
 import lombok.experimental.Accessors;
@@ -73,6 +74,7 @@ public class SimpleTestCommand extends ClientCommand<Flags> {
     }
 
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     protected void run(BookKeeper bk, Flags flags) throws Exception {
         byte[] data = new byte[100]; // test data
 
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/helpers/DiscoveryCommand.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/helpers/DiscoveryCommand.java
index 5af6af3..0737d51 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/helpers/DiscoveryCommand.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/helpers/DiscoveryCommand.java
@@ -18,6 +18,7 @@
  */
 package org.apache.bookkeeper.tools.cli.helpers;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.net.URI;
 import java.util.Optional;
 import java.util.concurrent.Executors;
@@ -44,6 +45,7 @@ public abstract class DiscoveryCommand<DiscoveryFlagsT extends CliFlags> extends
     }
 
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     protected boolean apply(ClientConfiguration clientConf, DiscoveryFlagsT cmdFlags) {
         try {
             URI metadataServiceUri = URI.create(clientConf.getMetadataServiceUri());
diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/verifier/BookkeeperVerifier.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/verifier/BookkeeperVerifier.java
index 821d260..63c2457 100644
--- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/verifier/BookkeeperVerifier.java
+++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/verifier/BookkeeperVerifier.java
@@ -471,7 +471,7 @@ public class BookkeeperVerifier {
                                 current, ledger.ledgerID, result.length, check.length)
                         ));
                     }
-                        /* Verify contents */
+                    /* Verify contents */
                     if (!Arrays.equals(check, result)) {
                         int i = 0;
                         for (; i < check.length; ++i) {
@@ -657,7 +657,7 @@ public class BookkeeperVerifier {
 
         /* Wait for all in progress ops to complete, outstanding*Count is updated under the lock */
         while ((System.currentTimeMillis() < testDrainEnd)
-               && (outstandingReadCount > 0 || outstandingWriteCount > 0)) {
+                && (outstandingReadCount > 0 || outstandingWriteCount > 0)) {
             System.out.format("reads: %d, writes: %d%n", outstandingReadCount, outstandingWriteCount);
             System.out.format("openingLedgers:%n");
             for (LedgerInfo li: openingLedgers) {
diff --git a/cpu-affinity/src/main/java/org/apache/bookkeeper/common/util/affinity/impl/NativeUtils.java b/cpu-affinity/src/main/java/org/apache/bookkeeper/common/util/affinity/impl/NativeUtils.java
index 218e9f1..1c37147 100644
--- a/cpu-affinity/src/main/java/org/apache/bookkeeper/common/util/affinity/impl/NativeUtils.java
+++ b/cpu-affinity/src/main/java/org/apache/bookkeeper/common/util/affinity/impl/NativeUtils.java
@@ -45,7 +45,7 @@ public class NativeUtils {
      * @throws Exception
      */
     @SuppressFBWarnings(
-            value = "OBL_UNSATISFIED_OBLIGATION",
+            value = "RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE",
             justification = "work around for java 9: https://github.com/spotbugs/spotbugs/issues/493")
     public static void loadLibraryFromJar(String path) throws Exception {
         com.google.common.base.Preconditions.checkArgument(path.startsWith("/"), "absolute path must start with /");
diff --git a/microbenchmarks/src/main/java/org/apache/bookkeeper/proto/ProtocolBenchmark.java b/microbenchmarks/src/main/java/org/apache/bookkeeper/proto/ProtocolBenchmark.java
index 4cea634..ab24402 100644
--- a/microbenchmarks/src/main/java/org/apache/bookkeeper/proto/ProtocolBenchmark.java
+++ b/microbenchmarks/src/main/java/org/apache/bookkeeper/proto/ProtocolBenchmark.java
@@ -25,7 +25,7 @@ import io.netty.buffer.ByteBufAllocator;
 import io.netty.buffer.Unpooled;
 import io.netty.util.ReferenceCountUtil;
 
-import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.bookkeeper.proto.BookieProtoEncoding.EnDecoder;
@@ -69,12 +69,11 @@ public class ProtocolBenchmark {
     @Setup
     public void prepare() {
         this.masterKey = "test-benchmark-key".getBytes(UTF_8);
-        Random r = new Random(System.currentTimeMillis());
         byte[] data = new byte[this.size];
-        r.nextBytes(data);
+        ThreadLocalRandom.current().nextBytes(data);
         this.entry = Unpooled.wrappedBuffer(data);
-        this.ledgerId = r.nextLong();
-        this.entryId = r.nextLong();
+        this.ledgerId = ThreadLocalRandom.current().nextLong();
+        this.entryId = ThreadLocalRandom.current().nextLong();
         this.flags = 1;
 
         // prepare the encoder
diff --git a/pom.xml b/pom.xml
index f007fb0..eba48ec 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1180,25 +1180,6 @@
         </plugins>
       </build>
     </profile>
-
-    <profile>
-      <id>jdk11-no-spotbugs</id>
-      <activation>
-        <jdk>[11,)</jdk>
-      </activation>
-      <build>
-        <plugins>
-           <plugin>
-             <groupId>com.github.spotbugs</groupId>
-             <artifactId>spotbugs-maven-plugin</artifactId>
-             <configuration>
-                 <skip>true</skip>
-             </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-
     <profile>
       <id>apache-release</id>
       <build>
diff --git a/tests/backward-compat/pom.xml b/tests/backward-compat/pom.xml
index 94b3fea..0de9997 100644
--- a/tests/backward-compat/pom.xml
+++ b/tests/backward-compat/pom.xml
@@ -38,4 +38,15 @@
     <module>yahoo-custom-version</module>
     <module>bc-non-fips</module>
   </modules>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>com.github.spotbugs</groupId>
+        <artifactId>spotbugs-maven-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/tests/integration-tests-utils/build.gradle b/tests/integration-tests-utils/build.gradle
index 649421e..020773a 100644
--- a/tests/integration-tests-utils/build.gradle
+++ b/tests/integration-tests-utils/build.gradle
@@ -20,6 +20,7 @@ dependencies {
     implementation depLibs.arquillianCubeDocker
     implementation depLibs.zookeeper
     implementation depLibs.junit
+    compileOnly depLibs.spotbugsAnnotations
     compileOnly depLibs.lombok
     implementation depLibs.slf4j
     implementation depLibs.groovy
diff --git a/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/integration/utils/DockerUtils.java b/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/integration/utils/DockerUtils.java
index 35d58e4..1577309 100644
--- a/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/integration/utils/DockerUtils.java
+++ b/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/integration/utils/DockerUtils.java
@@ -25,7 +25,7 @@ import com.github.dockerjava.api.command.InspectContainerResponse;
 import com.github.dockerjava.api.command.InspectExecResponse;
 import com.github.dockerjava.api.model.ContainerNetwork;
 import com.github.dockerjava.api.model.Frame;
-
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.Closeable;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -105,6 +105,7 @@ public class DockerUtils {
         }
     }
 
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     public static void dumpContainerDirToTargetCompressed(DockerClient dockerClient, String containerId,
                                                           String path) {
         final int readBlockSize = 10000;
diff --git a/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/integration/utils/MavenClassLoader.java b/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/integration/utils/MavenClassLoader.java
index 9c24186..05724fe 100644
--- a/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/integration/utils/MavenClassLoader.java
+++ b/tests/integration-tests-utils/src/main/java/org/apache/bookkeeper/tests/integration/utils/MavenClassLoader.java
@@ -18,7 +18,7 @@
 package org.apache.bookkeeper.tests.integration.utils;
 
 import com.google.common.collect.Lists;
-
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import groovy.lang.Closure;
 
 import java.io.Closeable;
@@ -270,6 +270,7 @@ public class MavenClassLoader implements AutoCloseable {
         }
     }
 
+    @SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
     private static void extractTarGz(File tarGz, File output) throws Exception {
         File tarFile = new File(output, tarGz.getName().replace(".gz", ""));
         tarFile.delete();
@@ -289,11 +290,12 @@ public class MavenClassLoader implements AutoCloseable {
         return tarFile;
     }
 
+    @SuppressFBWarnings({"RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE", "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE"})
     private static void unTar(final File inputFile, final File outputDir) throws Exception {
-        try (TarArchiveInputStream debInputStream = (TarArchiveInputStream)
-                new ArchiveStreamFactory().createArchiveInputStream("tar",
-                        new FileInputStream(inputFile))) {
-            TarArchiveEntry entry = null;
+        try (final FileInputStream fis = new FileInputStream(inputFile);
+                TarArchiveInputStream debInputStream = (TarArchiveInputStream)
+                new ArchiveStreamFactory().createArchiveInputStream("tar", fis)) {
+            TarArchiveEntry entry;
             while ((entry = (TarArchiveEntry) debInputStream.getNextEntry()) != null) {
                 final File outputFile = new File(outputDir, entry.getName());
                 if (entry.isDirectory()) {
diff --git a/tools/perf/build.gradle b/tools/perf/build.gradle
index 1223e20..36d0490 100644
--- a/tools/perf/build.gradle
+++ b/tools/perf/build.gradle
@@ -40,6 +40,7 @@ dependencies {
     implementation project(':stream:distributedlog:protocol')
     implementation project(':stream:proto')
 
+    compileOnly depLibs.spotbugsAnnotations
     compileOnly depLibs.lombok
     implementation depLibs.commonsConfiguration
     implementation depLibs.guava
diff --git a/tools/perf/src/main/java/org/apache/bookkeeper/tools/perf/table/PerfClient.java b/tools/perf/src/main/java/org/apache/bookkeeper/tools/perf/table/PerfClient.java
index 835f816..f8d7c2d 100644
--- a/tools/perf/src/main/java/org/apache/bookkeeper/tools/perf/table/PerfClient.java
+++ b/tools/perf/src/main/java/org/apache/bookkeeper/tools/perf/table/PerfClient.java
@@ -25,6 +25,7 @@ import com.beust.jcommander.Parameter;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectWriter;
 import com.google.common.util.concurrent.RateLimiter;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.buffer.ByteBuf;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
@@ -231,6 +232,7 @@ public class PerfClient implements Runnable {
         runBenchmarkTasks();
     }
 
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     private void runBenchmarkTasks() throws Exception {
         StorageClientSettings settings = StorageClientSettings.newBuilder()
             .serviceUri(serviceURI.getUri().toString())
diff --git a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/cluster/InitClusterCommand.java b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/cluster/InitClusterCommand.java
index 4ee3d39..8903ca7 100644
--- a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/cluster/InitClusterCommand.java
+++ b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/cluster/InitClusterCommand.java
@@ -24,6 +24,7 @@ import static org.apache.bookkeeper.stream.cli.Commands.OP_INIT;
 import com.beust.jcommander.Parameter;
 import com.google.common.base.Strings;
 import com.google.common.util.concurrent.UncheckedExecutionException;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.net.URI;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.bookkeeper.common.net.ServiceURI;
@@ -107,6 +108,7 @@ public class InitClusterCommand extends BKCommand<Flags> {
     }
 
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     protected boolean apply(ServiceURI ignored,
                             CompositeConfiguration conf,
                             BKFlags globalFlags,
diff --git a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/DelCommand.java b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/DelCommand.java
index 44d17d4..5027f4e 100644
--- a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/DelCommand.java
+++ b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/DelCommand.java
@@ -23,6 +23,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.apache.bookkeeper.common.concurrent.FutureUtils.result;
 import static org.apache.bookkeeper.stream.cli.Commands.OP_DEL;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import org.apache.bookkeeper.api.StorageClient;
@@ -56,6 +57,7 @@ public class DelCommand extends ClientCommand<Flags> {
     }
 
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     protected void run(StorageClient client, Flags flags) throws Exception {
         checkArgument(flags.arguments.size() >= 2,
             "table and key/value are not provided");
diff --git a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/GetCommand.java b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/GetCommand.java
index 093b669..7687ce5 100644
--- a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/GetCommand.java
+++ b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/GetCommand.java
@@ -23,6 +23,7 @@ import static org.apache.bookkeeper.common.concurrent.FutureUtils.result;
 import static org.apache.bookkeeper.stream.cli.Commands.OP_GET;
 
 import com.beust.jcommander.Parameter;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufUtil;
 import io.netty.buffer.Unpooled;
@@ -62,6 +63,7 @@ public class GetCommand extends ClientCommand<Flags> {
     }
 
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     protected void run(StorageClient client, Flags flags) throws Exception {
         checkArgument(flags.arguments.size() >= 2,
             "table and key are not provided");
diff --git a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/IncrementCommand.java b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/IncrementCommand.java
index 25a2fb5..9b3c29e 100644
--- a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/IncrementCommand.java
+++ b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/IncrementCommand.java
@@ -22,6 +22,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.apache.bookkeeper.common.concurrent.FutureUtils.result;
 import static org.apache.bookkeeper.stream.cli.Commands.OP_INC;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import org.apache.bookkeeper.api.StorageClient;
@@ -55,6 +56,7 @@ public class IncrementCommand extends ClientCommand<Flags> {
     }
 
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     protected void run(StorageClient client, Flags flags) throws Exception {
         checkArgument(flags.arguments.size() >= 3,
             "table and key/amount are not provided");
diff --git a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/PutCommand.java b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/PutCommand.java
index b43f91e..f890b0d 100644
--- a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/PutCommand.java
+++ b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/commands/table/PutCommand.java
@@ -22,6 +22,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.apache.bookkeeper.common.concurrent.FutureUtils.result;
 import static org.apache.bookkeeper.stream.cli.Commands.OP_PUT;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import org.apache.bookkeeper.api.StorageClient;
@@ -55,6 +56,7 @@ public class PutCommand extends ClientCommand<Flags> {
     }
 
     @Override
+    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE")
     protected void run(StorageClient client, Flags flags) throws Exception {
         checkArgument(flags.arguments.size() >= 3,
             "table and key/value are not provided");