ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 8510] - shutdown hook does not fire in forked java task under JDK1.4
Date Thu, 24 Oct 2002 10:16:20 GMT
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=8510>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=8510

shutdown hook does not fire in forked java task under JDK1.4





------- Additional Comments From luors@iii.org.tw  2002-10-24 10:16 -------
I make some experiments and make a "guess".
Maybe the guess is wrong, but hope the other information
will help to solve the problem.


 == Experiment 1: use JDK to invoke MyProg ==

"MyProg" is a program with shutdown hook installed.
Press "Ctrl+C" to stop it.

"Yes" means the showdown hook of "MyProg" is invoked.

java.exe MyProg
    JDK 1.3.1 Yes      (1.3.1_03-b03)
    JDK 1.4.0 Yes      (1.4.0-b92)


 == Experiment 2: use Ant 1.5.1 to invoke MyProg ==

Run "MyProg" with Ant. Press "Ctrl+C" to stop it.

Ant 1.5.1 has its own shotdown hook (added by
ProcessDestroyer.java) which call java.lang.Process.destroy()
on the process of "MyProg".

"Yes" means the showdown hook of "MyProg" is invoked.

Ant 1.5.1 -> MyProg
    JDK 1.3.1 *Yes*
    JDK 1.4.0  No


 == Experiment 3: use "Invoker" to invoke MyProg ==

"Invoker" is a program which launches "MyProg" with
System.exec().
"Invoker" has its own shotdown hook which call
java.lang.Process.destroy() on the process of "MyProg".

"Yes" means the showdown hook of "MyProg" been invoked.

java.exe Invoker -> MyProg
    JDK 1.3.1       JDK 1.4.0
        0  No           0  No
        1  No           1  No
        2 *Yes*         2  No

    case 0: Invoker call proc.destroy() directly
            (not in its shutdown hook)
    case 1: Invoker call proc.destroy() in its own
            shutdown hook triggered when the
            "main" thread completed.
    case 2: Invoker call proc.destroy() in its own
            shutdown hook triggered by Ctrl+C.


 == Code and Document ==

On Win32 systems java.lang.Process.destroy()
make system call TerminateProcess() in both
JDK 1.3.1 and 1.4.0 which unconditionally
cause a process to exit.
(src\win32\native\java\lang\Win32Process_md.c)

In the JavaDoc of java.lang.Runtime,
  "In rare circumstances the virtual machine may abort,
   that is, stop running without shutting down cleanly.
   This occurs when the virtual machine is terminated
   externally, for example with the SIGKILL signal on
   Unix or the TerminateProcess call on Win32.".


 == My guess ==

Process.destroy() which calls TerminateProcess() should
give "MyProg" no chance to run its shutdown hook.
There are two exceptions: (marked with '*')

    JDK 1.3.1 + Ant 1.5.1 + MyProg (with Ctrl+C)
    JDK 1.3.1 + Invoker + MyProg (with Ctrl+C)

I "guess" that JDK 1.3.1 also send "Ctrl+C" to MyProg
which cause it to run the shutdown hook before killed
by TerminateProcess() from Ant and Invoker. But I have
no evidence.



 == Code: MyProg.java ==

import java.io.FileWriter;
import java.io.IOException;

public class MyProg
{
    public static void log(String s)
    {
        try
        {
            FileWriter fw = new FileWriter("MyProg.txt", true);
            fw.write(s + "\n");
            fw.flush();
            fw.close();
        } catch (IOException e) { }
    }

    public static void main(String[] args) throws Exception
    {
        log("MyProg: main() : " + System.getProperty("java.runtime.version"));
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run()
            {
                log("MyProg: hook invoked");
            }});
        log("MyProg: hook installed");
        while (true) ;
    }

}


 == Code: Invoker.java ==

public class Invoker
{
    public static Process exec()
    {
        try
        {
            System.out.println("before exec");
            Process proc = Runtime.getRuntime().exec("java MyProg");
            System.out.println("after exec, sleep 5 sec");
            Thread.currentThread().sleep(5 * 1000);
            System.out.println("ready");
            return proc;
        } catch (Exception e) { e.printStackTrace(); return null; }
    }

    public static void addHook(final Process proc)
    {
        System.out.println("enter addHook");
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run()
            {
                System.out.println("Invoker: hook invoked");
                System.out.println("before destory");
                proc.destroy();
                System.out.println("after destory");
            }});
        System.out.println("leave addHook");
    }

    public static void destroyDirectly()
    {
        Process proc = exec();
        System.out.println("before destroy");
        proc.destroy();
        System.out.println("after destroy");
    }

    public static void destroyFromHook1()
    {
        Process proc = exec();
        addHook(proc);
    }

    public static void destroyFromHook2()
    {
        Process proc = exec();
        addHook(proc);
        System.out.println("waiting for ctrl+c");
        while (true) ;
    }


    public static void main(String[] args) throws Exception
    {
        switch (Integer.parseInt(args[0]))
        {
            case 0 :
                destroyDirectly();
                break;
            case 1 :
                destroyFromHook1();
                break;
            case 2 :
                destroyFromHook2();
                break;

        }
    }
}

 == build.xml ==
 
<project name="A" default="A" basedir=".">
    <target name="A">
        <java classname="MyProg" fork="yes">
            <classpath>
                <pathelement location="."/>
            </classpath>
        </java>
    </target>
</project>

--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message