amit kumar
amit kumar

Reputation: 21022

Java Process "The pipe has been ended" problem

I am using Java Process API to write a class that receives binary input from the network (say via TCP port A), processes it and writes binary output to the network (say via TCP port B). I am using Windows XP. The code looks like this. There are two functions called run() and receive(): run is called once at the start, while receive is called whenever there is a new input received via the network. Run and receive are called from different threads.

The run process starts an exe and receives the input and output stream of the exe. Run also starts a new thread to write output from the exe on to the port B.

    public void run() {
        try {
            Process prc = // some exe is `start`ed using ProcessBuilder
                    OutputStream procStdIn = new BufferedOutputStream(prc.getOutputStream());
            InputStream procStdOut = new BufferedInputStream(prc.getInputStream());
                    Thread t = new Thread(new ProcStdOutputToPort(procStdOut));
                    t.start();

                    prc.waitFor();
                    t.join();
                    procStdIn.close();
                    procStdOut.close();
        } catch (Exception e) {
            e.printStackTrace();
            printError("Error : " + e.getMessage());
        }
    }

The receive forwards the received input from the port A to the exe.

    public void receive(byte[] b) throws Exception {
        procStdIn.write(b);
    }

    class ProcStdOutputToPort implements Runnable {
        private BufferedInputStream bis;
        public ProcStdOutputToPort(BufferedInputStream bis) {
            this.bis = bis;
        }
        public void run() {
            try {
                int bytesRead;
                int bufLen = 1024;
                byte[] buffer = new byte[bufLen];
                while ((bytesRead = bis.read(buffer)) != -1) {
                    // write output to the network
                }
            } catch (IOException ex) {
                Logger.getLogger().log(Level.SEVERE, null, ex);
            }
        }
    }

The problem is that I am getting the following stack inside receive() and the prc.waitfor() returns immediately afterwards. The line number shows that the stack is while writing to the exe.

 The pipe has been ended
 java.io.IOException: The pipe has been ended
 at java.io.FileOutputStream.writeBytes(Native Method)
 at java.io.FileOutputStream.write(FileOutputStream.java:260)
 at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
 at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
 at java.io.BufferedOutputStream.write(BufferedOutputStream.java:109)
 at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
 at xxx.receive(xxx.java:86)

Any advice about this will be appreciated.

Upvotes: 2

Views: 8127

Answers (2)

Kao
Kao

Reputation: 7374

I have had the same problem recently and I have found a solution.

First of all, "The pipe has been ended" error is not a Java error - it comes from Windows system. According to MSDN:

The using process has closed the pipe or, if you are trying to write to the pipe, there are no available readers.

Not very informative. However, if process has closed the pipe itself, it may mean that some errors occurred in process.

To check this, redirect errors coming from process, for instance, to a file:

File f = new File("errors.txt");
pb.redirectError(f);

In my case (I've been trying to execute SrcML parser) file contained this:

.\libs\srcML-Win\src2srcml.exe: unrecognised option `--language Java'
Try 'src2srcml --help' for more information.

Fixing this solved the problem.

Upvotes: 1

user207421
user207421

Reputation: 310985

This means you are writing to the pipe after the other end has already closed it.

That indicates a major error in your application protocol.

Upvotes: 1

Related Questions