ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Luoh Ren-Shan" <lu...@iii.org.tw>
Subject Re: <java> task: shutdown hook / NoClassDefFoundError
Date Thu, 24 Oct 2002 10:13:09 GMT
Hi,

I also make some experiment about shutdown hook.
I hope that the "NoClassDefFoundError" problem can also be solved.

Luoh Ren-Shan


 == 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>



----- Original Message -----
From: "Markus Kieninger" <Markus.Kieninger@jSoft.de>
To: <luors@iii.org.tw>; <ant-user@jakarta.apache.org>
Sent: Wednesday, October 23, 2002 7:45 PM
Subject: Re: <java> task: shutdown hook / NoClassDefFoundError


> Hi,
>
> > Hi,
> >     I'm using Ant 1.5.1 + Sun JDK 1.4.0-b92 on Win 2K Pro SP2.
> >
> >     When using the <java> task to launch my program,
> >     I'm in a dilemma about forking or not.
> >
> >     If I choose not to fork, then I will get some
> >     NoClassDefFoundError with sun.reflect.* classes.
> >     The problem has been mentioned before,
> >     and it seems that Steve Loughran has a fix for it.
> >     But 1.5.1 doesn't has the fix inside.
> >
> >     If I choose to fork, then the shutdown hook of my
> >     program will not be triggered while Ctrl+C being
> >     pressed on the console window.
> >     (ProcessDestroyer.java -> java.lang.Process.destroy()
> >      -> Win32Process_md.c -> TerminateProcess()
> >      -> shutdown hook will NOT be invoked)
>
> I have got the same problem with the shutdown hook and it is already
> marked in the ant bug database (Bug #8510).
>
> The strange thing is that shutdown hook + ant works fine if you use
> jdk 1.3.1 or lower on windows. Starting with jdk 1.4.0 the shutdown hook
> of the forked program is not triggered anymore. I tried this with Ant
> 1.5 and 1.5.1.
> On linux it always works with all jdk and ant versions.
> (-> see my test results)
>
> >     Please help. Thank you.
> >
> > Luoh Ren-Shan
>
> Markus
>
>
> --
> To unsubscribe, e-mail:   <mailto:ant-user-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail: <mailto:ant-user-help@jakarta.apache.org>
>
>


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


Mime
View raw message