|
The Java Specialists' Newsletter
Issue 011 2001-02-28
Category:
Language
Java version: Hooking into the shutdown callby Dr. Heinz M. Kabutz
Welcome to the 11th issue of "The Java(tm) Specialists'
Newsletter", where we have a "gloves-off" approach to the
Java(tm) language and development environment. Thank you
again for your support and the feedback you send me.
I am sitting outside in a mild South African summer evening,
looking up at the Southern Cross hoping the milky way will
inspire me to bring you a newsletter that is worth not pressing
delete on. I am always interested in hearing about "gotchas"
that you found while using Java, so please keep on sending me
your ideas.
Since the GUI is 63% of the JDK, I was tempted to send another
interesting bit about setting the focus to a component besides
the first one on a modal dialog. This seemingly simple problem
had me quite stumped, but luckily the Cape Town Java User
Group gave me one solution and I found another solution myself.
Next week I will write about that, so stay tuned. I know that
"real" programmers don't write GUIs, but if you are a "real"
Java programmer, other less real programmers might ask you
how to do these fancy tricks, and it's good to then have an
answer ;-) There is another newsletter in the pipeline that
tells you how to serialize GUI components across the network.
Would you like to really understand Java concurrency? Join us for an
in-depth study of how threading works in Java. During the course,
you will learn how to write correct and fast multi-threaded Java code.
Please
click here if you would like to learn more. Hooking into the shutdown call
Last year, while I was trying out the jBoss EJB application
server, I happened to notice that you could shutdown the server
by pressing CTRL+C. Somehow, the server "knew" you had killed
the program, and shutdown all the necessary services before
exiting the Java VM.
My Java-Guru-In-The-Making colleague told me that it was
possible to add a "shutdown hook" which would be called when
the application was being shutdown. This shutdown event
would happen when you call System.exit(), which in turn gets
called when you press CTRL+C. As was hinted in last week's
newsletter, once you use any GUI components, the VM starts
up GUI threads that you cannot shutdown cleanly. This means
that the only option you have of exiting your program is to
call System.exit()!!!
However, System.exit() can be called from anywhere in your
program and if it gets called, we want to have a central place
where we can add methods that will be called when we want
to exit. This central place was added, without much fanfare
(actually no fanfare at all!), in JDK 1.3, together with many
other cool features like the java.awt.Robot.
Here is an example of how you could add a shutdown hook into
the current VM runtime. You do this by constructing a new
Thread and passing that to the runtime to start when it wants
to shutdown.
public class ShoutdownTrick {
public static void main(String args[]) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("You wanna quit, hey?");
System.out.println("... fry eggs on your CPU.");
while(true);
}
};
System.out.println("Let's take a break...");
try {
Thread.sleep(5000);
}
catch(InterruptedException ex) {}
System.out.println("That's it, I'm outta here");
System.exit(0);
System.out.println("This line will not show!");
}
}
Try run this on your machine and you will notice that the only
way to stop the program is via the task manager. This of course
highlights one of the problems with writing code to call during
shutdown. What happens when the shutdown code does not exit?
I am told that in Delphi you can solve the Halting Problem,
unfortunately Java is not that powerful, so the VM cannot
know whether the shutdown code will stop or not. Ideally,
you should in the shutdown code only do what is absolutely
necessary to put the system in a state that is usable next time
you want to run the program, i.e. close DB connections cleanly,
close log files, etc.
A feature I did not know about until tonight is that you can
bypass the shutdown hooks and actually "halt" the VM without
further ado. So, the obvious next step in our Shutdown Hook
example is to add another thread that will halt the VM after
some timeout:
public class ShoutdownTrickWithHaltTimeout {
public static void main(String args[]) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("You wanna quit, hey?");
System.out.println("... fry eggs on your CPU.");
while(true);
}
});
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
Thread.sleep(10000);
} catch(InterruptedException ex) {}
// halt will bail out without calling further shutdown hooks or
// finalizers
Runtime.getRuntime().halt(1);
}
});
System.out.println("Let's take a break...");
try {
Thread.sleep(5000);
}
catch(InterruptedException ex) {}
System.out.println("That's it, I'm outta here");
System.exit(0);
System.out.println("This line will not show!");
}
}
The problem with this code is that even though you know that
after 10 seconds you will definitely halt the VM, you will
have to wait for 10 seconds each time you try to exit the VM,
because there is no way of knowing if the other threads are
finished yet. This brings out another interesting feature,
which is that all the shutdown hooks are threads and it seems
that they are all started at the same time. The obvious
solution is to make the "Halting" shutdown thread a Daemon
thread, but, alas, at that point in the VM processing, it
doesn't matter whether a thread is a Daemon thread or not,
it will run until it is finished.
It seems that, even though our friends at Sun have noticed
that such a shutdown hook feature is necessary, they have
not fully thought through the possibilities of what could go
wrong and how to solve it. Perhaps a System.exit(int status, long timeout)
would be appropriate?
There are some really cool extras in JDK 1.3 which are not very
widely publicised, or perhaps I'm reading the wrong magazines?
Shall we take a bet how long it takes before all the
System.exit(0) code in the world is replaced with
Runtime.getRuntime().halt(0)?
Until next week
Heinz
Language Articles
Related Java Course
Discuss at The Java Specialist Club
|