I'm working on a Java program, and it's been over a year since the last time I used Java, so I'm a little rusty. This program uses Runtime.exec() to call other programs to do its dirty work, and needs to parse their output and update its own GUI accordingly in real time while the other programs are working. What's the best way to do this? I'm currently thinking of having my external-program-executor class have its own internal thread that polls the external program's output stream and then raises events when noteworthy things happen, and then implementing my own EventListener interface for my UI classes. I worry however how that will handle the asynchronous nature of the events being fired. Can anyone give any tips on how to protect the listeners from race conditions, and/or a better approach? Thanks.
You don't have to poll for output in the external process. The Process object returned from Runtime.exec(String) has methods for getting the InputStream for both stderr and stdout and the OutputStream for stdin.
You can communicate by sending messages over the OutputStream. Simply push your data on the stream.
Spawn a Thread that waits on the stdout OutputStream. Everytime there is new data to read, it will read the data and create an event.
Dispatch the event using the Event Dispatcher Thread, EDT. It's used by the Swing/AWT GUI too, so no problems there.
You can also use events for sending stuff to the stdin. Simply create an EventListener that listens for certain output events. These events are (possibly translated to a different format) onto the OutputStream and can be read by the stdin of the external process.
Good luck.
Related
Does Netty 4(or 5) continue reading while the handler chain is invoked ? Like reading in the background and filling up a huge queue and processing all reads after the handler chain is completely ready ?
I'm asking because I want to save incoming buffers to a file but files are blocking and if there are more incoming messages than the hard drive can handle do those messages queue up or does blocking the event simply stops the event queue from reading more messages ? On the sending side I use FileRegion so flow control for the writer is given.
I looked into the source but I'm not entirely sure how those ChannelInvokers work, it seems that if no one is specified a default one is created using eventLoop.next().
Would be nice if someone could help me to make sure that I'm not introducing a potential flow control bug...
I saw the option setAutoRead but I'm pretty sure this does something different.
If you want to do something like this you should specify a custom DefaultEventExecutorGroup when adding the handler that writes to the FS. This way you will hand-over the work from the EventLoop and so not block anything here.
Is there any possibility to communicate with clients by events? I mean:
I have connected client, InputStreamReader and PrintWriter
in = new BufferedReader(new InputStreamReader(
client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
when I use in.readLine() server waits for incoming data. But i have this situation:
Client didn't send any data
Connection is still alive
I need to send some data to client (but in.readLine() is still hanging process) and wait for respond
The questions are:
What is the best way to handle asynchronously incoming data? I mean something like "events". Should I create thread for read and another thread for write? If i can do it in one thread, could you give an example of the code please?
Is possible to abort waiting for in.readLine()?
Java provides non-blocking i/o through the java.nio package (see here). But Java's "nio" channels do not inter-operate with streams from java.io. So, if you want to use nio, you'll have to build your server with nio from the listener on down.
If you're stuck with the existing java.io streams, then you'll either have to use a thread-per-client model; or you'll need to devise a system for having a single thread (or pool of threads) manage a bunch of clients by looping over them repeatedly, polling instream.available() to figure out which ones have data ready to be handled. Of course, in this latter case, you'd want to avoid busy-looping, so some appropriate use of Thread.sleep is probably also in-order.
In my opinion having a separate thread to perform socket IO is best if you want your program to behave asynchronously. Have a look at http://en.wikipedia.org/wiki/Observer_pattern.
For a simple application, what I'll do is create a separate thread to listen for incoming data, and register 'observers' or 'event listener' to this thread. When a data comes in, notify your observers so they can perform necessary actions.
While the listener thread is idle waiting for data, your main thread still can progress normally.
Make sure you're also familiar with Java concurrency programming
I'm writing a chess program in Java. The GUI should be able to communicate with a chess engine supporting the Chess Engine Communication Protocol. But I'm having some difficulties reconciling the protocol with Java's I/O facilities.
Because engines that predate protocol version 2 do not send "feature", xboard uses a timeout mechanism: when it first starts your engine, it sends "xboard" and "protover N", then listens for feature commands for two seconds before sending any other commands.
It seems that Java's facilities for interrupting I/O operations are limited. The only option I can find is NIO's InterruptibleChannel, which closes itself when interrupted.
I don't want the stream to close when the timeout occurs -- I just want to interrupt the read. Does anyone know a solution?
I think you may be overthinking the problem. You don't need to abort the read() call after 2 seconds, you just need your backing logic to understand that after 2 seconds it should not expect to receive any "feature" commands. Then your implementation can write the next command, and your read() will return the byte(s) from the response to that command.
That's how I'd approach it anyways, by having generic code that reads in bytes and passes them further up the chain where context-specific processing can be done. Then you don't need to interrupt the read, the upstream code just needs to understand that the data it eventually gets back may be a "feature" command, or it may not be.
It's not clear to me that you need to do anything much. What you have quoted is the timeout behaviour of the board. You don't have to implement that, it is done, at the board, which is the peer, i.e. the other end.
For my current application, I am struggling with identifying the Swing threads in my application. With Swing threads I mean:
Initial threads
The event dispatch thread
Worker threads
My application:
simple user interface which is supposed to display data received on a socket
the data is described by many model classes
the received data is XML which is parsed and the model objects are instantiated
the user interface is supposed to display the received data
these data is updated very frequently, which means the XML messages are short, but there are many of them
to put it into context: I am programming a Java profiler.
I have read the Swing tutorial so far, so here are my guesses and questions:
The background task is the server socket, respectively the background tasks are the number of opened connections on which the application receives data.
The tasks have no final result, so I guess the SwingWorker<T,S> should only define the generic type for the Interim Result? For every parsed XML I would make a call to publish. But how do I distinguish which data I have received? Maybe the XML data contains only enough information to build a class A or maybe the data contains enough information to build class A and class B, but how do I wrap both into one Interim Result? A wrapper class?
The process() method invokes changes to make it visible to the user interface, doesn't it? I don't see how this works. Where do I launch my tasks? Is it in order to invoke the SwingWorker.execute() in the JFrame constructor?
Should the XML Reader be the Task or should each Thread which handles an incoming connection be the task?
In the context you describe, I am not sure I would use SwingWorker.
My basic idea would be:
from your main(), start several threads for serving sockets (standard Thread API)
when one such socket thread gets some input, it parses the XML right away (as you describe it, parsing should be very fast, hence I don't think you would need to start a new thread just for that)
once the XML is parsed, the socket thread creates some "result object" to be displayed, declare this object in a final variable, and call SwingUtilities.invokeLater() to display this result in your UI
Another alternative that I have used successfully in the past would be to use an EventBus that would take care of callingthe UI update method in the EDT, your socket threads would send the "result object" to that EventBus.
About SwingWorker use, I would say the main use is when the end user starts an action (e.g. by clicking a button or a menu item) and this action is long and should be processed in background, the background processing method would then have to feed back information to the UI.
I managed to programm an app that communicates with a server. I can write and I can read. I even managed to do it with Java NIO.
My problem is that I have a endless while loop that is listening for new data to read. It blocks the whole program and I can't write anymore data.
I need a solution so the loop keeps running in background listening for new data to read while I send data.
Any suggestions?
Use AsyncTask. It was created just for this kind of jobs (doing long running background tasks, while still have a possibility to update UI).
You could either create a separate thread to handle the socket asynchronously and pass messages through a handler, or create a local service to handle the comms.
You should never do a long wait on the main (UI) thread.
If your loop is blocking the whole program there is something wrong with it. I don't see what other answer you can realistically expect until you post some code.