You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2013/03/15 11:16:55 UTC

svn commit: r1456861 - in /sling/trunk/launchpad/base/src: main/java/org/apache/sling/launchpad/app/Main.java test/java/org/apache/sling/launchpad/app/MainTest.java

Author: fmeschbe
Date: Fri Mar 15 10:16:54 2013
New Revision: 1456861

URL: http://svn.apache.org/r1456861
Log:
SLING-2791 add support to prevent shutdown hook installation

- New command line option -n to not install shutdown hook
- New system property sling.shutdown.hook to control
  shutdown hook installation
- New property sling.shutdown.hook to Main constructor
  to control shutdown hook installation (constructor
  property overwrites system property)

Modified:
    sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java
    sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/app/MainTest.java

Modified: sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java?rev=1456861&r1=1456860&r2=1456861&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java (original)
+++ sling/trunk/launchpad/base/src/main/java/org/apache/sling/launchpad/app/Main.java Fri Mar 15 10:16:54 2013
@@ -92,6 +92,18 @@ public class Main {
     private static final String PROP_HOST = "org.apache.felix.http.host";
 
     /**
+     * Name of the configuration property (or system property) indicating
+     * whether the shutdown hook should be installed or not. If this property is
+     * not set or set to {@code true} (case insensitive), the shutdown hook
+     * properly shutting down the framework is installed on startup. Otherwise,
+     * if this property is set to any value other than {@code true} (case
+     * insensitive) the shutdown hook is not installed.
+     * <p>
+     * The respective command line option is {@code -n}.
+     */
+    private static final String PROP_SHUTDOWN_HOOK = "sling.shutdown.hook";
+
+    /**
      * The main entry point to the Sling Launcher Standalone Java Application.
      * This method is generally only called by the Java VM to launch Sling.
      *
@@ -134,6 +146,15 @@ public class Main {
     private final Map<String, String> commandLineArgs;
 
     /**
+     * Whether to install the shutdown hook.
+     *
+     * @see #PROP_SHUTDOWN_HOOK
+     * @see #installShutdownHook(Map)
+     * @see #addShutdownHook()
+     */
+    private boolean installShutdownHook;
+
+    /**
      * The shutdown hook installed into the Java VM after Sling has been
      * started. The hook is removed again when Sling is being shut down
      * or the {@link Notified notifier} is notified of the framework shutdown.
@@ -185,6 +206,8 @@ public class Main {
                 ? new HashMap<String, String>()
                 : args;
 
+        this.installShutdownHook = installShutdownHook(this.commandLineArgs);
+
         // sling.home from the command line or system properties, else default
         String home = getSlingHome(commandLineArgs);
         final File slingHomeFile = new File(home);
@@ -433,9 +456,8 @@ public class Main {
     }
 
     private void addShutdownHook() {
-        if (this.shutdownHook == null) {
-            this.shutdownHook = new Thread(new ShutdownHook(),
-                "Apache Sling Terminator");
+        if (this.installShutdownHook && this.shutdownHook == null) {
+            this.shutdownHook = new Thread(new ShutdownHook(), "Apache Sling Terminator");
             Runtime.getRuntime().addShutdownHook(this.shutdownHook);
         }
     }
@@ -658,6 +680,7 @@ public class Main {
             System.out.println("    -a address    the interfact to bind to (use 0.0.0.0 for any)");
             System.out.println("    -p port       the port to listen to (default 8080)");
             System.out.println("    -r path       the root servlet context path for the http service (default is /)");
+            System.out.println("    -n            don't install the shutdown hook");
             System.out.println("    -D n=v        sets property n to value v");
             System.out.println("    -h            prints this usage message");
 
@@ -666,6 +689,15 @@ public class Main {
         return false;
     }
 
+    private static boolean installShutdownHook(Map<String, String> props) {
+        String prop = props.remove(PROP_SHUTDOWN_HOOK);
+        if (prop == null) {
+            prop = System.getProperty(PROP_SHUTDOWN_HOOK);
+        }
+
+        return (prop == null) ? true : Boolean.valueOf(prop);
+    }
+
     // default accessor to enable unit tests wihtout requiring reflection
     static Map<String, String> convertCommandLineArgs(
             Map<String, String> rawArgs) {
@@ -756,6 +788,10 @@ public class Main {
                         props.put(PROP_CONTEXT_PATH, value);
                         break;
 
+                    case 'n':
+                        props.put(PROP_SHUTDOWN_HOOK, Boolean.FALSE.toString());
+                        break;
+
                     case 'D':
                         if (value == arg.getKey()) {
                             errorArg("-D", "Missing property assignment");

Modified: sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/app/MainTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/app/MainTest.java?rev=1456861&r1=1456860&r2=1456861&view=diff
==============================================================================
--- sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/app/MainTest.java (original)
+++ sling/trunk/launchpad/base/src/test/java/org/apache/sling/launchpad/app/MainTest.java Fri Mar 15 10:16:54 2013
@@ -18,6 +18,8 @@
  */
 package org.apache.sling.launchpad.app;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -338,6 +340,26 @@ public class MainTest extends TestCase {
         assertNull(props2);
     }
 
+    public void test_converCommandLineArgs_n() {
+        Map<String, String> props = Main.convertCommandLineArgs(new HashMap<String, String>() {
+            {
+                put("n", "n");
+            }
+        });
+        assertNotNull(props);
+        assertEquals(1, props.size());
+        assertEquals(Boolean.FALSE.toString(), props.get("sling.shutdown.hook"));
+
+        Map<String, String> props1 = Main.convertCommandLineArgs(new HashMap<String, String>() {
+            {
+                put("D", "sling.shutdown.hook=" + Boolean.TRUE.toString());
+            }
+        });
+        assertNotNull(props1);
+        assertEquals(1, props1.size());
+        assertEquals(Boolean.TRUE.toString(), props1.get("sling.shutdown.hook"));
+    }
+
     public void test_converCommandLineArgs_D() {
         Map<String, String> props = Main.convertCommandLineArgs(new HashMap<String, String>() {
             {
@@ -365,4 +387,88 @@ public class MainTest extends TestCase {
         });
         assertNull(props1);
     }
+
+    public void test_installShutdownHook() throws SecurityException, NoSuchMethodException, IllegalArgumentException,
+            IllegalAccessException, InvocationTargetException {
+        final Method m = Main.class.getDeclaredMethod("installShutdownHook", Map.class);
+        m.setAccessible(true);
+
+        final String key = "sling.shutdown.hook";
+        System.getProperties().remove(key);
+
+        TestCase.assertEquals(Boolean.TRUE, m.invoke(null, new HashMap<String, String>()));
+        TestCase.assertEquals(Boolean.TRUE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "true");
+            }
+        }));
+        TestCase.assertEquals(Boolean.TRUE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "TRUE");
+            }
+        }));
+        TestCase.assertEquals(Boolean.FALSE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "false");
+            }
+        }));
+        TestCase.assertEquals(Boolean.FALSE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "not true");
+            }
+        }));
+
+        System.setProperty(key, "true");
+        TestCase.assertEquals(Boolean.TRUE, m.invoke(null, new HashMap<String, String>()));
+        System.setProperty(key, "TRUE");
+        TestCase.assertEquals(Boolean.TRUE, m.invoke(null, new HashMap<String, String>()));
+        System.setProperty(key, "false");
+        TestCase.assertEquals(Boolean.FALSE, m.invoke(null, new HashMap<String, String>()));
+        System.setProperty(key, "not true");
+        TestCase.assertEquals(Boolean.FALSE, m.invoke(null, new HashMap<String, String>()));
+
+        System.setProperty(key, "true");
+        TestCase.assertEquals(Boolean.TRUE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "true");
+            }
+        }));
+        TestCase.assertEquals(Boolean.TRUE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "TRUE");
+            }
+        }));
+        TestCase.assertEquals(Boolean.FALSE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "false");
+            }
+        }));
+        TestCase.assertEquals(Boolean.FALSE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "not true");
+            }
+        }));
+
+        System.setProperty(key, "false");
+        TestCase.assertEquals(Boolean.TRUE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "true");
+            }
+        }));
+        TestCase.assertEquals(Boolean.TRUE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "TRUE");
+            }
+        }));
+        TestCase.assertEquals(Boolean.FALSE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "false");
+            }
+        }));
+        TestCase.assertEquals(Boolean.FALSE, m.invoke(null, new HashMap<String, String>() {
+            {
+                put(key, "not true");
+            }
+        }));
+    }
 }