Java Runtime.exec ()

I can run this command from the command line without any problems (script check is in progress):

c:/Python27/python ../feedvalidator/feedvalidator/src/demo.py https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators 

and from java if I left the URL parameter and just do:

 String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" }; Runtime r = Runtime.getRuntime(); Process p = r.exec(args1); 

It works great. If I use specific URLs for the parameter, for example:

 String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" , "http://www.intertwingly.net/blog/index.atom"}; // or String[] args1 = {"c:/Python27/python", "../feedvalidator/feedvalidator/src/demo.py" , "http://www.cnn.com"}; 

It works great.

But if I use this particular URL https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators , then the script just hangs (java is waiting for the process to complete). I'm not sure why it works from the command line for this url, but not from a java program. I tried adding quotes to surround the URL parameter, but that didn't work either. I do not see a single character in the URL, which, it seems to me, should be escaped.

Full code:

 String urlToValidate = "https://das.dynalias.org:8080/das_core/das/2.16.840.1.113883.4.349/1012581676V377802/otherAdminData/careCoordinators"; String[] args1 = {"c:/Python27/python", "C:/Documents and Settings/vhaiswcaldej/DAS_Workspace/feedvalidator/feedvalidator/src/demo.py", urlToValidate }; System.out.println(args1[0] + " " + args1[1] + " " + args1[2]); Runtime r = Runtime.getRuntime(); Process p = r.exec(args1); BufferedReader br = new BufferedReader(new InputStreamReader( p.getInputStream())); int returnCode = p.waitFor(); System.out.println("Python Script or OS Return Code: " + Integer.toString(returnCode)); if (returnCode >= 2) { .out.println("OS Error: Unable to Find File or other OS error."); } String line = ""; while (br.ready()) { String str = br.readLine(); System.out.println(str); if (str.startsWith("line")) { //TODO: Report this error back to test tool. //System.out.println("Error!"); } } 
+19
java
Dec 21 '11 at 20:14
source share
3 answers

You need to merge the output and error streams of the process, otherwise it will be blocked when the executable program issues output.

From the Process Documentation :

Since some proprietary platforms provide a limited buffer size for standard input and output streams, the inability to quickly write to the input stream or read the output stream of a subprocess can lead to blocking of the subprocess and even deadlock.

+17
Dec 21 2018-11-21T00:
source share

Read (and close) p.getInputStream() and p.getErrorStream() .

For example:

 // com.google.common.io.CharStreams CharStreams.toString(new InputStreamReader(p.getInputStream())); CharStreams.toString(new InputStreamReader(p.getErrorStream())); 
+7
Dec 21 2018-11-11T00:
source share

People usually fall under the usual exec procedure in Java. I realized that too. The problem is that the process you are trying to execute may (depending on a lot of things) write to stdOut or stdErr first. If you handle them in the wrong order, exec freezes. To handle this correctly, you must create 2 threads to read stdErr and stdOut at the same time . Sth like:

 Process proc = Runtime.getRuntime().exec( cmd ); // handle process' stdout stream Thread out = new StreamHandlerThread( stdOut, proc.getInputStream() ); out.start(); // handle process' stderr stream Thread err = new StreamHandlerThread( stdErr, proc.getErrorStream() ); err.start(); exitVal = proc.waitFor(); // InterruptedException ... out.join(); err.join(); 
+7
Jan 28 '12 at 20:53
source share



All Articles