Dec 27, 2002
onlsbc1, Red Hat Linux 8.0 のシステムでのJNIの実行
--- hello world実行#1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(http://www-online.kek.jp/~inoue/para-CAMAC/
Work/SBC-Java3.html)
高エネルギー加速器研究機構
素粒子原子核研究所
物理、オンライングループ
井上 栄二
目的
SBC、PCM-9370にインストールしてある Red Hat Linux 8.0 のシステム上で
JNIを使って Hello Word が実行できることを確認する。
(1). 構成
(2). コンパイル
(3). 実行
--------------------------------------------------------------------
(1). 構成
テストに使用するマシンは onlsbc1 である。 このマシンはアドバンテク社の
SBC、PCM-9370である。 動作している OSはRed Hat Linux 8.0 で、Javaの
バージョンは1.4.1_01 である。 最終的にはコンパクトフラッシュ上に構成した
Linuxシステムで実行できることを目指すのであるが、ソフトウェアの開発段階
では 2.5" IDE ハードディスク上に構成したLinuxシステムを使ってテストを
行うことにする。
(2). コンパイル
(2-1). Javaのチェック
[inoue@onlsbc1 inoue]$ java -version
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
[inoue@onlsbc1 inoue]$
(2-2). 実行環境
[inoue@onlsbc1 JNI]$ env
MANPATH=:/usr/java/man
HOSTNAME=onlsbc1.kek.jp
PVM_RSH=/usr/bin/rsh
TERM=vt100
SHELL=/bin/bash
JLESSCHARSET=japanese
HISTSIZE=1000
SSH_CLIENT=130.87.153.9 33049 22
QTDIR=/usr/lib/qt3-gcc3.2
SSH_TTY=/dev/pts/1
USER=inoue
LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;0
1:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.b
tm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:
*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*
.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;3
5:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:
PVM_ROOT=/usr/share/pvm3
MAIL=/var/spool/mail/inoue
PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/java/bin
:/home/inoue/bin
INPUTRC=/etc/inputrc
PWD=/home/inoue/JNI
LANG=ja_JP.eucJP
LAMHELPFILE=/etc/lam/lam-helpfile
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SHLVL=1
HOME=/home/inoue
XPVM_ROOT=/usr/share/pvm3/xpvm
LOGNAME=inoue
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env
OLDPWD=/home/inoue
[inoue@onlsbc1 JNI]$
(2-3). Javaコードを書く
この実行で使用するソースコードは、以下のURLから入手した。
http://java.sun.com/j2se/1.4/ja/docs/ja/guide/jni/index.html
[inoue@onlsbc1 JNI]$ cat HelloWorld.java
class HelloWorld {
public native void displayHelloWorld();
static {
System.loadLibrary("hello");
}
public static void main(String[] args) {
new HelloWorld().displayHelloWorld();
}
}
[inoue@onlsbc1 JNI]$
(2-4). Javaコードをコンパイルする
[inoue@onlsbc1 JNI]$ ls -l
合計 4
-rw-rw-r-- 1 inoue inoue 224 12月 26 17:01 HelloWorld.java
[inoue@onlsbc1 JNI]$ javac HelloWorld.java
[inoue@onlsbc1 JNI]$ ls -l
合計 8
-rw-rw-r-- 1 inoue inoue 462 12月 26 17:05 HelloWorld.class
-rw-rw-r-- 1 inoue inoue 224 12月 26 17:01 HelloWorld.java
[inoue@onlsbc1 JNI]$
(2-5). .hファイルの生成
C++言語のヘッダーファイルは、以下のようにjavahというコマンドで生成
できる。 オプションには-jniを指定し、引数には項目(2-4)でコンパイルした
クラスの拡張子を除いたものを指定する。
[inoue@onlsbc1 JNI]$ javah -jni HelloWorld
[inoue@onlsbc1 JNI]$ ls -l
合計 12
-rw-rw-r-- 1 inoue inoue 462 12月 26 17:05 HelloWorld.class
-rw-rw-r-- 1 inoue inoue 401 12月 26 17:13 HelloWorld.h
-rw-rw-r-- 1 inoue inoue 224 12月 26 17:01 HelloWorld.java
[inoue@onlsbc1 JNI]$ cat HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
[inoue@onlsbc1 JNI]$
(2-6). C言語のソースファイルの作成
[inoue@onlsbc1 JNI]$ cat HelloWorldImp.c
#include <jni.h>
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
{
printf("Hello world!\n");
return;
}
[inoue@onlsbc1 JNI]$
(2-7). C言語のソースファイルをコンパイルしてシェアード・ライブラリを作成
[inoue@onlsbc1 JNI]$ pwd
/home/inoue/JNI
[inoue@onlsbc1 JNI]$ ls -l
合計 16
-rw-rw-r-- 1 inoue inoue 462 12月 26 17:05 HelloWorld.class
-rw-rw-r-- 1 inoue inoue 401 12月 26 17:13 HelloWorld.h
-rw-rw-r-- 1 inoue inoue 224 12月 26 17:01 HelloWorld.java
-rw-rw-r-- 1 inoue inoue 192 12月 26 17:17 HelloWorldImp.c
[inoue@onlsbc1 JNI]$
[inoue@onlsbc1 JNI]$ ls -l /usr/java/include
合計 152
-r--r--r-- 1 root root 8497 9月 30 19:13 jawt.h
-r--r--r-- 1 root root 67553 9月 30 19:13 jni.h
-r--r--r-- 1 root root 39103 9月 30 19:13 jvmdi.h
-r--r--r-- 1 root root 21994 9月 30 19:13 jvmpi.h
drwxr-xr-x 2 root root 4096 9月 30 19:13 linux
[inoue@onlsbc1 JNI]$ ls -l /usr/java/include/linux
合計 8
-r--r--r-- 1 root root 947 9月 30 19:13 jawt_md.h
-r--r--r-- 1 root root 453 9月 30 19:13 jni_md.h
[inoue@onlsbc1 JNI]$
[inoue@onlsbc1 JNI]$ gcc -G -I/usr/java/include -I/usr/java/include/linux HelloW
orldImp.c -o libhello.so
gcc: 認識不能なオプション `-G'
/usr/lib/gcc-lib/i386-redhat-linux/3.2/../../../crt1.o: In function `_start':
/usr/lib/gcc-lib/i386-redhat-linux/3.2/../../../crt1.o(.text+0x18): undefined re
ference to `main'
collect2: ld はステータス 1 で終了しました
[inoue@onlsbc1 JNI]$
SUNコンパイラの cc の man をチェック。
onlsun1[36]% man cc
User Commands cc(1)
名前
cc - C コンパイラ
形式
cc [ -# ] [ -### ] [ -A <名前>[(<トークン>)] ]
[ -B[static|dynamic] ] [ -C ] [ -c ]
:
:
-G このオプションを指定すると、リンカーは、動的にリンクさ
れた実行可能ファイルではなく、共有オブジェクトを作成し
ます。このオプションは ld に渡されます。 -dn オプション
と一緒に使用することはできません。
:
onlsun1[37]%
Linuxの gcc の man をチェック。
[inoue@onlsbc1 JNI]$ man gcc
名称
gcc, g++ - GNU プロジェクト C および C++ コンパイラ (gcc-2.95.3)
書式
gcc [ option | filename ]...
:
:
こ こに追加するオプションは System V Release 4 において、これらのシステ
ム上の他のコンパイラとの互換性のために提供されるものです。
-G SVr4 システムにおいて、gcc は `-G' オプションを受け付けます ( そ
し てこれをシステムリンカに渡します)。これは他のコンパイラとの互
換性のためです。しかし、リンカオプションを gcc のコマンドライ ン
から渡すよりも、我々は `-symbolic' または `-shared' の使用が適当
であると考えています。
[inoue@onlsbc1 JNI]$ gcc -shared -I/usr/java/include -I/usr/java/include/linux H
elloWorldImp.c -o libhello.so
[inoue@onlsbc1 JNI]$ ls -l
合計 24
-rw-rw-r-- 1 inoue inoue 462 12月 26 17:05 HelloWorld.class
-rw-rw-r-- 1 inoue inoue 401 12月 26 17:13 HelloWorld.h
-rw-rw-r-- 1 inoue inoue 224 12月 26 17:01 HelloWorld.java
-rw-rw-r-- 1 inoue inoue 192 12月 26 17:17 HelloWorldImp.c
-rwxrwxr-x 1 inoue inoue 5658 12月 27 09:10 libhello.so
[inoue@onlsbc1 JNI]$
(3). 実行
[inoue@onlsbc1 JNI]$ pwd
/home/inoue/JNI
[inoue@onlsbc1 JNI]$ ls -l
合計 24
-rw-rw-r-- 1 inoue inoue 462 12月 26 17:05 HelloWorld.class
-rw-rw-r-- 1 inoue inoue 401 12月 26 17:13 HelloWorld.h
-rw-rw-r-- 1 inoue inoue 224 12月 26 17:01 HelloWorld.java
-rw-rw-r-- 1 inoue inoue 192 12月 26 17:17 HelloWorldImp.c
-rwxrwxr-x 1 inoue inoue 5658 12月 27 09:10 libhello.so
[inoue@onlsbc1 JNI]$ java HelloWorld
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.libr
ary.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1403)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:832)
at HelloWorld.<clinit>(HelloWorld.java:5)
[inoue@onlsbc1 JNI]$
ライブラリpathが正しくセットされていない。
[inoue@onlsbc1 JNI]$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
[inoue@onlsbc1 JNI]$ java HelloWorld
Hello world!
[inoue@onlsbc1 JNI]$
ok. JNIによる Hello World は正常に実行できた。
---xxxx