Several of our projects deal with sensor hardware of different types often connected via the good old™ serial port. That is fine most of the time because most protocols are simple and RXTX provides a nice cross-platform library for most of your serial port needs. But many new computers do not feature the old RS232 serial ports anymore or other contraints prevent the use of a plain RS232 serial port. Here come serial converters like the Advantech ADAM 4570 (serial-to ethernet) or usb-to-serial converters into play. Usually this works fine.
Now one of our customers had a test system using an unreliable converter with sensor hardware. The hardware problems uncovered a robustness issue in our software which crashed the JVM when the virtual serial port of the converter disappeared and our app tried to write to it. Despite the faulty hardware our software had to be robust because it manages many more devices other than just that one sensor over serial. Looking at the problem we discovered that the crash occurred somewhere in the native part of RXTX. So we decided to scratch our own itch (and the one of the customer) and set out to fix the issue in RXTX at a Open Source Love Day (OSLD) . So we fixed the problem and submitted the patch to the bugtracker of the RXTX project. Our sample program now worked flawlessly and threw an IOException when the serial port failed in some way.
Happy to have fixed the problem we incorporated the patch RXTX in our production software but it still crashed and no
IOException appeared anywhere in the logs. After another bughunting session we spotted the subtle difference of sample and production program: the use of
OutputStream insted of
PrintStream silently swallows all exceptions which proved fatal in our use case with the unreliable stream carrier. So the final fix was essentially replacing our
RXTXPort port = new RXTXPort("COM6"); PrintStream p = new PrintStream(port.getOutputStream(), true, "iso8859"); p.print("command");
RXTXPort port = new RXTXPort("COM6"); OutputStream o = port.getOutputStream(); o.write("command".getBytes("iso8859"));
Be careful when using
PrintStream with unreliable stream carriers it swallows exceptions! That may shadow problems which you may want to know of. Often
PrintStreams behaviour will not be a problem but in certain cases like the one depicted above it causes a lot of headaches.