|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectbb.util.Execute
public class Execute
Executes a "task",
defined here as arbitrary Java code that is contained inside either a Callable
or Runnable
instance.
The following always occurs:
UncaughtThrowableLogger
to Thread
,
which ensures that every uncaught Throwable is properly logged.
Note that this assignment will remain for the life of the JVM, unless subsequently changed by other code.
EventQueue
's dispatch thread
instead of the calling thread (this is required by Java GUI components)
This functionality is exposed via static methods like
thenContinue
, thenExitIfEntryPoint
, usingEdt
.
The original motivation of this class was to simplify and standardize the implementation of main
methods,
since they often require the same boilerplate code (the functionality described above).
One way to write a (non-GUI) main
method using this class is:
/**
...
If this method is this Java process's entry point (i.e. first main
method),
then its final action is a call to System.exit
, which means that this method never returns;
its exit code is 0 if it executes normally, 1 if it throws a Throwable (which will be caught and logged).
Otherwise, this method returns and leaves the JVM running.
/
public static void main(final String[] args) {
Execute.thenExitIfEntryPoint( new Callable() { public Void call() throws Exception {
// insert here whatever specific code your main is supposed to do
return null;
} } );
}
If the purpose is to launch a GUI, then this form almost certainly should be used:
/**
Creates a GUI and then returns.
/
public static void main(final String[] args) {
Execute.usingEdt( new Runnable() { public void run() {
// insert here whatever specific code your main is supposed to do
} } );
}
Concerning the execution time that is always logged by this class:
it can serve as a quick and dirty benchmark only if
a) task runs long enough that a single execution yields an accurate execution time
and b) you do not care about execution statistics (i.e. means, standard deviations, confidence intervals).
For all serious benchmarking needs, use Benchmark
.
Here is an example of how some quick benchamrks may be obtained:
/**
Benchmarks a series of tasks; see the logs (files and/or console) for results.
/
public static void main(final String[] args) {
Execute.thenContinue( new Runnable() { public void run() {
// insert here code for task #1
} } );
Execute.thenContinue( new Runnable() { public void run() {
// insert here code for task #2
} } );
// etc...
}
This class is multithread safe: its public api is static methods which use no shared state. (Its instance state is completely encapsulated, and is mostly immutable or thread safe).
Nested Class Summary | |
---|---|
private static class |
Execute.Caller
Records information about the class that is calling Execute: its class name, method name, and whether or not it is the actual program entry point of the current Java process. |
private static class |
Execute.TestGui
|
static class |
Execute.UnitTest
See the Overview page of the project's javadocs for a general description of this unit test class. |
Field Summary | |
---|---|
private String |
classCalling
|
private boolean |
exitWhenDone
|
private Level |
levelEvents
|
private Logger |
logger
|
private String |
methodCalling
|
private boolean |
soundOnTaskSuccess
|
private Object |
task
|
Constructor Summary | |
---|---|
private |
Execute(String classCalling,
String methodCalling,
Object task,
Level levelEvents,
boolean soundOnTaskSuccess,
boolean exitWhenDone,
Logger logger)
Constructor. |
Method Summary | ||
---|---|---|
private void |
ensureUncaughtThrowablesHandled()
|
|
private Object |
executeTask()
|
|
private void |
log(Level level,
String msg,
Throwable t)
|
|
private void |
logProblem(Throwable t)
Contract: should never throw any Throwable, since may be implicitly used in a finally clause. |
|
private void |
logStart()
|
|
private void |
logStop(long t1)
Contract: should never throw any Throwable, since will be used in a finally clause. |
|
private Object |
perform()
Fundamental API method that implements the essential functionality of this class. |
|
private void |
playSound(int exitCode)
Contract: should never throw any Throwable, since will be used in a finally clause. |
|
private void |
seeIfShouldExit(int exitCode)
Contract: should never throw any Throwable, since will be used in a finally clause. |
|
static
|
thenContinue(Callable<T> task)
Returns . |
|
static
|
thenContinue(Callable<T> task,
Logger logger)
Executes task, returns its result (or rethrows any Throwable task threw as a RuntimeException), and leaves the JVM running. |
|
static void |
thenContinue(Runnable task)
Simply calls . |
|
static void |
thenContinue(Runnable task,
Logger logger)
Same as , except that task is a Runnable, and so has no result. |
|
private static Object |
thenContinueImpl(Object task,
Logger logger)
|
|
static
|
thenExitIfEntryPoint(Callable<T> task)
Returns . |
|
static
|
thenExitIfEntryPoint(Callable<T> task,
Logger logger)
Executes task and plays a distinct sound depending on if task returned normally or threw a Throwable. |
|
static void |
thenExitIfEntryPoint(Runnable task)
Simply calls . |
|
static void |
thenExitIfEntryPoint(Runnable task,
Logger logger)
Same as , except that task is a Runnable, and so has no result. |
|
private static Object |
thenExitIfEntryPointImpl(Object task,
Logger logger)
|
|
static
|
usingEdt(Callable<T> task)
Simply calls . |
|
static
|
usingEdt(Callable<T> task,
Logger logger)
Schedules task for asynchronous execution on EventQueue 's dispatch thread (aka the EDT),
so this method soon returns, and leaves the JVM running. |
|
static void |
usingEdt(Runnable task)
Simply calls . |
|
static void |
usingEdt(Runnable task,
Logger logger)
Same as , except that task is a Runnable, and so has no result. |
|
private static void |
usingEdtImpl(Object task,
Logger logger)
|
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
private final String classCalling
private final String methodCalling
private final Object task
private final Level levelEvents
private final boolean soundOnTaskSuccess
private final boolean exitWhenDone
private final Logger logger
Constructor Detail |
---|
private Execute(String classCalling, String methodCalling, Object task, Level levelEvents, boolean soundOnTaskSuccess, boolean exitWhenDone, Logger logger) throws IllegalArgumentException
classCalling
- name of the class which is calling Execute; this is the class name that will be used in the log recordsmethodCalling
- name of the method which is calling Execute; this is the method name that will be used in the log recordstask
- wraps arbitrary code to be executedlevelEvents
- the logging Level to use for normal (non-Throwable) eventssoundOnTaskSuccess
- if true, causes a sound to be played if task completes normally
(a sound is always played if task throws a Throwable)exitWhenDone
- if true, then
a) ensures that System.exit
is called at the end of this method
(with an exit code of 0 if task.call returned normally, and an exit code of 1 if task.call threw some Throwable),
which means that this method never actually returns to the caller,
b) a sound is played when task returns normally (a sound is always played if task returns abnormally),
and c) task's return value or Throwable thrown are logged;
if false, then control should return to the caller (unless task or some other code calls System.exit)logger
- used to log all events to (start/stop dates and execution times, uncaught Throwables, etc)
IllegalArgumentException
- if if classCalling or methodCalling is blank
;
task is null; task is not an instanceof Callable or Runnable;
levelEvents is null; logger is nullMethod Detail |
---|
public static <T> T thenContinue(Callable<T> task) throws IllegalArgumentException, RuntimeException
thenContinue
(task, LogUtil.getLogger2()
)
.
IllegalArgumentException
RuntimeException
public static <T> T thenContinue(Callable<T> task, Logger logger) throws IllegalArgumentException, RuntimeException
Level.INFO
(Throwables are always logged at Level.SEVERE
).
IllegalArgumentException
- if the constructor
objects to one of this method's params, or some other method on the call stack throws this
RuntimeException
- (or some subclass) if any other Throwable is thrown while executing task; this may merely wrap the underlying Throwablepublic static void thenContinue(Runnable task) throws IllegalArgumentException, RuntimeException
thenContinue
(task, LogUtil.getLogger2()
)
.
IllegalArgumentException
RuntimeException
public static void thenContinue(Runnable task, Logger logger) throws IllegalArgumentException, RuntimeException
thenContinue
, except that task is a Runnable, and so has no result.
IllegalArgumentException
RuntimeException
private static Object thenContinueImpl(Object task, Logger logger) throws IllegalArgumentException, RuntimeException
IllegalArgumentException
RuntimeException
public static <T> T thenExitIfEntryPoint(Callable<T> task) throws IllegalArgumentException, RuntimeException
thenExitIfEntryPoint
(task, LogUtil.getLogger2()
)
.
IllegalArgumentException
RuntimeException
public static <T> T thenExitIfEntryPoint(Callable<T> task, Logger logger) throws IllegalArgumentException, RuntimeException
main
method)
then logs task's result (or any Throwable it threw)
and calls System.exit
with an appropriate exit code (0 if task returned normally, 1 if it threw a Throwable),
which means that this method never returns.
Otherwise, this method returns task's result (or rethrows any Throwable it threw as a RuntimeException) and leaves the JVM running.
All normal events (e.g. task's start/stop dates and execution time) are logged at Level.INFO
(Throwables are always logged at Level.SEVERE
).
Altho many Java style guides
warn
against
programs explicitly forcing JVM exit,
this behavior is necessary if the program that main
belongs to
is actually is part of a sequence of programs that rely on exit codes to stop processing in the event of failure.
IllegalArgumentException
- if the constructor
objects to one of this method's params, or some other method on the call stack throws this
RuntimeException
- (or some subclass) if any other Throwable is thrown while executing task; this may merely wrap the underlying Throwablepublic static void thenExitIfEntryPoint(Runnable task) throws IllegalArgumentException, RuntimeException
thenExitIfEntryPoint
(task, LogUtil.getLogger2()
)
.
IllegalArgumentException
RuntimeException
public static void thenExitIfEntryPoint(Runnable task, Logger logger) throws IllegalArgumentException, RuntimeException
thenExitIfEntryPoint
, except that task is a Runnable, and so has no result.
IllegalArgumentException
RuntimeException
private static Object thenExitIfEntryPointImpl(Object task, Logger logger) throws IllegalArgumentException, RuntimeException
IllegalArgumentException
RuntimeException
public static <T> void usingEdt(Callable<T> task) throws IllegalArgumentException, RuntimeException
usingEdt
(task, LogUtil.getLogger2()
)
.
IllegalArgumentException
RuntimeException
public static <T> void usingEdt(Callable<T> task, Logger logger) throws IllegalArgumentException, RuntimeException
EventQueue
's dispatch thread
(aka the EDT),
so this method soon returns, and leaves the JVM running.
When it is eventually executed on the EDT, task's result (or any Throwable it throws) is always logged to logger.
A sound is played only if task throws a Throwable (nothing is played if it returns normally).
All normal events (e.g. task's start/stop dates and execution time) are logged at Level.INFO
(Throwables are always logged at Level.SEVERE
).
IllegalArgumentException
- if the constructor
objects to one of this method's params, or some other method on the call stack throws this
RuntimeException
- (or some subclass) if any other Throwable is thrown while executing task; this may merely wrap the underlying Throwablepublic static void usingEdt(Runnable task) throws IllegalArgumentException, RuntimeException
usingEdt
(task, LogUtil.getLogger2()
)
.
IllegalArgumentException
RuntimeException
public static void usingEdt(Runnable task, Logger logger) throws IllegalArgumentException, RuntimeException
usingEdt
, except that task is a Runnable, and so has no result.
IllegalArgumentException
RuntimeException
private static void usingEdtImpl(Object task, Logger logger) throws IllegalArgumentException, RuntimeException
IllegalArgumentException
RuntimeException
private Object perform() throws RuntimeException
task
.call
RuntimeException
- (or some subclass) if task.call throws it; this may wrap the underlying Throwableprivate void ensureUncaughtThrowablesHandled()
private void logStart()
private void logStop(long t1)
private void logProblem(Throwable t)
private void log(Level level, String msg, Throwable t)
private Object executeTask() throws Exception
Exception
private void playSound(int exitCode)
private void seeIfShouldExit(int exitCode)
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |