Implementing the system command in Java

I need a call to the "system" function, the same as in Python, Perl, PHP, Ruby, and c. It will compile a standard JavaScript library called Narwhal when it runs on the Rhino JavaScript engine, which in turn runs on Java.

The problem is that the standard Java library seems to have been distracted by the ability to generate a subprocess that is shared by the stdio parent process. This means that you cannot defer interactivity to the subprocess.

My first crack in this was the Python implementation of subprocess.popen. This uses three β€œpumper” threads to actively copy the parent stdio process independently (to prevent deadlocks). Unfortunately, this gives us two problems. First, the entry does not automatically close when the subprocess voluntarily exits. Secondly, threads of the child process are not buffered or merged properly.

I am looking for solutions that would force our require ("os") command. system () work as you would expect.

The project is at http://narwhaljs.org

Relevant Code:

+4
source share
4 answers

Not sure if this is what you are looking for, but you can call the C system function through the JNA library :

 public class System { public interface C extends Library { C INSTANCE = (C) Native.loadLibrary( (Platform.isWindows() ? "msvcrt" : "c"), C.class); public int system(String format); } public static void main(String[] args) { C.INSTANCE.system("vi"); } } 

In any case, work on Windows worked on Windows.

+2
source

You need to track the exit status of the process separately, either by polling the exit code, or by a separate thread waiting in Process.waitFor() .

As for buffering and flushing threads, I'm not sure if there is a simple solution. There are several Java classes that perform buffering in various forms ( BufferedInputStream , etc.). Maybe one of them can help?

+1
source

If I understand you correctly, you want something like this:

 import java.util.*; import java.io.*; class StreamGobbler extends Thread { InputStream is; String type; OutputStream os; StreamGobbler(InputStream is, String type) { this(is, type, null); } StreamGobbler(InputStream is, String type, OutputStream redirect) { this.is = is; this.type = type; this.os = redirect; } public void run() { try { PrintWriter pw = null; if (os != null) pw = new PrintWriter(os); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line=null; while ( (line = br.readLine()) != null) { if (pw != null) pw.println(line); System.out.println(type + ">" + line); } if (pw != null) pw.flush(); } catch (IOException ioe) { ioe.printStackTrace(); } } } public class GoodWinRedirect { public static void main(String args[]) { if (args.length < 1) { System.out.println("USAGE java GoodWinRedirect <outputfile>"); System.exit(1); } try { FileOutputStream fos = new FileOutputStream(args[0]); Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("java jecho 'Hello World'"); // any error message? StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR"); // any output? StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT", fos); // kick them off errorGobbler.start(); outputGobbler.start(); // any error??? int exitVal = proc.waitFor(); System.out.println("ExitValue: " + exitVal); fos.flush(); fos.close(); } catch (Throwable t) { t.printStackTrace(); } } } 

I found this piece of code in JavaWorld once when I was looking for a similar solution to wrap system calls with some exe.

My code has changed a bit since then, but I think this is a good example.

+1
source

It is very important to use standard output and process error at the same time. See the Carlos Tasada code example elsewhere.

If you do not, your code may (or may not) work depending on the result of your child process. How and when this output changes (if your generated process encounters an error, say), then without simultaneous consumption your process will be inhibited. Most of the problems that I see in SO related to Process.exec() are related to locking.

0
source

All Articles