I'd been googling around for a way for me to send in command to a running Java program, but most of the post suggested to implement listener or wrap the program with a Jetty (or other server) implementation.
Is there a way to do this without adding additional dependencies?
The scenario is, i have a Java program which will be running indefinitely, and which will spawn a few running threads. I would like to be able to run a script to stop it, when it needs to be shut down, somewhat like the shutdown script servers tend to have. This will allow me to handle the shutdown process in the program. The program runs in a linux environment.
Thank you.
Implemented the shutdown hook and so far it looks good. The implementation codes:
final Thread mainThread = Thread.currentThread();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
logger.info("Shut down detected. Setting isRunning to false.");
if(processors != null && !processors.isEmpty()){
for (Iterator<IProcessor> iterator = processors.iterator(); iterator.hasNext();) {
IProcessor iProcessor = (IProcessor) iterator.next();
iProcessor.setIsRunning(false);
try {
iProcessor.closeConnection();
} catch (SQLException e1) {
logger.error("Error closing connection",e1);
}
}
}
try {
mainThread.join();
} catch (InterruptedException e) {
logger.error("Error while joining mainthread to shutdown hook",e);
}
}
});
Thanks for the suggestion.
Related
I'm currently developing a Vaadin-based program in Java which extracts documents from Domino databases and writes them to a MongoDB collection. The program works perfectly but has one small flaw:
Currently i've found no way to stop the program other then send "KILL" to the process. My shutdown hook/signal handler is totally ignored. I've narrowed down the problem to a single line of code:
NotesThread.sinitThread();
When i remove this line, the hook works perfectly and my program is shutdown properly. When the line is inserted, then the hook is never called.
Here is some example code:
private boolean running = true;
...
#Override
public void run() {
try {
NotesGC.runWithAutoGC(() -> {
NotesThread.sinitThread() // --> "Kills" all signal handling
Session session = NotesFactory.createSession();
while (running) {
Thread.sleep(1000);
System.out.println("Running ...");
}
session.recycle();
return null;
});
} catch (Exception e) {
} finally {
NotesThread.stermThread();
}
}
public void kill() {
System.out.println("Killed!");
this.running = false;
}
...
Signal.handle(new Signal("TERM"), sig -> runner.kill()); // Signal handler from main-method
I've asks friends and colleagues and nobody ever had the same problem.
NotesGC.runWithAutoGC
As I see you are using Domino JNA, a side project.
It use the domino CAPI.
It's open source: https://github.com/klehmann/domino-jna
You can create issue ticket or ask question.
BTW, func "runWithAutoGC" call initThread() in his body.
This link for source code: https://github.com/klehmann/domino-jna/blob/master/domino-jna/src/main/java/com/mindoo/domino/jna/gc/NotesGC.java
I have Shutdown hook that i attach to runtime
Runtime.getRuntime().addShutdownHook(new ShutDownHook(false));
Here is a shutDownHook Class
public class ShutDownHook extends Thread {
private final boolean interupt;
public ShutDownHook(boolean interupt) {
this.interupt = interupt;
}
#Override
public void run() {
if (interupt) {
return;
}
System.out.println("ShutdownHook Execution");
DbUtil.insertIntoDailyStats(MainDataModel.downloadedBytesSessionProperty().getValue());
MainDataModel.getInstance().loginProfile.getPreferences().putLong(
Info.PreferenceData.PREF_USER_DAILY_STAT_DOWNBYTE, MainDataModel.downloadedBytesTodayProperty().get());
System.out.println("ShutdownHook Execution finished");
}
}
And i close my application from System tray icon with a method
exit.addActionListener((ActionEvent e) -> {
try {
GlobalScreen.unregisterNativeHook();
System.exit(0);
} catch (NativeHookException ex) {
ex.printStackTrace();
}
});
Application closes bud hook execution didnt went thru, any idea why?
I know there are cases when ShutdownHook doesnt execute bud im closing my application with System.exit(0); that shoud be all safe and sound?
Ok i found a problem i had multiple ShutDownHooks hooked in for some reason this one didnt executed , i removed all beside one and now everything works ok.Maybe too much of a load.
Works flawlessly , also if you use netbeans dont use RED TERMINATION BUTTON , - just a note.That way you never get execution of SDH.
I have some service that both consumes from an inbound queue and produces to some outbound queue (where another thread, created by this service, picks up the messages and "transports" them to their destination).
Currently I use two plain Threads as seen in the code bellow but I know that in general you should not use them anymore and instead use the higher level abstractions like the ExecutorService.
Would this make sense in my case? More specifically I mean ->
would it reduce code?
make the code more robust in case of failure?
allow for smoother thread termination? (which is helpfull when running tests)
Am I missing something important here? (maybee some other classes from java.util.concurrent)
// called on service startup
private void init() {
// prepare everything here
startInboundWorkerThread();
startOutboundTransporterWorkerThread();
}
private void startInboundWorkerThread() {
InboundWorkerThread runnable = injector.getInstance(InboundWorkerThread.class);
inboundWorkerThread = new Thread(runnable, ownServiceIdentifier);
inboundWorkerThread.start();
}
// this is the Runnable for the InboundWorkerThread
// the runnable for the transporter thread looks almost the same
#Override
public void run() {
while (true) {
InboundMessage message = null;
TransactionStatus transaction = null;
try {
try {
transaction = txManager.getTransaction(new DefaultTransactionDefinition());
} catch (Exception ex) {
// logging
break;
}
// blocking consumer
message = repository.takeOrdered(template, MESSAGE_POLL_TIMEOUT_MILLIS);
if (message != null) {
handleMessage(message);
commitTransaction(message, transaction);
} else {
commitTransaction(transaction);
}
} catch (Exception e) {
// logging
rollback(transaction);
} catch (Throwable e) {
// logging
rollback(transaction);
throw e;
}
if (Thread.interrupted()) {
// logging
break;
}
}
// logging
}
// called when service is shutdown
// both inbound worker thread and transporter worker thread must be terminated
private void interruptAndJoinWorkerThread(final Thread workerThread) {
if (workerThread != null && workerThread.isAlive()) {
workerThread.interrupt();
try {
workerThread.join(TimeUnit.SECONDS.toMillis(1));
} catch (InterruptedException e) {
// logging
}
}
}
The main benefit for me in using ThreadPools comes from structuring the work in single, independent and usually short jobs and better abstraction of threads in a ThreadPools private Workers. Sometimes you may want more direct access to those, to find out if they are still running etc. But there are usually better, job-centric ways to do that.
As for handling failures, you may want to submit your own ThreadFactory to create threads with a custom UncaughtExceptionHandler and in general, your Runnable jobs should provide good exception handling, too, in order to log more information about the specific job that failed.
Make those jobs non-blocking, since you don't want to fill up your ThreadPool with blocked workers. Move blocking operations before the job is queued.
Normally, shutdown and shutdownNow as provided by ExecutorServices, combined with proper interrupt handling in your jobs will allow for smooth job termination.
I'm working on a Java project where I need to have multiple tasks running asynchronously. I'm led to believe Executor is the best way for me to do this, so I'm familiarizing myself with it. (Yay getting paid to learn!) However, it's not clear to me what the best way is to accomplish what I'm trying to do.
For the sake of argument, let's say I have two tasks running. Neither is expected to terminate, and both should run for the duration of the application's life. I'm trying to write a main wrapper class such that:
If either task throws an exception, the wrapper will catch it and restart the task.
If either task runs to completion, the wrapper will notice and restart the task.
Now, it should be noted that the implementation for both tasks will wrap the code in run() in an infinite loop that will never run to completion, with a try/catch block that should handle all runtime exceptions without disrupting the loop. I'm trying to add another layer of certainty; if either I or somebody who follows me does something stupid that defeats these safeguards and halts the task, the application needs to react appropriately.
Is there a best practice for approaching this problem that folks more experienced than me would recommend?
FWIW, I've whipped-up this test class:
public class ExecTest {
private static ExecutorService executor = null;
private static Future results1 = null;
private static Future results2 = null;
public static void main(String[] args) {
executor = Executors.newFixedThreadPool(2);
while(true) {
try {
checkTasks();
Thread.sleep(1000);
}
catch (Exception e) {
System.err.println("Caught exception: " + e.getMessage());
}
}
}
private static void checkTasks() throws Exception{
if (results1 == null || results1.isDone() || results1.isCancelled()) {
results1 = executor.submit(new Test1());
}
if (results2 == null || results2.isDone() || results2.isCancelled()) {
results2 = executor.submit(new Test2());
}
}
}
class Test1 implements Runnable {
public void run() {
while(true) {
System.out.println("I'm test class 1");
try {Thread.sleep(1000);} catch (Exception e) {}
}
}
}
class Test2 implements Runnable {
public void run() {
while(true) {
System.out.println("I'm test class 2");
try {Thread.sleep(1000);} catch (Exception e) {}
}
}
}
It's behaving the way I want, but I don't know if there are any gotchas, inefficiencies, or downright wrong-headedness waiting to surprise me. (In fact, given that I'm new to this, I'd be shocked if there wasn't something wrong/inadvisable about it.)
Any insight is welcomed.
I faced a similar situation in my previous project, and after my code blew in the face of an angry customer, my buddies and I added two big safe-guards:
In the infinite loop, catch Errors too, not just exceptions. Sometimes unexcepted things happen and Java throws an Error at you, not an Exception.
Use a back-off switch, so if something goes wrong and is non-recoverable, you don't escalate the situation by eagerly starting another loop. Instead, you need to wait until the situation goes back to normal and then start again.
For example, we had a situation where the database went down and during the loop an SQLException was thrown. The unfortunate result was that the code went through the loop again, only to hit the same exception again, and so forth. The logs showed that we hit the same SQLException about 300 times in a second!! ... this happened intermittently several times with occassional JVM pauses of 5 seconds or so, during which the application was not responsive, until eventually an Error was thrown and the thread died!
So we implemented a back-off strategy, approximately shown in the code below, that if the exception is not recoverable (or is excepted to recover within a matter of minutes), then we wait for a longer time before resuming operations.
class Test1 implements Runnable {
public void run() {
boolean backoff = false;
while(true) {
if (backoff) {
Thread.sleep (TIME_FOR_LONGER_BREAK);
backoff = false;
}
System.out.println("I'm test class 1");
try {
// do important stuff here, use database and other critical resources
}
catch (SqlException se) {
// code to delay the next loop
backoff = true;
}
catch (Exception e) {
}
catch (Throwable t) {
}
}
}
}
If you implement your tasks this way then I don't see a point in having a third "watch-dog" thread with the checkTasks() method. Furthermore, for the same reasons I outlined above, I'd be cautious to just start the task again with the executor. First you need to understand why the task failed and whether the environment is in a stable condition that running the task again would be useful.
Aside to eyeballing it, I generally run Java code against static analysis tools like PMD and FindBugs to look for deeper issues.
Specifically for this code FindBugs didn't like that results1 and results2 are not volatile in the lazy init, and that the run() methods might ignore the Exception because they aren't explicitly being handled.
In general I am a bit leery of the use of Thread.sleep for concurrency testing, preferring timers or terminating states/conditions. Callable might be useful in returning something in the event of a disruption that throws an exception if unable to compute a result.
For some best practices and more food for thought, check out Concurrency in Practice.
how about this
Runnable task = () -> {
try{
// do the task steps here
} catch (Exception e){
Thread.sleep (TIME_FOR_LONGER_BREAK);
}
};
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(task,0, 0,TimeUnit.SECONDS);
have you tried Quartz framework ?
There is a console Java application which is supposed to run until it is stopped by Ctrl+C or closing the console window. How that application can be programmed to execute a clean up code before exit?
You could use a Shutdown Hook.
Basically you need to create a Thread which will perform your shutdown actions, and then add it as a shutdown hook. For example:
class ShutdownHook extends Thread
{
public void run()
{
// perform shutdown actions
}
}
// Then, somewhere in your code
Runtime.getRuntime().addShutdownHook(new ShutdownHook())
A Shutdown hook is the way to go, but be aware that there is no guarantee that the code is actually executed. JVM crashes, power failures, or a simple "kill -9" on your JVM can prevent the code from cleaning up. Therefore you must ensure that your program stays in a consistent state even if it has been aborted abruptly.
Personally, I simply use a database for all state-storage. Its transactions model makes sure that the persistent storage is in a sane state no matter what happens. They spend years making that code fool-proof, so why should I waste my time on problems already solved.
Program to delete temp file bat.bat when program is exited:
public class Backup {
public static void createBackup(String s)
{
try{
String fileName ="C:\\bat"+ ".bat";
FileWriter writer=new FileWriter(fileName);
String batquery="cd C:\\Program Files\\MySQL\\MySQL Server 5.0\\bin"
+ "\nmysqldump -uroot -proot bankdb > \""+s+".sql\""
+"\nexit";
writer.append(batquery);
writer.close();
}
catch(Exception e){e.getMessage();}
try{
Process p =Runtime.getRuntime().exec("cmd /c start C:\\bat.bat");
}
catch(Exception e){e.getMessage();}
ShutDownHook sdh=new ShutDownHook();
Runtime.getRuntime().addShutdownHook(sdh);
}
}
class ShutDownHook extends Thread
{
public void run()
{
try
{
File f=new File("c:/bat.bat");
f.delete();
}
catch(Exception e){e.getMessage();}
}
}
The code written inside a Threads run() method will execute when the runtime object terminates...
class ShutdownHookclass extends Thread {
public void run() {
// perform shutdown actions
}
}
//could be written anywhere in your code
Runtime.getRuntime().addShutdownHook(new ShutdownHookclass())