What is the best way to manage unix process from java? - java

I'm looking for some simple tasks like listing all the running process of a user, or kill a particular process by pid etc. Basic unix process management from Java. Is there a library out there that is relatively mature and documented? I could run a external command from the JVM and then parse the standard output/error but that seems like a lot of work and not robust at all. Any suggestions?

You will need to roll your own solution I think. Killing an external process created using the Process APIs can be done using Process.destroy(). (But note that destroy() as implemented on Linux / Unix does a "soft" kill, not a SIGKILL, so the external process may be able to avoid being killed.)
Anything beyond that is non-portable.
Listing processes (on a Linux machine) can be done by reading the /proc file system.
Other things can be done by calling a native command using Process. It depends on whether your management functionality requires use of syscalls that are not available to a "pure" Java program.
It is possible (in theory) to use JNI and native code to dig around in the JVM's native data structures to find the OS-level PID for the process and send it a signal.
If you go down the JNI + native library route, beware that native pointer problems and native threading issues can kill your JVM. You may also need to deal with building and distributing the native library for multiple architectures, etc. Also beware that the internal data structures are liable to be different for different JVM platforms, releases, etc, and that they are liable to change without notice.

I recommend JavaSysMon: You can list processes (pid, ppid, name and so on), kill processes (inclusive child processes) and monitor your computer. If you want to use it in a Maven project:
<dependency>
<groupId>javasysmon</groupId>
<artifactId>javasysmon</artifactId>
<version>0.3.3</version>
</dependency>
<repository>
<id>javasysmon-repo</id>
<url>http://openr66.free.fr/maven2/</url>
</repository>

You could try JNA Posix. If the appropriate functions aren't exported by that library, it's very easy to add support for them with JNA (I've done so for many Win32 APIs).

Here's a method to send SIGKILL to a process from Java. It use reflection to get the pid value from the Process subclass. Tested succesfully on Mac OS X 1.6 (Snow Leopard) and OpenSuse 11.4, java 1.6 64-bit HotSpot JVM but obviously no guarantees of portability.
try {
Process p = Runtime.getRuntime().exec("sleep 10000");
Field pidField = p.getClass().getDeclaredField("pid");
pidField.setAccessible(true);
final int pid = pidField.getInt(p);
Process killProcess = Runtime.getRuntime().exec("kill -9 " + pid);
killProcess.waitFor();
System.out.println(p.exitValue());
} catch (Exception e) {
e.printStackTrace();
}

The Gnome System Monitor (linux version of Windows Task Manager) uses libgtop2 package. Documnetation here: http://library.gnome.org/devel/libgtop/stable/
Also you can check the source of System Monitor to see how it uses the libgtop2 functions.

Most of the information you require is available via the /proc filesystem, although you may require the correct permissionings to read everything there. Note that the contents of /proc are Unix-specific - e.g. different on Linux/Solaris, and I have no idea re. MacOSX.
If you want to kill a process you've spawned yourself, then Process.destroy() is worth looking at. Otherwise you're going to have to execute kill. To use this nicely you should send a SIGINT, and if that doesn't work, then send a SIGKILL (to forceably terminate - I'm not sure if Process.destroy() does this)

Related

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.

In C++ or Java is there a way to get the CPU usage?

I'd like to write a little program just to display the CPU usage as a percent, like the task manager does. I know intermediate C++ and Java. Is there a way to do this with either language? If so, perhaps a short example? I saw some page of a C++ command, but I couldn't make heads or tails of it.
I'm using Windows 7 on one computer and XP on the other. As for the multiple core response, I simply want to display the CPU usage percent as the task manager does, even with a multiple core processor.
double sysLoad = ManagementFactory.
getOperatingSystemMXBean().
getSystemLoadAverage();
does not work on every platform,
returns an average load of the past one minute
EDIT:
Recently found this one
http://sellmic.com/blog/2011/07/21/hidden-java-7-features-cpu-load-monitoring/
In Java 7 you can use com.sun.management package to get process load or system load.
usage:
OperatingSystemMXBean osBean = ManagementFactory
.getPlatformMXBean(com.sun.management.OperatingSystemMXBean.class);
// What % CPU load this current JVM is taking, from 0.0-1.0
System.out.println(osBean.getProcessCpuLoad());
// What % load the overall system is at, from 0.0-1.0
System.out.println(osBean.getSystemCpuLoad());
there are some system call functions provided in "windows.h", such as GetProcessorInfo(), CallNTPowerInformation(), GetTickCount(), QueryPerformanceFrequency(), QueryPerformanceCounter() and so on. You can google them, or find them in MSDN. I hope this answer can help you.
The answer is going to be platform specific, and differs between the Java and C++ cases. At some level you need to interface with OS specific APIs to extract the statistics. There are four possible approaches:
Call an appropriate external system monitoring command (system specific) and "scrape" the output of the command. You can do this from Java or C++.
In C++ (or using JNI / JNA in Java ... if you really have to), make calls on the OS-specific native APIs that provide the information used by the external system monitoring.
In Java, use some existing 3rd-party library that deals with the system specific JNI/JNA stuff. Possible examples include JavaSysMon and SIGAR ... though I can't make specific recommendations.
You could use the Java monitoring APIs ... but they don't provide enough information. You can get information about this processes resource usage, and the overall load average, but you can't get information about other processes.
Now the problem with all of the above (except, possibly, the last one) is that porting to a new platform requires work.
CPU usage is an operating system property, not a language property. The way to retrieve it would be specific to the OS you're using (which you fail to identify).
In addition, "CPU usage" is a very nebulous term anymore, with multiple cores, et al.
In Java you can do it using JavaSysMon
Assuming you're using Windows system, you can use Windows Management Instrumentation (WMI). It's powerful once you get it working. I never did it using Java. Of course, it's easier with C# .NET.
A good link is WMI info
If you try this, please tell me. I might be interested in helping you since this is also my interest.
IF you are using the Linux system, consider using shell scripting, like bash. The reason is shell scripting is powerful for operating system calls, like getting process ID and usage (pid command). And IT technicians are more comfortable with bash scripts than Java or C++.

Are there any Java libraries for adjusting IO scheduler priority on linux

I have a Java program running on a linux system, which I would like to give a higher IO Scheduler priority. Is there a library JNI/JNA based that would allow me to do that from within my code?
You could spawn and external command and call ionice on your process.
You can get the PID of the Java Process by using the Java Management API, at least when using the Sun JVM. Have a look at the actual implementations of the management objects, one returns the pid (don't know which for the moment).
Then I would use jnative to call the linux function, so you don't have to rely on ionice to be installed.

How to obtain the consumption memory of running "exe"

I'm developing an "Online Judge System",like SGU "http://acm.sgu.ru/"
I wangt to obtain the accurate consumption memory of running ".exe"(.c/.cpp-->.exe) using Java.
Process : submit code-->hello.cpp/.c--compile-->hello.exe--run-->results
I want to know how to obtain the consumption memory of running "hello.exe"
The code:
Runtime rn = Runtime.getRuntime();
Process proc =rn.exec("hello.exe");
Thank you for helping me.
You cannot do this using pure Java.
On a UNIX / Linux machine, you would configure your operating system to enable process accounting, then read the information logged in the "acct" file. According to the acct(5) manual entry I read, this logs "average" memory usage rather than maximum memory usage.
A Windows system is bound to be different.
GetProcessMemoryInfo will tell you how much memory a process is using once you have a handle open to it. Microsoft even has an example for using the function.
To get the process ID you're looking for, you will need to enumerate through all the processes in the system. Microsoft has an example that would be useful for that too.
Edit:
The examples are all in C. This is the language the Win32 API was designed for. From Java, you'll either need to translate it to the JNI or find a Java package that does the same things.

Sending a POSIX signal from the JVM

How do I send a POSIX signal from within the JVM? (in Java or Clojure)
I never thought this would be an issue until I tried googling it — there is lots of information about handling signals, but nothing about sending them.
Short of using the JNI or calling the shell to execute "kill", is there any other way to send a signal to a PID?
Ok. Answering myself: I looked at the suggested libraries, but I am wary of introducing new dependencies on lots of code, especially if I'll only use a small part of it.
It turns out the easiest way is to use JNA and interface with the system (libc) API. In clojure this pretty much amounts to:
(jna-invoke Integer kill pid signo)
after doing a (:use net.n01se.clojure-jna) of course.
Since this software is not intended to ever run on Windows, I'm fine with this solution which should work on all POSIX systems (MacOS and Linux are what I'm interested in).
POSIX signals is OS specific functions, but JVM is tried to be OS independent VM. So there are no standard functions for this.
But you can execute shell commands (using Runtime class) or use some lbrary for your needs, like a Posix for Java

Categories

Resources