Class StdioBridge<O>


  • public class StdioBridge<O>
    extends java.lang.Object

    This class offers a possibility to communicate from within a Java application with another, external program.

    This is useful for the connection to applications written in a language for which no direct binding from Java exist. This class resorts to the simple exchange of messages via standard input and output, thus, a pipe. For this purpose, the external process is started using a ProcessBuilder. Once the external process is started, messages can be send to the process via send(byte[]) and sendAndReceive(byte[]). After a message is sent, an answer can be received via receive().

    The send(byte[]) method is synchronous, i.e. this class waits until the given message has been sent to the external process. To not miss the answer, a background thread is always reading lines from the standard input of the external process. To get these messages, call receive(). This method either gets existing messages that already have been read or it waits for a message to arrive. Thus, the method might block indefinitely in case that no message is sent by the external process. This is why calls to send(byte[]) and receive() should always come in pairs. For this purpose, the method sendAndReceive(byte[]) is helpful.

    This class supports arbitrary requests and one-line responses by default. By setting the Options.multilineResponseDelimiter field, multiple lines can be read for each request.

    If the external program outputs logging that is not a result in the sense of this class the actual output line must be marked, e.g. by a prefix like Result: or similar

    The Options class accepts a Predicate to recognize such specific output lines. The Options class also allows setting the actual program command whereas the program arguments are set to the descriptor of this class. Refer to Options for details about configuration settings offered there.

    The terminate the external process and the receiver thread and also the STDERR reading thread, call stop() one the bridge is no longer required.

    IMPORTANT NOTE FOR PYTHON PROGRAMS: When working with Python for the external program, always specify the -u switch in the program arguments. It causes Python to refrain from internal input/output buffering. Without the switch, the communication between Java and Python via STDOUT/IN will most like get stuck because the buffers don't get filled at some point an no data is actually sent.

    • Constructor Summary

      Constructors 
      Constructor Description
      StdioBridge​(Options<O> options, java.lang.String... arguments)  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      java.util.stream.Stream<O> receive()
      Receives data from the external process.
      void send​(byte[] data)
      Synchronously sends the given string data to the external program.
      void send​(java.lang.String data)  
      java.util.stream.Stream<O> sendAndReceive​(byte[] data)
      Just calls send(byte[]) and receive() one ofter the other.
      java.util.stream.Stream<O> sendAndReceive​(java.lang.String data)  
      void start()  
      void stop()  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • StdioBridge

        public StdioBridge​(Options<O> options,
                           java.lang.String... arguments)
    • Method Detail

      • start

        public void start()
                   throws java.io.IOException
        Throws:
        java.io.IOException
      • stop

        public void stop()
                  throws java.lang.InterruptedException,
                         java.io.IOException
        Throws:
        java.lang.InterruptedException
        java.io.IOException
      • send

        public void send​(byte[] data)
        Synchronously sends the given string data to the external program. It must be programmed in a way to accept these data.
        Parameters:
        data - The message to be sent to the external process.
      • send

        public void send​(java.lang.String data)
      • receive

        public java.util.stream.Stream<O> receive()
                                           throws java.lang.InterruptedException

        Receives data from the external process.

        For this purpose, this method will block until data is available. If Options.getResultLineIndicator() is given, the method will wait until a line is encountered that is accepted by the respective predicate.

        This method should only be called if send(byte[]) has been called before. Otherwise, there will probably be nothing to read the the method will block indefinitely

        Returns:
        The next data line received from the external process.
        Throws:
        java.lang.InterruptedException - If the method is interrupted while waiting for the next input.
      • sendAndReceive

        public java.util.stream.Stream<O> sendAndReceive​(byte[] data)
                                                  throws java.lang.InterruptedException
        Just calls send(byte[]) and receive() one ofter the other. Exclusively using this method ensures that there is always something to read and the receive method does not block forever.
        Parameters:
        data - The data to send.
        Returns:
        The received response.
        Throws:
        java.lang.InterruptedException - It waiting for a response is interrupted.
      • sendAndReceive

        public java.util.stream.Stream<O> sendAndReceive​(java.lang.String data)
                                                  throws java.lang.InterruptedException
        Throws:
        java.lang.InterruptedException