System.exit working in "sbt run" but not in .jar - java

When shutting down my program I need to let my akka actors finish what they're doing before shutting down, so I have a shutdown hook:
sys.addShutdownHook(
{
log.info("\n shutting down startWorkScheduler\n")
assignWorkScheduler.cancel()
log.info("\ntelling manager to shutdown gracefully\n")
manager ! Manager.ShutdownGracefully
//spam shutdown messages until we exit
val resendShutDown = system.scheduler.schedule(5 seconds, 2 seconds){
manager ! Manager.ShutdownGracefully
}
system.awaitTermination()
}
and elsewhere I wait for a "all ok, you can shutdown" message:
case Terminated(httpDlrSqlRouter) => {
println("received terminated message from http router")
if(shuttingDown) {
println("httpDlrRouter done, shutting down......")
log.info("httpDlrRouter done, shutting down......")
context.system.shutdown()
java.lang.System.exit(0)
}else{
log.warning("httpDlrRouter terminated, don't know why!")
}
}
When I run the code using sbt run it works as expected: kill or CTRL+c finishes the work, prints "httpDlrRouter done, shutting down......" and exits.
When I build a .jar using sbt assembly and run it using java -jar filename.jar it does the same except actually exiting, it just hangs until i kill it with kill -9
do I need any alternatives to System.exit or some configuration to make it work?

Apparently changing
java.lang.System.exit(0)
to
Runtime.getRuntime().halt(0)
solved the problem

Related

Windows Task Scheduler doesn't restart java app after failure

I have a java application that terminates with System.exit(1);. And I have created a task "C:\Program Files\Java\jre1.8.0_221\bin\java.exe" -Dfile.encoding=UTF-8 -jar C:\test\transfer-1.0.jar. In the settings tab of Task Scheduler I have checked
allow task to be run on demand,
if the task fails, restart every 1 minute,
attempt to restart up to 10 times,
if the running task does not end when requested, force it to stop,
stop the existing instance
But when I run the task it doesn't restart after 1 minute. The history logs say "Information: Action completed, and Task completed".
What I need to to so that the Task Scheduler restarts the java application?

Authorization required to install jzos batch launcher?

We are trying to install the JZOS Batch Launcher. The function consists of three pieces: a load module that must be put into a z/OS PDSE, a sample start proc that can be tailored and put into an appropriate PROCLIB, and sample JCL that can be tailored and put into an appropriate SAMPLIB.
On submitting the job we are getting return code=0101. Below are the trace details which we are getting in the job:
Output from DD:STDENV config shell script:
waiting for child shell process to complete
waitChild()
child shell process exited with exit code 0
waitChild()
Child shell process exited without printing environment; //STDENV should not contain 'exit'
adoptEnvironment()
run()
cleanup()
JZOS batch launcher elapsed time=0 seconds, cpu time=0.040000 seconds
JZOS batch launcher failed, return code=101
cleanup()
~JzosVM()
~JzosVM()
After looking this up and reading more,we then tried to run the job with superuser access and the job ran fine. So we need to know what privileges we require without being a superuser which will enable us to run the job successfully.

Run jar from within a Java application

I am trying to build a simple auto updater for my application. I am currently checking the local application version against my remote version. If there is a newer version I want to start my updater.jar - which basically downloads and replaces the old application.
My problem is that I cannot seem to get the updater.jar to start if there is a new version.
The code I am currently using is:
Runtime runtime = Runtime.getRuntime();
try {
Process proc = runtime.exec("java -jar updater.jar");
} catch (IOException ex) {
Logger.getLogger(Splash.class.getName()).log(Level.SEVERE, null, ex);
}
System.exit(0);
The application exits but updater.jar is never launched..
Any ideas?
Your child process is likely exiting when your parent process exits.
When you launch a process you should usually:
consume stdout/stderr from the child process. If you don't do this your child process can block waiting for its output to be consumed. You should consume in separate threads. See this answer for more details
use Process.waitFor() to capture the exit code from the child process
It looks to me like you want to spawn the updater, let it perform a download and then exit your parent process. Anything more complex would likely be platform dependent (e.g. spawning a background process and disowning it)
Maybe the path to updater.jar should be specified in the java -jar command.
You better use the URLClassLoader since jre1.2
see How to load a jar file at runtime

Java - programmatically set exit code from SIGTERM

Situation: I have a keep-alive shell script that restarts an application whenever it shuts down. However I do not want it to do this if the application was closed via a SIGTERM or SIGINT (kill, Ctrl+C, etc.) i.e. a shutdown hook. However I have no way of setting the exit code, hence communicating to the keep-alive script, when exiting from a shutdown hook as calling exit is illegal.
From Javadocs for exit:
If this method is invoked after the virtual machine has begun its shutdown sequence then if shutdown hooks are being run this method will block indefinitely. If shutdown hooks have already been run and on-exit finalization has been enabled then this method halts the virtual machine with the given status code if the status is nonzero; otherwise, it blocks indefinitely.
Is this possible?
If the process has been killed by a signal, the $? variable will be set to 128 + signal:
bash$ sleep 3;echo $?
0
bash$ sleep 3;echo $?
^C
130
Here, 130 is 128 + SIGINT.
Grab the PID of the process in a variable and use the wait builtin: if the process has been terminated by a signal, the return code of wait will be 128 + the signal number.
#
# Note: output from shell trimmed
#
# Launch cat in the background, capture the PID
$ cat & PIDTOCHECK=$!
$ echo $PIDTOCHECK
27764
#
# Call wait a first time: the program is halted waiting for input (SIGTTIN)
#
$ wait $PIDTOCHECK ; echo $?
149
#
# Now kill cat, and call wait again
#
$ kill %1
$ wait $PIDTOCHECK ; echo $?
143
Here's what I do:
Runtime.getRuntime().halt(0);
Note that this will exit the program immediately, so you need to do it after the last shutdown hook has finished.

How does jstack -F affect a running Java process?

I am trying to diagnose a problem where a Java web application I'm using (Jenkins) becomes unresponsive. If I run jstack without the -F flag it doesn't give me anything, but if I put the flag in to force a thread dump not only do I get a result, but the application starts responding and goes on as if nothing had happened until it eventually stops responding again.
What does jstack -F flag do that would affect a running JVM and cause an unresponsive application to start responding again?
You can see the source to jstack here. The -F argument changes how jstack connects to the jvm. With -F (or -m) JStack connects to the jvm using the java debugger interface. If a pid is specified, JStack connects with the SA PID Attaching Connector which says,
The process to be debugged need not have been started in debug
mode(ie, with -agentlib:jdwp or -Xrunjdwp). It is permissable for the
process to be hung.
I don't know why it would cause an unresponsive application to start responding again, but the link above also says,
The process is suspended when this connector attaches and resumed when
this connector detaches.
This may have an effect.
jstack -F -l pid is similarly to (assume working dir is JAVA_HOME)
bin/java -Dsun.jvm.hotspot.debugger.useWindbgDebugger -Dsun.jvm.hotspot.debugger.useProcDebugger -cp lib/sa-jdi.jar;lib/tools.jar sun.tools.jstack.JStack -F -l pid
and in the sun.tools.jstack.JStack code
if (arg.equals("-F")) {
useSA = true;
}
.....
// now execute using the SA JStack tool or the built-in thread dumper
if (useSA) {
// parameters (<pid> or <exe> <core>
...
runJStackTool(mixed, locks, params);
} else {
// pass -l to thread dump operation to get extra lock info
String pid = args[optionCount];
...
runThreadDump(pid, params);
}
and since -F is passed in, runJStackTool is called to load sun.jvm.hotspot.tools.JStack, it have same effect of invoking directly
bin\java -Dsun.jvm.hotspot.debugger.useWindbgDebugger -Dsun.jvm.hotspot.debugger.useProcDebugger -cp lib/sa-jdi.jar;lib/tools.jar sun.jvm.hotspot.tools.JStack pid
and sun.jvm.hotspot.tools.JStack will call sun.jvm.hotspot.bugspot.BugSpotAgent attach -> go ->setupVM method
Maybe below code is the magic
jvmdi = new ServiceabilityAgentJVMDIModule(debugger, saLibNames);
if (jvmdi.canAttach()) {
jvmdi.attach();
jvmdi.setCommandTimeout(6000);
debugPrintln("Attached to Serviceability Agent's JVMDI module.");
// Jog VM to suspended point with JVMDI module
resume();
suspendJava();
suspend();
debugPrintln("Suspended all Java threads.");
}
it will suspend all Java threads in the target process. if your application is hang for thread starvation, the suspend method call may relax them.

Categories

Resources