Is there an alternative to Runtime.getRuntime().exec() - java

Just wondering, if there is something better, newer, safer, faster, etc than Runtime.getRuntime().exec().
I want to run another process from my application on linux, and this is the only way i know how. Would be nice to have an alternative.

How about ProcessBuilder?
A bit more:
Introduced in Java 1.5, allows you to gain more control on the process environment - set the working directory, let you redirect the error stream to the input stream (from java POV) and a few more things.
From Oracle's site:
ProcessBuilder - The new ProcessBuilder class provides a more
convenient way to invoke subprocesses than does Runtime.exec. In
particular, ProcessBuilder makes it easy to start a subprocess with a
modified process environment (that is, one based on the parent's
process environment, but with a few changes).

Related

How to increase performance when using ProcessBuilder to execute external command in Java

I use ProcessBuilder class to execute external commands in Java.
The code likes below.
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process process = pb.start();
...
// instance a new thread to read process output
...
process.waitFor();
...
But If a lot of commands are used to executed by this approach.
As waitFor() would cost plenty time, and command executing time would cost more then Linux command line.
Is there any approach to increase the waitfor() performance, or other efficient approach to executing command in java?
Is there any approach to increase the waitfor() performance,
No.
or other efficient approach to executing command in java?
No.
In fact, assuming that you are reading all of the external command's output, the waitFor() call is unlikely to take much time at all.
First of all, I think you are doing what is known as "premature optimization". That is, you are trying to optimize something before you know that optimization is required. Unless you have gotten your code working, measured its performance, and profiled it, you are only guessing that waitFor() in particular and using ProcessBuilder in general are a significant bottleneck. If your guess is wrong, then optimization is a waste of time.
Assuming that that using ProcessBuilder >>is<< a bottleneck, then there is not much you can do about it ... in Java. Possible non-Java solutions are:
Write / rewrite the external application so that you don't need to run multiple commands.
Write a script or batch file, and get >>that<< to run multiple commands.
And of course, another approach might be to get the Java application to do the work of the external commands for itself. (Depending on what the commands are doing, etcetera.)
You can take a look at NuProcess.
However, the README states:
Speed-wise, there is not a significant difference between NuProcess
and the standard Java Process class, even when running 500 concurrent
processes. On some platforms such as MacOS X or Linux, NuProcess is
20% faster than java.lang.Process for large numbers of processes.
It may be worth a try and see if it helps in your case.

Runtime.exec() without fork in java

How can i invoke batch file without fork in java?
I use NSSM command-line interface to install my product as windows service. I always use Runtime.exec() to operate with command-line. I bypass bytes from new process's streams and periodically check for it finish job. I wonder, if there is easy way to use command line? I don't need forked process, is there a way not to use it? I want just call some exec("command") function, which acts as simple procedure.
You cannot do the equivalent of Unix / Linux exec() syscall or the Posix shell exec command ... without forking ... in Java. It is not supported by the standard Java class libraries.
It may be possible to write a native code method to call the OS-provided native libraries to do an exec or equivalent. However, this could behave in unexpected ways (e.g. no shutdown hooks) and would definitely be non-portable. And in the case of Windows, I don't think it is possible to do the equivalent of UNIX exec without fork: source Wikipedia.
However, you can easily run a batch file from Java:
How do I run a batch file from my Java Application?
But I don't understand the point of doing an exec to run a batch file instead of the normal fork / exec ... which is what Runtime.exec() does under the covers. Perhaps if you explained, we could understand why you need to do it, and offer a suggestion.

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

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.

Java - C-Like Fork?

Is it possible to do a "C like" fork in java, using an new independent jvm process ?
How?
This answer is probably a little late but:
http://akuma.kohsuke.org/
seems to be exactly what your looking for
Funnily, I am just working on this: a Java process running other Java processes. I used the article From Runtime.exec() to ProcessBuilder as a solid base, and When Runtime.exec() won't as a good advice how to gobble the output streams.
PS.: For those wondering, I had to do that (instead of spawning new threads) because yet another Java process is checking the presence of these processes which are, normally, ran separately with shell commands.
The Application Isolation API (JSR 121) introduces Isolate which addresses this use case.

Categories

Resources