Find and kill a specific Java process from another Java App - java

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.

Related

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

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?

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.

Java process suspend and continue

I'm looking for a solution capable of doing this on Java:
Spawn a process.
Suspend it (like kill -STOP does in Linux).
Continue a suspended process (like kill -CONT in Linux).
Read/Write their standard input/output pipes at runtime.
Working on (at least) Linux and Windows.
As far as I know, the Java standar only implements first and fourth, but not the second neither the third.
What could I do?
There is no way of doing "directly" from Java.
You will need to do something specific for Windows / Linux, in each case executing an external program, or invoking native code.
On Linux, you can use kill as you suggest.
On Windows, you can call SuspendThread(), or maybe you can launch the SysInternals tool 'PsSuspend'. There is some information that may help you here:
How to pause / resume any external process under Windows?
How to suspend/resume a process in Windows?
If you wish to invoke native code from Java, JNIWrapper may help you.
Also, if you need the PIDs of the spawned processes, then you may need to launch them via native code also, as Java will not give you their PIDs.

Run java command in different JVM

Goal: I have client-server program in which client and server runs in different jvms.
To test the same, I want to invoke the Server in a different JVM programatically and then use current jvm to run the client and execute different C/S tests.
Is there any way I can execute a method or run Java commands in different jvm programatically?
1) The most powerful tool in java to run process is ProcessBuilder:
ProcessBuilder pb = new ProcessBuilder("java", "-server", "-jar", "yourJar.jar");
Process p = pb.start();
Than using Process you are able to manipulate child process e.g. read InputStream, destroy e.t.c.
2) If you are able to edit both source code review this question to build efficient communication between JVM on the same host.
If you cannot change code, simply create own loader which load Server and implements inter JVM communication and invoke methods you need, because it in the same JVM space.
You can run virtually any command which you otherwise run manually using
Runtime.getRuntime().exec(command);
For more refer to Runtime.getRuntime().exec(...) documentation.
But also note that running any platform specific command using exec will rob your program its platform independent nature.
Sometime back I saw someone using "mv" to move a file. That made the entire program to Unix-based OS specific. Charm of Java or any virtual machine based language is its platform independent nature.
You can use command line:
Runtime.getRuntime().exec("java -server MyServer")
or if you want to build some more complicated call just use http://commons.apache.org/exec/ to build and run program.
From what I know, this is not possible with plain java. Probably grid enabled frameworks could provide a way of running a java program on multiple JVMs. A similar problem was resolved here:
how-to-run-a-java-file-project-in-remote-jvm-which-is-present-in-other-network

Run Java Threads On One CPU

We Have a Multi-threaded Application in JAVA which has multiple threads running in parallel. Now we want to run all these threads on a single core. Currently application is running on a system having more then one Cores.
We know there is a technique available ProcesAffinity in .Net Framework to set process affinity.
But we don't want to depend on .Net Framework, because our application is build in java.
Do we set Process affinity using Bat file and run our application executable jar file through Bat file?
Currently our application is running on Window XP. So we need a solution that should be working fine on XP platform.
EDIT:
It's possible: See Java thread affinity
Pure Java doesn't support running a thread on specific processor. Check the SO question linked above.
Personally, I don't think that the fact that this cannot be set in pure Java is a bad thing, as to me, how an app is run does very much depend on the OS, so therefore a OS-specific solution isn't a bad thing.
You can use the MS psexec utility to set the affinity:
psexec -a 1 java -jar myapplication.jar
Would instruct that all of the threads created by java would be run on the lowest CPU.
And this line would be your .BAT file...
You cannot do it in pure Java. But on some versions of Windows, you can do it via operating system utilities; see https://superuser.com/questions/309617/how-to-limit-a-process-to-a-single-cpu-core ... and you might be able to do this by calling native libraries via JNI.

Categories

Resources