javax.comm API

Implemented entirely with SerialPort

Testimonial



"...had problems with Sun's COMM API implementation... I order your product and no more problems! I didn't even have to change my code since you provide the Comm API wrapper..." testimonials.

"...We are were using the open-source RxTx package but we had stability issues with RxTX. We decided to use SerialPort ... Took 30 minutes to replaces RxTx implementation in our code and now everything runs as expected... I love nice little products like SerialPort" testimonials.

"...was creating a Windows-based controller to manage a modem bank using Java. After initially trying serial drivers from RxTxComm, IBM and Sun each with various problems in stability and operational behavior, I purchased serialio.com's SerialPort package. I was immensely pleased when the package went in seamlessly with no coding changes (using the javax.comm.SerialPort layer), and more so that it has been working reliably ever since..." testimonials.

"Your product has solved the performance problems that I was faced with using the RXTX Java Serial comm package on OS X"testimonials.

"...We tried to use the open source commapi from RXTX. The RXTX commapi has a bug which causes our program to freeze. With SerialPort our application works reliably." testimonials.



People frequently ask if SerialPort provides support for javax.comm.SerialPort. Yes, absolutely. This information will help you determine if you wish to use the superior SerialPort API directly, or the javax.comm.SerialPort API. SerialPort provides maximum flexibility (evident by the fact that javax.comm.SerialPort is implemented entirely using SerialPort). The SerialPort API was shipping commercially for about 18 months before Sun introduced javax.comm.SerialPort. As diagrammed below, the Serialio.com implementation of javax.comm.SerialPort was built completely using the SerialPort API and is based on the Comm API 2.0 (the first release in spite of the version number).

"I always select the SerialPort API over javax.comm.SerialPort whenever I have a choice. The javax.comm API is difficult to setup and to use..." testimonials.

The SerialPort API is so efficient that in initial benchmarks, our javax.comm.SerialPort implementation was 2% faster than Sun's running on Windows.

Benefits unique to the SerialPort API

SerialPort provides a very flexible solution, and provides a consistent API across all devices.

Did you know you may have to code your solution twice?
javax.comm.SerialPort API and CommConnection API note
If you use javax.comm.SerialPort you may have to recode your solution if you want to run it on MIDP. If you use CommConnection, you may have to recode your solution to run on a non-MIDP environment. If you code your solution with the SerialPort API, use the same code on both MIDP, and non-MIDP environments.

The original SerialPort design was robust enough to port to J2ME MIDP on WME. Developers using the SerialPort API, can use the same powerful API for all their target devices, from Super Computer class, to MIDP class devices. The javax.comm API design is insufficient for such flexibility; therefore the CommConnection interface was developed to replace javax.comm on MIDP. The CommConnection API is even more restrictive than the javax.comm.SerialPort API, and requires the developer to learn another API only to be limited by its design.

API Feature SerialPort javax.comm.SerialPort
Source code available Yes No
Precise control of event loop Yes No
Allows polling Yes No
Supports platform dependent features Yes No
Advanced Power Management (APM)* Yes No
APM Battery life status Yes No
APM CF slot status (detect CF serial port) Yes No
APM Wakeup detection Yes No
Flexible 'isSupported' cross-platform feature implementation Yes No
Selectable blocking at Java or Native level Yes No
Supports transmit timeouts** Yes No
Works on MIDP Yes No
Extendable Yes No
Continued enhancement since inception Yes No
*Provided on several platforms Yes None

**javax.comm.CommPort provides the method enableReceiveTimeout, however does NOT provide the parity method enableTransmitTimeout. This means that threads that transmit data using javax.comm.SerialPort, can potentially lockup. This can occur for example, when hardware flow control is selected, but no hardware is present, or the client has flow control disabled indefinitely.

JavaPOS Support

The Serialio.com implementation of javax.comm.SerialPort supports JavaPOS.

Limitations of Comm API 2.0 design

When Sun released the first early version of the Comm API Solutions Consulting implemented that API using SerialPort and reported these design problems with the API. Many of the issues reported were apparently ignored by Sun, as those issues still remain with the Comm API in the initial release (long after the issues were reported).

There should be some way to determine if some set/is???, and notifyOn??? API methods are supported. The SerialPort product does this with the 'isSupported' methods. Since the Comm API does not provide this feature, it should at least define some of the methods to throw unsupportedCommOperationException. For example, Macintosh hardware does not have DSR or RTS hardware so isDSR and setRTS make absolutely no sense on the Mac. Likewise, notifyOnCD, and notifyOnRingIndicator make no sense on the Mac. When using our javax.comm.SerialPort implementation on a platform that does not support one of these features (e.g. setDTR on UnixWareIA32) a message similar to the one shown below will appear on the console:

The correct thing to do is to throw an
UnsupportedCommOperationException however Sun's API does
not define this. For source code compatibility with Sun's
API we can not do it the correct way. You should contact
Sun and encourage them to fix their API. (We suggested
they do this in early 1998)

It also seems odd that methods like setDTR, setRTS, and sendBreak are not declared to throw an IOExcepion.

Note that the Comm API defines isDTR and isRTS methods. From the serial hardware level, these signals are write-only, so these methods can be misleading. In addition these methods make no sense on some platforms.

The Comm API provides no method for polling (or to disable event generation). For many applications this is not a problem, however for some high-performance applications the overhead of event creation/propagation can be limiting. Note also that some platforms may not provide a mechanism to generate interrupts for all of the events defined in the Comm API. This means that a thread must be dedicated to polling at the Java level to generate the required events.

Dynamic port configuration is a questionable cross-platform strategy. In the Comm API when the methods setSerialPortParams and setFlowControlMode are called, the driver must reconfigure an open port. Performing port configuration changes without resetting the port can be risky since some OS’s do not support the concept, or can have subtle bugs associated with it. (This is one of the reasons the Solutions Consulting SerialPort API uses the SerialConfig object)

The file name UnsupportedCommOperationException.java is too long for the Mac file system.

The Solutions Consulting SerialPort product has none of these limitations. In fact our implementation of the Comm API is done with SerialPort reflecting SerialPort's robust design. By using SerialPort the developer is provided with maximum flexibility since the Comm API or the SerialPort API can be used.

Is it 100% Java?

It is unfortunate, but there seems to be much confusion about what 100% Pure Java means. One of the requirements to be 100% pure is that classes do not contain native methods. Since native methods are required to implement the Java Virtual Machine (VM) this in effect means that Java itself is not 100% Pure. Only applications can be 100% pure Java. Classes for doing things like communicating with serial ports cannot be 100% pure, however this does not mean that applications that use these classes cannot be 100% pure. Many 100% pure Java applications/applets have been written that use the SerialPort product.

Sun has said that the Comm API provides a Java extension API that allows applications that use the Comm API to be certified as 100% pure. Implementations of the Comm API are not 100% pure and thus the Comm API implementations from Sun are not 100% pure, any more than other implementations. This is an unfortunate confusion since many people tend to think if it comes from Sun it is 100% pure. In summary, applications that use implementations of the Comm API should at some future time be capable of being labeled 100% pure, implementations themselves can not be 100% pure. Currently even applications that use the Comm API cannot be 100% pure because Sun has not provided the specs for testing to KeyLabs (the company that does 100% Java certification).

Note: Using the Comm API 2.0 release your application may in the future be able to be 100% pure, however it will be less cross-platform compatible than an application written using the SerialPort API. This is due to the above listed design issues with the Comm API release 2.0.

Installation

Install SerialPort per instructions. SerialPort must be installed for the Comm API to function.

Update any Serialio files included with the Comm API package (e.g. SerialPortLocal.java, SerInputStream.java) and rebuild the Serialio class file(s).

Here are two common ways to install the Comm API classes

You can use the JAR file as follows:

1) Add the jspComm.jar file to the CLASSPATH. For example on Windows if you have jspComm.jar in c:\jsp then CLASSPATH=…;c:\jsp\jspComm.jar;…

Or do it this way if you have the separate classes:

1) Create a directory named javax.comm (case sensitive) that is a subdirectory of where the main Java Comm API classes will exist e.g. on Windows create the directory C:\jsp\javax\comm

2) Copy the Comm API class files into the directory created in 1).

3) Add the parent directory of the javax.comm directory to the CLASSPATH. For this example on Windows CLASSPATH=…;c:\jsp;…

Port enumeration

Note enumeration requires that the OS provide some type of ‘registry’ functionality, this is not provided on all platforms. The Solutions Consulting implementation is very flexible in that it provides the developer the direct ability to add ports in case the developer does not wish to rely on enumeration. This is done as follows:

CommPortIdentifier.addPortName(devName, CommPortIdentifier.PORT_SERIAL, null);

Where devName is the device name (e.g. "COM2", "/dev/tty1", "Modem Port"). Note that the Driver parameter is set to null. This indicates you simply want to add a name to the list, and use the the default (Solutions Consulting) driver.

You can see an example of this in the Comm API version of TermTest.java.

You can also hard code device names into the list by modifying JSPDriver.java.

Events

The term event is misleading in this context. Those who have worked with serial ports at the UART level might immediately think that this means these would be hardware interrupt driven. This certainly makes sense, if the platform serial port drivers supported such an interface, unfortunately many do not. Even for those platforms that do provide some event type of event interface there is no guarantee that the driver itself is not polling the hardware.

Although we have no access to Sun's implementation of javax.comm, it is our belief that this implmentation is similar to ours in that it has a thread that does the polling and delivery of events. If you dump out Sun's comm.jar (jar -tvf comm.jar) you will see this class:
com/sun/comm/NotificationThread.class

If you dump out jspComm.jar in SerialPort you will see this class:
javax/comm/SerialPortEventTask.class

We believe that these are functionally equivalent. As for performance, our last test showed the implementation provided with SerialPort was about 2% faster than Sun's on WinNT. Considering the implementation we provide, sits on top of the SerialPort API, this is quite good. So even if we are wrong, and Sun has gone to great links to use 'events' in Win32 (i.e. Overlapped IO) then our polling strategy is still faster. As for polling directly with the SerialPort API (i.e. doing essentially what javax.comm.SeralPort does, but directly in the application) SerialPort will happily run 96 port (or more) on a single machine.

Polling is very efficient when done properly.

The fact is polling can be more efficient than the event model provided by the javax.comm especially for fast changing events. Consider that each time an event is produced, a JNI interface call, a JVM system call, memory allocation (which may create additional overhead by creating more work for the garbage collector), then the event must be posted (in javax.comm, this is a method call to the listener). In the polling scenario there is only a method call from the JVM to the native driver.

Example code

All the serial port example code that ships with the 2.0 release of the Comm API. Has been tested with the Solutions Consulting implementation. Depending on your VM, when you run the SimpleWrite.java example you may need to use CTL-C to stop the program. You can avoid this by adding the following one line of code to SimpleWrite.java where the code exits.

    System.exit(1); //proper exit

Sun's SerialDemo example: Note when using this example program it may appear that it will not work when trying to communicate with a modem. This is NOT a problem with Solutions Consulting javax.comm.SerialPort implementation. There are two issues here. First some modems (and other devices) will not respond unless the DTR is set, since SerialDemo does not provide a hook to set DTR your modem will not send a reply. Secondly, if you note that SerialDemo works with your modem on JDK 1.1.x, but not JDK 1.2.x, then this is an issue of a change that Sun made to the way the Enter key event is handled. In JDK 1.2.x the Enter key does not send the CR, and the modem will not respond until it sees a CR. You should use JavaTerm not SerialDemo, as JavaTerm provides smart and flexible CR control as well as the ability to set DTR.

Example code

All the serial port example code that ships with the 2.0 release of the Comm API. Has been tested with the Solutions Consulting

Implementation Requirements & Limitations

  • Split flow control (handshake) is not supported for SerialPort versions previous to 3.2.
  • Parallel ports are not currently supported (Parallel ports don’t even exist on many of the platforms that SerialPort runs on)
  • Port enumeration is not supported for SerialPort versions previous to 4.0.
  • Port enumeration is currently supported on Win7/Vista/XP/2008/2003/NT/98/95, Mac OS X & OS/2, and only on JNI compliant VM’s. This feature requires jspWin.dll version 3.7 or later on Win32 and shared library version 2.8 or later on Mac, and 3.2 or later on OS/2.
  • When an array of buf[size] is defined, and when InputStream.read(buf) is used, Sun's implementation will return immediately after reading the available bytes (regardless of the size). Our implementation will block until size bytes are available (this is the most logical behaviour). If you want to prevent blocking use rdyCnt=InputStream.available() and pass the rdyCnt returned to the InputStream.read(buf, off, len) method where len=rdyCnt.