Java Shutdown Hooks on PC Shutdown - java

Does Shutdown Hooks run when a computer shut down? I saw a post about this from a while back, and it is from 2015... so it makes me think that this could have been fixed/changed since then. If not, how should I do this, without causing any issues?
EDIT: I have done some testing myself and found that it does not run on system shut down. Using this:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
//some code here
}
});
I am using this so I could be able to disable some token/key that was generated at the start of the program. If I cannot disable the token at the end of the program, things will get all messed up...
Thanks for any input given!

Related

Detect Ctrl+C in Java Console

I have a Console-Java game. The score from the game will be saved in a JSON file if Ctrl+C is pressed. The process to save the score in a JSON file works. But I don't know, how to detect Ctrl+C from the console and if this happens, I will save the score (just a method call).
With KeyListener it doesn't work on the console (only with JFrame as far as I know).
I couldn't find a solution to my problem on the internet.
Do I have to do it with Runtime? I have tried it, but it didn't work...
Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
Test.mainThread.interrupt();
}
});
There are similar questions on Stackoverflow, but not for use on the console Catching Ctrl+C in Java
Adding a shutdown hook is the right way to do it, but Test.mainThread.interrupt(); probably will not work. The JVM is already shutting down. Your mainThread is unlikely to have time to respond to an interrupt; once all shutdown hooks finish, Java terminates.
Just have your shutdown hook explicitly perform whatever actions you need taken:
Runtime.getRuntime().addShutdownHook(new Thread()
{
#Override
public void run()
{
try
{
Test.saveScore();
}
catch (IOException e)
{
System.err.println("Couldn't save score before terminating.");
e.printStackTrace();
}
}
});
We know that CTRL-C closes the application and shuts down the JVM. And since it is a normal shutdown, it runs the shutdown hooks. So creating a shutdown hook is a correct approach:
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
// Do something to save the score
}));
Note that we're passing a Runnable here as the shutdown task. So we can pass an object that has the required functionality:
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
gameScores.save(); // assuming we have a gameScores object in this scope
}));
Your initial attempt by interrupting the thread can be viewed as a variant of this approach. Instead of passing the business object - gameScores - we can pass the thread to interrupt it later. But it's better to operate on the business level.

JavaFX app using retrofit async request quitting very slowly

I'm developing a JavaFX app with Java 8 and for api requests I'm using retrofit 2.1.0 with converter-gson 2.1.0.
If I make the synchronous request:
Patient p = Core.api.getPatient(2).execute().body();
Everything works fine, but if I do the asynchronous version:
Core.api.getPatient(2).enqueue(new Callback<Patient>() {
#Override
public void onResponse(Call<Patient> call, Response<Patient> response) {
System.out.println("DONE");
}
#Override
public void onFailure(Call<Patient> call, Throwable t) {
// Nothing
}
});
Everything also works out correctly (it prints "DONE"). However when I quit the application using the standard JavaFX call Platform.exit() the UI closes but the application lingers open still and will only exit after ~40 seconds.
If I just do System.exit(0) everything works as intended so I'm guessing this might be some threading issue but I'm not sure.
Anyone have an idea on what might be wrong?
EDIT:
I found out that after doing Platform.exit() a few threads, with names like RMI TCP Connection(2) keep alternating and using 100% of the CPU.
OkHttp uses two thread pools that keep threads alive for 60 seconds after use. You can shut em down with force by calling shutdown on the dispatcher's executor and by calling evictAll on the connection pool.

Apache Camel, send message when server starts and stops

I have a simply camel MINA server using the JAVA DSL, and I am running like the example documented here:
Running Camel standalone and have it keep running in JAVA
MINA 2 Component
Currently this server receives reports from a queue, updates them, and then sends them away to the next server. A very simple code:
public class MyApp_B {
private Main main;
public static void main(String... args) throws Exception {
MyApp_B loadbalancer = new MyApp_B();
loadbalancer.boot();
}
public void boot() throws Exception {
main = new Main();
main.enableHangupSupport();
main.addRouteBuilder(
new RouteBuilder(){
#Override
public void configure() throws Exception {
from("mina:tcp://localhost:9991")
.setHeader("minaServer", constant("localhost:9991"))
.beanRef("service.Reporting", "updateReport")
.to("direct:messageSender1");
from("direct:messageSender1")
.to("mina:tcp://localhost:9993")
.log("${body}");
}
}
);
System.out.println("Starting Camel MyApp_B. Use ctrl + c to terminate the JVM.\n");
main.run();
}
}
Now, I would like to know if it is possible to do two things:
Make this server send a message to a master server when it starts running. This is an "Hello" message with this server's information basically.
Tell the master server to forget him when I shut it down pressing CTRL+C or doing something else.
I have also read this:
http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/support/ServiceSupport.html#doStart%28%29
technically, by overriding the doStart and doStop methods I should get the intended behavior, however, those methods (specially the doStop method) don't work at all.
Is there a way to do this ? If yes how? If not, what are my options?
Thanks in advance, Pedro.
The code does work properly after all. The problem is my IDE, Eclipse. When using the Terminate button, Eclipse simply kills the process instead of send the CTRL+C signal to it. Furthermore it looks like Eclipse has no way of being able to send a CTRL+C signal to a process running on its console.
I have also created a discussion on Eclipse's official forums:
http://www.eclipse.org/forums/index.php/m/1176961/#msg_1176961
And may it some day help some one in a situation similar to mine.

Regarding shutdownhook understanding

I was going through shutdown hook feature of java , My analysis was ..shutdownhook allows to register a thread that will be created immediatly but started only when the JVM ends ! So it is some kind of "global jvm finalizer", and you can make useful stuff in this thread (for example shutting down java ressources like an embedded hsqldb server). This works with System.exit(), or with CTRL-C / kill -15 (but not with kill -9 on unix, of course).
Please advise more practical uses and please also if possibe an small example will help to make understanding more clear..!
When a shutdown hook is added to a Runtime instance, it is added to a list of Threads to start upon clean termination of the JVM.
Example: Using shutdown hook to ensure that a java.awt.TrayIcon is removed from the system tray.
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
if (SystemTray.isSupported()) {
SystemTray.getSystemTray().remove(yourTrayIcon);
}
} catch (Exception e) {
// failed to remove
e.printStackTrace();
}
}
});
More can be read in the offical documentation.

Call a method when java applcation force close

I want to call a method when I terminating my Java application forcefully. I need to release resource I used in my application.
Please help me.
Thanks
It depends a bit on what you mean by "forcefully", but I expect you want to add a Shutdown hook.
Shutdown hooks are small threads which are called whenever Java attempts to shut down. You can add one using the Runtime API, like so:
Runtime.getRuntime().addShutdownHook(Thread hook)
Of course, if you really force a shutdown (by turning the machine off, or running kill -9 on it,) the operating system will shut down Java without giving it a chance to clean up anything. In that case, you won't be able to do anything about it.
This'll be what you want:
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
// release your resource
}
});
You need to use Shutdownhook: Here is example:
Runtime.getRuntime ().addShutdownHook (
new Thread () {
#Override
public void run () {
System.out.println ( "Shutdown hook" );
}
} );

Categories