JNI(Java Native Interface)を使用する場合の注意事項を教えてください。

Interstage Application Server の技術情報はこちら

JNI(Java Native Interface)を使用する場合の注意事項を教えてください。
JNI(Java Native Interface)を使用する場合の注意事項は、以下のとおりです。

■アプリケーションがすべてJavaで記述できないか、検討してください。
アプリケーションミスによるトラブルを事前に防止するためには、(C/C++などを使用した)ネイティブプログラムをJNI経由で利用しないでください。
最初に、ネイティブプログラムで実現しようとしている機能が、Javaで記述できるか、再度、検討してください。
Javaで記述できない場合は、ネイティブプログラムの利用は最小限にし、十分なテストを実施してください。
JNI経由でネイティブプログラムを使用する際に必須となる前提スキルは、以下のとおりです。

  • C/C++でマルチスレッドプログラミングの経験がある。
  • トラブルが発生した場合にも自分でデバッグできる。

■ファイナライズ処理を期待したリソース管理は、行わないでください。
JNI関連で、もっともトラブルが多いのは、ネイティブプログラム側で確保したメモリの後処理漏れです。例えば、次のようなプログラミングをしますと、メモリリークが発生し、最終的にはアプリケーション自体が停止する可能性があります。

  ------- Java ---------------
  class A {
    native long nativeAlloc();
    native void nativeFree(long a);
    long address;
    A() {
      address = nativeAlloc();
    }
    public void finalize() {
      nativeFree(address);
    }
  }
  ------- Java ---------------

  ------- C ---------------
  JNIEXPORT jlong JNICALL Java_A_nativeAlloc(JNIEnv *env, jobject o)
  {
    return (jlong)malloc(10);
  }
  JNIEXPORT void JNICALL Java_A_nativeFree(JNIEnv *env, jobject o, jlong p)
  {
    free((void*)p);
  }
  ------- C ---------------

問題が起き易いのは、ファイナライズ処理です。論理としては、メモリリークではありませんが、実際に回収される処理が動作しなければ、メモリリークと同じです。
Javaのファイナライズ処理を期待したリソース管理は、行わないでください。

■シグナルハンドラは、使用できません。
JNIを使用したプログラムの中で、シグナルハンドラは、使用できません。
Java VM(Java Virtual Machine)は、独自にシグナルハンドラを設定して、Java VM固有のシグナル処理を行っています。そのため、利用者がJNI関数の中でシグナルハンドラを設定すると、本来Java VMが処理すべきシグナルが正しく処理されず、場合によっては、Java VMが異常終了することもあります。
アプリケーションの実装では、特にシグナルを使わなければできないという機能はほとんどありませんので、シグナル操作(シグナル発行、シグナルハンドラの書き換え、または、シグナルマスクの書き換え)をネイティブプログラムで行わないでください。
なお、JDK/JRE 1.4.0以降でサポートされたシグナル連鎖機能(Signal Chaining)を利用するためには、マルチスレッド環境におけるシグナル動作など、OSやJava VM自身のシグナル動作、および、プログラミングについての知識が必要です。しかし、これらの事項は、バージョンやプラットフォームにより違いがあり、文書化されず、公開されていない情報に基づくものも多々あるため、安定稼動が要求されるシステム設計においては、事実上この機能の使用はできません。

■エラー処理は、必ず行ってください。
ネイティブプログラム側でJNI関数(注1)呼び出しをしたとき、色々なケースでJavaレベルのエラーになることがあります。このエラーに対する後処理をネイティブプログラム側で行わないと、例外がスローされている状態のままになり、それ以降のJNI関数(注1)の呼び出しに失敗し、アプリケーションが正しく動作しません。

 (注1)
 「JNI関数」とは、以下のJNI仕様書に記述されている関数のことです。
 https://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html
 これらを使う場合は、その度にExceptionOccurredを使用しエラーチェックをする必要があります。

■JNIの呼び出し先は、マルチスレッド対応にしてください。
Javaはマルチスレッドのシステムですので、JNIの呼び出し先は、無条件でマルチスレッド対応にしてください。マルチスレッドでは動作しないという想定で設計したネイティブプログラムが、実際には意に反してマルチスレッドで動作し、トラブルが発生した事例があります。

製品・サービス区分 Interstage
製品・サービス情報
対象製品 Interstage Application Server
バージョン V9, V8, V7, V6, V5, V4, V3
プラットフォーム Windows, Solaris, Linux
アンサー種別 設計/開発
このページの先頭へ