diff --git a/jpos/src/main/java/org/jpos/q2/Q2.java b/jpos/src/main/java/org/jpos/q2/Q2.java index 005abde787..6fad9270cd 100644 --- a/jpos/src/main/java/org/jpos/q2/Q2.java +++ b/jpos/src/main/java/org/jpos/q2/Q2.java @@ -137,6 +137,9 @@ public class Q2 implements FileFilter, Runnable { private static String DEPLOY_PREFIX = "META-INF/q2/deploy/"; private static String CFG_PREFIX = "META-INF/q2/cfg/"; private String nameRegistrarKey; + + private boolean noShutdownHook; + private long shutdownHookDelay = 0L; public Q2 (String[] args, BundleContext bundleContext) { super(); @@ -219,7 +222,7 @@ public Object run() { factory = new QFactory(loaderName, this); writePidFile(); initSystemLogger(); - if (bundleContext == null) + if (bundleContext == null && !noShutdownHook) addShutdownHook(); q2Thread = Thread.currentThread(); q2Thread.setContextClassLoader(loader); @@ -428,10 +431,13 @@ private void addShutdownHook () { Runtime.getRuntime().addShutdownHook ( new Thread ("Q2-ShutdownHook") { public void run () { + log.info ("shutting down (hook/" + shutdownHookDelay + ")"); + if (shutdownHookDelay > 0) + ISOUtil.sleep(shutdownHookDelay); shuttingDown = true; shutdown.countDown(); if (q2Thread != null) { - log.info ("shutting down (hook)"); + log.info ("shutting down (join/" + SHUTDOWN_TIMEOUT + ")"); try { q2Thread.join (SHUTDOWN_TIMEOUT); } catch (InterruptedException ignored) { @@ -725,8 +731,10 @@ private void parseCmdLine (String[] args) { options.addOption ("sa", "ssh-authorized-keys", true, "Path to authorized key file (defaults to 'cfg/authorized_keys')"); options.addOption ("su", "ssh-user", true, "SSH user (defaults to 'admin')"); options.addOption ("sh", "ssh-host-key-file", true, "SSH host key file, defaults to 'cfg/hostkeys.ser'"); + options.addOption ("sd", "shutdown-delay", true, "Shutdown delay in seconds (defaults to immediate)"); options.addOption ("Ns", "no-scan", false, "Disables deploy directory scan"); options.addOption ("Nd", "no-dynamic", false, "Disables dynamic classloader"); + options.addOption ("Nh", "no-shutdown-hook", false, "Disable shutdown hook"); options.addOption ("E", "environment", true, "Environment name.\nCan be given multiple times (applied in order, and values may override previous ones)"); options.addOption ("Ed", "envdir", true, "Environment file directory, defaults to cfg"); @@ -783,18 +791,21 @@ private void parseCmdLine (String[] args) { sshAuthorizedKeys = line.getOptionValue ("sa", "cfg/authorized_keys"); sshUser = line.getOptionValue("su", "admin"); sshHostKeyFile = line.getOptionValue("sh", "cfg/hostkeys.ser"); - } catch (MissingArgumentException e) { + noShutdownHook = line.hasOption("Nh"); + shutdownHookDelay = line.hasOption ("sd") ? 1000L*Integer.parseInt(line.getOptionValue("sd")) : 0; + + if (noShutdownHook && shutdownHookDelay > 0) + throw new IllegalArgumentException ("--no-shutdown-hook incompatible with --shutdown-delay argument"); + } catch (MissingArgumentException | IllegalArgumentException | IllegalAccessError | + UnrecognizedOptionException e) { System.out.println("ERROR: " + e.getMessage()); System.exit(1); - } catch (IllegalAccessError | UnrecognizedOptionException e) { - System.out.println(e.getMessage()); - System.exit(1); } catch (Exception e) { e.printStackTrace (); System.exit (1); } } - private void deployBundle (File bundle, boolean encrypt) + private void deployBundle (File bundle, boolean encrypt) throws JDOMException, IOException, ISOException, GeneralSecurityException {