Monday, October 28, 2013

RXTX on Mac with Oracle Java 7

I've been using RXTX on the mac for quite some time with the -d32 vm argument. This was necessary with 64-bit Java since the native libraries for RXTX are only compiled for 32-bit mode. Without -d32, you'd get the following error:

java.lang.UnsatisfiedLinkError: librxtxSerial.jnilib: no suitable image found

Apple had always bundled Java with OS X, but about 3 years ago they announced they would no longer do so. Now, to get Java 7 for the mac you need to get it from Oracle. Recently I tried running one of my RXTX apps with Oracle's Java 7 and I got the following error:

Error: This Java instance does not support a 32-bit JVM.

Please install the desired version.

It seems that Oracle no longer supports the -d32 vm argument. You can still run the Apple version of Java 6. The Apple bundled Java versions can be found in

/System/Library/Frameworks/JavaVM.framework/Versions/

For example:

$ /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java -d32 -version
java version "1.6.0_37"
Java(TM) SE Runtime Environment (build 1.6.0_37-b06-434-11M3909)
Java HotSpot(TM) Client VM (build 20.12-b01-434, mixed mode)

So to run Oracle Java 7 we need a 64-bit version of RXTX. A few searches led me to Arduino article that mentions Robert Harder's blog post http://blog.iharder.net/2009/08/18/rxtx-java-6-and-librxtxserial-jnilib-on-intel-mac-os-x/ In this post Robert describes how he compiled RXTX for 64-bit Java (apparently not a trivial task). After downloading his librxtxSerial.jnilib it worked, the first time; the second time I got an exception:

“gnu.io.PortInUseException: Unknown Application”

This was super annoying since I didn't have any other Java processes running that had the port open. I read through the comments and found a solution:

sudo mkdir /var/lock

sudo chmod a+wrx /var/lock

Apparently RXTX needs this directory to manage locks. This was also mentioned on the Arduino article but I missed it the first time. It seems that the Arduino IDE must rely on Java 6 since the RXTX library that comes with the IDE is 32-bit. At some point I imagine (Java 8 perhaps), we'll see more interest in 64-bit RXTX. Please leave a comment if you have any insight on this problem and/or alternative solutions.

Sunday, June 9, 2013

XBee on the Raspberry Pi

When I first started writing xbee-api in 2007, there were no options for a cost effective, low power host computer with Java support. In 2009 I purchased a Sheevaplug ARM computer and that worked for a while but proved to be problematic: the power supply failed after a year (a known issue), and it experienced periodic boot errors. Last year I received a Raspberry Pi after a long wait, due demand far exceeding supply.


In order to run Java on the the Raspberry Pi it requires the soft-float version of Debian OS, available from the Pi website. Once you get your Pi up and running, you'll need to install the Oracle Java for ARM. I don't recommend openjdk as I found it to be much slower and buggier on ARM.

Update Java8 is available and although it says "jdk" in the name, javac is not present. Choose the following version from the above link:ejdk-8u111-linux-arm-sflt.tar.gz This works on my raspberry pi version 1, model B. This version includes a few binaries, I've been using the first with no issues:

/opt/java/ejdk1.8.0_111/linux_arm_sflt/jre/bin/java
/opt/java/ejdk1.8.0_111/linux_arm_sflt/compact2/bin/java
/opt/java/ejdk1.8.0_111/linux_arm_sflt/compact3/bin/java

/opt/java/ejdk1.8.0_111/linux_arm_sflt/compact1/bin/java

There are several versions of Java for ARM on the Oracle site. The version compatible with the Raspberry Pi is ARMv6/7 Linux - Headless EABI, VFP, SoftFP ABI, Little Endian. The current release as of this writing is ejre-7u21-fcs-b11-linux-arm-vfp-client_headless-04_apr_2013.tar.gz.

Move the gzip file to your Pi and unpack

gunzip ejre-7u10-fcs-b18-linux-arm-vfp-client_headless-28_nov_2012.gz 
tar xvf ejre-7u10-fcs-b18-linux-arm-vfp-client_headless-28_nov_2012

I installed it in /opt/java

sudo mv -v ejre1.7.0_10/ /opt/java/

Create the symbolic link

cd /opt/java/ejre1.7.0_10/
sudo update-alternatives --install "/usr/bin/java" "java" "/opt/java/ejre1.7.0_10/bin/java" 1
sudo update-alternatives --set java /opt/java/ejre1.7.0_10/bin/java

Open .bashrc and set the JAVA_HOME environment variable

export JAVA_HOME="/opt/java/ejre1.7.0_10"

Now you should be able to execute java

java -version

And see something like

java version "1.7.0_10"
Java(TM) SE Embedded Runtime Environment (build 1.7.0_10-b18, headless)
Java HotSpot(TM) Embedded Client VM (build 23.6-b04, mixed mode)

Although the Pi has a GPIO serial port that is well suited for XBee, since it runs at 3.3V, I'm using a usb-serial XBee Explorer since I already had this hardware available and the configuration is less complicated. These can be found relatively cheap from Chinese vendors on ebay, or from a local supplier if you need it quicker. I'm using the SparkFun USB Explorer.

Install RXTX to provide serial port access to Java

sudo apt-get install librxtx-java

Now when you plug your XBee into the Pi, via USB, it should appear as /dev/ttyUSB0 and can be opened with xbee-api

XBee xbee = new XBee()
xbee.open("/dev/ttyUSB0")

Now, to run your xbee-api application on the Pi, you need to provide a few key arguments to Java.

java -Djava.library.path=/usr/lib/jni/ -classpath ".:/usr/share/java/RXTXcomm.jar" com.fooYourApp

The -Djava.library.path argument tells Java where to find the native RXTX library (JNI).

 If you exported your application from Eclipse into an executable JAR, use "*:/usr/share/java/RXTXcomm.jar" for classpath. This tells Java to load all JAR files in the current directory, in addition to the RXTX JAR. Alternatively, if you copied your Eclipse folder to the Pi, the classfiles are in the bin directory, so use "bin:/usr/share/java/RXTXcomm.jar". Of course replace com.fooYourApp with the package + class name of the main class. It's a good idea to put the full Java command in a script (e.g. myapp.sh). Then make it executable with chmod u+x myapp.sh.

Now modify add the non-root user that you run your apps to the group that owns the device. This is only necessary if you don't run as root:


ls -l /dev/ttyUSB0 
crw-rw---- 1 root dialout 188, 0 Dec 31  1969 /dev/ttyUSB0

Only root and the dialout group has read/write to the device, so add your user to the dialout group, ex:

sudo usermod -a -G dialout arapp

If you want your app to start every time the Pi boots, add the script to the do_start() function in /etc/init.d/rc.local

do_start() {
        if [ -x /etc/rc.local ]; then
                cd /home/pi/path-to-your-app && sudo -u pi nohup ./myapp.sh &

I've been running my Garage Door XBee application on the Pi for about 6 months now and it has been very reliable. The only problems I've encountered so far were related to a failing power supply. When the voltage drops below 4.75, mysterious things can start to happen. My power supply dropped to 4.69 and I noticed periodic crashes.

I'm running my Pi with ethernet connectivity. The Pi can use Wifi but due to the limited current supply of the USB port, it only works with a select number of Wifi chips. Perhaps later versions of the Pi will supply more power to the USB to overcome this limitation.

In a future post I'll show how to interface the Pi's GPIO Serial port directly with the XBee UART.