I'm using a method in shell script to execute a jar file.
function executeJar(){
java -cp $BASE_PATH"myjar.jar":$CLASSPATH/* com.sample.main.App config.json
}
Even after the jar completes execution, the java process is still active and not getting killed. Should i kill it manually ? What is a solution for this.
Check if you have any resource still opened (a database connection, an input reader, a socket, etc.). Be sure to .close() those resources or to use try-with-resources statements (they close it for you)
If you are using threads, maybe there's still some thread running. Or maybe something you used has reated threads (a database connection pool for example). Use the Visual VM tool (it comes with every JDK, just type jvisualvm on your console). Open Visual VM, run your app and make sure it won't exit automatically, select your app runtime on the left panel of Visual VM, then monitor the Threads tab on Visual VM. Close your app and check if there's still anything running.
https://docs.oracle.com/javase/7/docs/technotes/guides/visualvm/threads.html
If you are running inside Windows, maybe it's only the parent process (a console) that is still running. Try to use javaw instead of java.
Difference between java/javaw/javaws
Related
I use Windows.
I have a java application wrapped in an exe with launch4j. When I run it, I see two processes in my task manager: the exe wrapper, and the underlying java. When the program ends, both processes disappear.
When I run the exe with the command line, if I want to stop the process prematurely, I Ctrl-C, and both processes are terminated.
But in some cases, the program is run by another java application, with the process api. In this case, if the application must be stopped prematurely, I tried using myProcess.destroy(), but only the exe wrapper was stopped, the underlying java continued to run. I also tried destroyForcibly() with the same result.
Why the difference in behavior? How can I really emulate the behavior of Ctrl-C and kill both processes?
I have a Java application that needs to run several times. Every time it runs, it checks if there's data to process and if so, it processes the data.
I'm trying to figure out what's the best approach (performance, resource consumption, etc.) to do this:
1.- Launch it once, and if there's nothing to process make it sleep (All Java).
2.- Using a bash script to launch the Java app, and when it finishes, sleep (the script) and then relaunch the java app.
I was wondering if it is best to keep the Java app alive (sleeping) or relaunching every time.
It's hard to answer your question without the specific context. On the face of it, your questions sounds like it could be a premature optimization.
Generally, I suggest you do what's easier for you to do (and to maintain), unless you have good reasons not to. Here are some possible good reasons, pick the ones appropriate to your situation:
For sleeping in Java:
The check of whether there's new data is easier in Java
Starting the Java program takes time or other resources, for example if on startup, your program needs to load a bunch of data
Starting the Java process from bash is complex for some reason - maybe it requires you to fiddle with a bunch of environment variables, files or something else.
For re-launching the Java program from bash:
The check of whether there's new data is easier in bash
Getting the Java process to sleep is complex - maybe your Java process is a complex multi-threaded beast, and stopping, and then re-starting the various threads is complicated.
You need the memory in between Java jobs - killing the Java process entirely would free all of its memory.
I would not keep it alive.
Instead of it you can use some Job which runs at defined intervals you can use jenkins or you can use Windows scheduler and configure it to run every 5 minutes (as you wish).
Run a batch file with Windows task scheduler
And from your batch file you can do following:
javac JavaFileName.java // To Compile
java JavaFileName // to execute file
See here how to execute java file from cmd :
How do I run a Java program from the command line on Windows?
I personally would determine it, by the place where the application is working.
if it would be my personal computer, I would use second option with bash script (as resources on my local machine might change a lot, due to extensive use of some other programs and it can happen that at some point I might be running out of memory for example)
if it goes to cloud (amazon, google, whatever) I know exactly what kind of processes are running there (it should not change so dynamically comparing to my local PC) and long running java with some scheduler would be fine for me
I have a Stand-alone Java application. At the moment I am running this Java application using a start-script i.e. startApplicatoin.bat in windows and startApplicatoin.sh in Linux which sets up the class-paths and then it executes: java -classpath .
Now I have to add a stopApplication.bat and stopApplication.sh script. This stop script has to shutdown/close this java application gracefully.
To achieve this I am planning to take the following steps:
1. When my java application runs it will store the process-id of the launched application in a file i.e. in a known file myapplication.pid.
Looks like ManagementFactory.getRuntimeMXBean().getName() call will work on both Linux and Windows to get the process ID. So I shall collect process ID in this way and will store it in the specified file myapplication.pid.
2. Then when running stop application script, this script will issue a “kill” request to the process-id as specified by that myapplication.pid file.
For Windows I shall run the "taskkill" command to stop this application. And for Linux environment "kill" command will serve that purpose.
And in my java code I shall add a addShutdownHook which will enable the graceful shutdown operations that I want to run i.e. there I shall handle whatever stuffs I want to persist before this program is going to stop.
http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29
Now I would like to do a sanity check to ensure the way I am thinking is the proper way to do. Or there is a better way to do this. Any suggestion is appreciated. And thanks in advance.
If you're wanting a "graceful" shutdown, it may be more practical (and easier cross-platform) to open a socket in your long-running process and have your "stop" script connect to it and issue a shutdown command; this might even be practical through JMX, depending on how your application overall is structured. Approaches that are "inline" rather than requiring interaction with the OS are generally easier to reason about and test.
This looks like a Daemon.
The easiest way to run a daemon with start/stop functionality without resorting to a lot of scripting is with jsvc. This allows your code to implement an interface with four methods:
void init(String[] arguments): Here open configuration files, create a trace file, create ServerSockets, Threads
void start(): Start the Thread, accept incoming connections
void stop(): Inform the Thread to terminate the run(), close the ServerSockets
void destroy(): Destroy any object created in init()
You then have platform specific binaries that deal with keeping track of the process and stopping it when requested to do so.
The most useful thing is that jsvc can start a process as a superuser (root on unix) and then drop to a peon user the for auction running of the process.
This is how Tomcat (for example) works, it starts as root and performs privileged actions such as binding to port 80. It then drops down to a peon use called tomcat for security reasons.
If I'm using javaw.exe to launch a Java application, the shutdown hook isn't executed when users log off from their Windows account. The application is actually launched using a launch4j generated .exe file but I know it uses javaw.exe to start it.
This seems to be a known bug:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4302814
Has anyone else had this problem? If so, how did you fix it?
Thanks!
The application is actually launched using a launch4j generated .exe file but I know it uses javaw.exe to start it.
I haven't used launch4j in a while, but I'd be fairly suprised if it directly did this. Most of these apps start the jvm themselves, rather than shelling out to javaw.
The only difference between java.exe and javaw.exe is that java.exe automatically attaches a console. The bug that you reference (and the others referenced by it) were closed as Sun doesn't appear to be interested in making the handling of Windows logoff events better. From what I can tell, it only works with java.exe, because the console itself handles the WM_MESSAGES in such a way that it slows down the shutdown process.
It appears that the only easy workaround at the moment is to change the "headerType" in your launch4j config to "console". Obviously, this brings with it an ugly console.
I think the other alternative would be to use some sort of native wrapper of your on that handles windows messages in a cleaner way.
I need to spawn a process in Java (under Linux exclusively) that will continue to run after the JVM has exited. How can I do this?
Basically the Java app should spawn an updater which stops the Java app, updates files and then starts it again.
I'm interested in a hack & slash method to just get it working as well as a better design proposal if you have one :)
If you're spawning the process using java.lang.Process it should "just work" - I don't believe the spawned process will die when the JVM exits. You might find that the Ant libraries make it easier for you to control the spawning though.
It does actually "just work", unless you're trying to be clever.
My wrapped java.lang.Process was trying to capture the script's output, so when the JVM died, the script didn't have anywhere to send output so it just dies. If I don't try to capture the output, or the script doesn't generate any or redirects everything to a file or /dev/null, everything works as it should.
I was having trouble with this and the launched process was getting killed when the JVM shutdown.
Redirecting stdout and stderr to a file fixed the issue. I guess the process was tied to the launched java app as by default it was expecting to pass its output to it.
Here's the code that worked for me (minus exception handling):
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectOutput(logFile);
pb.redirectError(logFile);
Process p = pb.start();
I thought the whole point of Java was that it's fully contained within the JVM. It's kinda hard to run bytecode when there's no runtime.
If you're looking to have a totally separate process you might look into trying to start a second java.exe instance. Although for your application, it might be easier to simply make a synchronized block that stops (but doesn't kill) your app, does the updating, and then re-initializes your app's data.
It won't always "just work". When JVM spawns the child and then shuts down, the child process will also shutdown in some cases. That is expected behaviour of the process. Under WIN32 systems, it just works.
E.g. If WebLogic server was started up by a Java process, and then that process exits, it also sends the shutdown signal to the WebLogic via shutdown hook in JVM, which causes WebLogic to also shutdown.
If it "just works" for you then there is no problem, however if you find yourself in a position that child process also shutsdown with JVM it is worth having a look at the "nohup" command. The process won't respond to SIGTERM signal, but will respond to SIGKILL signal, as well as normal operations.
Update: The way described above is a bit of an overkill. Another way of doing this would be to use "&" on the end of command. This will spawn a new process that is not a child of current java process.
P.S. Sorry for so many updates, I have been learning and trying it from scratch.
>>don't believe the spawned process will die when the JVM exits.
Child process is always dying on my box(SuSE) whenever I kill java. I think, the child process will die if it's dealing with I/O of the parent process(i.e., java)
If you're looking at making an updater on Linux, you're probably barking up the wrong tree. I believe all major linux distros have a package manager built in. You should use the package manager to do your updating. Nothing frustrates me more than programs that try to self-update... (I'm looking at you, Eclipse)