diff --git a/excludeFindBugsFilter.xml b/excludeFindBugsFilter.xml index c836911dbe9..a2965944837 100644 --- a/excludeFindBugsFilter.xml +++ b/excludeFindBugsFilter.xml @@ -7,8 +7,5 @@ - - - diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/Version.java b/zookeeper-server/src/main/java/org/apache/zookeeper/Version.java index 181e4638841..4029c60ede3 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/Version.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/Version.java @@ -20,6 +20,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.apache.zookeeper.server.ExitCode; +import org.apache.zookeeper.util.ServiceUtils; public class Version implements org.apache.zookeeper.version.Info { @@ -48,7 +49,7 @@ public static void printUsage() { System.out.print("Usage:\tjava -cp ... org.apache.zookeeper.Version " + "[--full | --short | --revision],\n\tPrints --full version " + "info if no arg specified."); - System.exit(ExitCode.UNEXPECTED_ERROR.getValue()); + ServiceUtils.requestSystemExit(ExitCode.UNEXPECTED_ERROR.getValue()); } /** @@ -68,7 +69,7 @@ public static void main(String[] args) { } if (args.length == 0 || (args.length == 1 && args[0].equals("--full"))) { System.out.println(getFullVersion()); - System.exit(ExitCode.EXECUTION_FINISHED.getValue()); + ServiceUtils.requestSystemExit(ExitCode.EXECUTION_FINISHED.getValue()); } if (args[0].equals("--short")) { System.out.println(getVersion()); @@ -77,7 +78,7 @@ public static void main(String[] args) { } else { printUsage(); } - System.exit(ExitCode.EXECUTION_FINISHED.getValue()); + ServiceUtils.requestSystemExit(ExitCode.EXECUTION_FINISHED.getValue()); } } diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperMain.java b/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperMain.java index 857b16fcc70..734cf7ec0ee 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperMain.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/ZooKeeperMain.java @@ -66,6 +66,7 @@ import org.apache.zookeeper.cli.VersionCommand; import org.apache.zookeeper.client.ZKClientConfig; import org.apache.zookeeper.server.ExitCode; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -353,7 +354,7 @@ void run() throws CliException, IOException, InterruptedException { // Command line args non-null. Run what was passed. processCmd(cl); } - System.exit(exitCode); + ServiceUtils.requestSystemExit(exitCode); } public void executeLine(String line) throws CliException, InterruptedException, IOException { @@ -396,7 +397,7 @@ protected boolean processZKCmd(MyCommandOptions co) throws CliException, IOExcep if (cmd.equals("quit")) { zk.close(); - System.exit(exitCode); + ServiceUtils.requestSystemExit(exitCode); } else if (cmd.equals("redo") && args.length >= 2) { Integer i = Integer.decode(args[1]); if (commandCount <= i || i < 0) { // don't allow redoing this redo diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/DataTree.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/DataTree.java index f370d88f400..0dc54580699 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/DataTree.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/DataTree.java @@ -78,6 +78,7 @@ import org.apache.zookeeper.txn.SetDataTxn; import org.apache.zookeeper.txn.Txn; import org.apache.zookeeper.txn.TxnHeader; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -301,7 +302,7 @@ public DataTree() { childWatches = WatchManagerFactory.createWatchManager(); } catch (Exception e) { LOG.error("Unexpected exception when creating WatchManager, exiting abnormally", e); - System.exit(ExitCode.UNEXPECTED_ERROR.getValue()); + ServiceUtils.requestSystemExit(ExitCode.UNEXPECTED_ERROR.getValue()); } } diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/LogFormatter.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/LogFormatter.java index 459f80246da..e02a63df296 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/LogFormatter.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/LogFormatter.java @@ -33,6 +33,7 @@ import org.apache.zookeeper.server.persistence.FileTxnLog; import org.apache.zookeeper.server.util.SerializeUtils; import org.apache.zookeeper.txn.TxnHeader; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,13 +52,13 @@ public class LogFormatter { public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println("USAGE: LogFormatter log_file"); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); } String error = ZKUtil.validateFileInput(args[0]); if (null != error) { System.err.println(error); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); } FileInputStream fis = new FileInputStream(args[0]); @@ -67,7 +68,7 @@ public static void main(String[] args) throws Exception { if (fhdr.getMagic() != FileTxnLog.TXNLOG_MAGIC) { System.err.println("Invalid magic number for " + args[0]); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); } System.out.println("ZooKeeper Transactional Log File with dbid " + fhdr.getDbid() diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/PurgeTxnLog.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/PurgeTxnLog.java index f7fbde301c5..0c9206647e1 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/PurgeTxnLog.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/PurgeTxnLog.java @@ -30,6 +30,7 @@ import org.apache.yetus.audience.InterfaceAudience; import org.apache.zookeeper.server.persistence.FileTxnSnapLog; import org.apache.zookeeper.server.persistence.Util; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -230,7 +231,7 @@ private static int validateAndGetCount(String number) { private static void printUsageThenExit() { printUsage(); - System.exit(ExitCode.UNEXPECTED_ERROR.getValue()); + ServiceUtils.requestSystemExit(ExitCode.UNEXPECTED_ERROR.getValue()); } } diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/RequestThrottler.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/RequestThrottler.java index 880ac49d9b2..16a1c6f1517 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/RequestThrottler.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/RequestThrottler.java @@ -20,6 +20,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.concurrent.LinkedBlockingQueue; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -257,7 +258,7 @@ public void shutdown() { } catch (InterruptedException e) { LOG.warn("Interrupted while waiting for {} to finish", this); //TODO apply ZOOKEEPER-575 and remove this line. - System.exit(ExitCode.UNEXPECTED_ERROR.getValue()); + ServiceUtils.requestSystemExit(ExitCode.UNEXPECTED_ERROR.getValue()); } } diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/SnapshotFormatter.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/SnapshotFormatter.java index b3bf51b25bd..a276ef3d0b2 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/SnapshotFormatter.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/SnapshotFormatter.java @@ -35,6 +35,7 @@ import org.apache.zookeeper.server.persistence.FileSnap; import org.apache.zookeeper.server.persistence.SnapStream; import org.apache.zookeeper.server.persistence.Util; +import org.apache.zookeeper.util.ServiceUtils; import org.json.simple.JSONValue; /** @@ -72,18 +73,19 @@ public static void main(String[] args) throws Exception { System.err.println("USAGE: SnapshotFormatter [-d|-json] snapshot_file"); System.err.println(" -d dump the data for each znode"); System.err.println(" -json dump znode info in json format"); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); + return; } String error = ZKUtil.validateFileInput(snapshotFile); if (null != error) { System.err.println(error); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); } if (dumpData && dumpJson) { System.err.println("Cannot specify both data dump (-d) and json mode (-json) in same call"); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); } new SnapshotFormatter().run(snapshotFile, dumpData, dumpJson); diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/TraceFormatter.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/TraceFormatter.java index 36a1e680be5..d1fd989b243 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/TraceFormatter.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/TraceFormatter.java @@ -25,6 +25,7 @@ import java.text.DateFormat; import java.util.Date; import org.apache.zookeeper.ZooDefs.OpCode; +import org.apache.zookeeper.util.ServiceUtils; public class TraceFormatter { @@ -35,7 +36,7 @@ public class TraceFormatter { public static void main(String[] args) throws IOException { if (args.length != 1) { System.err.println("USAGE: TraceFormatter trace_file"); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); } FileChannel fc = new FileInputStream(args[0]).getChannel(); while (true) { diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java index 1e15f34201f..65be888380e 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServer.java @@ -80,6 +80,7 @@ import org.apache.zookeeper.server.util.RequestPathMetricsCollector; import org.apache.zookeeper.txn.CreateSessionTxn; import org.apache.zookeeper.txn.TxnHeader; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -511,7 +512,7 @@ public void takeSnapshot(boolean syncSnap) { LOG.error("Severe unrecoverable error, exiting", e); // This is a severe error that we cannot recover from, // so we need to exit - System.exit(ExitCode.TXNLOG_ERROR_TAKING_SNAPSHOT.getValue()); + ServiceUtils.requestSystemExit(ExitCode.TXNLOG_ERROR_TAKING_SNAPSHOT.getValue()); } long elapsed = Time.currentElapsedTime() - start; LOG.info("Snapshot taken in {} ms", elapsed); diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServerMain.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServerMain.java index 3b87312a2fc..7ddb1deb9e6 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServerMain.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/ZooKeeperServerMain.java @@ -35,6 +35,7 @@ import org.apache.zookeeper.server.persistence.FileTxnSnapLog.DatadirException; import org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException; import org.apache.zookeeper.server.util.JvmPauseMonitor; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,29 +70,29 @@ public static void main(String[] args) { LOG.info(USAGE); System.err.println(USAGE); ZKAuditProvider.addServerStartFailureAuditLog(); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); } catch (ConfigException e) { LOG.error("Invalid config, exiting abnormally", e); System.err.println("Invalid config, exiting abnormally"); ZKAuditProvider.addServerStartFailureAuditLog(); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); } catch (DatadirException e) { LOG.error("Unable to access datadir, exiting abnormally", e); System.err.println("Unable to access datadir, exiting abnormally"); ZKAuditProvider.addServerStartFailureAuditLog(); - System.exit(ExitCode.UNABLE_TO_ACCESS_DATADIR.getValue()); + ServiceUtils.requestSystemExit(ExitCode.UNABLE_TO_ACCESS_DATADIR.getValue()); } catch (AdminServerException e) { LOG.error("Unable to start AdminServer, exiting abnormally", e); System.err.println("Unable to start AdminServer, exiting abnormally"); ZKAuditProvider.addServerStartFailureAuditLog(); - System.exit(ExitCode.ERROR_STARTING_ADMIN_SERVER.getValue()); + ServiceUtils.requestSystemExit(ExitCode.ERROR_STARTING_ADMIN_SERVER.getValue()); } catch (Exception e) { LOG.error("Unexpected exception, exiting abnormally", e); ZKAuditProvider.addServerStartFailureAuditLog(); - System.exit(ExitCode.UNEXPECTED_ERROR.getValue()); + ServiceUtils.requestSystemExit(ExitCode.UNEXPECTED_ERROR.getValue()); } LOG.info("Exiting normally"); - System.exit(ExitCode.EXECUTION_FINISHED.getValue()); + ServiceUtils.requestSystemExit(ExitCode.EXECUTION_FINISHED.getValue()); } protected void initializeAndRun(String[] args) throws ConfigException, IOException, AdminServerException { diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLogToolkit.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLogToolkit.java index bb95d006ac9..984fb03e281 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLogToolkit.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLogToolkit.java @@ -58,6 +58,7 @@ import org.apache.zookeeper.txn.SetDataTxn; import org.apache.zookeeper.txn.Txn; import org.apache.zookeeper.txn.TxnHeader; +import org.apache.zookeeper.util.ServiceUtils; public class TxnLogToolkit implements Closeable { @@ -126,7 +127,7 @@ public static void main(String[] args) throws Exception { printHelpAndExit(e.getExitCode(), e.getOptions()); } catch (TxnLogToolkitException e) { System.err.println(e.getMessage()); - System.exit(e.getExitCode()); + ServiceUtils.requestSystemExit(e.getExitCode()); } } @@ -424,7 +425,7 @@ private static TxnLogToolkit parseCommandLine(String[] args) throws TxnLogToolki private static void printHelpAndExit(int exitCode, Options options) { HelpFormatter help = new HelpFormatter(); help.printHelp(120, "TxnLogToolkit [-dhrvc] (-z )", "", options, ""); - System.exit(exitCode); + ServiceUtils.requestSystemExit(exitCode); } private void printStat() { diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java index 4b786dab0ea..12e552f9d7d 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/FollowerZooKeeperServer.java @@ -34,6 +34,7 @@ import org.apache.zookeeper.server.ZKDatabase; import org.apache.zookeeper.server.persistence.FileTxnSnapLog; import org.apache.zookeeper.txn.TxnHeader; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -100,7 +101,7 @@ public void commit(long zxid) { if (firstElementZxid != zxid) { LOG.error("Committing zxid 0x" + Long.toHexString(zxid) + " but next pending txn 0x" + Long.toHexString(firstElementZxid)); - System.exit(ExitCode.UNMATCHED_TXN_COMMIT.getValue()); + ServiceUtils.requestSystemExit(ExitCode.UNMATCHED_TXN_COMMIT.getValue()); } Request request = pendingTxns.remove(); request.logLatency(ServerMetrics.getMetrics().COMMIT_PROPAGATION_LATENCY); diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java index 515c0de899d..0896d88a1d7 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/Learner.java @@ -52,6 +52,7 @@ import org.apache.zookeeper.server.util.ZxidUtils; import org.apache.zookeeper.txn.SetDataTxn; import org.apache.zookeeper.txn.TxnHeader; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -455,14 +456,13 @@ protected void syncWithLeader(long newLeaderZxid) throws Exception { if (!truncated) { // not able to truncate the log LOG.error("Not able to truncate the log 0x{}", Long.toHexString(qp.getZxid())); - System.exit(ExitCode.QUORUM_PACKET_ERROR.getValue()); + ServiceUtils.requestSystemExit(ExitCode.QUORUM_PACKET_ERROR.getValue()); } zk.getZKDatabase().setlastProcessedZxid(qp.getZxid()); } else { LOG.error("Got unexpected packet from leader: {}, exiting ... ", LearnerHandler.packetToString(qp)); - System.exit(ExitCode.QUORUM_PACKET_ERROR.getValue()); - + ServiceUtils.requestSystemExit(ExitCode.QUORUM_PACKET_ERROR.getValue()); } zk.getZKDatabase().initConfigInZKDatabase(self.getQuorumVerifier()); zk.createSessionTracker(); diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/QuorumCnxManager.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/QuorumCnxManager.java index e37986d4e78..47a9ca97c46 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/QuorumCnxManager.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/QuorumCnxManager.java @@ -55,6 +55,7 @@ import org.apache.zookeeper.server.quorum.flexible.QuorumVerifier; import org.apache.zookeeper.server.util.ConfigUtils; import org.apache.zookeeper.util.CircularBlockingQueue; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -825,7 +826,7 @@ public class Listener extends ZooKeeperThread { private static final int DEFAULT_PORT_BIND_MAX_RETRY = 3; private final int portBindMaxRetry; - private Runnable socketBindErrorHandler = () -> System.exit(ExitCode.UNABLE_TO_BIND_QUORUM_PORT.getValue()); + private Runnable socketBindErrorHandler = () -> ServiceUtils.requestSystemExit(ExitCode.UNABLE_TO_BIND_QUORUM_PORT.getValue()); volatile ServerSocket ss = null; public Listener() { diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/QuorumPeerMain.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/QuorumPeerMain.java index bf97488e97b..054a47dcd69 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/QuorumPeerMain.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/quorum/QuorumPeerMain.java @@ -38,6 +38,7 @@ import org.apache.zookeeper.server.persistence.FileTxnSnapLog.DatadirException; import org.apache.zookeeper.server.quorum.QuorumPeerConfig.ConfigException; import org.apache.zookeeper.server.util.JvmPauseMonitor; +import org.apache.zookeeper.util.ServiceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -92,29 +93,29 @@ public static void main(String[] args) { LOG.info(USAGE); System.err.println(USAGE); ZKAuditProvider.addServerStartFailureAuditLog(); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); } catch (ConfigException e) { LOG.error("Invalid config, exiting abnormally", e); System.err.println("Invalid config, exiting abnormally"); ZKAuditProvider.addServerStartFailureAuditLog(); - System.exit(ExitCode.INVALID_INVOCATION.getValue()); + ServiceUtils.requestSystemExit(ExitCode.INVALID_INVOCATION.getValue()); } catch (DatadirException e) { LOG.error("Unable to access datadir, exiting abnormally", e); System.err.println("Unable to access datadir, exiting abnormally"); ZKAuditProvider.addServerStartFailureAuditLog(); - System.exit(ExitCode.UNABLE_TO_ACCESS_DATADIR.getValue()); + ServiceUtils.requestSystemExit(ExitCode.UNABLE_TO_ACCESS_DATADIR.getValue()); } catch (AdminServerException e) { LOG.error("Unable to start AdminServer, exiting abnormally", e); System.err.println("Unable to start AdminServer, exiting abnormally"); ZKAuditProvider.addServerStartFailureAuditLog(); - System.exit(ExitCode.ERROR_STARTING_ADMIN_SERVER.getValue()); + ServiceUtils.requestSystemExit(ExitCode.ERROR_STARTING_ADMIN_SERVER.getValue()); } catch (Exception e) { LOG.error("Unexpected exception, exiting abnormally", e); ZKAuditProvider.addServerStartFailureAuditLog(); - System.exit(ExitCode.UNEXPECTED_ERROR.getValue()); + ServiceUtils.requestSystemExit(ExitCode.UNEXPECTED_ERROR.getValue()); } LOG.info("Exiting normally"); - System.exit(ExitCode.EXECUTION_FINISHED.getValue()); + ServiceUtils.requestSystemExit(ExitCode.EXECUTION_FINISHED.getValue()); } protected void initializeAndRun(String[] args) throws ConfigException, IOException, AdminServerException { diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/server/util/LogChopper.java b/zookeeper-server/src/main/java/org/apache/zookeeper/server/util/LogChopper.java index 3a070788ac2..e0e52a9d88d 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/server/util/LogChopper.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/server/util/LogChopper.java @@ -36,6 +36,7 @@ import org.apache.zookeeper.server.persistence.FileHeader; import org.apache.zookeeper.server.persistence.FileTxnLog; import org.apache.zookeeper.txn.TxnHeader; +import org.apache.zookeeper.util.ServiceUtils; /** * this class will chop the log at the specified zxid @@ -49,7 +50,7 @@ public static void main(String[] args) { System.out.println("Usage: LogChopper zxid_to_chop_to txn_log_to_chop chopped_filename"); System.out.println(" this program will read the txn_log_to_chop file and copy all the transactions"); System.out.println(" from it up to (and including) the given zxid into chopped_filename."); - System.exit(rc.getValue()); + ServiceUtils.requestSystemExit(rc.getValue()); } String txnLog = args[1]; String choppedLog = args[2]; @@ -63,7 +64,7 @@ public static void main(String[] args) { } catch (Exception e) { System.out.println("Got exception: " + e.getMessage()); } - System.exit(rc.getValue()); + ServiceUtils.requestSystemExit(rc.getValue()); } public static boolean chop(InputStream is, OutputStream os, long zxid) throws IOException { diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/util/ServiceUtils.java b/zookeeper-server/src/main/java/org/apache/zookeeper/util/ServiceUtils.java new file mode 100644 index 00000000000..68a25ebb487 --- /dev/null +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/util/ServiceUtils.java @@ -0,0 +1,77 @@ +/* + * 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. + */ +package org.apache.zookeeper.util; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.util.Objects; +import java.util.function.Consumer; +import org.apache.zookeeper.server.ExitCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utilities for service management. + */ +public abstract class ServiceUtils { + + private static final Logger LOG = LoggerFactory.getLogger(ServiceUtils.class); + + private ServiceUtils() { + } + + /** + * Default strategy for shutting down the JVM. + */ + @SuppressFBWarnings("DM_EXIT") + public static final Consumer SYSTEM_EXIT = (code) -> { + LOG.error("Exiting JVM with code {}", code); + System.exit(code); + }; + + /** + * No-op strategy, useful for tests. + */ + public static final Consumer LOG_ONLY = (code) -> { + LOG.error("Fatal error, JVM should exit with code {}. " + + "Actually System.exit is disabled", code); + }; + + private static Consumer systemExitProcedure = SYSTEM_EXIT; + + /** + * Override system callback. Useful for preventing the JVM to exit in tests + * or in applications that are running an in-process ZooKeeper server. + * + * @param systemExitProcedure + */ + public static void setSystemExitProcedure(Consumer systemExitProcedure) { + Objects.requireNonNull(systemExitProcedure); + ServiceUtils.systemExitProcedure = systemExitProcedure; + } + + /** + * Force shutdown of the JVM using System.exit. + * + * @param code the exit code + * @see ExitCode + */ + public static void requestSystemExit(int code) { + systemExitProcedure.accept(code); + } + +} diff --git a/zookeeper-server/src/main/java/org/apache/zookeeper/version/util/VerGen.java b/zookeeper-server/src/main/java/org/apache/zookeeper/version/util/VerGen.java index c7f9fd96236..3e9e62aee1c 100644 --- a/zookeeper-server/src/main/java/org/apache/zookeeper/version/util/VerGen.java +++ b/zookeeper-server/src/main/java/org/apache/zookeeper/version/util/VerGen.java @@ -18,6 +18,7 @@ package org.apache.zookeeper.version.util; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.File; import java.io.FileWriter; import java.io.IOException; @@ -25,6 +26,7 @@ import java.util.regex.Pattern; import org.apache.zookeeper.server.ExitCode; +@SuppressFBWarnings("DM_EXIT") public class VerGen { private static final String PACKAGE_NAME = "org.apache.zookeeper.version"; @@ -123,7 +125,7 @@ public static void generateFile(File outputDir, Version version, String rev, Str w.write("}\n"); } catch (IOException e) { System.out.println("Unable to generate version.VersionInfoMain file: " + e.getMessage()); - System.exit(1); + System.exit(ExitCode.UNEXPECTED_ERROR.getValue()); } } diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/ZKTestCase.java b/zookeeper-server/src/test/java/org/apache/zookeeper/ZKTestCase.java index d9d481aa24d..78e3cd79e82 100644 --- a/zookeeper-server/src/test/java/org/apache/zookeeper/ZKTestCase.java +++ b/zookeeper-server/src/test/java/org/apache/zookeeper/ZKTestCase.java @@ -22,6 +22,7 @@ import static org.junit.Assert.fail; import java.io.File; import java.time.LocalDateTime; +import org.apache.zookeeper.util.ServiceUtils; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.rules.TestWatcher; @@ -42,6 +43,11 @@ public class ZKTestCase { protected static final File testBaseDir = new File(System.getProperty("build.test.dir", "build")); private static final Logger LOG = LoggerFactory.getLogger(ZKTestCase.class); + static { + // Disable System.exit in tests. + ServiceUtils.setSystemExitProcedure(ServiceUtils.LOG_ONLY); + } + private String testName; protected String getTestName() {