I would like to determine the exit status of the process during the shutdown hook runtime.
I want to have a logic which is based on the status code (0 or nonzero)
(ex: if zero do nothing else nonzero send an alert email)
Do you know how I can get this information?
I tried to override the SecurityManager checkExit(int status) method - this works if System.exit(status) is called anywhere explicitly - however, it doesn't set the status when the application exits "normally" (no active threads), or an error kills the VM.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.Permission;
public class ExitChecker {
public ExitChecker() {
System.setSecurityManager(new ExitMonitorSecurityManager());
Runtime.getRuntime().addShutdownHook(new Thread(new MyShutdownHook()));
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String line = "";
while (!line.equalsIgnoreCase("Q")) {
try {
System.out.println("Press a number to exit with that status.");
System.out.println("Press 'R' to generate a RuntimeException.");
System.out.println("Press 'O' to generate an OutOfMemoryError.");
System.out.println("Press 'Q' to exit normally.");
line = input.readLine().trim();
processInput(line);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
}
private void processInput(String line) {
if (line.equalsIgnoreCase("Q")) {
// continue, will exit loop and exit normally
} else if (line.equalsIgnoreCase("R")) {
throwRuntimeException();
} else if (line.equals("O")) {
throwError();
} else {
// try to parse to number
try {
int status = Integer.parseInt(line);
callExit(status);
} catch(NumberFormatException x) {
// not a number.. repeat question...
System.out.println("\nUnrecognized input...\n\n");
}
}
}
public void callExit(int status) {
System.exit(status);
}
public void throwError() {
throw new OutOfMemoryError("OutOfMemoryError");
}
public void throwRuntimeException() {
throw new RuntimeException("Runtime Exception");
}
public static void main(String[] args) {
new ExitChecker();
}
private static class ExitMonitorSecurityManager extends SecurityManager {
#Override
public void checkPermission(Permission perm) {
//System.out.println(perm.getName());
//System.out.println(perm.getActions());
}
#Override
public void checkPermission(Permission perm, Object context) {
//System.out.println(perm.getName());
//System.out.println(perm.getActions());
}
#Override
public void checkExit(int status) {
System.out.println("Setting exit value via security manager...");
MyShutdownHook.EXIT_STATUS = status;
}
}
private static class MyShutdownHook implements Runnable {
public static Integer EXIT_STATUS;
public void run() {
System.out.println("In MyShutdownHook - exit status is " + EXIT_STATUS);
}
}
}
Here is some example code whereby a dedicated class is used to initiate a System.exit call via a call to doExit(int). The class also stores the exit status and subsequently acts as a shut-down hook.
public class ShutDownHook implements Runnable {
private volatile Integer exitStatus;
// Centralise all System.exit code under control of this class.
public void doExit(int exitStatus) {
this.exitStatus = exitStatus;
System.exit(exitStatus); // Will invoke run.
}
public void run() {
// Verify that an exit status has been supplied.
// (Application could have called System.exit(int) directly.)
if (this.exitStatus != null) {
switch(exitStatus) {
case 0: // Process based on exit status.
// Yada yada ...
}
}
}
}
Why do this in the application itsellf? If your application is not sending a e-mails as part of normal operations, incorporating this kind of functionality is not a good idea, IMHO.
I would just trust to setting an appropriate return value from the JVM process and let a shell script or whatever take care of the conditional creation of the e-mail.
Shutdownhooks are supposed to run for a short time only, sending an e-mail could consume quite some time.
You must save the exit status in main into a global (public static) variable.
Related
I am trying to make a program that can detect my key strokes then based on them do something but every time I run my program it just finishes with exit code 0 even though I have the listeners initialized any ideas? (I got no errors)
public class Main {
public static void main(String[] args) {
InitializeEvents initializeEvents = new InitializeEvents();
try {
GlobalScreen.registerNativeHook();
} catch (NativeHookException e) {
e.printStackTrace();
}
GlobalScreen.getInstance().addNativeKeyListener(initializeEvents.getKeyboard());
GlobalScreen.getInstance().addNativeMouseListener(initializeEvents.getMouse());
}
}
Here is where I initialize my event
public class InitializeEvents {
private final NativeKeyboardEvent keyboard;
private final NativeMouseClickEvent mouse;
public InitializeEvents() {
keyboard = new NativeKeyboardEvent();
mouse = new NativeMouseClickEvent();
}
public NativeKeyboardEvent getKeyboard() {
return keyboard;
}
public NativeMouseClickEvent getMouse() {
return mouse;
}
}
Lastly here is my event
public class NativeKeyboardEvent implements NativeKeyListener {
#Override
public void nativeKeyPressed(NativeKeyEvent e) {
System.out.println("test");
}
#Override
public void nativeKeyReleased(NativeKeyEvent e) {
System.out.println("test");
}
#Override
public void nativeKeyTyped(NativeKeyEvent e) {
System.out.println("test");
}
}
The weird thing about it is that it was working earlier but then it randomly stopped printing "test" when I clicked a key even though nothing changed.
As soon as your application no longer has any non-daemon threads running, it will terminate. You can easily validate this by putting
while(true) {
Thread.sleep(Long.MAX_VALUE);
}
on the last line in your main method. Eventually, I can imagine that your application will either have an active window or a taskbar icon that keeps it alive and that adds an application quit option, replacing the need for this temporary solution.
I'm currently writing a simple java app. I have a menu where I can perform different functions. What I'm wanting to do is execute a process, and while that process is running, still be able to navigate around the app, choosing different options from the menu. I also want to be able to stop the process from the menu.
So suppose I had this:
public class UserInterface {
Console c = System.console();
boolean quitFlag = false;
public void userInput()
{
String choice = c.readline("> ");
while(choice != "exit")
{
switch(choice){
case "1":
startProcess();
break;
case "2":
endProcess();
break;
}
}
public void startProcess()
{
int i = 0;
while(!quitFlag)
i = i + 1;
}
public void endProcess()
{
quitFlag = true;
}
}
How would I go about letting startProcess() continue while executing userInput()? Is there a general principle for this? How would I do it if startProcess() and endProcess() were in different classes?
There are several ways to do this but the simplest is via the Thread class. The Java docs for java.lang.Thread show examples, but the principle is that you place your separate process code inside a Thread subclass or in the run() method of a Runnable interface implementation which is passed to the Thread.
Call start() or run() on the thread to start processing. The UI thread continues independently.
Although Thread includes a stop() method, it is deprecated and the Java docs explain why. Best practice is to create your own method that sets a flag indicating that the process should end early, and then check this flag at frequent intervals.
Something like:
public class UserInterface {
MyProcessor processor = null;
...
public void startProcess() {
processor = new MyProcessor();
new Thread(processor).start();
}
public void endProcess() {
if (processor != null) {
processor.endProcess();
}
}
private class MyProcessor implements Runnable {
private boolean quitFlag = false;
#Override
public void run() {
int i = 0;
while (!quitFlag) {
i = i + 1;
}
}
public void endProcess() {
quitFlag = true;
}
}
}
I am making a Java app which does something on a HotKey combination. I have an infinite while loop to wait for HotKey input to close, but it makes the app very CPU time costing.
Following is how my code looks in the simplest way:
static boolean isOpen = true;
void main()
{
....
add SomeHotKeyListener();
....
while(isOpen)
{ }
releaseResources();
}
void onHotKey(int hotKeyIdentifier)
{
if(hotKeyIdentifier == something)
do something;
if(hotKeyIdentifier == something)
isOpen = false;
}
I need a multi-threading approach to achieve this, or if someone has something better to fit in.
I recommend you read about the synchronized keyword in Java. Just Google it, and you should find a ton of examples and tutorials.
This should solve your case:
static boolean isOpen = true;
static Object lock = new Object();
void main()
{
....
add SomeHotKeyListener();
....
synchronized(lock)
{
while(isOpen)
{
try {
lock.wait()
} catch(InterruptedException e) {
}
}
}
releaseResources();
}
void onHotKey(int hotKeyIdentifier)
{
if(hotKeyIdentifier == something)
do something;
if(hotKeyIdentifier == something)
{
synchronized(lock)
{
isOpen = false;
lock.notify();
}
}
}
Infinite while loop can consume quite a lot of system resource. Using wait and notify is recommended. Also you have to declare your boolean volatile as otherwise there is no guarantee that the changes made by one thread is picked up by the other. Below is an example which does something in a separate thread and until interrupted by the calling thread based on a user input (an enter in this case). See also the example from Oracle here
import java.util.Scanner;
public class WaitTest implements Runnable {
private volatile boolean shutdown = false;
public static void main(String[] args) {
WaitTest w = new WaitTest();
new Thread(w).start();
System.out.println("Press any key to interrupt");
Scanner sc = new Scanner(System.in);
sc.nextLine();
w.triggerShutDown();
}
#Override
public void run() {
while (!shutdown) {
synchronized (this) {
try {
System.out.println("doing some silly things");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Server shutdown successfully");
}
public synchronized void triggerShutDown() {
this.shutdown = true;
notify();
}
}
I have a bunch of threads running concurrently. Sometimes a thread needs to notify other threads to wait for it to finish a job and signal them again to resume. Since I'm somehow new to Java's synchronization, I wonder what is the right way to do such thing. My code is something like this:
private void Concurrent() {
if (shouldRun()) {
// notify threads to pause and wait for them
DoJob();
// resume threads
}
// Normal job...
}
Update:
Note that the code I wrote is inside a class which will be executed by each thread. I don't have access to those threads or how they are running. I'm just inside threads.
Update 2:
My code is from a crawler class. The crawler class (crawler4j) knows how to handle concurrency. The only thing I need is to pause other crawlers before running a function and resume them afterwards. This code is the basics of my crawler:
public class TestCrawler extends WebCrawler {
private SingleThread()
{
//When this function is running, no other crawler should do anything
}
#Override
public void visit(Page page) {
if(SomeCriteria())
{
//make all other crawlers stop until I finish
SingleThread();
//let them resume
}
//Normal Stuff
}
}
Here is a short example on how to achieve this with the cool java concurrency stuff:
snip old code doesn't matter anymore with the Pause class.
EDIT:
Here is the new Test class:
package de.hotware.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
private Pause mPause;
public Test() {
this.mPause = new Pause();
}
public void concurrent() throws InterruptedException {
while(true) {
this.mPause.probe();
System.out.println("concurrent");
Thread.sleep(100);
}
}
public void crucial() throws InterruptedException {
int i = 0;
while (true) {
if (i++ % 2 == 0) {
this.mPause.pause(true);
System.out.println("crucial: exclusive execution");
this.mPause.pause(false);
} else {
System.out.println("crucial: normal execution");
Thread.sleep(1000);
}
}
}
public static void main(String[] args) {
final Test test = new Test();
Runnable run = new Runnable() {
#Override
public void run() {
try {
test.concurrent();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Runnable cruc = new Runnable() {
#Override
public void run() {
try {
test.crucial();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
ExecutorService serv = Executors.newCachedThreadPool();
serv.execute(run);
serv.execute(run);
serv.execute(cruc);
}
}
And the utility Pause class:
package de.hotware.test;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Utility class to pause and unpause threads
* with Java Concurrency
* #author Martin Braun
*/
public class Pause {
private Lock mLock;
private Condition mCondition;
private AtomicBoolean mAwait;
public Pause() {
this.mLock = new ReentrantLock();
this.mCondition = this.mLock.newCondition();
this.mAwait = new AtomicBoolean(false);
}
/**
* waits until the threads until this.mAwait is set to true
* #throws InterruptedException
*/
public void probe() throws InterruptedException {
while(this.mAwait.get()) {
this.mLock.lock();
try {
this.mCondition.await();
} finally {
this.mLock.unlock();
}
}
}
/**
* pauses or unpauses
*/
public void pause(boolean pValue) {
if(!pValue){
this.mLock.lock();
try {
this.mCondition.signalAll();
} finally {
this.mLock.unlock();
}
}
this.mAwait.set(pValue);
}
}
The basic usage is to call probe() before each run. This will block if it is paused until pause(false) is called.
Your class would look like this:
public class TestCrawler extends WebCrawler {
private Pause mPause;
public TestCrawler(Pause pPause) {
this.mPause = pPause;
}
private SingleThread()
{
//When this function is running, no other crawler should do anything
}
#Override
public void visit(Page page) {
if(SomeCriteria())
{
//only enter the crucial part once if it has to be exclusive
this.mPause.probe();
//make all other crawlers stop until I finish
this.mPause.pause(true);
SingleThread();
//let them resume
this.mPause.pause(false);
}
this.mPause.probe();
//Normal Stuff
}
}
public class StockMonitor extends Thread {
private boolean suspend = false;
private volatile Thread thread;
public StockMonitor() {
thread = this;
}
// Use name with underscore, in order to avoid naming crashing with
// Thread's.
private synchronized void _wait() throws InterruptedException {
while (suspend) {
wait();
}
}
// Use name with underscore, in order to avoid naming crashing with
// Thread's.
public synchronized void _resume() {
suspend = false;
notify();
}
// Use name with underscore, in order to avoid naming crashing with
// Thread's.
public synchronized void _suspend() {
suspend = true;
}
public void _stop() {
thread = null;
// Wake up from sleep.
interrupt();
}
#Override
public void run() {
final Thread thisThread = Thread.currentThread();
while (thisThread == thread) {
_wait();
// Do whatever you want right here.
}
}
}
Calling _resume and _suspend will enable you to resume and pause the Thread. _stop will let you stop the thread gracefully. Note that, once you stop the Thread, there is no way to resume it again. The Thread is no longer usable.
The code is being picked from a real world open source project : http://jstock.hg.sourceforge.net/hgweb/jstock/jstock/file/b17c0fbfe37c/src/org/yccheok/jstock/engine/RealTimeStockMonitor.java#l247
You can use wait() and notify()
thread waiting:
// define mutex as field
Object mutex = new Object();
// later:
synchronized(mutex) {
wait();
}
notify the thread to continue
synchronized (mutex) {
notify();
}
I have developed an application which is intended to allow users to execute queries.Once the user enters the query and clicks on execute button the control is passed to RMI server which in turn starts the thread.
User should be able to execute other quesries one after the other and each query will b executed in different thread.
I am not able to stop the execution of the thread. I want to stop the execution while it is executing or on the button click event based on the thread id passed.
I am trying below code
public class AcQueryExecutor implements Runnable {
private volatile boolean paused = false;
private volatile boolean finished = false;
String request_id="",usrnamee="",pswd="",driver="",url="";
public AcQueryExecutor(String request_id,String usrnamee,String pswd,String driver,String url) {
this.request_id=request_id;
this.usrnamee=usrnamee;
this.pswd=pswd;
this.url=url;
this.driver=driver;
}
public void upload() throws InterruptedException {
//some code
stop();
//some more code
}
public void run() {
try {
while(!finished) {
upload();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void stop() {
finished = true;
}
}
RMI server class from where I start the thread
public class ExecutorServer extends UnicastRemoteObject implements ExecutorInterface
{
public ExecutorServer()throws RemoteException
{
System.out.println("Server is in listening mode");
}
public void executeJob(String req_id,String usrname,String pwd,String driver,String url)throws RemoteException
{
try{
System.out.println("Inside executeJob.wew..");
AcQueryExecutor a=new AcQueryExecutor(req_id,usrname,pwd,driver,url);
Thread t1 = new Thread(a);
t1.start();
}
catch(Exception e)
{
System.out.println("Exception " + e);
}
}
public void killJob(String req_id)throws RemoteException{
logger.debug("Kill task");
AcQueryExecutor a=new AcQueryExecutor(req_id,"","","","");
a.stop();
}
public static void main(String arg[])
{
try{
LocateRegistry.createRegistry(2007);
ExecutorServer p=new ExecutorServer();
Naming.rebind("//localhost:2007/exec1",p);
System.out.println ("Server is connected and ready for operation.");
}catch(Exception e)
{
System.out.println("Exception occurred : "+e.getMessage());
e.printStackTrace();
}
}
}
RMI client
ExecutorInterface p=(ExecutorInterface)Naming.lookup("//localhost:2007/exec1");
System.out.println("Inside client.."+ p.toString());
p.executeJob(id, usrname, pswd);
p.killJob(id);
}
Till my knowlegde p.killJob() will wont be invoked untill executeJob() is finished.
I want to stop the execution while it is running
The problem appears to be that you are allocating a fresh instance of the Runnable AcQueryExecutor for each thread. This means each is seeing its own finished flag. Setting one in killJob will not lead to any other thread exiting because no other thread shares this flag.
You'll need to share Runnables or else make the finish field static. The latter will cause all threads to exit whenever any instance's stop is called, so may not be what you want.