Runtime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run()
{
updateZonas();
db.close();
}
});
This works for any Java application(Swing/AWT/Console)
Answer from Santhosh Kumar Tekuri on Stack OverflowRuntime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run()
{
updateZonas();
db.close();
}
});
This works for any Java application(Swing/AWT/Console)
Are you using a JFrame? if so you can try this:
myframe.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(WindowEvent winEvt) {
updateZonas();
db.close();
System.exit(0);
}
});
The Runtime.addShutdownHook method can be used to add a shutdown hook, which is basically a unstarted Thread, which executes on shutdown of the Java Virtual Machine.
However, this is territory that should to be tread carefully, as it is being performed at a very sensitive time of the JVM's life cycle. From the API Specifications for the Runtime.addShutdownHook method:
Shutdown hooks run at a delicate time in the life cycle of a virtual machine and should therefore be coded defensively. They should, in particular, be written to be thread-safe and to avoid deadlocks insofar as possible.
In any event, be sure to read up a bit on how shutdown hooks work, as they probably should not be approached without some good preparation. Be sure to carefully read the API Specification for the Runtime.addShutdownHook method.
Here's are a couple articles I found from searching for information for this answer:
Shutdown Hooks -- it shows a little example of how a shutdown hook is added for logging at shutdown.
Design of the Shutdown Hooks API -- addresses some design decisions of shutdown hooks in a question and answer style.
The function Runtime.addShutdownHook(Thread thehook) allows you to register a hook into the Java Virtual Machine.
The hook works as an initialized but unstarted thread, which will be called by the JVM on exit. In case you register more than one hook, note that the order in which the hooks are called is undefined.
You do not want to use File.deleteOnExit(): your web application should run for months without exiting the JVM, right? Instead, you need to clean-up after yourself properly.
Use File.delete() and check the return status (it returns a boolean: check it). If that returns false, figure out why that's happening. For instance, if you are on Windows, there are some (IMO foolish) restrictions on deleting files that are opened by a live process -- including the process trying to delete them. So, if you have another thread that has a file handle to the file you are trying to delete, you are not going to be able to delete the file.
So, what is holding-open that file lock? Find that and fix it. Specifically, make sure that you have properly-closed all your file handles (did you use finally blocks? If no, you're doing it wrong) and that you aren't trying to do something silly like dynamically-generate a file, save it to the disk, have Tomcat serve it using the DefaultServlet, and then delete the file.
If you can't manage to make the file-deletion work synchronously, then maybe try asynchronous deletion: keep a queue of files to delete (maybe in the application scope) and process them every few minutes. Just try to delete each one and, if the deletion succeeds, remove it from the queue. If the queue exceeds some size, automatically send an email to an administrator to complain about the size of the queue.
Have you tried below steps in the same web app?
- Read existing files in temp folder
- Delete all files(if there any) which are created earlier.
- Now start stuff's which creates new temp files
ProcessImpl.java on destroy method call native function terminateProcess:
public void destroy() { terminateProcess(handle); }
private static native void terminateProcess(long handle);
terminateProcess is platform dependent and for Windows you can find sources here. It's just call Windows TerminateProcess function (link to this function was in previously answer or you can google it) with uExitCode=1 - thats why exit code of destroyed process is 1.
In linux looks like is used something similar to this. And as proof next code return 143 in ubuntu, that correspond to SIGTERM (https://stackoverflow.com/a/4192488/3181901):
public static void main(final String[] args) throws IOException, InterruptedException {
final Process process = Runtime.getRuntime().exec(args[0]);
process.destroy();
Thread.sleep(1000);
System.out.println(process.exitValue());
}
Why would it show a problem? You're trying to destroy a process that was already destroyed. The specification of
Process.destroy()doesn't say what happens if there was nothing to destroy, so it is logical (I suppose) to assume that if there's nothing to destroy, then there's nothing to complain about. Compare withThread.join(), which doesn't just die if the thread has already ended.The only way to kill a process is to send it a signal. On some OS's, there are other, more "violent" ways (on some platforms, for example, it is possible to simply remove the process from the OS's list of running processes. Results are undefined and it usually ends ugly), but at least with platforms that I know of, it's really all about sending signals.
Possible, indeed, that it's because it takes time to invoke
Thread.sleep(). Try increasing the timeout value.
Add shutdown hook. See this javadoc.
Example:
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
System.out.println("In shutdown hook");
}
}, "Shutdown-thread"));
}
Since you are using Swing. When you close your application (by pressing the close button), you could simply hide your frame. Run the method you would want which creates the file and then exit the Frame. This would result in a graceful exit. Should there be any errors/exceptions, you can log that into a separate file.
Here is the code
package test;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
public class TestFrame extends JFrame{
public TestFrame thisFrame;
public TestFrame(){
this.setSize(400, 400);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
public static void main(String[] args){
TestFrame test = new TestFrame();
test.addComponentListener(new ComponentAdapter() {
@Override
public void componentHidden(ComponentEvent e) {
System.out.println("Replace sysout with your method call");
((JFrame)(e.getComponent())).dispose();
}
});
}
}
Please be aware of using shutdown hooks. As given in the Javadoc, it states that
When the virtual machine is terminated due to user logoff or system shutdown the underlying operating system may only allow a fixed amount of time in which to shut down and exit. It is therefore inadvisable to attempt any user interaction or to perform a long-running computation in a shutdown hook
I seem to have solved the problem. The problem with the I2C is that the reserved id "my-i2c-bus" can be applied only once to a Pi4J Context. Using a new instance of the Context for each I2C device solves that problem. This is not a problem with DigitalOutput since I set the id to "PINn" where n is the pin number. Pi4J doesn't seem to mind that. I think the real problem is that I had a polling loop in a separate Thread running and I wasn't giving it time to stop polling before I do a shutdown(). All is well now.
Some of the IO are still in use while shutting down the application. Are you able to call pi4j.shutdown(); before the program exits?
Parameters and local variables are allocated on the stack (with reference types, the object lives on the heap and a variable in the stack references that object on the heap). The stack typically lives at the upper end of your address space and as it is used up it heads towards the bottom of the address space (i.e. towards zero).
Your process also has a heap, which lives at the bottom end of your process. As you allocate memory, this heap can grow towards the upper end of your address space. As you can see, there is a potential for the heap to "collide" with the stack (a bit like tectonic plates!!!).
The common cause for a stack overflow is a bad recursive call. Typically, this is caused when your recursive functions doesn't have the correct termination condition, so it ends up calling itself forever. Or when the termination condition is fine, it can be caused by requiring too many recursive calls before fulfilling it.
However, with GUI programming, it's possible to generate indirect recursion. For example, your app may be handling paint messages, and, whilst processing them, it may call a function that causes the system to send another paint message. Here you've not explicitly called yourself, but the OS/VM has done it for you.
To deal with them, you'll need to examine your code. If you've got functions that call themselves then check that you've got a terminating condition. If you have, then check that when calling the function you have at least modified one of the arguments, otherwise there'll be no visible change for the recursively called function and the terminating condition is useless. Also mind that your stack space can run out of memory before reaching a valid terminating condition, thus make sure your method can handle input values requiring more recursive calls.
If you've got no obvious recursive functions then check to see if you're calling any library functions that indirectly will cause your function to be called (like the implicit case above).
If you have a function like:
int foo()
{
// more stuff
foo();
}
Then foo() will keep calling itself, getting deeper and deeper, and when the space used to keep track of what functions you're in is filled up, you get the stack overflow error.
Check for any recusive calls for methods. Mainly it is caused when there is recursive call for a method. A simple example is
public static void main(String... args) {
Main main = new Main();
main.testMethod(1);
}
public void testMethod(int i) {
testMethod(i);
System.out.println(i);
}
Here the System.out.println(i); will be repeatedly pushed to stack when the testMethod is called.
One of the (optional) arguments to the JVM is the stack size. It's -Xss. I don't know what the default value is, but if the total amount of stuff on the stack exceeds that value, you'll get that error.
Generally, infinite recursion is the cause of this, but if you were seeing that, your stack trace would have more than 5 frames.
Try adding a -Xss argument (or increasing the value of one) to see if this goes away.