Reputation: 5875
I need your suggestions and guidance in following task. I am using libdmtx which comes with a command line utility which reads the image files for ECC200 Data Matrix barcodes, reads their contents, and writes the decoded messages to standard output. I want to use this command line utility in my java program on linux platform. I amd using ubuntu linux. I have installed the libdmtx on my linux machine. and when I invoke the command
dmtxread -n /home/admin/ab.tif
on linux terminal it gives the decoded value of barcode in image immediately.
when I am going to invoke this command using my java program the code stuks in execution of the command and dotn gives output. it looks like the program is processing or got hang.
Following is my java code which invokes the following command
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class Classtest {
public static void getCodes(){
try
{
Process p;
String command[]=new String[3];
command[0]="dmtxread";
command[1]="-n";
command[2]="/home/admin/ab.tif";
System.out.println("Command : "+command[0]+command[1]+command[2]);
p=Runtime.getRuntime().exec(command); //I think hangs over here.
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getErrorStream()));
String line=reader.readLine();
if(line==null){
reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
line=reader.readLine();
System.out.print("Decoded :- "+line);
}else{
System.out.print("Error :- "+line);
}
System.out.println(p.waitFor());
}catch(IOException e1) {
e1.getMessage();
e1.printStackTrace();
}catch(InterruptedException e2) {
e2.getMessage();
e2.printStackTrace();
}
}
public static void main(String args[]){
getCodes();
}
}
Please tell me friends where my code is going wrong.
I refered to following article but dint get any help
http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1
Please guide me friends! Thank you!
Here is the new code in which I used the ProcessBuilder Class this code also giving the same output as above code that is it hangs at the line Process process = pb.start();
public class Test {
public static void main(final String[] args) throws IOException, InterruptedException {
//Build command
List<String> commands = new ArrayList<String>();
commands.add("dmtxread");
commands.add("-n");
commands.add("/home/admin/ab.tif");
System.out.println(commands);
//Run macro on target
ProcessBuilder pb = new ProcessBuilder(commands);
pb.redirectErrorStream(true);
Process process = pb.start();
//Read output
StringBuilder out = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null, previous = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
//Check result
if (process.waitFor() == 0)
System.out.println("Success!");
System.exit(0);
//Abnormal termination: Log command parameters and output and throw ExecutionException
System.err.println(commands);
System.err.println(out.toString());
System.exit(1);
}
}
Please guide me to solve this problem. Thanks You!
Upvotes: 3
Views: 3896
Reputation: 9110
The readLine blocks until it receives a new line from the error stream. So, if there is no output, your program won't get past the first readLine.
For simplicity I would recommend you use a ProcessBuilder
instead of Runtime.exec()
, which lets you merge the two InputStreams as follows:
ProcessBuilder builder = new ProcessBuilder(cmd,arg0,arg1);
builder.redirectErrorStream(true);
Process process = builder.start();
So, now you can just read from one.
Alternatively you can use separate threads to consume the two InputStreams.
Hope that helps
Upvotes: 4
Reputation: 200168
Your stream-consumption code is very confused. You try to read a single line from the stderr, then abandon that reader, then try to read a single line from the stdout.
waitFor
.The proper way to consume the process's output streams is covered in detail in that article you have linked. Take that advice, nobody can give you better advice than that.
Upvotes: 2
Reputation: 35594
I am not sure what exactly happens with your program and where does it hang (you could use a debugger or trace output to check that), but here is the possible scenario:
Imagine that the program wants to output 2 lines of text. Or only one line but into stderr. Your code reads only 1 line fro stdout and than waits for the process to exit. This means that the child program may wait for the reader to read the next line, so it waits in write
until someone unblocks the pipe -- forever.
When you run dmtxread
from command line, there is no blocking on output pipe, so the program runs just finely.
Upvotes: 0