以前のJavaバージョンJava 8では、共有ライブラリにネイティブコードが存在する必要がありますが、Java 8で静的リンクライブラリを使用することが可能ですJNI。例を検索しましたが、見つかりませんでした。
JavaアプリケーションにJNIライブラリを静的にリンクするにはどうすればよいですか?
Java SE 8仕様は静的リンクをサポートするように変更され、静的リンクはJDKで実装されています。これは System.loadLibrary の仕様で簡単に説明されています。それが参照するJNI仕様のセクションは here および here です。
ネイティブメソッドシグネチャとデータ型は、静的および動的にリンクされたメソッドで同じです。ただし、ライブラリを静的にリンクするには、JDKメイクファイルをハックする必要がある場合があります。
大きな違いの1つは、静的ライブラリの初期化方法です。動的ライブラリは、_JNI_OnLoad
_関数を呼び出して初期化され、_JNI_OnUnload
_を呼び出して初期化解除されます。各動的ライブラリは、これらの関数の独自のバージョンを持つことができます。静的にリンクされたライブラリが複数ある場合、それらすべてに同じ名前の関数を含めることはできません。 libname
という名前の静的ライブラリの場合、ロード/アンロード関数は_JNI_OnLoad_libname
_および_JNI_OnUnload_libname
_です。
_JNI_OnLoad_libname
_関数は、_JNI_VERSION_1_8
_以上の値を返す必要があります。そうでない場合、JVMは静的ライブラリを無視します。
基本的に、System.loadLibrary("foo")
を呼び出すと、システムは実行中の実行可能イメージで関数_JNI_OnLoad_foo
_を探し、見つかった場合は、ライブラリが静的にリンクされていると想定し、そのネイティブメソッドが検索されます実行中のイメージ内。 _JNI_OnLoad_foo
_が見つからない場合、通常の検索と動的ライブラリの読み込みが行われ、見つかった動的ライブラリからネイティブメソッドがリンクされます。
コメントでリンクしたJEP 178に従って、別のことをする必要はありません。 System.loadLibrary
は、動的ライブラリと静的ライブラリの両方をロードします。
動的なネイティブライブラリではなく静的なネイティブライブラリを使用するために、既存のJavaコードに変更を加える必要はありません。特に、System.loadLibrary( "foo")という形式のメソッド呼び出しは、ライブラリが静的形式で提供されるか動的形式で提供されるかに関係なく、「foo」ライブラリをロードできる必要があります。
おそらく、Java.library.pathが正しく設定されていることを確認する必要があるだけです。
Java 8の拡張 https://openjdk.Java.net/jeps/178 は、JVM向けです。
2つのファイルがあるとします。
Libnative.soを作成します。
javac Main.Java
javah Main
gcc -c Main.c
gcc -c Main.c -I /home/dx/.sdkman/candidates/Java/current/include/linux -I /home/dx/.sdkman/candidates/Java/current/include
gcc -shared -o libnative.so Main.o
Libnative.aを作成します。
ar -cvq libnative.a Main.o
Libnative.a、libnative.soのテストごとに、以下を実行します。
Java -Djava.library.path=. Main
結果:
libnative.so
が成功した場合libnative.a
のときに実行が失敗するこれは、178がJVM用であることを証明しています。
参照: