-
Notifications
You must be signed in to change notification settings - Fork 53
Java
In this article you will do these followings:
- Install Java Development Kit and Runtime Environment (openjdk-7)
- Install an external Java library (RXTXcomm)
- Compile a console application written Java using the above two.
Note that this article does not present a cross development environment. Java's bytecode is portable by design. So it is easy to compile a piece of Java code on an x86 workstation and deploy to an ARM device. However we intentionally avoid such workflow for now. Unlike C/C++ which is extensively documented, Yocto Project's SDK lacks Java cross development.
Hence we will native-compile a simple TwoWaySerialComm
Java app that dumps the standard output into a unoccupied serial console and vice versa. It is originally written by Johannes Eickhold for EclipseSource.com.
This program relies on RXTX, a Java communication API. RXTX is available as a recipe and is also a part of the Gumstix Package Repository.
Make sure you are running a recent version of Gumstix Yocto image on your Gumstix board.
Here we install JRE, JVM, and RXTXComm API on your Gumstix:
$ smart update
$ smart install librxtx-java openjdk-7-jre openjdk-7-jdk
When this is successful, you will have javac
, the compiler, and RXTX Java class like this:
root@overo:~# ls /usr/share/java
rxtx.jar
RXTXcomm.jar
...
Before we compile any Java code, let's set classpath
and LD_LIBRARY_PATH
:
export CLASSPATH="/usr/share/java/RXTXcomm.jar"
export LD_LIBRARY_PATH="/usr/lib/jni"
Skipping this step will result in compile error. Here CLASSPATH
refers to the location where Java user class files are. And LD_LIBRARY_PATH
refers to the Java system library.
Copy the following source code into TwoWaySerialComm.java
file:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
public class TwoWaySerialComm {
void connect( String portName ) throws Exception {
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier( portName );
if( portIdentifier.isCurrentlyOwned() ) {
System.out.println( "Error: Port is currently in use" );
} else {
int timeout = 2000;
CommPort commPort = portIdentifier.open( this.getClass().getName(), timeout );
if( commPort instanceof SerialPort ) {
SerialPort serialPort = ( SerialPort )commPort;
serialPort.setSerialPortParams( 57600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE );
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
( new Thread( new SerialReader( in ) ) ).start();
( new Thread( new SerialWriter( out ) ) ).start();
} else {
System.out.println( "Error: Only serial ports are handled by this example." );
}
}
}
public static class SerialReader implements Runnable {
InputStream in;
public SerialReader( InputStream in ) {
this.in = in;
}
public void run() {
byte[] buffer = new byte[ 1024 ];
int len = -1;
try {
while( ( len = this.in.read( buffer ) ) > -1 ) {
System.out.print( new String( buffer, 0, len ) );
}
} catch( IOException e ) {
e.printStackTrace();
}
}
}
public static class SerialWriter implements Runnable {
OutputStream out;
public SerialWriter( OutputStream out ) {
this.out = out;
}
public void run() {
try {
int c = 0;
while( ( c = System.in.read() ) > -1 ) {
this.out.write( c );
}
} catch( IOException e ) {
e.printStackTrace();
}
}
}
public static void main( String[] args ) {
String SerialPortID = args[0];
System.setProperty("gnu.io.rxtx.SerialPorts", SerialPortID);
try {
( new TwoWaySerialComm() ).connect( args[0] );
} catch( Exception e ) {
System.out.println( "Can't find serial port\n" );
e.printStackTrace();
}
}
}
Note that the code has been slightly modified from the original version. The original code is missing some key import
clause. It also fails to set the default port for RXTX.
Then you can compile like below:
javac TwoWaySerialComm.java
If the code compiled, you should have 4 files:
$ ls TwoWaySerialComm*
TwoWaySerialComm.class TwoWaySerialComm.java
TwoWaySerialComm$SerialReader.class TwoWaySerialComm$SerialWriter.class
If you run into an issue like this:
Error: Could not find or load main class TwoWaySerialComm
Add the path to your Java bytecode to CLASSPATH
:
export CLASSPATH=$CLASSPATH:/Path-To-Bytecode/
The example program will refer to locations above CLASSPATH
when it executes:
java TwoWaySerialComm /dev/ttyO0