Java 2 SDK Solaris 版は NMI をサポートしません。インストールによっては、NMI は JNI 1.0、JNI は JNI 1.1 と呼ばれます。
ネイティブメソッドを含むアプリケーションはプラットフォームに依存し、「Write Once Run AnywhereTM」ではありません。このことは、NMI または JNI のどちらが使用されているかに関係ありません。ネイティブメソッドのサポートが変更されても、アプレットには影響しません。
NMI を使用するアプリケーションを JNI インタフェースを使用するように変更するのは簡単です。たとえば、不慣れな技術者でも 2 日ほどで 6000 行の C コードを移植しました。この例では、NMI は少し使われているだけでしたが、使用箇所は広く分散していました。
javah コマンドは、ネイティブメソッドの実装に必要な C ヘッダとソースファイルを生成します。C プログラムは生成されたヘッダとソースファイルを使用して、ネイティブソースコードのオブジェクトのインスタンス変数を参照します。JNI には、ヘッダ情報やスタブファイルは必要ありません。引き続き javah コマンドで jni オプションを使用して、JNI 形式のネイティブメソッドに必要なネイティブメソッド関数プロトタイプを生成することができます。結果は、.h ファイルに書き込まれます。
JDK 1.1 のデフォルトのモードでは、javah コマンドは NMI 出力を生成します。
NMI インタフェースは Java 2 SDK Solaris 版の実装とまったく互換性がないため、Java 2 SDK Solaris 版で -old フラグを使用して、NMI 形式の出力を生成することはできません。Java 2 SDK Solaris 版では、-old フラグは解析され、見つかった場合は、-old not supported メッセージが生成され、javah は終了します。
ネイティブメソッドをコンパイルするときにコンパイラが行うことがある最適化によって、VM を実行できないことがあります。VM はスレッドのスタックにある関数のスタックフレーム検査機能に依存します。このため、ネイティブ関数のコードは、非リーフ関数に対するシステム呼び出し規則の規定にしたがってつねにスタックフレームを作成する必要があります。またフレームポインタレジスタは、つねに有効なスタックフレームを指す必要があります。
Intel (IA) プラットフォーム上で Sun WorkshopTM C コンパイラを使用すると、最適化レベルの -xO4 および -xO5 で上記の条件に違反するコードが生成されることがあります。このため、-xO3 より高い最適化レベルは使用しないでください。
SPARC プラットフォーム上では、すべての最適化レベルで問題はありません。別のコンパイラを使用する場合は、そのコンパイラのドキュメントで上記の条件を満たすコードが生成されるかどうか確認してください。
上記の制限事項に違反しているネイティブメソッドは、VM を異常終了させることがあります。
ネイティブの Solaris アプリケーションは、-lthread を使用してリンクしてください。そのようにしないと、不正な動作をすることがあります。
JNI を使用するネイティブアプリケーションをリンクするときは、libc.so ライブラリ (-lc オプション) の前に libthread.so ライブラリ (-lthread オプション) を指定する必要があります。Sun C コンパイラの -mt オプションは、-lthread オプションを自動的に追加します。一般的に -lc オプションは指定しません (デフォルトでリストの末尾になります)。このため、Sun のコンパイラやリンカを使用するときは、かならず -mt または -lthread オプションを指定しなければなりません。
Java 2 SDK Solaris 版では、Get*ArrayElements() 呼び出しの代わりに jni_GetPrimitiveArrayCritical() および jni_ReleasePrimitiveArrayCritical() を使用することによって JNI 配列へのアクセスを高速にすることができます。
これらの *Critical() オペレーションを使用するコードは、次の制限事項を守っている必要があります。
配列の要素の取得後に速やかにそれらの要素を解放しなければならない
配列の要素を保持した状態で Java に戻ることはできない
他の JNI 操作を呼び出すことはできない
これらの制限事項があるため、データ固定やコピーを行わずに配列の要素にアクセスすることはできません。詳細は次のサイトを参照してください。
http://java.sun.com/products/jdk/1.2/ja/docs/ja/guide/jni/jni-12.html
Solaris 2.5.1 または 2.6 ソフトウェアを使用していて、デフォルトの /usr/java1.2 以外の場所に JDK をインストールした場合、JNI のネイティブアプリケーションが JDK 共有ライブラリを検出できないことがあります。この問題は、LD_LIBRARY_PATH 環境変数に JDK のインストール先の jre/lib/sparc または jre/lig/i386 ディレクトリを含めることによって回避することができます。この問題は Solaris 7、Solaris 8 ソフトウェアでは発生しません。
JNI を使用するネイティブコードがシグナルの処理状態を変更してはなりません。VM はシグナルを使用します。シグナル処理に変更を加えると、VM で障害が発生することがあります。