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

mmerli 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 ee56a953fe Use mockito instead of powermock (#4212)
ee56a953fe is described below

commit ee56a953fe0f7ff5ea5ecc2c1afd57c5376ff780
Author: Zixuan Liu <node...@gmail.com>
AuthorDate: Wed Feb 21 02:13:16 2024 +0800

    Use mockito instead of powermock (#4212)
---
 .../org/apache/bookkeeper/bookie/BookieImpl.java   |  17 +-
 .../org/apache/bookkeeper/bookie/BookieShell.java  |  16 +-
 .../bookkeeper/bookie/GarbageCollectorThread.java  |  10 +-
 .../java/org/apache/bookkeeper/bookie/Journal.java |  37 +++-
 .../bookkeeper/bookie/LegacyCookieValidation.java  |   7 +
 .../bookkeeper/bookie/SortedLedgerStorage.java     |  11 +-
 .../org/apache/bookkeeper/bookie/SyncThread.java   |   7 +-
 .../bookkeeper/bookie/stats/JournalStats.java      |   8 +-
 .../apache/bookkeeper/client/BookKeeperAdmin.java  |   7 +
 .../org/apache/bookkeeper/client/LedgerHandle.java |   4 +
 .../bookkeeper/meta/zk/ZKMetadataBookieDriver.java |   8 +
 .../bookkeeper/meta/zk/ZKMetadataClientDriver.java |  18 +-
 .../org/apache/bookkeeper/proto/BookieServer.java  |  11 ++
 .../apache/bookkeeper/server/EmbeddedServer.java   |   9 +-
 .../bookkeeper/server/service/BookieService.java   |   4 +-
 .../tools/cli/commands/bookie/LastMarkCommand.java |   6 +
 .../cli/commands/bookies/ClusterInfoCommand.java   |   5 +
 .../cli/commands/bookies/ListBookiesCommand.java   |  13 +-
 .../tools/cli/commands/bookies/RecoverCommand.java |   3 +-
 .../cli/commands/client/SimpleTestCommand.java     |  13 +-
 .../bookkeeper/bookie/BookieJournalForceTest.java  |  59 +++---
 .../bookie/BookieJournalMaxMemoryTest.java         |  21 +--
 .../bookie/BookieJournalPageCacheFlushTest.java    |  40 +++--
 .../bookkeeper/bookie/BookieJournalTest.java       |  36 ++--
 .../apache/bookkeeper/bookie/BookieShellTest.java  | 197 ++++++++++-----------
 .../bookie/BookieWriteToJournalTest.java           |  19 +-
 .../bookie/GarbageCollectorThreadTest.java         |   5 +-
 .../bookkeeper/bookie/LedgerDirsManagerTest.java   |  19 +-
 .../bookie/LedgerStorageCheckpointTest.java        |  41 +++--
 .../storage/ldb/LedgersIndexRebuildTest.java       |  14 +-
 .../bookkeeper/client/BookieWriteLedgerTest.java   |   3 +-
 .../bookkeeper/client/api/WriteAdvHandleTest.java  |   2 +-
 .../discover/AbstractTestZkRegistrationClient.java |  13 +-
 .../meta/AbstractZkLedgerManagerTest.java          |  26 +--
 .../meta/zk/ZKMetadataBookieDriverTest.java        |  36 ++--
 .../meta/zk/ZKMetadataClientDriverTest.java        |  26 ++-
 .../meta/zk/ZKMetadataDriverBaseTest.java          |  39 ++--
 .../meta/zk/ZKMetadataDriverTestBase.java          |  14 +-
 .../bookkeeper/server/TestEmbeddedServer.java      | 154 ++++++++++------
 .../bookkeeper/server/http/TestHttpService.java    |   2 +-
 .../zookeeper/MockZooKeeperTestCase.java           |  52 +++---
 .../powermock/extensions/configuration.properties  |  22 ---
 pom.xml                                            |  23 +--
 .../bookkeeper/clients/StorageClientImpl.java      |  20 ++-
 .../bookkeeper/clients/StorageClientImplTest.java  |  49 ++---
 .../clients/impl/kv/ByteBufTableImpl.java          |   6 +
 .../shaded/DistributedLogCoreShadedJarTest.java    |  17 +-
 47 files changed, 639 insertions(+), 530 deletions(-)

diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieImpl.java 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieImpl.java
index 6aac4ecf68..654ace4547 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieImpl.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieImpl.java
@@ -433,7 +433,7 @@ public class BookieImpl extends BookieCriticalThread 
implements Bookie {
         // instantiate the journals
         journals = Lists.newArrayList();
         for (int i = 0; i < journalDirectories.size(); i++) {
-            journals.add(new Journal(i, journalDirectories.get(i),
+            journals.add(Journal.newJournal(i, journalDirectories.get(i),
                     conf, ledgerDirsManager, statsLogger.scope(JOURNAL_SCOPE), 
allocator, journalAliveListener));
         }
 
@@ -496,6 +496,21 @@ public class BookieImpl extends BookieCriticalThread 
implements Bookie {
         this.bookieStats = new BookieStats(statsLogger, 
journalDirectories.size(), conf.getJournalQueueSize());
     }
 
+    @VisibleForTesting
+    public static BookieImpl newBookieImpl(ServerConfiguration conf,
+                                           RegistrationManager 
registrationManager,
+                                           LedgerStorage storage,
+                                           DiskChecker diskChecker,
+                                           LedgerDirsManager ledgerDirsManager,
+                                           LedgerDirsManager indexDirsManager,
+                                           StatsLogger statsLogger,
+                                           ByteBufAllocator allocator,
+                                           Supplier<BookieServiceInfo> 
bookieServiceInfoProvider)
+            throws IOException, InterruptedException, BookieException {
+        return new BookieImpl(conf, registrationManager, storage, diskChecker,
+                ledgerDirsManager, indexDirsManager, statsLogger, allocator, 
bookieServiceInfoProvider);
+    }
+
     StateManager initializeStateManager() throws IOException {
         return new BookieStateManager(conf, statsLogger, registrationManager,
                 ledgerDirsManager, bookieServiceInfoProvider);
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java
index 6f66766d40..73409e37ea 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java
@@ -19,6 +19,10 @@
 package org.apache.bookkeeper.bookie;
 
 import static 
org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithLedgerManagerFactory;
+import static 
org.apache.bookkeeper.tools.cli.commands.bookie.LastMarkCommand.newLastMarkCommand;
+import static 
org.apache.bookkeeper.tools.cli.commands.bookies.ClusterInfoCommand.newClusterInfoCommand;
+import static 
org.apache.bookkeeper.tools.cli.commands.bookies.ListBookiesCommand.newListBookiesCommand;
+import static 
org.apache.bookkeeper.tools.cli.commands.client.SimpleTestCommand.newSimpleTestCommand;
 
 import com.google.common.annotations.VisibleForTesting;
 import java.io.File;
@@ -1007,13 +1011,13 @@ public class BookieShell implements Tool {
             int ackQuorum = getOptionIntValue(cmdLine, "ackQuorum", 2);
             int numEntries = getOptionIntValue(cmdLine, "numEntries", 1000);
 
-            SimpleTestCommand.Flags flags = new SimpleTestCommand.Flags()
+            SimpleTestCommand.Flags flags = SimpleTestCommand.Flags.newFlags()
                 .ensembleSize(ensemble)
                 .writeQuorumSize(writeQuorum)
                 .ackQuorumSize(ackQuorum)
                 .numEntries(numEntries);
 
-            SimpleTestCommand command = new SimpleTestCommand(flags);
+            SimpleTestCommand command = newSimpleTestCommand(flags);
 
             command.apply(bkConf, flags);
             return 0;
@@ -1292,7 +1296,7 @@ public class BookieShell implements Tool {
 
         @Override
         public int runCmd(CommandLine c) throws Exception {
-            LastMarkCommand command = new LastMarkCommand();
+            LastMarkCommand command = newLastMarkCommand();
             command.apply(bkConf, new CliFlags());
             return 0;
         }
@@ -1351,12 +1355,12 @@ public class BookieShell implements Tool {
                 return 1;
             }
 
-            ListBookiesCommand.Flags flags = new ListBookiesCommand.Flags()
+            ListBookiesCommand.Flags flags = 
ListBookiesCommand.Flags.newFlags()
                 .readwrite(readwrite)
                 .readonly(readonly)
                 .all(all);
 
-            ListBookiesCommand command = new ListBookiesCommand(flags);
+            ListBookiesCommand command = newListBookiesCommand(flags);
 
             command.apply(bkConf, flags);
             return 0;
@@ -2552,7 +2556,7 @@ public class BookieShell implements Tool {
 
         @Override
         int runCmd(CommandLine cmdLine) throws Exception {
-            ClusterInfoCommand cmd = new ClusterInfoCommand();
+            ClusterInfoCommand cmd = newClusterInfoCommand();
             cmd.apply(bkConf, new CliFlags());
             return 0;
         }
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 bc55af1fe2..9839e49c65 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
@@ -90,7 +90,7 @@ public class GarbageCollectorThread implements Runnable {
 
     // Entry Logger Handle
     final EntryLogger entryLogger;
-    final AbstractLogCompactor compactor;
+    AbstractLogCompactor compactor;
 
     // Stats loggers for garbage collection operations
     private final GarbageCollectorStats gcStats;
@@ -138,8 +138,12 @@ public class GarbageCollectorThread implements Runnable {
                                   final CompactableLedgerStorage ledgerStorage,
                                   EntryLogger entryLogger,
                                   StatsLogger statsLogger) throws IOException {
-        this(conf, ledgerManager, ledgerDirsManager, ledgerStorage, 
entryLogger, statsLogger,
-                Executors.newSingleThreadScheduledExecutor(new 
DefaultThreadFactory("GarbageCollectorThread")));
+        this(conf, ledgerManager, ledgerDirsManager, ledgerStorage, 
entryLogger, statsLogger, newExecutor());
+    }
+
+    @VisibleForTesting
+    static ScheduledExecutorService newExecutor() {
+        return Executors.newSingleThreadScheduledExecutor(new 
DefaultThreadFactory("GarbageCollectorThread"));
     }
 
     /**
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 91c9885717..3b730cb476 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
@@ -630,18 +630,20 @@ public class Journal extends BookieCriticalThread 
implements CheckpointSource {
 
     // journal entry queue to commit
     final BatchedBlockingQueue<QueueEntry> queue;
-    final BatchedBlockingQueue<ForceWriteRequest> forceWriteRequests;
+    BatchedBlockingQueue<ForceWriteRequest> forceWriteRequests;
 
     volatile boolean running = true;
     private final LedgerDirsManager ledgerDirsManager;
     private final ByteBufAllocator allocator;
-    private final MemoryLimitController memoryLimitController;
 
     // Expose Stats
     private final JournalStats journalStats;
 
     private JournalAliveListener journalAliveListener;
 
+    private MemoryLimitController memoryLimitController;
+
+
     public Journal(int journalIndex, File journalDirectory, 
ServerConfiguration conf,
             LedgerDirsManager ledgerDirsManager) {
         this(journalIndex, journalDirectory, conf, ledgerDirsManager, 
NullStatsLogger.INSTANCE,
@@ -724,6 +726,14 @@ public class Journal extends BookieCriticalThread 
implements CheckpointSource {
         this.journalAliveListener = journalAliveListener;
     }
 
+    @VisibleForTesting
+    static Journal newJournal(int journalIndex, File journalDirectory, 
ServerConfiguration conf,
+                                     LedgerDirsManager ledgerDirsManager, 
StatsLogger statsLogger,
+                                     ByteBufAllocator allocator, 
JournalAliveListener journalAliveListener) {
+        return new Journal(journalIndex, journalDirectory, conf, 
ledgerDirsManager, statsLogger, allocator,
+                journalAliveListener);
+    }
+
     JournalStats getJournalStats() {
         return this.journalStats;
     }
@@ -923,6 +933,14 @@ public class Journal extends BookieCriticalThread 
implements CheckpointSource {
         return queue.size();
     }
 
+    @VisibleForTesting
+    JournalChannel newLogFile(long logId, Long replaceLogId) throws 
IOException {
+        return new JournalChannel(journalDirectory, logId, 
journalPreAllocSize, journalWriteBufferSize,
+                journalAlignmentSize, removePagesFromCache,
+                journalFormatVersionToWrite, getBufferedChannelBuilder(),
+                conf, fileChannelProvider, replaceLogId);
+    }
+
     /**
      * A thread used for persisting journal entries to journal files.
      *
@@ -991,10 +1009,7 @@ public class Journal extends BookieCriticalThread 
implements CheckpointSource {
                         ? journalIds.get(0) : null;
 
                     journalCreationWatcher.reset().start();
-                    logFile = new JournalChannel(journalDirectory, logId, 
journalPreAllocSize, journalWriteBufferSize,
-                                        journalAlignmentSize, 
removePagesFromCache,
-                                        journalFormatVersionToWrite, 
getBufferedChannelBuilder(),
-                                        conf, fileChannelProvider, 
replaceLogId);
+                    logFile = newLogFile(logId, replaceLogId);
 
                     
journalStats.getJournalCreationStats().registerSuccessfulEvent(
                             
journalCreationWatcher.stop().elapsed(TimeUnit.NANOSECONDS), 
TimeUnit.NANOSECONDS);
@@ -1275,4 +1290,14 @@ public class Journal extends BookieCriticalThread 
implements CheckpointSource {
     long getMemoryUsage() {
         return memoryLimitController.currentUsage();
     }
+
+    @VisibleForTesting
+    void setMemoryLimitController(MemoryLimitController memoryLimitController) 
{
+        this.memoryLimitController = memoryLimitController;
+    }
+
+    @VisibleForTesting
+    public void setForceWriteRequests(BatchedBlockingQueue<ForceWriteRequest> 
forceWriteRequests) {
+        this.forceWriteRequests = forceWriteRequests;
+    }
 }
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LegacyCookieValidation.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LegacyCookieValidation.java
index 2a9744d682..2f15f6b4cf 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LegacyCookieValidation.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/LegacyCookieValidation.java
@@ -17,6 +17,7 @@
  */
 package org.apache.bookkeeper.bookie;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Lists;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -51,6 +52,12 @@ public class LegacyCookieValidation implements 
CookieValidation {
         this.registrationManager = registrationManager;
     }
 
+    @VisibleForTesting
+    public static LegacyCookieValidation 
newLegacyCookieValidation(ServerConfiguration conf,
+                                                                   
RegistrationManager registrationManager) {
+        return new LegacyCookieValidation(conf, registrationManager);
+    }
+
     @Override
     public void checkCookies(List<File> directories) throws BookieException {
         try {
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/SortedLedgerStorage.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/SortedLedgerStorage.java
index c3c9e97213..689668eb93 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/SortedLedgerStorage.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/SortedLedgerStorage.java
@@ -92,10 +92,15 @@ public class SortedLedgerStorage
             statsLogger,
             allocator);
 
-        this.scheduler = Executors.newSingleThreadScheduledExecutor(
+        this.scheduler = newScheduledExecutorService();
+    }
+
+    @VisibleForTesting
+    static ScheduledExecutorService newScheduledExecutorService() {
+        return Executors.newSingleThreadScheduledExecutor(
                 new ThreadFactoryBuilder()
-                .setNameFormat("SortedLedgerStorage-%d")
-                .setPriority((Thread.NORM_PRIORITY + Thread.MAX_PRIORITY) / 
2).build());
+                        .setNameFormat("SortedLedgerStorage-%d")
+                        .setPriority((Thread.NORM_PRIORITY + 
Thread.MAX_PRIORITY) / 2).build());
     }
 
     @Override
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/SyncThread.java 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/SyncThread.java
index b6a994e174..c3a4c8fc71 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/SyncThread.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/SyncThread.java
@@ -80,11 +80,16 @@ class SyncThread implements Checkpointer {
         this.dirsListener = dirsListener;
         this.ledgerStorage = ledgerStorage;
         this.checkpointSource = checkpointSource;
-        this.executor = Executors.newSingleThreadScheduledExecutor(new 
DefaultThreadFactory(executorName));
+        this.executor = newExecutor();
         this.syncExecutorTime = 
statsLogger.getThreadScopedCounter("sync-thread-time");
         this.executor.submit(() -> ThreadRegistry.register(executorName, 0));
     }
 
+    @VisibleForTesting
+    static ScheduledExecutorService newExecutor() {
+        return Executors.newSingleThreadScheduledExecutor(new 
DefaultThreadFactory(executorName));
+    }
+
     @Override
     public void startCheckpoint(Checkpoint checkpoint) {
         doCheckpoint(checkpoint);
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/stats/JournalStats.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/stats/JournalStats.java
index 2396acb1f7..d5f68e7267 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/stats/JournalStats.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/stats/JournalStats.java
@@ -43,6 +43,7 @@ import static 
org.apache.bookkeeper.bookie.BookKeeperServerStats.JOURNAL_SCOPE;
 import static org.apache.bookkeeper.bookie.BookKeeperServerStats.JOURNAL_SYNC;
 import static 
org.apache.bookkeeper.bookie.BookKeeperServerStats.JOURNAL_WRITE_BYTES;
 
+import com.google.common.annotations.VisibleForTesting;
 import java.util.function.Supplier;
 import lombok.Getter;
 import org.apache.bookkeeper.bookie.BookKeeperServerStats;
@@ -150,7 +151,7 @@ public class JournalStats {
         name = JOURNAL_NUM_FLUSH_MAX_OUTSTANDING_BYTES,
         help = "The number of journal flushes triggered by 
MAX_OUTSTANDING_BYTES"
     )
-    private final Counter flushMaxOutstandingBytesCounter;
+    private Counter flushMaxOutstandingBytesCounter;
     @StatsDoc(
         name = JOURNAL_NUM_FLUSH_EMPTY_QUEUE,
         help = "The number of journal flushes triggered when journal queue 
becomes empty"
@@ -222,4 +223,9 @@ public class JournalStats {
         statsLogger.registerGauge(JOURNAL_MEMORY_USED, journalMemoryUsedStats);
     }
 
+    @VisibleForTesting
+    public void setFlushMaxOutstandingBytesCounter(Counter 
flushMaxOutstandingBytesCounter) {
+        this.flushMaxOutstandingBytesCounter = flushMaxOutstandingBytesCounter;
+    }
+
 }
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 ed2db8a032..51f0425935 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
@@ -24,6 +24,7 @@ import static 
com.google.common.base.Preconditions.checkArgument;
 import static 
org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithMetadataBookieDriver;
 import static 
org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithRegistrationManager;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
@@ -173,6 +174,12 @@ public class BookKeeperAdmin implements AutoCloseable {
         this.mFactory = bkc.ledgerManagerFactory;
     }
 
+    @VisibleForTesting
+    public static BookKeeperAdmin newBookKeeperAdmin(ClientConfiguration conf)
+            throws IOException, InterruptedException, BKException {
+        return new BookKeeperAdmin(conf);
+    }
+
     /**
      * Constructor that takes in a BookKeeper instance . This will be useful,
      * when user already has bk instance ready.
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerHandle.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerHandle.java
index 6a98af5503..d56e10872a 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerHandle.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/LedgerHandle.java
@@ -2367,4 +2367,8 @@ public class LedgerHandle implements WriteHandle {
         executor.execute(runnable);
     }
 
+    @VisibleForTesting
+    public Queue<PendingAddOp> getPendingAddOps() {
+        return pendingAddOps;
+    }
 }
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/zk/ZKMetadataBookieDriver.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/zk/ZKMetadataBookieDriver.java
index d66ef338c6..252f4b7c1d 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/zk/ZKMetadataBookieDriver.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/zk/ZKMetadataBookieDriver.java
@@ -20,6 +20,7 @@ package org.apache.bookkeeper.meta.zk;
 
 import static org.apache.bookkeeper.bookie.BookKeeperServerStats.BOOKIE_SCOPE;
 
+import com.google.common.annotations.VisibleForTesting;
 import java.util.Optional;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.bookkeeper.conf.ServerConfiguration;
@@ -30,6 +31,7 @@ import org.apache.bookkeeper.meta.MetadataDrivers;
 import org.apache.bookkeeper.meta.exceptions.MetadataException;
 import org.apache.bookkeeper.stats.StatsLogger;
 import org.apache.bookkeeper.zookeeper.BoundExponentialBackoffRetryPolicy;
+import org.apache.zookeeper.ZooKeeper;
 
 /**
  * ZooKeeper based metadata bookie driver.
@@ -65,6 +67,12 @@ public class ZKMetadataBookieDriver
 
     @Override
     public synchronized RegistrationManager createRegistrationManager() {
+        ZKRegistrationManager zkRegistrationManager = 
newZKRegistrationManager(serverConf, zk);
+        return zkRegistrationManager;
+    }
+
+    @VisibleForTesting
+    ZKRegistrationManager newZKRegistrationManager(ServerConfiguration 
serverConf, ZooKeeper zk) {
         return new ZKRegistrationManager(serverConf, zk);
     }
 
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/zk/ZKMetadataClientDriver.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/zk/ZKMetadataClientDriver.java
index 909e37a8ad..1fe6210ce9 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/zk/ZKMetadataClientDriver.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/meta/zk/ZKMetadataClientDriver.java
@@ -18,6 +18,7 @@
  */
 package org.apache.bookkeeper.meta.zk;
 
+import com.google.common.annotations.VisibleForTesting;
 import java.util.Optional;
 import java.util.concurrent.ScheduledExecutorService;
 import lombok.extern.slf4j.Slf4j;
@@ -31,6 +32,7 @@ import org.apache.bookkeeper.stats.StatsLogger;
 import org.apache.bookkeeper.zookeeper.BoundExponentialBackoffRetryPolicy;
 import org.apache.zookeeper.Watcher.Event.EventType;
 import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooKeeper;
 
 /**
  * ZooKeeper based metadata client driver.
@@ -76,15 +78,21 @@ public class ZKMetadataClientDriver
     @Override
     public synchronized RegistrationClient getRegistrationClient() {
         if (null == regClient) {
-            regClient = new ZKRegistrationClient(
-                zk,
-                ledgersRootPath,
-                scheduler,
-                bookieAddressTracking);
+            regClient = newZKRegistrationClient(
+                    zk,
+                    ledgersRootPath,
+                    scheduler,
+                    bookieAddressTracking);
         }
         return regClient;
     }
 
+    @VisibleForTesting
+    ZKRegistrationClient newZKRegistrationClient(ZooKeeper zk, String 
ledgersRootPath,
+                                                 ScheduledExecutorService 
scheduler, boolean bookieAddressTracking) {
+        return new ZKRegistrationClient(zk, ledgersRootPath, scheduler, 
bookieAddressTracking);
+    }
+
     @Override
     public synchronized void close() {
         if (null != regClient) {
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java
index e50a09dba8..049425a2d9 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/proto/BookieServer.java
@@ -108,6 +108,17 @@ public class BookieServer {
         this.nettyServer.setRequestProcessor(this.requestProcessor);
     }
 
+    @VisibleForTesting
+    public static BookieServer newBookieServer(ServerConfiguration conf,
+                                               Bookie bookie,
+                                               StatsLogger statsLogger,
+                                               ByteBufAllocator allocator,
+                                               UncleanShutdownDetection 
uncleanShutdownDetection)
+            throws CompatibilityException, UnavailableException, 
SecurityException, IOException,
+            InterruptedException, KeeperException, BookieException {
+        return new BookieServer(conf, bookie, statsLogger, allocator, 
uncleanShutdownDetection);
+    }
+
     /**
      * Currently the uncaught exception handler is used for DeathWatcher to 
notify
      * lifecycle management that a bookie is dead for some reasons.
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/EmbeddedServer.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/EmbeddedServer.java
index 92e6462b2b..b2ac638db8 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/EmbeddedServer.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/EmbeddedServer.java
@@ -25,6 +25,8 @@ import static 
com.google.common.base.Preconditions.checkNotNull;
 import static org.apache.bookkeeper.bookie.BookKeeperServerStats.BOOKIE_SCOPE;
 import static 
org.apache.bookkeeper.bookie.BookKeeperServerStats.LD_INDEX_SCOPE;
 import static 
org.apache.bookkeeper.bookie.BookKeeperServerStats.LD_LEDGER_SCOPE;
+import static org.apache.bookkeeper.bookie.BookieImpl.newBookieImpl;
+import static 
org.apache.bookkeeper.bookie.LegacyCookieValidation.newLegacyCookieValidation;
 import static org.apache.bookkeeper.client.BookKeeperClientStats.CLIENT_SCOPE;
 import static 
org.apache.bookkeeper.replication.ReplicationStats.REPLICATION_SCOPE;
 import static org.apache.bookkeeper.server.Main.storageDirectoriesFromConf;
@@ -50,7 +52,6 @@ import org.apache.bookkeeper.bookie.BookieResources;
 import org.apache.bookkeeper.bookie.CookieValidation;
 import org.apache.bookkeeper.bookie.LedgerDirsManager;
 import org.apache.bookkeeper.bookie.LedgerStorage;
-import org.apache.bookkeeper.bookie.LegacyCookieValidation;
 import org.apache.bookkeeper.bookie.ReadOnlyBookie;
 import org.apache.bookkeeper.bookie.ScrubberStats;
 import org.apache.bookkeeper.bookie.UncleanShutdownDetection;
@@ -403,8 +404,8 @@ public class EmbeddedServer {
                         registrationManager, integCheck);
                 
cookieValidation.checkCookies(storageDirectoriesFromConf(conf.getServerConf()));
             } else {
-                CookieValidation cookieValidation =
-                        new LegacyCookieValidation(conf.getServerConf(), 
registrationManager);
+                CookieValidation cookieValidation = 
newLegacyCookieValidation(conf.getServerConf(),
+                        registrationManager);
                 
cookieValidation.checkCookies(storageDirectoriesFromConf(conf.getServerConf()));
                 // storage should be created after legacy validation or it 
will fail (it would find ledger dirs)
                 storage = 
BookieResources.createLedgerStorage(conf.getServerConf(), ledgerManager,
@@ -419,7 +420,7 @@ public class EmbeddedServer {
                         bookieStats, allocator,
                         bookieServiceInfoProvider);
             } else {
-                bookie = new BookieImpl(conf.getServerConf(), 
registrationManager, storage,
+                bookie = newBookieImpl(conf.getServerConf(), 
registrationManager, storage,
                         diskChecker,
                         ledgerDirsManager, indexDirsManager,
                         bookieStats, allocator,
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/service/BookieService.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/service/BookieService.java
index e36a62c552..7fcb60db59 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/service/BookieService.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/service/BookieService.java
@@ -18,6 +18,8 @@
 
 package org.apache.bookkeeper.server.service;
 
+import static org.apache.bookkeeper.proto.BookieServer.newBookieServer;
+
 import java.io.IOException;
 import java.lang.Thread.UncaughtExceptionHandler;
 import java.net.UnknownHostException;
@@ -54,7 +56,7 @@ public class BookieService extends ServerLifecycleComponent {
                          UncleanShutdownDetection uncleanShutdownDetection)
             throws Exception {
         super(NAME, conf, statsLogger);
-        this.server = new BookieServer(conf.getServerConf(),
+        this.server = newBookieServer(conf.getServerConf(),
                                        bookie,
                                        statsLogger,
                                        allocator,
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/LastMarkCommand.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/LastMarkCommand.java
index 5fab517a5d..46fae40ae2 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/LastMarkCommand.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookie/LastMarkCommand.java
@@ -18,6 +18,7 @@
  */
 package org.apache.bookkeeper.tools.cli.commands.bookie;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.util.concurrent.UncheckedExecutionException;
 import java.io.File;
 import java.io.IOException;
@@ -49,6 +50,11 @@ public class LastMarkCommand extends BookieCommand<CliFlags> 
{
             .build());
     }
 
+    @VisibleForTesting
+    public static LastMarkCommand newLastMarkCommand(){
+        return new LastMarkCommand();
+    }
+
     @Override
     public boolean apply(ServerConfiguration conf, CliFlags flags) {
         try {
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/ClusterInfoCommand.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/ClusterInfoCommand.java
index e18daea933..4ff9c5932e 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/ClusterInfoCommand.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/ClusterInfoCommand.java
@@ -56,6 +56,11 @@ public class ClusterInfoCommand extends 
BookieCommand<CliFlags> {
                 .build());
     }
 
+    @VisibleForTesting
+    public static ClusterInfoCommand newClusterInfoCommand() {
+        return new ClusterInfoCommand();
+    }
+
     /**
      * POJO definition for the cluster info response.
      */
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/ListBookiesCommand.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/ListBookiesCommand.java
index 84b02874ba..dcbfd9c2e5 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/ListBookiesCommand.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/ListBookiesCommand.java
@@ -22,6 +22,7 @@ import static 
org.apache.bookkeeper.common.concurrent.FutureUtils.result;
 import static 
org.apache.bookkeeper.tools.cli.helpers.CommandHelpers.getBookieSocketAddrStringRepresentation;
 
 import com.beust.jcommander.Parameter;
+import com.google.common.annotations.VisibleForTesting;
 import java.util.Collection;
 import java.util.Set;
 import lombok.Setter;
@@ -48,7 +49,7 @@ public class ListBookiesCommand extends 
DiscoveryCommand<Flags> {
     private static final Logger LOG = 
LoggerFactory.getLogger(ListBookiesCommand.class);
 
     public ListBookiesCommand() {
-        this(new Flags());
+        this(Flags.newFlags());
     }
 
     public ListBookiesCommand(Flags flags) {
@@ -59,6 +60,11 @@ public class ListBookiesCommand extends 
DiscoveryCommand<Flags> {
             .build());
     }
 
+    @VisibleForTesting
+    public static ListBookiesCommand newListBookiesCommand(Flags flags) {
+        return new ListBookiesCommand(flags);
+    }
+
     /**
      * Flags for list bookies command.
      */
@@ -73,6 +79,11 @@ public class ListBookiesCommand extends 
DiscoveryCommand<Flags> {
         @Parameter(names = { "-a", "--all" }, description = "Print all 
bookies")
         private boolean all = false;
 
+        @VisibleForTesting
+        public static Flags newFlags(){
+            return new Flags();
+        }
+
     }
 
     @Override
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/RecoverCommand.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/RecoverCommand.java
index 3a0ed6dc27..401d6a2063 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/RecoverCommand.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/tools/cli/commands/bookies/RecoverCommand.java
@@ -18,6 +18,7 @@
  */
 package org.apache.bookkeeper.tools.cli.commands.bookies;
 
+import static org.apache.bookkeeper.client.BookKeeperAdmin.newBookKeeperAdmin;
 import static 
org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithRegistrationManager;
 
 import com.beust.jcommander.Parameter;
@@ -152,7 +153,7 @@ public class RecoverCommand extends 
BookieCommand<RecoverCommand.RecoverFlags> {
         LOG.info("Constructing admin");
         conf.setReplicationRateByBytes(replicateRate);
         ClientConfiguration adminConf = new ClientConfiguration(conf);
-        BookKeeperAdmin admin = new BookKeeperAdmin(adminConf);
+        BookKeeperAdmin admin = newBookKeeperAdmin(adminConf);
         LOG.info("Construct admin : {}", admin);
         try {
             if (query) {
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 7b43006a19..3007c3b7d7 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 com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableMap;
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.nio.charset.StandardCharsets;
@@ -67,9 +68,14 @@ public class SimpleTestCommand extends ClientCommand<Flags> {
         @Parameter(names = { "-n", "--num-entries" }, description = "Entries 
to write (default 100)")
         private int numEntries = 100;
 
+        @VisibleForTesting
+        public static Flags newFlags(){
+            return new Flags();
+        }
+
     }
     public SimpleTestCommand() {
-        this(new Flags());
+        this(Flags.newFlags());
     }
 
     public SimpleTestCommand(Flags flags) {
@@ -80,6 +86,11 @@ public class SimpleTestCommand extends ClientCommand<Flags> {
             .build());
     }
 
+    @VisibleForTesting
+    public static SimpleTestCommand newSimpleTestCommand(Flags flags) {
+        return new SimpleTestCommand(flags);
+    }
+
     @Override
     @SuppressFBWarnings({"RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE", 
"DMI_RANDOM_USED_ONLY_ONCE"})
     protected void run(BookKeeper bk, Flags flags) throws Exception {
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalForceTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalForceTest.java
index 99845bd2d6..dee9502bda 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalForceTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalForceTest.java
@@ -23,14 +23,16 @@ package org.apache.bookkeeper.bookie;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.powermock.api.mockito.PowerMockito.whenNew;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -53,18 +55,13 @@ import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 import org.mockito.invocation.InvocationOnMock;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.reflect.Whitebox;
 
 /**
  * Test the bookie journal.
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", "javax.xml.*", 
"com.sun.org.apache.xerces.*"})
-@PrepareForTest({JournalChannel.class, Journal.class, 
DefaultFileChannel.class})
+@RunWith(MockitoJUnitRunner.class)
 @Slf4j
 public class BookieJournalForceTest {
 
@@ -83,17 +80,17 @@ public class BookieJournalForceTest {
             .setMetadataServiceUri(null)
             .setJournalAdaptiveGroupWrites(false);
 
-        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
-        whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
-
         LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
         Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
-
         // machinery to suspend ForceWriteThread
         CountDownLatch forceWriteThreadSuspendedLatch = new CountDownLatch(1);
         BatchedArrayBlockingQueue<ForceWriteRequest> supportQueue =
                 
enableForceWriteThreadSuspension(forceWriteThreadSuspendedLatch, journal);
 
+        journal = spy(journal);
+        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
+        doReturn(jc).when(journal).newLogFile(anyLong(), nullable(Long.class));
+
         journal.start();
 
         LogMark lastLogMarkBeforeWrite = 
journal.getLastLogMark().markLog().getCurMark();
@@ -146,15 +143,17 @@ public class BookieJournalForceTest {
             .setMetadataServiceUri(null)
             .setJournalAdaptiveGroupWrites(false);
 
-        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
-        whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
-
         LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
         Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
-
         // machinery to suspend ForceWriteThread
         CountDownLatch forceWriteThreadSuspendedLatch = new CountDownLatch(1);
-        enableForceWriteThreadSuspension(forceWriteThreadSuspendedLatch, 
journal);
+        BatchedArrayBlockingQueue<ForceWriteRequest> supportQueue =
+                
enableForceWriteThreadSuspension(forceWriteThreadSuspendedLatch, journal);
+
+        journal = spy(journal);
+        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
+        doReturn(jc).when(journal).newLogFile(anyLong(), nullable(Long.class));
+
         journal.start();
 
         LogMark lastLogMarkBeforeWrite = 
journal.getLastLogMark().markLog().getCurMark();
@@ -202,21 +201,21 @@ public class BookieJournalForceTest {
             .setMetadataServiceUri(null)
             .setJournalAdaptiveGroupWrites(false);
 
-        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
-        whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
-
         LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
         Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
-
         // machinery to suspend ForceWriteThread
         CountDownLatch forceWriteThreadSuspendedLatch = new CountDownLatch(1);
         enableForceWriteThreadSuspension(forceWriteThreadSuspendedLatch, 
journal);
 
+        journal = spy(journal);
+        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
+        doReturn(jc).when(journal).newLogFile(anyLong(), nullable(Long.class));
+
         JournalStats journalStats = journal.getJournalStats();
         TestStatsProvider testStatsProvider = new TestStatsProvider();
         Counter flushMaxOutstandingBytesCounter = 
testStatsProvider.getStatsLogger("test")
                                                         
.getCounter("flushMaxOutstandingBytesCounter");
-        Whitebox.setInternalState(journalStats, 
"flushMaxOutstandingBytesCounter", flushMaxOutstandingBytesCounter);
+        
journalStats.setFlushMaxOutstandingBytesCounter(flushMaxOutstandingBytesCounter);
 
         journal.start();
 
@@ -263,10 +262,11 @@ public class BookieJournalForceTest {
             .setMetadataServiceUri(null);
 
         JournalChannel jc = spy(new JournalChannel(journalDir, 1));
-        whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
 
         LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
-        Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
+        Journal journal = spy(new Journal(0, journalDir, conf, 
ledgerDirsManager));
+        doReturn(jc).when(journal).newLogFile(anyLong(), nullable(Long.class));
+
         journal.start();
 
         final int numEntries = 100;
@@ -316,7 +316,7 @@ public class BookieJournalForceTest {
             ForceWriteRequest[] array = iom.getArgument(0);
             return supportQueue.takeAll(array);
         }).when(forceWriteRequests).takeAll(any());
-        Whitebox.setInternalState(journal, "forceWriteRequests", 
forceWriteRequests);
+        journal.setForceWriteRequests(forceWriteRequests);
         return supportQueue;
     }
 
@@ -329,16 +329,17 @@ public class BookieJournalForceTest {
         conf.setJournalDirName(journalDir.getPath());
         conf.setJournalAdaptiveGroupWrites(false);
 
-        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
-        whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
-
         LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
         Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
-
         // machinery to suspend ForceWriteThread
         CountDownLatch forceWriteThreadSuspendedLatch = new CountDownLatch(1);
         BatchedArrayBlockingQueue<ForceWriteRequest> supportQueue =
                 
enableForceWriteThreadSuspension(forceWriteThreadSuspendedLatch, journal);
+
+        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
+        journal = spy(journal);
+        doReturn(jc).when(journal).newLogFile(anyLong(), nullable(Long.class));
+
         journal.start();
 
         LogMark lastLogMarkBeforeWrite = 
journal.getLastLogMark().markLog().getCurMark();
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalMaxMemoryTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalMaxMemoryTest.java
index cd9aac2b8b..9a288b6b8b 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalMaxMemoryTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalMaxMemoryTest.java
@@ -20,11 +20,13 @@
  */
 package org.apache.bookkeeper.bookie;
 
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.powermock.api.mockito.PowerMockito.whenNew;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -38,17 +40,12 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.reflect.Whitebox;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Test the bookie journal max memory controller.
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", 
"com.sun.org.apache.xerces.*"})
-@PrepareForTest({JournalChannel.class, Journal.class})
+@RunWith(MockitoJUnitRunner.class)
 @Slf4j
 public class BookieJournalMaxMemoryTest {
 
@@ -67,13 +64,11 @@ public class BookieJournalMaxMemoryTest {
                 .setJournalMaxMemorySizeMb(1);
 
         JournalChannel jc = spy(new JournalChannel(journalDir, 1));
-        whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
-
         LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
         Journal journal = spy(new Journal(0, journalDir, conf, 
ledgerDirsManager));
-        Whitebox.setInternalState(journal, "memoryLimitController",
-                spy(new MemoryLimitController(1)));
-        MemoryLimitController mlc = Whitebox.getInternalState(journal, 
"memoryLimitController");
+        doReturn(jc).when(journal).newLogFile(anyLong(), nullable(Long.class));
+        MemoryLimitController mlc = spy(new MemoryLimitController(1));
+        journal.setMemoryLimitController(mlc);
 
         journal.start();
 
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalPageCacheFlushTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalPageCacheFlushTest.java
index 7b169561f7..3683e948e1 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalPageCacheFlushTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalPageCacheFlushTest.java
@@ -23,12 +23,14 @@ package org.apache.bookkeeper.bookie;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.powermock.api.mockito.PowerMockito.whenNew;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -48,18 +50,13 @@ import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 import org.mockito.invocation.InvocationOnMock;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.reflect.Whitebox;
 
 /**
  * Test the bookie journal PageCache flush interval.
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", 
"com.sun.org.apache.xerces.*"})
-@PrepareForTest({JournalChannel.class, Journal.class})
+@RunWith(MockitoJUnitRunner.class)
 @Slf4j
 public class BookieJournalPageCacheFlushTest {
 
@@ -83,7 +80,7 @@ public class BookieJournalPageCacheFlushTest {
             ForceWriteRequest[] array = iom.getArgument(0);
             return supportQueue.takeAll(array);
         }).when(forceWriteRequests).takeAll(any());
-        Whitebox.setInternalState(journal, "forceWriteRequests", 
forceWriteRequests);
+        journal.setForceWriteRequests(forceWriteRequests);
         return supportQueue;
     }
 
@@ -99,15 +96,16 @@ public class BookieJournalPageCacheFlushTest {
                 .setJournalSyncData(true)
                 .setJournalPageCacheFlushIntervalMSec(5000);
 
-        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
-        whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
-
         LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
         Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
-
         CountDownLatch forceWriteThreadSuspendedLatch = new CountDownLatch(1);
         BatchedArrayBlockingQueue<ForceWriteRequest> supportQueue =
                 
enableForceWriteThreadSuspension(forceWriteThreadSuspendedLatch, journal);
+
+        journal = spy(journal);
+        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
+        doReturn(jc).when(journal).newLogFile(anyLong(), nullable(Long.class));
+
         journal.start();
 
         LogMark lastLogMarkBeforeWrite = 
journal.getLastLogMark().markLog().getCurMark();
@@ -166,15 +164,17 @@ public class BookieJournalPageCacheFlushTest {
                 .setJournalSyncData(true)
                 .setJournalPageCacheFlushIntervalMSec(5000);
 
-        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
-        whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
-
         LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
         Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
 
         CountDownLatch forceWriteThreadSuspendedLatch = new CountDownLatch(1);
         BatchedArrayBlockingQueue<ForceWriteRequest> supportQueue =
                 
enableForceWriteThreadSuspension(forceWriteThreadSuspendedLatch, journal);
+
+        journal = spy(journal);
+        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
+        doReturn(jc).when(journal).newLogFile(anyLong(), nullable(Long.class));
+
         journal.start();
 
         LogMark lastLogMarkBeforeWrite = 
journal.getLastLogMark().markLog().getCurMark();
@@ -229,15 +229,17 @@ public class BookieJournalPageCacheFlushTest {
                 .setJournalSyncData(false)
                 .setJournalPageCacheFlushIntervalMSec(5000);
 
-        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
-        whenNew(JournalChannel.class).withAnyArguments().thenReturn(jc);
-
         LedgerDirsManager ledgerDirsManager = mock(LedgerDirsManager.class);
         Journal journal = new Journal(0, journalDir, conf, ledgerDirsManager);
 
         CountDownLatch forceWriteThreadSuspendedLatch = new CountDownLatch(1);
         BatchedArrayBlockingQueue<ForceWriteRequest> supportQueue =
                 
enableForceWriteThreadSuspension(forceWriteThreadSuspendedLatch, journal);
+
+        journal = spy(journal);
+        JournalChannel jc = spy(new JournalChannel(journalDir, 1));
+        doReturn(jc).when(journal).newLogFile(anyLong(), nullable(Long.class));
+
         journal.start();
 
         CountDownLatch latch = new CountDownLatch(2);
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalTest.java
index a048bffc8a..21608a19b2 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieJournalTest.java
@@ -24,6 +24,10 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -37,6 +41,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Random;
+import lombok.Cleanup;
 import org.apache.bookkeeper.bookie.Journal.LastLogMark;
 import org.apache.bookkeeper.client.ClientUtil;
 import org.apache.bookkeeper.client.LedgerHandle;
@@ -47,21 +52,15 @@ import org.apache.commons.io.FileUtils;
 import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Test the bookie journal.
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({JournalChannel.class, FileChannelProvider.class})
-@PowerMockIgnore({"jdk.internal.loader.*", "javax.xml.*", "org.xml.*", 
"org.w3c.*",
-    "com.sun.org.apache.xerces.*", "javax.naming.*"})
+@RunWith(MockitoJUnitRunner.class)
 public class BookieJournalTest {
     private static final Logger LOG = 
LoggerFactory.getLogger(BookieJournalTest.class);
 
@@ -870,17 +869,14 @@ public class BookieJournalTest {
                 .setMetadataServiceUri(null);
 
         Journal.JournalScanner journalScanner = new DummyJournalScan();
-        BookieFileChannel bookieFileChannel = 
PowerMockito.mock(BookieFileChannel.class);
-        FileChannel fileChannel = PowerMockito.mock(FileChannel.class);
-        FileChannelProvider fileChannelProvider = 
PowerMockito.mock(FileChannelProvider.class);
-
-        PowerMockito.when(fileChannel.position(Mockito.anyLong()))
-                .thenThrow(new IOException());
-
-        PowerMockito.mockStatic(FileChannelProvider.class);
-        
PowerMockito.when(FileChannelProvider.newProvider(Mockito.any())).thenReturn(fileChannelProvider);
-        Mockito.when(fileChannelProvider.open(Mockito.any(), 
Mockito.any())).thenReturn(bookieFileChannel);
-        
Mockito.when(bookieFileChannel.getFileChannel()).thenReturn(fileChannel);
+        BookieFileChannel bookieFileChannel = mock(BookieFileChannel.class);
+        FileChannelProvider fileChannelProvider = 
mock(FileChannelProvider.class);
+
+        @Cleanup
+        MockedStatic<FileChannelProvider> fileChannelProviderMockedStatic = 
mockStatic(FileChannelProvider.class);
+        fileChannelProviderMockedStatic.when(() -> 
FileChannelProvider.newProvider(any()))
+                .thenReturn(fileChannelProvider);
+        doReturn(bookieFileChannel).when(fileChannelProvider).open(any(), 
any());
 
         BookieImpl b = new TestBookieImpl(conf);
 
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieShellTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieShellTest.java
index b40b9a4b6d..fce3ce8bb3 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieShellTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieShellTest.java
@@ -27,18 +27,18 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.powermock.api.mockito.PowerMockito.spy;
-import static org.powermock.api.mockito.PowerMockito.verifyNew;
-import static org.powermock.api.mockito.PowerMockito.whenNew;
 
 import com.google.common.collect.Maps;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.function.Function;
+import lombok.Cleanup;
 import org.apache.bookkeeper.bookie.BookieShell.MyCommand;
 import org.apache.bookkeeper.bookie.BookieShell.RecoverCmd;
 import org.apache.bookkeeper.client.BookKeeperAdmin;
@@ -46,14 +46,13 @@ import org.apache.bookkeeper.client.api.LedgerMetadata;
 import org.apache.bookkeeper.conf.ClientConfiguration;
 import org.apache.bookkeeper.conf.ServerConfiguration;
 import org.apache.bookkeeper.discover.RegistrationManager;
-import org.apache.bookkeeper.meta.MetadataBookieDriver;
 import org.apache.bookkeeper.meta.MetadataDrivers;
 import org.apache.bookkeeper.net.BookieId;
 import org.apache.bookkeeper.tools.cli.commands.bookie.LastMarkCommand;
 import org.apache.bookkeeper.tools.cli.commands.bookies.ClusterInfoCommand;
 import org.apache.bookkeeper.tools.cli.commands.bookies.ListBookiesCommand;
-import org.apache.bookkeeper.tools.cli.commands.bookies.RecoverCommand;
 import org.apache.bookkeeper.tools.cli.commands.client.SimpleTestCommand;
+import org.apache.bookkeeper.tools.cli.commands.client.SimpleTestCommand.Flags;
 import org.apache.bookkeeper.tools.framework.CliFlags;
 import org.apache.bookkeeper.util.EntryFormatter;
 import org.apache.bookkeeper.util.LedgerIdFormatter;
@@ -64,90 +63,58 @@ import org.apache.commons.cli.BasicParser;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.MissingArgumentException;
 import org.apache.commons.cli.ParseException;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Unit test for {@link BookieShell}.
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", 
"org.w3c.*"})
-@PrepareForTest({ BookieShell.class, MetadataDrivers.class, 
RecoverCommand.class })
+@RunWith(MockitoJUnitRunner.class)
 public class BookieShellTest {
 
     private ClientConfiguration clientConf;
     private BookieShell shell;
     private BookKeeperAdmin admin;
     private RegistrationManager rm;
-    private MetadataBookieDriver driver;
     private Cookie cookie;
     private Version version;
 
-    // commands
-    private LastMarkCommand mockLastMarkCommand;
-    private SimpleTestCommand.Flags mockSimpleTestFlags;
-    private SimpleTestCommand mockSimpleTestCommand;
     private ListBookiesCommand.Flags mockListBookiesFlags;
     private ListBookiesCommand mockListBookiesCommand;
-    private ClusterInfoCommand mockClusterInfoCommand;
+    private MockedStatic<ListBookiesCommand> listBookiesCommandMockedStatic;
+    private MockedStatic<MetadataDrivers> metadataDriversMockedStatic;
+    private MockedStatic<BookKeeperAdmin> bookKeeperAdminMockedStatic;
+    private MockedStatic<ListBookiesCommand.Flags> 
listBookiesCommandflagsMockedStatic;
 
     @Before
     public void setup() throws Exception {
-        // setup the required mocks before constructing bookie shell.
-        this.mockLastMarkCommand = mock(LastMarkCommand.class);
-        whenNew(LastMarkCommand.class)
-            .withNoArguments()
-            .thenReturn(mockLastMarkCommand);
-
-        // setup the mocks for simple test command
-        this.mockSimpleTestFlags = spy(new SimpleTestCommand.Flags());
-        whenNew(SimpleTestCommand.Flags.class)
-            .withNoArguments()
-            .thenReturn(mockSimpleTestFlags);
-
-        this.mockSimpleTestCommand = spy(new SimpleTestCommand());
-        doReturn(true).when(mockSimpleTestCommand)
-            .apply(any(ServerConfiguration.class), 
any(SimpleTestCommand.Flags.class));
-        whenNew(SimpleTestCommand.class)
-            .withParameterTypes(SimpleTestCommand.Flags.class)
-            .withArguments(mockSimpleTestFlags)
-            .thenReturn(mockSimpleTestCommand);
+        this.shell = new 
BookieShell(LedgerIdFormatter.LONG_LEDGERID_FORMATTER, 
EntryFormatter.STRING_FORMATTER);
 
-        // setup the mocks for list bookies command
         this.mockListBookiesFlags = spy(new ListBookiesCommand.Flags());
-        whenNew(ListBookiesCommand.Flags.class)
-            .withNoArguments()
-            .thenReturn(mockListBookiesFlags);
-
+        this.listBookiesCommandflagsMockedStatic = 
mockStatic(ListBookiesCommand.Flags.class);
+        listBookiesCommandflagsMockedStatic.when(() -> 
ListBookiesCommand.Flags.newFlags())
+                .thenReturn(mockListBookiesFlags);
         this.mockListBookiesCommand = spy(new ListBookiesCommand());
         doReturn(true).when(mockListBookiesCommand)
-            .apply(any(ServerConfiguration.class), 
any(ListBookiesCommand.Flags.class));
-        whenNew(ListBookiesCommand.class)
-            .withParameterTypes(ListBookiesCommand.Flags.class)
-            .withArguments(mockListBookiesFlags)
-            .thenReturn(mockListBookiesCommand);
-
-        this.mockClusterInfoCommand = spy(new ClusterInfoCommand());
-        whenNew(ClusterInfoCommand.class)
-                .withNoArguments()
-                .thenReturn(mockClusterInfoCommand);
+                .apply(any(ServerConfiguration.class), 
any(ListBookiesCommand.Flags.class));
+        listBookiesCommandMockedStatic = mockStatic(ListBookiesCommand.class);
+        listBookiesCommandMockedStatic.when(() -> 
ListBookiesCommand.newListBookiesCommand(mockListBookiesFlags))
+                .thenReturn(mockListBookiesCommand);
 
         // construct the bookie shell.
-        this.shell = new 
BookieShell(LedgerIdFormatter.LONG_LEDGERID_FORMATTER, 
EntryFormatter.STRING_FORMATTER);
-        this.admin = PowerMockito.mock(BookKeeperAdmin.class);
-        whenNew(BookKeeperAdmin.class)
-            .withParameterTypes(ClientConfiguration.class)
-            .withArguments(any(ClientConfiguration.class))
-            .thenReturn(admin);
+        this.admin = mock(BookKeeperAdmin.class);
+
+        bookKeeperAdminMockedStatic = mockStatic(BookKeeperAdmin.class);
+        bookKeeperAdminMockedStatic.when(() -> 
BookKeeperAdmin.newBookKeeperAdmin(any(ClientConfiguration.class)))
+                .thenReturn(admin);
         this.clientConf = new ClientConfiguration();
         
this.clientConf.setMetadataServiceUri("zk://127.0.0.1/path/to/ledgers");
         when(admin.getConf()).thenReturn(this.clientConf);
-        this.rm = PowerMockito.mock(RegistrationManager.class);
+        this.rm = mock(RegistrationManager.class);
         this.cookie = Cookie.newBuilder()
             .setBookieId("127.0.0.1:3181")
             .setInstanceId("xyz")
@@ -159,21 +126,23 @@ public class BookieShellTest {
         when(rm.readCookie(any(BookieId.class)))
             .thenReturn(new Versioned<>(cookie.toString().getBytes(UTF_8), 
version));
 
-        this.driver = mock(MetadataBookieDriver.class);
-        when(driver.createRegistrationManager())
-            .thenReturn(rm);
-
-        PowerMockito.mockStatic(MetadataDrivers.class);
-        PowerMockito.doAnswer(invocationOnMock -> {
-            Function<RegistrationManager, Object> function = 
invocationOnMock.getArgument(1);
-            function.apply(rm);
-            return null;
-        }).when(
-            MetadataDrivers.class,
-            "runFunctionWithRegistrationManager",
-            any(ServerConfiguration.class),
-            any(Function.class)
-        );
+        metadataDriversMockedStatic = mockStatic(MetadataDrivers.class);
+        metadataDriversMockedStatic
+                .when(() -> MetadataDrivers.runFunctionWithRegistrationManager(
+                        any(ServerConfiguration.class), any(Function.class)))
+                .thenAnswer(invocationOnMock -> {
+                    Function<RegistrationManager, Object> function = 
invocationOnMock.getArgument(1);
+                    function.apply(rm);
+                    return null;
+                });
+    }
+
+    @After
+    public void teardown() throws Exception {
+        listBookiesCommandMockedStatic.close();
+        listBookiesCommandflagsMockedStatic.close();
+        metadataDriversMockedStatic.close();
+        bookKeeperAdminMockedStatic.close();
     }
 
     private static CommandLine parseCommandLine(MyCommand cmd, String... args) 
throws ParseException {
@@ -191,7 +160,8 @@ public class BookieShellTest {
         } catch (MissingArgumentException e) {
             // expected
         }
-        PowerMockito.verifyNew(BookKeeperAdmin.class, 
never()).withArguments(any(ClientConfiguration.class));
+        bookKeeperAdminMockedStatic.verify(() -> 
BookKeeperAdmin.newBookKeeperAdmin(any(ClientConfiguration.class)),
+                never());
     }
 
     @Test
@@ -199,7 +169,8 @@ public class BookieShellTest {
         RecoverCmd cmd = (RecoverCmd) shell.commands.get("recover");
         CommandLine cmdLine = parseCommandLine(cmd, "non.valid$$bookie.id");
         assertEquals(-1, cmd.runCmd(cmdLine));
-        PowerMockito.verifyNew(BookKeeperAdmin.class, 
never()).withArguments(any(ClientConfiguration.class));
+        bookKeeperAdminMockedStatic.verify(() -> 
BookKeeperAdmin.newBookKeeperAdmin(any(ClientConfiguration.class)),
+                never());
     }
 
     @SuppressWarnings("unchecked")
@@ -212,9 +183,8 @@ public class BookieShellTest {
         RecoverCmd cmd = (RecoverCmd) shell.commands.get("recover");
         CommandLine cmdLine = parseCommandLine(cmd, "-force", "-q", 
"127.0.0.1:3181");
         assertEquals(0, cmd.runCmd(cmdLine));
-        PowerMockito
-            .verifyNew(BookKeeperAdmin.class, times(1))
-            .withArguments(any(ClientConfiguration.class));
+        bookKeeperAdminMockedStatic.verify(() -> 
BookKeeperAdmin.newBookKeeperAdmin(any(ClientConfiguration.class)),
+                times(1));
         verify(admin, times(1)).getLedgersContainBookies(any(Set.class));
         verify(admin, times(1)).close();
     }
@@ -268,14 +238,12 @@ public class BookieShellTest {
         RecoverCmd cmd = (RecoverCmd) shell.commands.get("recover");
         CommandLine cmdLine = parseCommandLine(cmd, args);
         assertEquals(0, cmd.runCmd(cmdLine));
-        PowerMockito
-            .verifyNew(BookKeeperAdmin.class, times(1))
-            .withArguments(any(ClientConfiguration.class));
+        bookKeeperAdminMockedStatic.verify(() -> 
BookKeeperAdmin.newBookKeeperAdmin(any(ClientConfiguration.class)),
+                times(1));
         verify(admin, times(1))
             .recoverBookieData(eq(ledgerId), any(Set.class), eq(dryrun), 
eq(skipOpenLedgers));
         verify(admin, times(1)).close();
         if (removeCookies) {
-            PowerMockito.verifyStatic(MetadataDrivers.class);
             
MetadataDrivers.runFunctionWithRegistrationManager(any(ServerConfiguration.class),
 any(Function.class));
             verify(rm, times(1)).readCookie(any(BookieId.class));
             verify(rm, times(1)).removeCookie(any(BookieId.class), 
eq(version));
@@ -342,14 +310,12 @@ public class BookieShellTest {
         RecoverCmd cmd = (RecoverCmd) shell.commands.get("recover");
         CommandLine cmdLine = parseCommandLine(cmd, args);
         assertEquals(0, cmd.runCmd(cmdLine));
-        PowerMockito
-            .verifyNew(BookKeeperAdmin.class, times(1))
-            .withArguments(any(ClientConfiguration.class));
+        bookKeeperAdminMockedStatic.verify(() -> 
BookKeeperAdmin.newBookKeeperAdmin(any(ClientConfiguration.class)),
+                times(1));
         verify(admin, times(1))
             .recoverBookieData(any(Set.class), eq(dryrun), 
eq(skipOpenLedgers), eq(skipUnrecoverableLedgers));
         verify(admin, times(1)).close();
         if (removeCookies) {
-            PowerMockito.verifyStatic(MetadataDrivers.class);
             
MetadataDrivers.runFunctionWithRegistrationManager(any(ServerConfiguration.class),
 any(Function.class));
             verify(rm, times(1)).readCookie(any(BookieId.class));
             verify(rm, times(1)).removeCookie(any(BookieId.class), 
eq(version));
@@ -361,14 +327,35 @@ public class BookieShellTest {
 
     @Test
     public void testLastMarkCmd() throws Exception {
+        LastMarkCommand mockLastMarkCommand = mock(LastMarkCommand.class);
+
+        @Cleanup
+        MockedStatic<LastMarkCommand> lastMarkCommandMockedStatic = 
mockStatic(LastMarkCommand.class);
+        lastMarkCommandMockedStatic.when(() -> 
LastMarkCommand.newLastMarkCommand()).thenReturn(mockLastMarkCommand);
+
         shell.run(new String[] { "lastmark"});
-        verifyNew(LastMarkCommand.class, times(1)).withNoArguments();
+        lastMarkCommandMockedStatic.verify(() -> 
LastMarkCommand.newLastMarkCommand(), times(1));
         verify(mockLastMarkCommand, times(1))
             .apply(same(shell.bkConf), any(CliFlags.class));
     }
 
     @Test
     public void testSimpleTestCmd() throws Exception {
+        SimpleTestCommand.Flags mockSimpleTestFlags = spy(new 
SimpleTestCommand.Flags());
+
+        @Cleanup
+        MockedStatic<Flags> flagsMockedStatic = mockStatic(Flags.class);
+        flagsMockedStatic.when(() -> 
Flags.newFlags()).thenReturn(mockSimpleTestFlags);
+
+        SimpleTestCommand mockSimpleTestCommand = spy(new SimpleTestCommand());
+        doReturn(true).when(mockSimpleTestCommand)
+                .apply(any(ServerConfiguration.class), 
any(SimpleTestCommand.Flags.class));
+
+        @Cleanup
+        MockedStatic<SimpleTestCommand> simpleTestCommandMockedStatic = 
mockStatic(SimpleTestCommand.class);
+        simpleTestCommandMockedStatic.when(() -> 
SimpleTestCommand.newSimpleTestCommand(mockSimpleTestFlags))
+                .thenReturn(mockSimpleTestCommand);
+
         shell.run(new String[] {
             "simpletest",
             "-e", "10",
@@ -376,8 +363,8 @@ public class BookieShellTest {
             "-a", "3",
             "-n", "200"
         });
-        verifyNew(SimpleTestCommand.class, times(1))
-            .withArguments(same(mockSimpleTestFlags));
+        simpleTestCommandMockedStatic.verify(() -> 
SimpleTestCommand.newSimpleTestCommand(mockSimpleTestFlags),
+                times(1));
         verify(mockSimpleTestCommand, times(1))
             .apply(same(shell.bkConf), same(mockSimpleTestFlags));
         verify(mockSimpleTestFlags, times(1)).ensembleSize(eq(10));
@@ -391,7 +378,9 @@ public class BookieShellTest {
         assertEquals(1, shell.run(new String[] {
             "listbookies"
         }));
-        verifyNew(ListBookiesCommand.class, times(0)).withNoArguments();
+
+        listBookiesCommandMockedStatic.verify(() -> 
ListBookiesCommand.newListBookiesCommand(mockListBookiesFlags)
+                , times(0));
     }
 
     @Test
@@ -399,7 +388,8 @@ public class BookieShellTest {
         assertEquals(1, shell.run(new String[] {
             "listbookies", "-rw", "-ro"
         }));
-        verifyNew(ListBookiesCommand.class, times(0)).withNoArguments();
+        listBookiesCommandMockedStatic.verify(() -> 
ListBookiesCommand.newListBookiesCommand(mockListBookiesFlags),
+                times(0));
     }
 
     @Test
@@ -407,8 +397,9 @@ public class BookieShellTest {
         assertEquals(0, shell.run(new String[] {
             "listbookies", "-ro"
         }));
-        verifyNew(ListBookiesCommand.class, times(1))
-            .withArguments(same(mockListBookiesFlags));
+
+        listBookiesCommandMockedStatic.verify(() -> 
ListBookiesCommand.newListBookiesCommand(mockListBookiesFlags),
+                times(1));
         verify(mockListBookiesCommand, times(1))
             .apply(same(shell.bkConf), same(mockListBookiesFlags));
         verify(mockListBookiesFlags, times(1)).readonly(true);
@@ -421,8 +412,8 @@ public class BookieShellTest {
         assertEquals(0, shell.run(new String[] {
             "listbookies", "-rw"
         }));
-        verifyNew(ListBookiesCommand.class, times(1))
-            .withArguments(same(mockListBookiesFlags));
+        listBookiesCommandMockedStatic.verify(() -> 
ListBookiesCommand.newListBookiesCommand(mockListBookiesFlags),
+                times(1));
         verify(mockListBookiesCommand, times(1))
             .apply(same(shell.bkConf), same(mockListBookiesFlags));
         verify(mockListBookiesFlags, times(1)).readonly(false);
@@ -435,8 +426,8 @@ public class BookieShellTest {
         assertEquals(0, shell.run(new String[] {
             "listbookies", "-a"
         }));
-        verifyNew(ListBookiesCommand.class, times(1))
-            .withArguments(same(mockListBookiesFlags));
+        listBookiesCommandMockedStatic.verify(() -> 
ListBookiesCommand.newListBookiesCommand(mockListBookiesFlags),
+                times(1));
         verify(mockListBookiesCommand, times(1))
             .apply(same(shell.bkConf), same(mockListBookiesFlags));
         verify(mockListBookiesFlags, times(1)).readonly(false);
@@ -467,9 +458,17 @@ public class BookieShellTest {
 
     @Test
     public void testClusterInfoCmd() throws Exception {
+        ClusterInfoCommand mockClusterInfoCommand = spy(new 
ClusterInfoCommand());
+
+        @Cleanup
+        MockedStatic<ClusterInfoCommand> clusterInfoCommandMockedStatic = 
mockStatic(ClusterInfoCommand.class);
+        clusterInfoCommandMockedStatic.when(() -> 
ClusterInfoCommand.newClusterInfoCommand())
+                .thenReturn(mockClusterInfoCommand);
+
         doReturn(true).when(mockClusterInfoCommand).apply(same(shell.bkConf), 
any(CliFlags.class));
         shell.run(new String[]{ "clusterinfo" });
-        verifyNew(ClusterInfoCommand.class, times(1)).withNoArguments();
+        clusterInfoCommandMockedStatic.verify(() -> 
ClusterInfoCommand.newClusterInfoCommand(),
+                times(1));
     }
 
 }
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieWriteToJournalTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieWriteToJournalTest.java
index 05c231dbaa..0907a62528 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieWriteToJournalTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/BookieWriteToJournalTest.java
@@ -26,9 +26,10 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertSame;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
-import static org.powermock.api.mockito.PowerMockito.whenNew;
+import static org.mockito.Mockito.mockStatic;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -37,6 +38,7 @@ import java.io.IOException;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import lombok.Cleanup;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.bookkeeper.client.api.BKException;
 import org.apache.bookkeeper.conf.ServerConfiguration;
@@ -49,19 +51,15 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
+import org.mockito.MockedStatic;
 import org.mockito.invocation.InvocationOnMock;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
 
 /**
  * Test the bookie journal.
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({BookieImpl.class})
-@PowerMockIgnore({"jdk.internal.loader.*", "javax.naming.*", "javax.xml.*",
-    "com.sun.org.apache.xerces.*", "org.w3c.*", "org.xml.*"})
+@RunWith(MockitoJUnitRunner.Silent.class)
 @Slf4j
 public class BookieWriteToJournalTest {
 
@@ -120,7 +118,10 @@ public class BookieWriteToJournalTest {
             return null;
         }).when(journal).joinThread();
 
-        whenNew(Journal.class).withAnyArguments().thenReturn(journal);
+        @Cleanup
+        MockedStatic<Journal> journalMockedStatic = mockStatic(Journal.class);
+        journalMockedStatic.when(() -> Journal.newJournal(anyInt(), any(), 
any(), any(), any(), any(), any()))
+                .thenReturn(journal);
 
         Bookie b = new NoOpJournalReplayBookie(conf);
         b.start();
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/GarbageCollectorThreadTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/GarbageCollectorThreadTest.java
index ebe07ce230..01d7e80f10 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/GarbageCollectorThreadTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/GarbageCollectorThreadTest.java
@@ -58,7 +58,6 @@ import org.junit.Test;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Spy;
-import org.powermock.reflect.Whitebox;
 
 /**
  * Unit test for {@link GarbageCollectorThread}.
@@ -99,11 +98,11 @@ public class GarbageCollectorThreadTest {
         AbstractLogCompactor mockCompactor = mock(AbstractLogCompactor.class);
         when(mockCompactor.compact(any(EntryLogMetadata.class)))
                 .thenThrow(new RuntimeException("Unexpected compaction 
error"));
-        Whitebox.setInternalState(mockGCThread, "compactor", mockCompactor);
+        mockGCThread.compactor = mockCompactor;
 
         // Although compaction of an entry log fails due to an unexpected 
error,
         // the `compacting` flag should return to false
-        AtomicBoolean compacting = Whitebox.getInternalState(mockGCThread, 
"compacting");
+        AtomicBoolean compacting = mockGCThread.compacting;
         assertFalse(compacting.get());
         mockGCThread.compactEntryLog(new EntryLogMetadata(9999));
         assertFalse(compacting.get());
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerDirsManagerTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerDirsManagerTest.java
index 2a171373fe..d6e01cec45 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerDirsManagerTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerDirsManagerTest.java
@@ -27,6 +27,8 @@ import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 
 import java.io.File;
 import java.io.IOException;
@@ -52,15 +54,13 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Test LedgerDirsManager.
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(LedgerDirsMonitor.class)
+@RunWith(MockitoJUnitRunner.class)
 public class LedgerDirsManagerTest {
 
     ServerConfiguration conf;
@@ -79,6 +79,7 @@ public class LedgerDirsManagerTest {
     // Thread used by monitor
     ScheduledExecutorService executor;
     MockExecutorController executorController;
+    MockedStatic<Executors> executorsMockedStatic;
 
     File createTempDir(String prefix, String suffix) throws IOException {
         File dir = IOUtils.createTempDir(prefix, suffix);
@@ -88,7 +89,7 @@ public class LedgerDirsManagerTest {
 
     @Before
     public void setUp() throws Exception {
-        PowerMockito.mockStatic(Executors.class);
+        executorsMockedStatic = mockStatic(Executors.class);
 
         File tmpDir = createTempDir("bkTest", ".dir");
         curDir = BookieImpl.getCurrentDirectory(tmpDir);
@@ -101,11 +102,10 @@ public class LedgerDirsManagerTest {
         conf.setIsForceGCAllowWhenNoSpace(true);
         conf.setMinUsableSizeForEntryLogCreation(Long.MIN_VALUE);
 
-        executor = PowerMockito.mock(ScheduledExecutorService.class);
+        executor = mock(ScheduledExecutorService.class);
         executorController = new MockExecutorController()
             .controlScheduleAtFixedRate(executor, 10);
-        PowerMockito.when(Executors.newSingleThreadScheduledExecutor(any()))
-            .thenReturn(executor);
+        
executorsMockedStatic.when(()->Executors.newSingleThreadScheduledExecutor(any())).thenReturn(executor);
 
         mockDiskChecker = new MockDiskChecker(threshold, warnThreshold);
         statsProvider = new TestStatsProvider();
@@ -119,6 +119,7 @@ public class LedgerDirsManagerTest {
 
     @After
     public void tearDown() throws Exception {
+        executorsMockedStatic.close();
         ledgerMonitor.shutdown();
         for (File dir : tempDirs) {
             FileUtils.deleteDirectory(dir);
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerStorageCheckpointTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerStorageCheckpointTest.java
index 8a094fcd4f..c468d2c2dc 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerStorageCheckpointTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/LedgerStorageCheckpointTest.java
@@ -22,6 +22,10 @@ package org.apache.bookkeeper.bookie;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.when;
 
 import io.netty.buffer.PooledByteBufAllocator;
 import java.io.File;
@@ -34,7 +38,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Random;
 import java.util.Set;
-import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -64,19 +67,15 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestName;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * LedgerStorageCheckpointTest.
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(SyncThread.class)
-@PowerMockIgnore({"java.*", "javax.*", "org.slf4j.*"})
+@RunWith(MockitoJUnitRunner.class)
 public class LedgerStorageCheckpointTest {
     private static final Logger LOG = LoggerFactory
             .getLogger(LedgerStorageCheckpointTest.class);
@@ -92,11 +91,13 @@ public class LedgerStorageCheckpointTest {
 
     // ScheduledExecutorService used by SyncThread
     MockExecutorController executorController;
+    private MockedStatic<SyncThread> syncThreadMockedStatic;
+    private MockedStatic<GarbageCollectorThread> 
garbageCollectorThreadMockedStatic;
+    private MockedStatic<SortedLedgerStorage> sortedLedgerStorageMockedStatic;
 
     @Before
     public void setUp() throws Exception {
         LOG.info("Setting up test {}", getClass());
-        PowerMockito.mockStatic(Executors.class);
 
         try {
             // start zookeeper service
@@ -106,17 +107,33 @@ public class LedgerStorageCheckpointTest {
             throw e;
         }
 
-        ScheduledExecutorService scheduledExecutorService = 
PowerMockito.mock(ScheduledExecutorService.class);
+        sortedLedgerStorageMockedStatic = 
mockStatic(SortedLedgerStorage.class);
+        ScheduledExecutorService scheduledExecutorService = 
mock(ScheduledExecutorService.class);
         executorController = new MockExecutorController()
                 .controlSubmit(scheduledExecutorService)
+                .controlExecute(scheduledExecutorService)
                 .controlScheduleAtFixedRate(scheduledExecutorService, 10);
-        PowerMockito.when(scheduledExecutorService.awaitTermination(anyLong(), 
any(TimeUnit.class))).thenReturn(true);
-        
PowerMockito.when(Executors.newSingleThreadScheduledExecutor(any())).thenReturn(scheduledExecutorService);
+        when(scheduledExecutorService.awaitTermination(anyLong(), 
any(TimeUnit.class))).thenReturn(true);
+        sortedLedgerStorageMockedStatic.when(() -> 
SortedLedgerStorage.newScheduledExecutorService())
+                .thenReturn(scheduledExecutorService);
+
+        syncThreadMockedStatic = mockStatic(SyncThread.class, 
CALLS_REAL_METHODS);
+        syncThreadMockedStatic.when(() -> SyncThread.newExecutor())
+                .thenReturn(scheduledExecutorService);
+
+        garbageCollectorThreadMockedStatic = 
mockStatic(GarbageCollectorThread.class);
+        garbageCollectorThreadMockedStatic.when(() -> 
GarbageCollectorThread.newExecutor())
+                .thenReturn(scheduledExecutorService);
     }
 
     @After
     public void tearDown() throws Exception {
         LOG.info("TearDown");
+
+        sortedLedgerStorageMockedStatic.close();
+        syncThreadMockedStatic.close();
+        garbageCollectorThreadMockedStatic.close();
+
         Exception tearDownException = null;
         // stop zookeeper service
         try {
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/storage/ldb/LedgersIndexRebuildTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/storage/ldb/LedgersIndexRebuildTest.java
index b18f13d95d..f955f713bd 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/storage/ldb/LedgersIndexRebuildTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/bookie/storage/ldb/LedgersIndexRebuildTest.java
@@ -21,7 +21,6 @@
 package org.apache.bookkeeper.bookie.storage.ldb;
 
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyString;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -34,7 +33,6 @@ import org.apache.bookkeeper.bookie.BookieShell;
 import org.apache.bookkeeper.bookie.LedgerDirsManager;
 import org.apache.bookkeeper.conf.ServerConfiguration;
 import org.apache.bookkeeper.conf.TestBKConfiguration;
-import org.apache.bookkeeper.meta.MetadataDrivers;
 import org.apache.bookkeeper.net.BookieId;
 import org.apache.bookkeeper.stats.NullStatsLogger;
 import org.apache.bookkeeper.util.DiskChecker;
@@ -44,15 +42,12 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Test for class {@link LedgersIndexRebuildOp}.
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ LedgersIndexRebuildTest.class, MetadataDrivers.class })
+@RunWith(MockitoJUnitRunner.class)
 public class LedgersIndexRebuildTest {
 
     private final BookieId bookieAddress = 
BookieId.parse(UUID.randomUUID().toString());
@@ -130,11 +125,6 @@ public class LedgersIndexRebuildTest {
         LedgerDirsManager ledgerDirsManager = new LedgerDirsManager(conf, 
conf.getLedgerDirs(),
                 new DiskChecker(conf.getDiskUsageThreshold(), 
conf.getDiskUsageWarnThreshold()));
 
-        
PowerMockito.whenNew(ServerConfiguration.class).withNoArguments().thenReturn(conf);
-
-        
PowerMockito.whenNew(BookieId.class).withParameterTypes(String.class).withArguments(anyString())
-                .thenReturn(bookieAddress);
-
         DbLedgerStorage ledgerStorage = new DbLedgerStorage();
         ledgerStorage.initialize(conf, null, ledgerDirsManager, 
ledgerDirsManager,
                 NullStatsLogger.INSTANCE, UnpooledByteBufAllocator.DEFAULT);
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieWriteLedgerTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieWriteLedgerTest.java
index 548629d0f5..52d1326af3 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieWriteLedgerTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/BookieWriteLedgerTest.java
@@ -84,7 +84,6 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
-import org.powermock.reflect.Whitebox;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -1045,7 +1044,7 @@ public class BookieWriteLedgerTest extends
         lh.asyncAddEntry(10, entry1.array(), 0, entry1.capacity(), this, 
syncObj1);
 
         // Make sure entry-10 goes to the bookies and gets response.
-        java.util.Queue<PendingAddOp> myPendingAddOps = 
Whitebox.getInternalState(lh, "pendingAddOps");
+        java.util.Queue<PendingAddOp> myPendingAddOps = lh.getPendingAddOps();
         PendingAddOp addOp = null;
         boolean pendingAddOpReceived = false;
 
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/api/WriteAdvHandleTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/api/WriteAdvHandleTest.java
index a68f6cd2d1..6c469c44e4 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/api/WriteAdvHandleTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/client/api/WriteAdvHandleTest.java
@@ -29,7 +29,7 @@ import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.powermock.api.mockito.PowerMockito.when;
+import static org.mockito.Mockito.when;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufUtil;
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/discover/AbstractTestZkRegistrationClient.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/discover/AbstractTestZkRegistrationClient.java
index 9740145d2e..127dd4b28d 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/discover/AbstractTestZkRegistrationClient.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/discover/AbstractTestZkRegistrationClient.java
@@ -55,7 +55,6 @@ import 
org.apache.bookkeeper.discover.RegistrationClient.RegistrationListener;
 import org.apache.bookkeeper.discover.ZKRegistrationClient.WatchTask;
 import org.apache.bookkeeper.net.BookieId;
 import org.apache.bookkeeper.net.BookieSocketAddress;
-import org.apache.bookkeeper.util.ZkUtils;
 import org.apache.bookkeeper.versioning.LongVersion;
 import org.apache.bookkeeper.versioning.Versioned;
 import org.apache.bookkeeper.zookeeper.MockZooKeeperTestCase;
@@ -71,16 +70,12 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestName;
 import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Unit test of {@link RegistrationClient}.
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", 
"com.sun.org.apache.xerces.*"})
-@PrepareForTest({ ZKRegistrationClient.class, ZkUtils.class })
+@RunWith(MockitoJUnitRunner.Silent.class)
 @Slf4j
 public abstract class AbstractTestZkRegistrationClient extends 
MockZooKeeperTestCase {
 
@@ -129,7 +124,9 @@ public abstract class AbstractTestZkRegistrationClient 
extends MockZooKeeperTest
     }
 
     @After
-    public void teardown() {
+    public void teardown() throws Exception{
+        super.teardown();
+
         if (null != zkRegistrationClient) {
             zkRegistrationClient.close();
         }
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/AbstractZkLedgerManagerTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/AbstractZkLedgerManagerTest.java
index 1c2eda8a46..8e53f2088d 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/AbstractZkLedgerManagerTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/AbstractZkLedgerManagerTest.java
@@ -34,6 +34,7 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.CALLS_REAL_METHODS;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -77,17 +78,13 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Unit test of {@link AbstractZkLedgerManager}.
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", 
"com.sun.org.apache.xerces.*"})
-@PrepareForTest({ AbstractZkLedgerManager.class, ZkUtils.class })
+@RunWith(MockitoJUnitRunner.Silent.class)
 public class AbstractZkLedgerManagerTest extends MockZooKeeperTestCase {
 
     private ClientConfiguration conf;
@@ -96,21 +93,22 @@ public class AbstractZkLedgerManagerTest extends 
MockZooKeeperTestCase {
     private MockExecutorController schedulerController;
     private LedgerMetadata metadata;
     private LedgerMetadataSerDe serDe;
+    private MockedStatic<Executors> executorsMockedStatic;
 
     @Before
     public void setup() throws Exception {
-        PowerMockito.mockStatic(Executors.class);
+        executorsMockedStatic = mockStatic(Executors.class, 
CALLS_REAL_METHODS);
 
         super.setup();
 
-        this.scheduler = PowerMockito.mock(ScheduledExecutorService.class);
+        this.scheduler = mock(ScheduledExecutorService.class);
         this.schedulerController = new MockExecutorController()
             .controlSubmit(scheduler)
             .controlSchedule(scheduler)
             .controlExecute(scheduler)
             .controlScheduleAtFixedRate(scheduler, 10);
-        PowerMockito.when(Executors.newSingleThreadScheduledExecutor(any()))
-            .thenReturn(scheduler);
+
+        executorsMockedStatic.when(() -> 
Executors.newSingleThreadScheduledExecutor(any())).thenReturn(scheduler);
 
         this.conf = new ClientConfiguration();
         this.ledgerManager = mock(
@@ -152,6 +150,10 @@ public class AbstractZkLedgerManagerTest extends 
MockZooKeeperTestCase {
 
     @After
     public void teardown() throws Exception {
+        super.teardown();
+
+        executorsMockedStatic.close();
+
         if (null != ledgerManager) {
             ledgerManager.close();
 
@@ -340,8 +342,6 @@ public class AbstractZkLedgerManagerTest extends 
MockZooKeeperTestCase {
 
         lm.removeLedgerMetadata(ledgerId, version).get();
 
-        PowerMockito.verifyStatic(
-            ZkUtils.class, times(1));
         ZkUtils.asyncDeleteFullPathOptimistic(
             eq(mockZk), eq(ledgerStr), eq(1234), any(VoidCallback.class), 
eq(ledgerStr));
 
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataBookieDriverTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataBookieDriverTest.java
index c5069c077a..de2e9f9fdc 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataBookieDriverTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataBookieDriverTest.java
@@ -21,31 +21,27 @@ package org.apache.bookkeeper.meta.zk;
 import static org.junit.Assert.assertSame;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
 import org.apache.bookkeeper.conf.ServerConfiguration;
 import org.apache.bookkeeper.discover.RegistrationManager;
-import org.apache.bookkeeper.discover.RegistrationManager.RegistrationListener;
 import org.apache.bookkeeper.discover.ZKRegistrationManager;
 import org.apache.bookkeeper.stats.NullStatsLogger;
-import org.apache.bookkeeper.zookeeper.ZooKeeperClient;
 import org.apache.zookeeper.ZooKeeper;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Unit test {@link ZKMetadataBookieDriver}.
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", 
"com.sun.org.apache.xerces.*"})
-@PrepareForTest({ ZKMetadataDriverBase.class, ZooKeeperClient.class, 
ZKMetadataBookieDriver.class })
+@RunWith(MockitoJUnitRunner.class)
 public class ZKMetadataBookieDriverTest extends ZKMetadataDriverTestBase {
 
     private ZKMetadataBookieDriver driver;
@@ -56,39 +52,29 @@ public class ZKMetadataBookieDriverTest extends 
ZKMetadataDriverTestBase {
         this.conf = new ServerConfiguration();
         super.setup(conf);
 
-        driver = new ZKMetadataBookieDriver();
+        driver = spy(new ZKMetadataBookieDriver());
     }
 
     @After
     public void teardown() {
+        super.teardown();
         driver.close();
     }
 
     @Test
     public void testGetRegManager() throws Exception {
-        RegistrationListener listener = mock(RegistrationListener.class);
         driver.initialize(conf, NullStatsLogger.INSTANCE);
 
         assertSame(conf, driver.serverConf);
 
-        ZKRegistrationManager mockRegManager = 
PowerMockito.mock(ZKRegistrationManager.class);
-
-        PowerMockito.whenNew(ZKRegistrationManager.class)
-            .withParameterTypes(
-                ServerConfiguration.class,
-                ZooKeeper.class)
-            .withArguments(
-                any(ServerConfiguration.class),
-                any(ZooKeeper.class))
-            .thenReturn(mockRegManager);
+        ZKRegistrationManager mockRegManager = 
mock(ZKRegistrationManager.class);
+        
doReturn(mockRegManager).when(driver).newZKRegistrationManager(any(ServerConfiguration.class),
+                any(ZooKeeper.class));
 
         try (RegistrationManager manager = driver.createRegistrationManager()) 
{
             assertSame(mockRegManager, manager);
 
-            PowerMockito.verifyNew(ZKRegistrationManager.class, times(1))
-                    .withArguments(
-                            same(conf),
-                            same(mockZkc));
+            verify(driver, times(1)).newZKRegistrationManager(same(conf), 
same(mockZkc));
         }
     }
 
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataClientDriverTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataClientDriverTest.java
index 6331f5dbb4..8b9ed9905d 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataClientDriverTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataClientDriverTest.java
@@ -24,7 +24,9 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -34,22 +36,16 @@ import org.apache.bookkeeper.conf.ClientConfiguration;
 import org.apache.bookkeeper.discover.RegistrationClient;
 import org.apache.bookkeeper.discover.ZKRegistrationClient;
 import org.apache.bookkeeper.stats.NullStatsLogger;
-import org.apache.bookkeeper.zookeeper.ZooKeeperClient;
 import org.apache.zookeeper.ZooKeeper;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Unit test {@link ZKMetadataClientDriver}.
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", 
"com.sun.org.apache.xerces.*"})
-@PrepareForTest({ ZKMetadataDriverBase.class, ZooKeeperClient.class, 
ZKMetadataClientDriver.class })
+@RunWith(MockitoJUnitRunner.class)
 public class ZKMetadataClientDriverTest extends ZKMetadataDriverTestBase {
 
     private ZKMetadataClientDriver driver;
@@ -60,7 +56,7 @@ public class ZKMetadataClientDriverTest extends 
ZKMetadataDriverTestBase {
         this.conf = new ClientConfiguration();
         super.setup(conf);
 
-        driver = new ZKMetadataClientDriver();
+        driver = spy(new ZKMetadataClientDriver());
     }
 
     @Test
@@ -72,19 +68,17 @@ public class ZKMetadataClientDriverTest extends 
ZKMetadataDriverTestBase {
         assertSame(mockExecutor, driver.scheduler);
         assertNull(driver.regClient);
 
-        ZKRegistrationClient mockRegClient = 
PowerMockito.mock(ZKRegistrationClient.class);
+        ZKRegistrationClient mockRegClient = mock(ZKRegistrationClient.class);
 
-        PowerMockito.whenNew(ZKRegistrationClient.class)
-            .withParameterTypes(ZooKeeper.class, String.class, 
ScheduledExecutorService.class, Boolean.TYPE)
-            .withArguments(any(ZooKeeper.class), anyString(), 
any(ScheduledExecutorService.class), anyBoolean())
-            .thenReturn(mockRegClient);
+        
doReturn(mockRegClient).when(driver).newZKRegistrationClient(any(ZooKeeper.class),
+                anyString(), any(ScheduledExecutorService.class), 
anyBoolean());
 
         RegistrationClient client = driver.getRegistrationClient();
         assertSame(mockRegClient, client);
         assertSame(mockRegClient, driver.regClient);
 
-        PowerMockito.verifyNew(ZKRegistrationClient.class, times(1))
-            .withArguments(eq(mockZkc), eq(ledgersRootPath), eq(mockExecutor), 
anyBoolean());
+        verify(driver, times(1)).newZKRegistrationClient(eq(mockZkc),
+                eq(ledgersRootPath), eq(mockExecutor), anyBoolean());
 
         driver.close();
         verify(mockRegClient, times(1)).close();
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataDriverBaseTest.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataDriverBaseTest.java
index e02fb29bae..3a387d1596 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataDriverBaseTest.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataDriverBaseTest.java
@@ -30,32 +30,29 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.Mockito.CALLS_REAL_METHODS;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.powermock.api.mockito.PowerMockito.mockStatic;
-import static org.powermock.api.mockito.PowerMockito.verifyStatic;
 
 import java.util.Optional;
+import lombok.Cleanup;
 import org.apache.bookkeeper.conf.ClientConfiguration;
 import org.apache.bookkeeper.meta.AbstractZkLedgerManagerFactory;
 import org.apache.bookkeeper.meta.LedgerManagerFactory;
 import org.apache.bookkeeper.stats.NullStatsLogger;
 import org.apache.bookkeeper.zookeeper.RetryPolicy;
 import org.apache.bookkeeper.zookeeper.ZooKeeperClient;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Unit test of {@link ZKMetadataDriverBase}.
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", 
"com.sun.org.apache.xerces.*"})
-@PrepareForTest({ ZKMetadataDriverBase.class, ZooKeeperClient.class, 
AbstractZkLedgerManagerFactory.class })
+@RunWith(MockitoJUnitRunner.class)
 public class ZKMetadataDriverBaseTest extends ZKMetadataDriverTestBase {
 
     private ZKMetadataDriverBase driver;
@@ -68,6 +65,11 @@ public class ZKMetadataDriverBaseTest extends 
ZKMetadataDriverTestBase {
         retryPolicy = mock(RetryPolicy.class);
     }
 
+    @After
+    public void teardown() {
+        super.teardown();
+    }
+
     @Test
     public void testInitialize() throws Exception {
         driver.initialize(
@@ -80,7 +82,7 @@ public class ZKMetadataDriverBaseTest extends 
ZKMetadataDriverTestBase {
 
         String readonlyPath = "/path/to/ledgers/" + AVAILABLE_NODE + "/" + 
READONLY;
         assertSame(mockZkc, driver.zk);
-        verifyStatic(ZooKeeperClient.class, times(1));
+
         ZooKeeperClient.newBuilder();
         verify(mockZkBuilder, times(1)).build();
         verify(mockZkc, times(1))
@@ -108,7 +110,7 @@ public class ZKMetadataDriverBaseTest extends 
ZKMetadataDriverTestBase {
 
         String readonlyPath = "/path/to/ledgers/" + AVAILABLE_NODE;
         assertSame(anotherZk, driver.zk);
-        verifyStatic(ZooKeeperClient.class, times(0));
+
         ZooKeeperClient.newBuilder();
         verify(mockZkBuilder, times(0)).build();
         verify(mockZkc, times(0))
@@ -127,18 +129,17 @@ public class ZKMetadataDriverBaseTest extends 
ZKMetadataDriverTestBase {
         driver.initialize(
             conf, NullStatsLogger.INSTANCE, retryPolicy, Optional.empty());
 
-        mockStatic(AbstractZkLedgerManagerFactory.class);
+        @Cleanup
+        MockedStatic<AbstractZkLedgerManagerFactory> 
abstractZkLedgerManagerFactoryMockedStatic =
+                mockStatic(AbstractZkLedgerManagerFactory.class);
         LedgerManagerFactory factory = mock(LedgerManagerFactory.class);
-        PowerMockito.when(
-            AbstractZkLedgerManagerFactory.class,
-            "newLedgerManagerFactory",
-            same(conf),
-            same(driver.layoutManager))
-            .thenReturn(factory);
+        abstractZkLedgerManagerFactoryMockedStatic.when(() ->
+                        
AbstractZkLedgerManagerFactory.newLedgerManagerFactory(same(conf), 
same(driver.layoutManager)))
+                .thenReturn(factory);
 
         assertSame(factory, driver.getLedgerManagerFactory());
         assertSame(factory, driver.lmFactory);
-        verifyStatic(AbstractZkLedgerManagerFactory.class, times(1));
+
         AbstractZkLedgerManagerFactory.newLedgerManagerFactory(
             same(conf),
             same(driver.layoutManager));
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataDriverTestBase.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataDriverTestBase.java
index c0f3383512..e5129fb716 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataDriverTestBase.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/meta/zk/ZKMetadataDriverTestBase.java
@@ -25,13 +25,13 @@ import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
-import static org.powermock.api.mockito.PowerMockito.mockStatic;
 
 import org.apache.bookkeeper.conf.AbstractConfiguration;
 import org.apache.bookkeeper.stats.StatsLogger;
 import org.apache.bookkeeper.zookeeper.RetryPolicy;
 import org.apache.bookkeeper.zookeeper.ZooKeeperClient;
-import org.powermock.api.mockito.PowerMockito;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
 
 /**
  * Unit test of {@link ZKMetadataDriverBase}.
@@ -43,6 +43,7 @@ public abstract class ZKMetadataDriverTestBase {
     protected String metadataServiceUri;
     protected ZooKeeperClient.Builder mockZkBuilder;
     protected ZooKeeperClient mockZkc;
+    protected MockedStatic<ZooKeeperClient> zooKeeperClientMockedStatic;
 
     public void setup(AbstractConfiguration<?> conf) throws Exception {
         ledgersRootPath = "/path/to/ledgers";
@@ -64,9 +65,12 @@ public abstract class ZKMetadataDriverTestBase {
 
         when(mockZkBuilder.build()).thenReturn(mockZkc);
 
-        mockStatic(ZooKeeperClient.class);
-        PowerMockito.when(ZooKeeperClient.class, "newBuilder")
-            .thenReturn(mockZkBuilder);
+        zooKeeperClientMockedStatic = 
Mockito.mockStatic(ZooKeeperClient.class);
+        zooKeeperClientMockedStatic.when(() -> 
ZooKeeperClient.newBuilder()).thenReturn(mockZkBuilder);
+    }
+
+    public void teardown() {
+        zooKeeperClientMockedStatic.close();
     }
 
 }
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/TestEmbeddedServer.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/TestEmbeddedServer.java
index 9d24b99af0..60b43032ab 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/TestEmbeddedServer.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/TestEmbeddedServer.java
@@ -28,12 +28,15 @@ import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.powermock.api.mockito.PowerMockito.when;
-import static org.powermock.api.mockito.PowerMockito.whenNew;
+import static org.mockito.Mockito.when;
 
 import java.io.IOException;
+import lombok.Cleanup;
 import org.apache.bookkeeper.bookie.BookieImpl;
 import org.apache.bookkeeper.bookie.BookieResources;
 import org.apache.bookkeeper.bookie.LedgerDirsManager;
@@ -51,24 +54,19 @@ import org.apache.bookkeeper.net.BookieSocketAddress;
 import org.apache.bookkeeper.proto.BookieServer;
 import org.apache.bookkeeper.server.component.ServerLifecycleComponent;
 import org.apache.bookkeeper.server.conf.BookieConfiguration;
-import org.apache.bookkeeper.server.service.BookieService;
 import org.apache.bookkeeper.stats.NullStatsProvider;
 import org.apache.bookkeeper.stats.StatsLogger;
 import org.apache.bookkeeper.stats.StatsProvider;
 import org.apache.bookkeeper.util.DiskChecker;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Unit test of {@link EmbeddedServer}.
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", 
"com.sun.org.apache.xerces.*"})
-@PrepareForTest({BookieService.class, BookieResources.class, 
EmbeddedServer.class})
+@RunWith(MockitoJUnitRunner.class)
 public class TestEmbeddedServer {
 
     static class TestComponent extends ServerLifecycleComponent {
@@ -93,11 +91,13 @@ public class TestEmbeddedServer {
 
     @Test
     public void testBuildBookieServer() throws Exception {
-        PowerMockito.mockStatic(BookieResources.class);
-        when(BookieResources.createMetadataDriver(any(), any()))
-            .thenReturn(new NullMetadataBookieDriver());
-        when(BookieResources.createAllocator(any())).thenReturn(
-                PowerMockito.mock(ByteBufAllocatorWithOomHandler.class));
+        @Cleanup
+        MockedStatic<BookieResources> bookieResourcesMockedStatic = 
mockStatic(BookieResources.class,
+                CALLS_REAL_METHODS);
+        bookieResourcesMockedStatic.when(() ->
+                BookieResources.createMetadataDriver(any(), 
any())).thenReturn(new NullMetadataBookieDriver());
+        bookieResourcesMockedStatic.when(() ->
+                
BookieResources.createAllocator(any())).thenReturn(mock(ByteBufAllocatorWithOomHandler.class));
 
         ServerConfiguration serverConf = new ServerConfiguration()
             .setAllowLoopback(true)
@@ -106,18 +106,26 @@ public class TestEmbeddedServer {
             .setExtraServerComponents(new String[] { 
TestComponent.class.getName() });
         BookieConfiguration conf = new BookieConfiguration(serverConf);
 
-        
whenNew(BookieImpl.class).withAnyArguments().thenReturn(PowerMockito.mock(BookieImpl.class));
-        whenNew(LegacyCookieValidation.class)
-            
.withAnyArguments().thenReturn(PowerMockito.mock(LegacyCookieValidation.class));
+        @Cleanup
+        MockedStatic<LegacyCookieValidation> 
legacyCookieValidationMockedStatic =
+                mockStatic(LegacyCookieValidation.class);
+        legacyCookieValidationMockedStatic.when(() -> 
LegacyCookieValidation.newLegacyCookieValidation(any(), any()))
+                .thenReturn(mock(LegacyCookieValidation.class));
 
-        BookieServer mockServer = PowerMockito.mock(BookieServer.class);
-        whenNew(BookieServer.class)
-            .withAnyArguments()
-            .thenReturn(mockServer);
+        @Cleanup
+        MockedStatic<BookieImpl> bookieMockedStatic = 
mockStatic(BookieImpl.class, CALLS_REAL_METHODS);
+        bookieMockedStatic.when(() -> BookieImpl.newBookieImpl(any(), any(), 
any(), any(), any(), any(), any(),
+                any(), any())).thenReturn(mock(BookieImpl.class));
+
+        BookieServer mockServer = mock(BookieServer.class);
 
         BookieSocketAddress bookieAddress = new 
BookieSocketAddress("127.0.0.1", 1281);
         when(mockServer.getLocalAddress()).thenReturn(bookieAddress);
-        when(mockServer.getBookieId()).thenReturn(bookieAddress.toBookieId());
+
+        @Cleanup
+        MockedStatic<BookieServer> bookieServerMockedStatic = 
mockStatic(BookieServer.class);
+        bookieServerMockedStatic.when(() -> 
BookieServer.newBookieServer(any(), any(), any(), any(), any()))
+                .thenReturn(mockServer);
 
         EmbeddedServer server = EmbeddedServer.builder(conf).build();
         LifecycleComponentStack stack = server.getLifecycleComponentStack();
@@ -158,25 +166,36 @@ public class TestEmbeddedServer {
 
         UncleanShutdownDetectionImpl uncleanShutdownDetection = new 
UncleanShutdownDetectionImpl(ledgerDirsManager);
 
-        ByteBufAllocatorWithOomHandler byteBufFromResources = 
PowerMockito.mock(ByteBufAllocatorWithOomHandler.class);
-        ByteBufAllocatorWithOomHandler byteBuf = 
PowerMockito.mock(ByteBufAllocatorWithOomHandler.class);
+        ByteBufAllocatorWithOomHandler byteBufFromResources = 
mock(ByteBufAllocatorWithOomHandler.class);
+        ByteBufAllocatorWithOomHandler byteBuf = 
mock(ByteBufAllocatorWithOomHandler.class);
 
-        PowerMockito.mockStatic(BookieResources.class);
-        when(BookieResources.createMetadataDriver(any(), 
any())).thenReturn(new NullMetadataBookieDriver());
-        
when(BookieResources.createAllocator(any())).thenReturn(byteBufFromResources);
+        @Cleanup
+        MockedStatic<BookieResources> bookieResourcesMockedStatic = 
mockStatic(BookieResources.class);
+        bookieResourcesMockedStatic.when(() ->
+                BookieResources.createMetadataDriver(any(), 
any())).thenReturn(new NullMetadataBookieDriver());
+        bookieResourcesMockedStatic.when(() ->
+                
BookieResources.createAllocator(any())).thenReturn(byteBufFromResources);
 
-        
whenNew(BookieImpl.class).withAnyArguments().thenReturn(PowerMockito.mock(BookieImpl.class));
-        whenNew(LegacyCookieValidation.class)
-                
.withAnyArguments().thenReturn(PowerMockito.mock(LegacyCookieValidation.class));
+        @Cleanup
+        MockedStatic<LegacyCookieValidation> 
legacyCookieValidationMockedStatic =
+                mockStatic(LegacyCookieValidation.class);
+        legacyCookieValidationMockedStatic.when(() -> 
LegacyCookieValidation.newLegacyCookieValidation(any(), any()))
+                .thenReturn(mock(LegacyCookieValidation.class));
 
-        BookieServer mockServer = PowerMockito.mock(BookieServer.class);
-        whenNew(BookieServer.class)
-                .withAnyArguments()
+        @Cleanup
+        MockedStatic<BookieImpl> bookieMockedStatic = 
mockStatic(BookieImpl.class, CALLS_REAL_METHODS);
+        bookieMockedStatic.when(() -> BookieImpl.newBookieImpl(any(), any(), 
any(), any(), any(), any(), any(), any(),
+                any())).thenReturn(mock(BookieImpl.class));
+
+        BookieServer mockServer = mock(BookieServer.class);
+
+        @Cleanup
+        MockedStatic<BookieServer> bookieServerMockedStatic = 
mockStatic(BookieServer.class);
+        bookieServerMockedStatic.when(() -> 
BookieServer.newBookieServer(any(), any(), any(), any(), any()))
                 .thenReturn(mockServer);
 
         BookieSocketAddress bookieAddress = new 
BookieSocketAddress("127.0.0.1", 1281);
         when(mockServer.getLocalAddress()).thenReturn(bookieAddress);
-        when(mockServer.getBookieId()).thenReturn(bookieAddress.toBookieId());
 
         EmbeddedServer server = EmbeddedServer.builder(conf)
                 .statsProvider(statsProvider)
@@ -211,9 +230,11 @@ public class TestEmbeddedServer {
 
     @Test
     public void testIgnoreExtraServerComponentsStartupFailures() throws 
Exception {
-        PowerMockito.mockStatic(BookieResources.class);
-        when(BookieResources.createMetadataDriver(any(), any()))
-            .thenReturn(new NullMetadataBookieDriver());
+        @Cleanup
+        MockedStatic<BookieResources> bookieResourcesMockedStatic = 
mockStatic(BookieResources.class,
+                CALLS_REAL_METHODS);
+        bookieResourcesMockedStatic.when(() ->
+                BookieResources.createMetadataDriver(any(), 
any())).thenReturn(new NullMetadataBookieDriver());
 
         ServerConfiguration serverConf = new ServerConfiguration()
             .setAllowLoopback(true)
@@ -223,18 +244,26 @@ public class TestEmbeddedServer {
             .setIgnoreExtraServerComponentsStartupFailures(true);
         BookieConfiguration conf = new BookieConfiguration(serverConf);
 
-        
whenNew(BookieImpl.class).withAnyArguments().thenReturn(PowerMockito.mock(BookieImpl.class));
-        whenNew(LegacyCookieValidation.class)
-            
.withAnyArguments().thenReturn(PowerMockito.mock(LegacyCookieValidation.class));
+        @Cleanup
+        MockedStatic<LegacyCookieValidation> 
legacyCookieValidationMockedStatic =
+                mockStatic(LegacyCookieValidation.class);
+        legacyCookieValidationMockedStatic.when(() -> 
LegacyCookieValidation.newLegacyCookieValidation(any(), any()))
+                .thenReturn(mock(LegacyCookieValidation.class));
+
+        @Cleanup
+        MockedStatic<BookieImpl> bookieMockedStatic = 
mockStatic(BookieImpl.class, CALLS_REAL_METHODS);
+        bookieMockedStatic.when(() -> BookieImpl.newBookieImpl(any(), any(), 
any(), any(), any(), any(), any(), any(),
+                any())).thenReturn(mock(BookieImpl.class));
 
-        BookieServer mockServer = PowerMockito.mock(BookieServer.class);
-        whenNew(BookieServer.class)
-            .withAnyArguments()
-            .thenReturn(mockServer);
+        BookieServer mockServer = mock(BookieServer.class);
+
+        @Cleanup
+        MockedStatic<BookieServer> bookieServerMockedStatic = 
mockStatic(BookieServer.class);
+        bookieServerMockedStatic.when(() -> 
BookieServer.newBookieServer(any(), any(), any(), any(), any()))
+                .thenReturn(mockServer);
 
         BookieSocketAddress bookieAddress = new 
BookieSocketAddress("127.0.0.1", 1281);
         when(mockServer.getLocalAddress()).thenReturn(bookieAddress);
-        when(mockServer.getBookieId()).thenReturn(bookieAddress.toBookieId());
 
         LifecycleComponentStack stack = 
EmbeddedServer.builder(conf).build().getLifecycleComponentStack();
         assertEquals(6, stack.getNumComponents());
@@ -250,9 +279,11 @@ public class TestEmbeddedServer {
 
     @Test
     public void testExtraServerComponentsStartupFailures() throws Exception {
-        PowerMockito.mockStatic(BookieResources.class);
-        when(BookieResources.createMetadataDriver(any(), any()))
-            .thenReturn(new NullMetadataBookieDriver());
+        @Cleanup
+        MockedStatic<BookieResources> bookieResourcesMockedStatic = 
mockStatic(BookieResources.class,
+                CALLS_REAL_METHODS);
+        bookieResourcesMockedStatic.when(() ->
+                BookieResources.createMetadataDriver(any(), 
any())).thenReturn(new NullMetadataBookieDriver());
 
         ServerConfiguration serverConf = new ServerConfiguration()
             .setAllowLoopback(true)
@@ -262,18 +293,23 @@ public class TestEmbeddedServer {
             .setIgnoreExtraServerComponentsStartupFailures(false);
         BookieConfiguration conf = new BookieConfiguration(serverConf);
 
-        
whenNew(BookieImpl.class).withAnyArguments().thenReturn(PowerMockito.mock(BookieImpl.class));
-        whenNew(LegacyCookieValidation.class)
-            
.withAnyArguments().thenReturn(PowerMockito.mock(LegacyCookieValidation.class));
+        @Cleanup
+        MockedStatic<LegacyCookieValidation> 
legacyCookieValidationMockedStatic =
+                mockStatic(LegacyCookieValidation.class);
+        legacyCookieValidationMockedStatic.when(() -> 
LegacyCookieValidation.newLegacyCookieValidation(any(), any()))
+                .thenReturn(mock(LegacyCookieValidation.class));
 
-        BookieServer mockServer = PowerMockito.mock(BookieServer.class);
-        whenNew(BookieServer.class)
-                .withAnyArguments()
-            .thenReturn(mockServer);
+        @Cleanup
+        MockedStatic<BookieImpl> bookieMockedStatic = 
mockStatic(BookieImpl.class, CALLS_REAL_METHODS);
+        bookieMockedStatic.when(() -> BookieImpl.newBookieImpl(any(), any(), 
any(), any(), any(), any(), any(), any(),
+                any())).thenReturn(mock(BookieImpl.class));
 
-        BookieSocketAddress bookieAddress = new 
BookieSocketAddress("127.0.0.1", 1281);
-        when(mockServer.getLocalAddress()).thenReturn(bookieAddress);
-        when(mockServer.getBookieId()).thenReturn(bookieAddress.toBookieId());
+        BookieServer mockServer = mock(BookieServer.class);
+
+        @Cleanup
+        MockedStatic<BookieServer> bookieServerMockedStatic = 
mockStatic(BookieServer.class);
+        bookieServerMockedStatic.when(() -> 
BookieServer.newBookieServer(any(), any(), any(), any(), any()))
+                .thenReturn(mockServer);
 
         try {
             EmbeddedServer.builder(conf).build().getLifecycleComponentStack();
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
index a59adcf6af..847c1118f5 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
@@ -23,8 +23,8 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
-import static org.powermock.api.mockito.PowerMockito.spy;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/zookeeper/MockZooKeeperTestCase.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/zookeeper/MockZooKeeperTestCase.java
index fdabc5e0d4..73f6762f96 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/zookeeper/MockZooKeeperTestCase.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/zookeeper/MockZooKeeperTestCase.java
@@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.anyList;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 
 import com.google.common.collect.Maps;
 import java.util.HashSet;
@@ -47,7 +48,7 @@ import org.apache.zookeeper.Watcher.Event.EventType;
 import org.apache.zookeeper.Watcher.Event.KeeperState;
 import org.apache.zookeeper.ZooKeeper;
 import org.apache.zookeeper.data.Stat;
-import org.powermock.api.mockito.PowerMockito;
+import org.mockito.MockedStatic;
 
 /**
  * A test base that provides mocked zookeeper.
@@ -58,11 +59,12 @@ public abstract class MockZooKeeperTestCase {
     protected ZooKeeper mockZk;
     protected ScheduledExecutorService zkCallbackExecutor;
     protected MockExecutorController zkCallbackController;
+    private MockedStatic<ZkUtils> zkUtilsMockedStatic;
 
     protected void setup() throws Exception {
         this.mockZk = mock(ZooKeeper.class);
 
-        PowerMockito.mockStatic(ZkUtils.class);
+        this.zkUtilsMockedStatic = mockStatic(ZkUtils.class);
 
         this.zkCallbackExecutor = mock(ScheduledExecutorService.class);
         this.zkCallbackController = new MockExecutorController()
@@ -72,6 +74,10 @@ public abstract class MockZooKeeperTestCase {
             .controlScheduleAtFixedRate(zkCallbackExecutor, 10);
     }
 
+    protected void teardown() throws Exception {
+        zkUtilsMockedStatic.close();
+    }
+
     private void addWatcher(String path, Watcher watcher) {
         if (null == watcher) {
             return;
@@ -104,26 +110,22 @@ public abstract class MockZooKeeperTestCase {
         int retCode,
         String retCreatedZnodeName
     ) throws Exception {
-
-        PowerMockito.doAnswer(invocationOnMock -> {
+        zkUtilsMockedStatic.when(() -> ZkUtils.asyncCreateFullPathOptimistic(
+                eq(mockZk),
+                eq(expectedLedgerPath),
+                any(byte[].class),
+                anyList(),
+                eq(expectedCreateMode),
+                any(StringCallback.class),
+                any())).thenAnswer(invocationOnMock -> {
             String path = invocationOnMock.getArgument(1);
             StringCallback callback = invocationOnMock.getArgument(5);
             Object ctx = invocationOnMock.getArgument(6);
 
             callback.processResult(
-                retCode, path, ctx, retCreatedZnodeName);
+                    retCode, path, ctx, retCreatedZnodeName);
             return null;
-        }).when(
-            ZkUtils.class,
-            "asyncCreateFullPathOptimistic",
-            eq(mockZk),
-            eq(expectedLedgerPath),
-            any(byte[].class),
-            anyList(),
-            eq(expectedCreateMode),
-            any(StringCallback.class),
-            any());
-
+        });
     }
 
     protected void mockZkDelete(
@@ -155,23 +157,19 @@ public abstract class MockZooKeeperTestCase {
         int expectedZnodeVersion,
         int retCode
     ) throws Exception {
-
-        PowerMockito.doAnswer(invocationOnMock -> {
+        zkUtilsMockedStatic.when(() -> ZkUtils.asyncDeleteFullPathOptimistic(
+                eq(mockZk),
+                eq(expectedLedgerPath),
+                eq(expectedZnodeVersion),
+                any(VoidCallback.class),
+                eq(expectedLedgerPath))).thenAnswer(invocationOnMock -> {
             String path = invocationOnMock.getArgument(1);
             VoidCallback callback = invocationOnMock.getArgument(3);
 
             callback.processResult(
                 retCode, path, null);
             return null;
-        }).when(
-            ZkUtils.class,
-            "asyncDeleteFullPathOptimistic",
-            eq(mockZk),
-            eq(expectedLedgerPath),
-            eq(expectedZnodeVersion),
-            any(VoidCallback.class),
-            eq(expectedLedgerPath));
-
+        });
     }
 
     protected void mockZkGetData(
diff --git 
a/bookkeeper-server/src/test/resources/org/powermock/extensions/configuration.properties
 
b/bookkeeper-server/src/test/resources/org/powermock/extensions/configuration.properties
deleted file mode 100644
index e58a6058e5..0000000000
--- 
a/bookkeeper-server/src/test/resources/org/powermock/extensions/configuration.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-#
-
-powermock.global-ignore=javax.management.*
diff --git a/pom.xml b/pom.xml
index 76ba479a94..69d1bbe56b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -157,7 +157,6 @@
     <netty.version>4.1.104.Final</netty.version>
     <netty-iouring.version>0.0.24.Final</netty-iouring.version>
     <ostrich.version>9.1.3</ostrich.version>
-    <powermock.version>2.0.9</powermock.version>
     <prometheus.version>0.15.0</prometheus.version>
     <datasketches.version>0.8.3</datasketches.version>
     <httpclient.version>4.5.13</httpclient.version>
@@ -672,16 +671,6 @@
         <artifactId>mockito-inline</artifactId>
         <version>${mockito.version}</version>
       </dependency>
-      <dependency>
-        <groupId>org.powermock</groupId>
-        <artifactId>powermock-api-mockito2</artifactId>
-        <version>${powermock.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.powermock</groupId>
-        <artifactId>powermock-module-junit4</artifactId>
-        <version>${powermock.version}</version>
-      </dependency>
       <dependency>
         <groupId>org.apache.hadoop</groupId>
         <artifactId>hadoop-minikdc</artifactId>
@@ -831,17 +820,7 @@
     </dependency>
     <dependency>
       <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-api-mockito2</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.powermock</groupId>
-      <artifactId>powermock-module-junit4</artifactId>
+      <artifactId>mockito-inline</artifactId>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git 
a/stream/clients/java/all/src/main/java/org/apache/bookkeeper/clients/StorageClientImpl.java
 
b/stream/clients/java/all/src/main/java/org/apache/bookkeeper/clients/StorageClientImpl.java
index 2b5bc4817c..dadd4e4f23 100644
--- 
a/stream/clients/java/all/src/main/java/org/apache/bookkeeper/clients/StorageClientImpl.java
+++ 
b/stream/clients/java/all/src/main/java/org/apache/bookkeeper/clients/StorageClientImpl.java
@@ -18,6 +18,7 @@
 
 package org.apache.bookkeeper.clients;
 
+import com.google.common.annotations.VisibleForTesting;
 import io.netty.buffer.ByteBuf;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
@@ -129,18 +130,23 @@ public class StorageClientImpl extends 
AbstractAutoAsyncCloseable implements Sto
                         "Can't open a non-table storage entity : " + 
props.getStreamConf().getStorageType())
                     );
                 }
-                return new PByteBufTableImpl(
-                    tableName,
-                    props,
-                    serverManager,
-                    scheduler.chooseThread(props.getStreamId()),
-                    settings.backoffPolicy()
-                ).initialize();
+                return newPByteBufTableImpl(tableName, props).initialize();
             }),
             future
         );
     }
 
+    @VisibleForTesting
+    PByteBufTableImpl newPByteBufTableImpl(String tableName, StreamProperties 
props) {
+        return new PByteBufTableImpl(
+                tableName,
+                props,
+                serverManager,
+                scheduler.chooseThread(props.getStreamId()),
+                settings.backoffPolicy()
+        );
+    }
+
     //
     // Closeable API
     //
diff --git 
a/stream/clients/java/all/src/test/java/org/apache/bookkeeper/clients/StorageClientImplTest.java
 
b/stream/clients/java/all/src/test/java/org/apache/bookkeeper/clients/StorageClientImplTest.java
index 9f0e6dfe8d..56f99d424e 100644
--- 
a/stream/clients/java/all/src/test/java/org/apache/bookkeeper/clients/StorageClientImplTest.java
+++ 
b/stream/clients/java/all/src/test/java/org/apache/bookkeeper/clients/StorageClientImplTest.java
@@ -22,8 +22,10 @@ import static 
org.apache.bookkeeper.stream.protocol.ProtocolConstants.DEFAULT_ST
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -43,18 +45,12 @@ import 
org.apache.bookkeeper.stream.proto.StreamConfiguration;
 import org.apache.bookkeeper.stream.proto.StreamProperties;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.reflect.Whitebox;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Unit test {@link StorageClientImpl}.
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({
-    StorageClientImpl.class,
-})
+@RunWith(MockitoJUnitRunner.class)
 @Slf4j
 public class StorageClientImplTest extends GrpcClientTestBase {
 
@@ -97,9 +93,7 @@ public class StorageClientImplTest extends GrpcClientTestBase 
{
         PByteBufTableImpl tableImpl = mock(PByteBufTableImpl.class);
         when(tableImpl.initialize()).thenReturn(FutureUtils.value(tableImpl));
 
-        PowerMockito.whenNew(PByteBufTableImpl.class)
-            .withAnyArguments()
-            .thenReturn(tableImpl);
+        doReturn(tableImpl).when(client).newPByteBufTableImpl(anyString(), 
any(StreamProperties.class));
 
         PTable<ByteBuf, ByteBuf> returnedTableImpl = FutureUtils.result(
             client.openPTable(STREAM_NAME)
@@ -134,18 +128,14 @@ public class StorageClientImplTest extends 
GrpcClientTestBase {
         PByteBufTableImpl tableImpl2 = mock(PByteBufTableImpl.class);
         
when(tableImpl2.initialize()).thenReturn(FutureUtils.value(tableImpl2));
 
-        PowerMockito.whenNew(PByteBufTableImpl.class)
-            .withAnyArguments()
-            .thenReturn(tableImpl1);
+        doReturn(tableImpl1).when(client).newPByteBufTableImpl(anyString(), 
any(StreamProperties.class));
 
         PTable<ByteBuf, ByteBuf> returnedTableImpl1 = FutureUtils.result(
             client.openPTable("table1")
         );
         assertSame(tableImpl1, returnedTableImpl1);
 
-        PowerMockito.whenNew(PByteBufTableImpl.class)
-            .withAnyArguments()
-            .thenReturn(tableImpl2);
+        doReturn(tableImpl2).when(client).newPByteBufTableImpl(anyString(), 
any(StreamProperties.class));
 
         PTable<ByteBuf, ByteBuf> returnedTableImpl2 = FutureUtils.result(
             client.openPTable("table2")
@@ -167,9 +157,7 @@ public class StorageClientImplTest extends 
GrpcClientTestBase {
         PByteBufTableImpl tableImpl = mock(PByteBufTableImpl.class);
         when(tableImpl.initialize()).thenReturn(FutureUtils.value(tableImpl));
 
-        PowerMockito.whenNew(PByteBufTableImpl.class)
-            .withAnyArguments()
-            .thenReturn(tableImpl);
+        doReturn(tableImpl).when(client).newPByteBufTableImpl(anyString(), 
any(StreamProperties.class));
 
         Table<ByteBuf, ByteBuf> returnedTableImpl = FutureUtils.result(
             client.openTable(STREAM_NAME)
@@ -177,7 +165,7 @@ public class StorageClientImplTest extends 
GrpcClientTestBase {
         assertTrue(returnedTableImpl instanceof ByteBufTableImpl);
         ByteBufTableImpl bytesTableImpl = (ByteBufTableImpl) returnedTableImpl;
 
-        assertSame(tableImpl, Whitebox.getInternalState(bytesTableImpl, 
"underlying"));
+        assertSame(tableImpl, bytesTableImpl.getUnderlying());
     }
 
     @SuppressWarnings("unchecked")
@@ -206,27 +194,23 @@ public class StorageClientImplTest extends 
GrpcClientTestBase {
         PByteBufTableImpl tableImpl2 = mock(PByteBufTableImpl.class);
         
when(tableImpl2.initialize()).thenReturn(FutureUtils.value(tableImpl2));
 
-        PowerMockito.whenNew(PByteBufTableImpl.class)
-            .withAnyArguments()
-            .thenReturn(tableImpl1);
+        doReturn(tableImpl1).when(client).newPByteBufTableImpl(anyString(), 
any(StreamProperties.class));
 
         Table<ByteBuf, ByteBuf> returnedTableImpl1 = FutureUtils.result(
             client.openTable("table1")
         );
         assertTrue(returnedTableImpl1 instanceof ByteBufTableImpl);
         ByteBufTableImpl bytesTableImpl1 = (ByteBufTableImpl) 
returnedTableImpl1;
-        assertSame(tableImpl1, Whitebox.getInternalState(bytesTableImpl1, 
"underlying"));
+        assertSame(tableImpl1, bytesTableImpl1.getUnderlying());
 
-        PowerMockito.whenNew(PByteBufTableImpl.class)
-            .withAnyArguments()
-            .thenReturn(tableImpl2);
+        doReturn(tableImpl2).when(client).newPByteBufTableImpl(anyString(), 
any(StreamProperties.class));
 
         Table<ByteBuf, ByteBuf> returnedTableImpl2 = FutureUtils.result(
             client.openTable("table2")
         );
         assertTrue(returnedTableImpl2 instanceof ByteBufTableImpl);
         ByteBufTableImpl bytesTableImpl2 = (ByteBufTableImpl) 
returnedTableImpl2;
-        assertSame(tableImpl2, Whitebox.getInternalState(bytesTableImpl2, 
"underlying"));
+        assertSame(tableImpl2, bytesTableImpl2.getUnderlying());
     }
 
     @SuppressWarnings("unchecked")
@@ -240,13 +224,6 @@ public class StorageClientImplTest extends 
GrpcClientTestBase {
         when(client.getStreamProperties(anyString(), anyString()))
             .thenReturn(FutureUtils.value(streamProps));
 
-        PByteBufTableImpl tableImpl = mock(PByteBufTableImpl.class);
-        when(tableImpl.initialize()).thenReturn(FutureUtils.value(tableImpl));
-
-        PowerMockito.whenNew(PByteBufTableImpl.class)
-            .withAnyArguments()
-            .thenReturn(tableImpl);
-
         try {
             FutureUtils.result(client.openPTable(STREAM_NAME));
             fail("Should fail #openTable on opening a non-table storage 
entity");
diff --git 
a/stream/clients/java/kv/src/main/java/org/apache/bookkeeper/clients/impl/kv/ByteBufTableImpl.java
 
b/stream/clients/java/kv/src/main/java/org/apache/bookkeeper/clients/impl/kv/ByteBufTableImpl.java
index ff2fefeae9..2d17fa5e99 100644
--- 
a/stream/clients/java/kv/src/main/java/org/apache/bookkeeper/clients/impl/kv/ByteBufTableImpl.java
+++ 
b/stream/clients/java/kv/src/main/java/org/apache/bookkeeper/clients/impl/kv/ByteBufTableImpl.java
@@ -17,6 +17,7 @@
  */
 package org.apache.bookkeeper.clients.impl.kv;
 
+import com.google.common.annotations.VisibleForTesting;
 import io.netty.buffer.ByteBuf;
 import java.util.concurrent.CompletableFuture;
 import org.apache.bookkeeper.api.kv.PTable;
@@ -39,6 +40,11 @@ public class ByteBufTableImpl implements Table<ByteBuf, 
ByteBuf> {
 
     private final PTable<ByteBuf, ByteBuf> underlying;
 
+    @VisibleForTesting
+    public PTable<ByteBuf, ByteBuf> getUnderlying() {
+        return underlying;
+    }
+
     public ByteBufTableImpl(PTable<ByteBuf, ByteBuf> underlying) {
         this.underlying = underlying;
     }
diff --git 
a/tests/shaded/distributedlog-core-shaded-test/src/test/java/org/apache/bookkeeper/tests/shaded/DistributedLogCoreShadedJarTest.java
 
b/tests/shaded/distributedlog-core-shaded-test/src/test/java/org/apache/bookkeeper/tests/shaded/DistributedLogCoreShadedJarTest.java
index 2ce04107a5..9dc6ee0193 100644
--- 
a/tests/shaded/distributedlog-core-shaded-test/src/test/java/org/apache/bookkeeper/tests/shaded/DistributedLogCoreShadedJarTest.java
+++ 
b/tests/shaded/distributedlog-core-shaded-test/src/test/java/org/apache/bookkeeper/tests/shaded/DistributedLogCoreShadedJarTest.java
@@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.same;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -39,17 +40,16 @@ import dlshade.org.apache.bookkeeper.meta.LayoutManager;
 import dlshade.org.apache.bookkeeper.meta.LedgerLayout;
 import dlshade.org.apache.bookkeeper.meta.LedgerManagerFactory;
 import java.io.IOException;
+import lombok.Cleanup;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 /**
  * Test whether the distributedlog-core-shaded jar is generated correctly.
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ AbstractZkLedgerManagerFactory.class, ReflectionUtils.class 
})
+@RunWith(MockitoJUnitRunner.class)
 public class DistributedLogCoreShadedJarTest {
 
     @Test(expected = ClassNotFoundException.class)
@@ -181,9 +181,10 @@ public class DistributedLogCoreShadedJarTest {
         LedgerManagerFactory factory = mock(LedgerManagerFactory.class);
         when(factory.initialize(any(AbstractConfiguration.class), 
same(manager), anyInt()))
             .thenReturn(factory);
-        PowerMockito.mockStatic(ReflectionUtils.class);
-        when(ReflectionUtils.newInstance(any(Class.class)))
-            .thenReturn(factory);
+
+        @Cleanup
+        MockedStatic<ReflectionUtils> reflectionUtilsMockedStatic = 
mockStatic(ReflectionUtils.class);
+        reflectionUtilsMockedStatic.when(()-> 
ReflectionUtils.newInstance(any(Class.class))).thenReturn(factory);
 
         try {
             LedgerManagerFactory result = 
AbstractZkLedgerManagerFactory.newLedgerManagerFactory(


Reply via email to