Kill a java launch4j-wrapped app launched with java Process api - java

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?

Related

Java process still running

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

Running Java application from C# properly

I am trying to execute Java application from my c# code. I use Process class from System.Diagnostics.
I am able to run it and kill, but it seems that java starts subprocess when I am executing application. And when I am trying to kill the Process, I kill the parent java process, the second one, which was started behind the scenes, is still running.
Multiple executions of this logic cause dozens of java.exe processes and memory overflow.
Is there a way to do such thing as proper running Java application from c# code and be able to kill started processes?
I wonder if it is possible at all to resolve this issue if I don't have administrative rights
I would be tempted to use taskkill. It runs from this cmd command:
string.Format("cmd /c \"taskkill /f /pid {0}\" /t", this.processId);
the /t does a tree kill, that ends the child processes.

Find and kill a specific Java process from another Java App

I have several java processes running on a windows machine. I have a Java process which is supposed to monitor the other processes and periodically kill or restart new ones.
If I have a java process running com.foo.Main1 and one running com.foo.Main2 - how can my monitoring process find and kill just the Main2 process?
Update: I have some code that can execute a command line tasklist.exe and parse it, but no matter what I do, I only see the java.exe process, not which class is executing
Update 2: I do not have the ability to install non-java programs.
It's probably going to be a lot simpler using OS-specific tools and using Runtime.exec() to run them, but I'll try and give a platform independent answer:
It might be possible to do this platform independently using the Attach API. This comes with the JDK, so to use it just include tools.jar from your JDK on your program's classpath.
To get a list of virtual machines on the system, use VirtualMachine.list(). You can get/parse arguments from the virtual machine descriptor objects that are returned from this.
The attach API also allows you to load agents into already-running Java processes. Since you want to kill a Java process, you can write a Java agent that simply runs System.exit() (or if you really want it dead use Runtime.halt() instead) when the agent loads.
Once you identify the one you want to kill, attach to it and load the killer agent (the agent has to be built as a JAR file, accessible to the Java process it needs to be loaded into). Shortly after the agent is attached that process should die.
These links might help also:
An Oracle blog on the attach API
Package documentation for java.lang.instrument (has detailed instructions on how to build an agent JAR)
This is specific to Windows.
I was facing the same issue where I have to kill the specific java program using taskkill. When I run the java program, tasklist was showing the same program with Image name set as java.exe. But killing it using taskkill /F java.exe will stop all other java applications other than intended one which is not required.
So I run the same java program using:
start "MyProgramName" java java-program..
Here start command will open a new window and run the java program with window's title set to MyProgramName.
Now to kil this java-program use the following taskkill command:
taskkill /fi "MyProgramName"
Your Java program will be killed only. Rest will be unaffected.

Run a process and find out that it was started

I need to run .exe file, and after launching this file execute some script once the process is loaded and running, before it has terminated. So script will throw an exception if previous .exe is not fully loaded..
How I can know that .exe file is fully loaded?
I can use Timer to schedule script execution to some time, but it's not good idea, because .exe file may still not be launched after some scheduling time.
Check out Apache Commons Exec which handles a lot of the pain of process launching. In particular look at the DefaultExecuteResultHandler, which will get a callback when the launched process exits. So long as you don't receive that callback your launched process is still running.
Note (in case it's not clear) that if your Java process launches an executable it will get an immediate callback when that process dies, provided Process.waitFor() has been called.
As the last thing in your exe files duty create a file in a shared location. Check for the file from your other code. So that shared file will act as the lock.
You could check the list of running processes regularly until you find the executable in the list - once you see it you know it has been launched.
Note: if the executable ends after 1 second for example, and you check the processes every 10 seconds, you might miss it.

Spawn a process in Java that survives a JVM shutdown

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)

Categories

Resources