ARMアーキテクチャ環境のJava7でRXTXをビルドする。
RXTX http://rxtx.qbang.org/wiki/index.php/Main_Page
OpenBlocksAX3にRXTXをインストールする時にハマった内容。
OpenBlocksAX3はarmv7lと言うアーキテクチャを使用しているので、
RXTXでダウンロードできるバイナリをそのままJRE配下へ持っていっても動かない。
以下のようなエラーが出る。
java.lang.UnsatisfiedLinkError: /usr/lib/jre/lib/arm/librxtxSerial.so: /usr/lib/jre/lib/arm/librxtxSerial.so: cannot open shared object file: No such file or directory (Possible cause: can't load IA 32-bit .so on a ARM-bit platform) thrown while loading gnu.io.RXTXCommDriver
これはarmv7l上でi686用のlibrxtxSerial.soを呼んでいるためであって、armv7l用のlibrxtxSerial.soを用意してやる必要がある。
Jim Connors' Weblog(https://blogs.oracle.com/jtc/entry/serial_port_communication_for_java)にビルド済みのarm用librxtxSerial.soが公開されているので、そこから取得すれば問題なく動作してくれる。
動作してくれるのだが、Java6でビルドしてあり、Java7で動かすにはどうにも気持ち悪いし、今後も同様に動作してくれるのか怪しいので、ソースからビルドする。
まず、OpenBlocksにはJREしか入っていないので、このJREを無効にする。
■すべてコメントアウトする。
$ sudo vi /etc/profile.d/java.sh
#JAVA_HOME=/usr/lib/jre
#PATH=$PATH:$JAVA_HOME/bin
#export JAVA_HOME PATH
■再起動する。
■javaコマンドが無効になっていることを確認。
$ sudo reboot
$ java -version
bash: java: command not found
OracleよりARMアーキテクチャ用のJDK7をダウンロードする。
・Linux ARM v6/v7 Soft Float ABI(jdk-7u21-linux-arm-sfp.tar.gz)
■解凍して/usr/localへコピー。
■update-alternatives --installでjava、javacを登録する。
$ tar zxvf jdk-7u21-linux-arm-sfp.tar.gz
$ sudo cp -R ./jdk1.7.0_21 /usr/local/
■確認
$ sudo update-alternatives --install /usr/bin/java java /usr/java/jdk1.7.0_21/bin/java 1
$ sudo update-alternatives --install /usr/bin/javac javac /usr/java/jdk1.7.0_21/bin/javac 1
$ java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) Client VM (build 23.21-b01, mixed mode)
$ javac -version
javac 1.7.0_21
RXTXからSource(rxtx-2.1.7r2.zip)をダウンロードし、解凍する。
■unzipコマンドをインストール
■解凍する。
$ sudo aptitude install unzip
Installationを見ながら何も考えずにビルドを行う。
$ unzip rxtx-2.1-7r2.zip
$ cd rxtx-2.1-7r2/
■Javaディレクトリ配下へコピーする。(シンボリックリンク張るのも忘れずに)
$ ./configure
$ make
$ sudo cp RXTXcomm.jar /usr/local/jdk1.7.0_21/jre/lib/ext/
$ sudo cp ./armv7l-unknown-linux-gnu/.libs/librxtxSerial-2.1-7.so /usr/local/jdk1.7.0_21/jre/lib/arm/
$ sudo ln -s librxtxSerial-2.1-7.so librxtxSerial.so
そうすると以下のエラーが出る。
java.lang.UnsatisfiedLinkError: gnu.io.RXTXCommDriver.nativeGetVersion()Ljava/lang/String; thrown while loading gnu.io.RXTXCommDriver
java.lang.NoClassDefFoundError: Could not initialize class gnu.io.RXTXCommDriver thrown while loading gnu.io.RXTXCommDriver
RXTX自体が古く、JDKのバージョンを追えていないので、configureファイルとconfigure.inファイルへ以下の変更を加える。
※上記の場所を以下へ変更する。
$ vi configure
case $JAVA_VERSION in
1.2*|1.3*|1.4*|1.5*)
↓
1.2*|1.3*|1.4*|1.5*|1.6*|1.7*)
configureファイル :21544、21614、21750、21802行目
configure.iniファイル:466、536、672、724行目
makeの以下のエラーを排除する。
error: 'UTS_RELEASE' undeclared (first use in this function)
■OSのバージョンを取得
■version.hを編集する。最終行に以下を追加する。
$ uname -r
3.0.6
再ビルドする。
$ sudo vi /usr/include/linux/version.h
#define UTS_RELEASE "3.0.6"
コピーして、起動して確認する。
$ make clean
$ ./configure
$ make
実行結果
$ sudo cp RXTXcomm.jar /usr/local/jdk1.7.0_21/jre/lib/ext/
$ sudo cp ./armv7l-unknown-linux-gnu/.libs/librxtxSerial-2.1-7.so /usr/local/jdk1.7.0_21/jre/lib/arm/
$ java Test
Experimental: JNI_OnLoad called.
Stable Library
=========================================
Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7
/dev/ttyUSB0
/dev/ttyS1
/dev/ttyS0
動作確認のサンプルコード
Test.java
import gnu.io.CommPortIdentifier;
import java.util.Enumeration;public class Test{
public static void main(String[] args){
System.out.println("main method start.");
try{
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
CommPortIdentifier port = null;
while (portList.hasMoreElements()) {
port = (CommPortIdentifier)portList.nextElement();
System.out.println(port.getName());
}
}catch(Exception e){
e.printStackTrace();
}
}
}