Tuesday, February 19, 2013

Serial Communication with RXTX in Java 1.6 for Mac OS X 10.7 (Lion) with Intel 64 bit processors

After spending way too many hours installing the RXTX library for Java on my Mac, I though it might be worthwhile to save others the trouble by sharing what I did to make it work. (Version 2.2) (2/18/2013)

None of the binaries I found that were available worked for me, and getting the configuration and build instructions right was neither completely trivial; some of my attempts plainly did not import at all (even though my code seemed to compile nicely), while in other attempts the code crashed and gave a non-sensical PortInUseException. (What I gathered from reading the online discussions, is that there are some issues regarding 32-bit vs 64-bit architectures, some issues regarding different parts of RXTX not working well together, some issues with the use of lock-files in Mac, and some issues with regards to RXTX not always working well with Java 1.6)

In any case, these are the steps I found to work:

(Most of which are based on this far more insightful walkthrough by Chris Bartley)

0. Remove all files from previous attempts to make RXTX work.

1. Install XCode Command Line tools, if you haven't already (I used XCode 4.6). (You can get XCode from the App Store. After XCode is installed, open XCode, and go to XCode -> Preferences -> Downloads -> Components -> Command Line Tools to install)

2. Download the source in order to build RXTX yourself. (None of the binaries that I found online worked for me, but you are welcome to jump to step 8 using my binaries if you want). You can get the source by telling this to the Terminal:

$ export CVSROOT=:pserver:anonymous@qbang.org:/var/cvs/cvsroot
$ cvs login
Logging in to :pserver:anonymous@qbang.org:2401/var/cvs/cvsroot
CVS password:
$ cvs checkout -r commapi-0-0-1 rxtx-devel

For the password you may have to type something random (e.g. a space character), if the Terminal goes off looking for a password in a file; but you should not need a password per se.

3. Check that, in your ~/.profile, the PATH environment variable has /usr/bin and /bin first (if needed, modify .profile so that the places where you set the PATH (e.g. "export PATH=$PATH:/opt/local/bin:/opt/local/sbin") have the additions at the end)

4. Set the variable JAVA_HOME:
$ export JAVA_HOME=`/usr/libexec/java_home`

(This step may not be necessary, but if Chris Bartley includes it, so do I)

5. Make sure there are no spaces in the absolute path to the rxtx-devel folder

6. Run the configuration script in the rxtx-devel folder
$ sh ./configure

7. In the rxtx-devel folder, manually edit the Makefile such that the JAVAINCLUDEDIR variable gives the correct path for the file jni_md.h (you will have to search for the file jni_md.h on your hard drive).
JAVAINCLUDEDIR = /System/Library/Frameworks/JavaVM.framework/Versions/Current/Headers

Of course, your path will be different than this; it will be the path to where you found jni_md.h. (This variable was found somewhere around line 107 in the Makefile when I did this.)

8. Build
$ make

Two files are produced with which we are concerned. They are:
    * rxtx-devel/RXTXcomm.jar
    * rxtx-devel/i386-apple-darwin11.4.2/librxtxSerial.jnilib
    
Note that the name of the folder I call "i386-apple-darwin11.4.2" may change depending on your system. This is simply the folder name I got, running OS X 10.7.5 (Lion) on a 2.4 GHz Intel Core 2 Duo (64-bit architecture).

(The files that I produced in this step are available here, in case you want to try those, rather than making your own.)

9. Move the two files acquired in step 8 to /Library/Java/Extensions
Updated! See below

10. Add execution permissions to RXTXcomm.jar
$ chmod +x RXTXcomm.jar

At this point, RXTX works for me. In your Java source file, you should only need to
import gnu.io.*


UPDATE (2/20/2013)
It turns out that step 9 above will break some other Java applications (e. g. the Arduino IDE). A better version of step 9 is the following (these steps are specific to Netbeans, but I am sure you can do something similar using other development environments):

9.1  Move the file RXTXcomm.jar to a location where you can access it from the project where the library is needed, e.g. in a folder "libraries" inside your project folder.

9.2  Move the file librxtxSerial.jnilib to the base directory of your project

9.3  Open your project in Netbeans, then right click on the "Libraries" folder and choose "Add JAR/Folder." Find and select the file RXTXcomm.jar in the dialog that shows up. Since librxtxSerial.jnilib is in the base directory for your project, it will be automatically recognised.

6 comments:

  1. Excellent Post! Very helpful, I have spent hours trying to setup my RxTx library! This post solved my problem

    ReplyDelete
  2. Hello,
    I followed all the steps in this tutorial. But still I face the gnu.io.PortInUseException problem. I have the Mac OS X Lion 10.7.5 .

    ReplyDelete
  3. Hello

    I followed all steps , but did not get the librxtxSerial.jnilib file . I got inside the i386-apple-darwin12.4.0/.libs the followings files :
    librxtxSerial-2.2.dylib ; librxtxSerial.lai; SerialImp.o;fuserImp.o.

    I did get the RXTXcomm.jar, I put it inside the /Library/Java/Extensions

    but when run the app got the following error:

    2013-08-18 00:51:30,496 [Thread-4] INFO org.smslib.modem.SerialModemDriver - GTW: modem1: Opening: /dev/tty.ZTEUSBATPort_ @19200

    java.io.IOException: Error instantiating class gnu.io.RXTXCommDriver
    gnu.io.RXTXCommDriver cannot be cast to javax.comm.CommDriver
    at javax.comm.CommPortIdentifier.loadDriver(CommPortIdentifier.java:238)
    at javax.comm.CommPortIdentifier.(CommPortIdentifier.java:109)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:186)
    at org.smslib.helper.CommPortIdentifier.(CommPortIdentifier.java:66)
    at org.smslib.modem.SerialModemDriver.connectPort(SerialModemDriver.java:69)
    at org.smslib.modem.AModemDriver.connect(AModemDriver.java:114)
    at org.smslib.modem.ModemGateway.startGateway(ModemGateway.java:189)
    at org.smslib.Service$1Starter.run(Service.java:277)
    Exception in thread "Thread-4" java.lang.UnsatisfiedLinkError: com.sun.comm.SunrayInfo.isSessionActive()Z
    at com.sun.comm.SunrayInfo.isSessionActive(Native Method)


    Any help will be appreciated. THX

    ReplyDelete
  4. Hi guys, and sorry for my late reply.

    I unfortunately do not have enough insight into RXTX to help you troubleshoot, but feel free to try the librxtxSerial.jnilib -file that I produced doing these steps myself. Follow the link in step 8 to download.

    ReplyDelete
  5. Thanks a lot Torstein. Found your article after hours of scouring the net and trial and error. Keep up the good work.

    ReplyDelete
  6. Thanks Torstein for detailed time saving instructions. Take a look at scm which is an alternative library to rxtx/javaxcomm for serial port communication. Wiki is here http://www.embeddedunveiled.com/

    ReplyDelete