Author: sgoeschl
Date: Tue Jan  1 14:50:59 2008
New Revision: 607936

URL: http://svn.apache.org/viewvc?rev=607936&view=rev
Log:
SANDBOX-107 - Make ProcessDestroyer optional and pluggable

Modified:
    commons/sandbox/exec/trunk/src/changes/changes.xml
    
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java
    
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java
    
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ProcessDestroyer.java
    
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ShutdownHookProcessDestroyer.java
    
commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java

Modified: commons/sandbox/exec/trunk/src/changes/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/sandbox/exec/trunk/src/changes/changes.xml?rev=607936&r1=607935&r2=607936&view=diff
==============================================================================
--- commons/sandbox/exec/trunk/src/changes/changes.xml (original)
+++ commons/sandbox/exec/trunk/src/changes/changes.xml Tue Jan  1 14:50:59 2008
@@ -6,6 +6,9 @@
   </properties>
   <body>
     <release version="1.0-SNAPSHOT" date="as in SVN" description="Sandbox 
release">
+      <action dev="sgoeschl" type="add" issue="SANDBOX-107" due-to="Niklas 
Gustavsson">
+        Made ProcessDestroyer optional and pluggable when using Executor.
+      </action>
       <action dev="sgoeschl" type="add">
         CommandLine can now expand the given command line by a user-suppied
         map. This allows to execute something like "${JAVA_HOME}/bin/java -jar 
${myapp}"

Modified: 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java?rev=607936&r1=607935&r2=607936&view=diff
==============================================================================
--- 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java
 (original)
+++ 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/DefaultExecutor.java
 Tue Jan  1 14:50:59 2008
@@ -40,9 +40,12 @@
     /** the exit values considerd to be successful */
     private int[] exitValues;
 
-    // TODO replace with generic launcher
+    /** launches the command in a new process */
     private CommandLauncher launcher;
 
+    /** optional cleanup of started processes */ 
+    private ProcessDestroyer processDestroyer;
+
     /**
      * Default Constrctor
      */
@@ -81,6 +84,20 @@
     }
 
     /**
+     * @see org.apache.commons.exec.Executor#getProcessDestroyer()
+     */
+    public ProcessDestroyer getProcessDestroyer() {
+      return this.processDestroyer;
+    }
+
+    /**
+     * @see 
org.apache.commons.exec.Executor#setProcessDestroyer(ProcessDestroyer)
+     */
+    public void setProcessDestroyer(ProcessDestroyer processDestroyer) {
+      this.processDestroyer = processDestroyer;
+    }
+
+    /**
      * @see org.apache.commons.exec.Executor#getWorkingDirectory()
      */
     public File getWorkingDirectory() {
@@ -131,13 +148,14 @@
      */
     public void execute(final CommandLine command, final Map environment,
             final ExecuteResultHandler handler) throws ExecuteException, 
IOException {
+
         if (workingDirectory != null && !workingDirectory.exists()) {
             throw new IOException(workingDirectory + " doesn't exist.");
         }
 
         new Thread() {
 
-            /* (non-Javadoc)
+            /**
              * @see java.lang.Thread#run()
              */
             public void run() {
@@ -152,11 +170,6 @@
                     handler.onProcessFailed(e);
                 } catch(Exception e) {
                     handler.onProcessFailed(new ExecuteException("Execution 
failed", exitValue, e));
-                } finally {
-                    // remove the process to the list of those to destroy if 
the VM
-                    // exits
-                    //
-                    // processDestroyer.remove(process);
                 }
             }
         }.start();
@@ -271,12 +284,14 @@
             process.destroy();
             throw e;
         }
+
         streams.start();
 
         try {
             // add the process to the list of those to destroy if the VM exits
-            //
-            // processDestroyer.add(process);
+            if(this.getProcessDestroyer() != null) {
+              this.getProcessDestroyer().add(process);
+            }
 
             if (watchdog != null) {
                 watchdog.start(process);
@@ -301,7 +316,6 @@
                     // TODO: include cause
                     throw new IOException(e.getMessage());
                 }
-
             }
 
             if(!this.isSuccess(exitValue)) {
@@ -310,10 +324,10 @@
 
             return exitValue;
         } finally {
-            // remove the process to the list of those to destroy if the VM
-            // exits
-            //
-            // processDestroyer.remove(process);
+            // remove the process to the list of those to destroy if the VM 
exits
+            if(this.getProcessDestroyer() != null) {
+              this.getProcessDestroyer().remove(process);
+            }
         }
     }
 

Modified: 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java?rev=607936&r1=607935&r2=607936&view=diff
==============================================================================
--- 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java 
(original)
+++ 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/Executor.java 
Tue Jan  1 14:50:59 2008
@@ -58,6 +58,13 @@
     ExecuteWatchdog getWatchdog();
     void setWatchdog(ExecuteWatchdog watchDog);
 
+    /**
+     * Optinal cleanup of started processes if the main process
+     * is going to terminate.
+     */
+    ProcessDestroyer getProcessDestroyer();
+    void setProcessDestroyer(ProcessDestroyer processDestroyer);
+
     /*
      * Set the working directory of the created process.
      */

Modified: 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ProcessDestroyer.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ProcessDestroyer.java?rev=607936&r1=607935&r2=607936&view=diff
==============================================================================
--- 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ProcessDestroyer.java
 (original)
+++ 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ProcessDestroyer.java
 Tue Jan  1 14:50:59 2008
@@ -50,4 +50,11 @@
         *      successfully removed
         */
        boolean remove(Process process);
+
+  /**
+   * Returns the number of registered processes.
+   *
+   * @return the number of register process
+   */
+  int size();
 }

Modified: 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ShutdownHookProcessDestroyer.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ShutdownHookProcessDestroyer.java?rev=607936&r1=607935&r2=607936&view=diff
==============================================================================
--- 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ShutdownHookProcessDestroyer.java
 (original)
+++ 
commons/sandbox/exec/trunk/src/main/java/org/apache/commons/exec/ShutdownHookProcessDestroyer.java
 Tue Jan  1 14:50:59 2008
@@ -164,7 +164,16 @@
                }
        }
 
-       /**
+  /**
+   * Returns the number of registered processes.
+   *
+   * @return the number of register process
+   */
+  public int size() {
+    return processes.size();
+  }
+
+  /**
         * Invoked by the VM when it is exiting.
         */
        public void run() {
@@ -172,8 +181,14 @@
                        running = true;
                        Enumeration e = processes.elements();
                        while (e.hasMoreElements()) {
-                               ((Process) e.nextElement()).destroy();
-                       }
+        Process process = (Process) e.nextElement();
+        try {
+          process.destroy();
+        }
+        catch(Throwable t) {
+          System.err.println("Unable to terminate process during process 
shutdown");
+        }
+      }
                }
        }
 }

Modified: 
commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java?rev=607936&r1=607935&r2=607936&view=diff
==============================================================================
--- 
commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
 (original)
+++ 
commons/sandbox/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
 Tue Jan  1 14:50:59 2008
@@ -269,5 +269,86 @@
             assertEquals(1, e.getExitValue());
             return;
         }
-    }    
+    }
+
+    /**
+     * Test the proper handling of ProcessDestroyer for an synchronous process.
+     */
+    public void testExecuteWithProcessDestroyer() throws Exception {
+
+      CommandLine cl = new CommandLine(testScript);
+      ShutdownHookProcessDestroyer processDestroyer = new 
ShutdownHookProcessDestroyer();
+      exec.setProcessDestroyer(processDestroyer);
+      
+      assertTrue(processDestroyer.size() == 0);
+      assertTrue(processDestroyer.isAddedAsShutdownHook() == false);
+      
+      int exitValue = exec.execute(cl);
+
+      assertEquals("FOO..", baos.toString().trim());
+      assertEquals(0, exitValue);
+      assertTrue(processDestroyer.size() == 0);
+      assertTrue(processDestroyer.isAddedAsShutdownHook() == false);
+    }
+  
+    /**
+     * Test the proper handling of ProcessDestroyer for an asynchronous 
process.
+     * Since we do not terminate the process it will be terminated in the
+     * ShutdownHookProcessDestroyer implementation
+     */
+    public void testExecuteAsyncWithProcessDestroyer1() throws Exception {
+
+      CommandLine cl = new CommandLine(foreverTestScript);
+      MockExecuteResultHandler handler = new MockExecuteResultHandler();
+      ShutdownHookProcessDestroyer processDestroyer = new 
ShutdownHookProcessDestroyer();
+      ExecuteWatchdog watchdog = new ExecuteWatchdog(Integer.MAX_VALUE);
+
+      assertTrue(exec.getProcessDestroyer() == null);      
+      assertTrue(processDestroyer.size() == 0);
+      assertTrue(processDestroyer.isAddedAsShutdownHook() == false);
+
+      exec.setWatchdog(watchdog);
+      exec.setProcessDestroyer(processDestroyer);
+      exec.execute(cl, handler);
+
+      // wait for script to run
+      Thread.sleep(2000);
+      assertNotNull(exec.getProcessDestroyer());      
+      assertTrue(processDestroyer.size() == 1);
+      assertTrue(processDestroyer.isAddedAsShutdownHook() == true);
+    }
+
+    /**
+     * Test the proper handling of ProcessDestroyer for an asynchronous 
process.
+     * Since we do not terminate the process it will be terminated in the
+     * ShutdownHookProcessDestroyer implementation
+     */
+    public void testExecuteAsyncWithProcessDestroyer2() throws Exception {
+
+      CommandLine cl = new CommandLine(foreverTestScript);
+      MockExecuteResultHandler handler = new MockExecuteResultHandler();
+      ShutdownHookProcessDestroyer processDestroyer = new 
ShutdownHookProcessDestroyer();
+      ExecuteWatchdog watchdog = new ExecuteWatchdog(Integer.MAX_VALUE);
+
+      assertTrue(exec.getProcessDestroyer() == null);
+      assertTrue(processDestroyer.size() == 0);
+      assertTrue(processDestroyer.isAddedAsShutdownHook() == false);
+
+      exec.setWatchdog(watchdog);
+      exec.setProcessDestroyer(processDestroyer);
+      exec.execute(cl, handler);
+
+      // wait for script to run
+      Thread.sleep(2000);
+      assertNotNull(exec.getProcessDestroyer());      
+      assertTrue(processDestroyer.size() == 1);
+      assertTrue(processDestroyer.isAddedAsShutdownHook() == true);
+
+      // teminate it
+      watchdog.destroyProcess();
+      assertTrue(watchdog.killedProcess());
+      Thread.sleep(100);
+      assertTrue(processDestroyer.size() == 0);
+      assertTrue(processDestroyer.isAddedAsShutdownHook() == false);
+    }
 }


Reply via email to