3

問題が解決しました。libjnidiagnosticsserver.so には、リンカー lib と libfesdiagnosticsserver.so へのパスがありませんでした。Java 1.4 は、Java 1.6 よりも未定義シンボルの検索に寛大でなければなりません。ご協力ありがとうございました。これを公平に締めくくるためのエチケットに関する提案はありますか?

(免責事項: Java初心者)

JNI を使用して C++ 共有ライブラリを呼び出す Java アプリケーションを作成しました。実行時に Java のバージョンを出力し、LD_LIBRARY_PATH を取得して出力します。

Java バージョン 1.4 - すべて問題ありません!:

/usr/bin/java -jar "javadiagnosticsserver-test.jar"
java version=1.4.2
LD_LIBRARY_PATH = /usr/lib/fesdiagnostics

Java バージョン 1.6 - UnsatisfiedLinkError :

未定義シンボル_ZN17DiagnosticsServerC1Evはlibfesdiagnosticsserver.soで定義されています。Java 1.4 はそれを認識しますが、Java 1.6 は認識しませんか? System.loadLibrary("fesdiagnosticsserver") 呼び出しが機能します。Java 1.6 の loadLibrary はどこを見たらよいかわからない?

/usr/java/jdk1.6.0_26/bin/java -jar "javadiagnosticsserver-test.jar"
version=1.6.0_26
class path=javadiagnosticsserver-test.jar
os.arch=i386
sun.arch.data.model=32
$HOME = /home/esutton
$LD_LIBRARY_PATH = /usr/java/jdk1.6.0_26/jre/lib/i386/client:/usr/java/jdk1.6.0_26/jre/lib/i386:/usr/java/jdk1.6.0_26/jre/../lib/i386:/usr/lib/fesdiagnostics
Dbg: Loading native lib dependencies...
Dbg: System.loadLibrary("fesdiagnostics");
Dbg: loaded fesdiagnostics
Dbg: The undefined symbol _ZN17DiagnosticsServerC1Ev is in libfesdiagnosticsserver.so
Dbg: System.loadLibrary("fesdiagnosticsserver"); 
Dbg: loaded fesdiagnosticsserver
Dbg: System.loadLibrary("jnidiagnosticsserver");
Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/lib/fesdiagnostics/libjnidiagnosticsserver.so: /usr/lib/fesdiagnostics/libjnidiagnosticsserver.so: undefined symbol: _ZN17DiagnosticsServerC1Ev
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1807)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1732)
        at java.lang.Runtime.loadLibrary0(Runtime.java:823)
        at java.lang.System.loadLibrary(System.java:1028)
        at fes.JniDiagnostics.libLoad(JniDiagnostics.java:30)
        at fes.JniDiagnostics.<clinit>(JniDiagnostics.java:38)
        at fes.FesDiagnostics.<clinit>(FesDiagnostics.java:17)
        at javadiagnosticsservertest.Main.main(Main.java:37)

どちらの場合も環境は同じです。

LD_LIBRARY_PATH =/usr/lib/fesdiagnostics
PATH = /opt/ActivePython-2.7/bin:/usr/java/jdk1.6.0_26/bin: \
/usr/kerberos/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin: \
/sbin:/opt/qtsdk-2010.01/qt/bin:/home/esutton/bin:/sbin: \
/opt/qtsdk-2010.01/qt/bin
JAVA_HOME = /usr/java/jdk1.6.0_26

ネイティブ C++ 共有ライブラリ コンパイル オプション:

g++ -Wl,-rpath,/opt/qtsdk-2010.01/qt/lib -shared \
-Wl,-soname,libjnidiagnosticsserver.so.1 \
-o libjnidiagnosticsserver.so.1.0.0 build/Debug/GNU-Linux-x86/ \ 
jnifesdiagnostics.o -L/opt/qtsdk-2010.01/qt/lib -lQtGui \
-L/opt/qtsdk-2010.01/qt/lib -L/usr/X11R6/lib -lQtCore -lpthread
ln -s libjnidiagnosticsserver.so.1.0.0 libjnidiagnosticsserver.so
ln -s libjnidiagnosticsserver.so.1.0.0 libjnidiagnosticsserver.so.1
ln -s libjnidiagnosticsserver.so.1.0.0 libjnidiagnosticsserver.so.1.0
rm -f dist/libjnidiagnosticsserver.so.1.0.0
rm -f dist/libjnidiagnosticsserver.so
rm -f dist/libjnidiagnosticsserver.so.1
rm -f dist/libjnidiagnosticsserver.so.1.0
mv -f libjnidiagnosticsserver.so.1.0.0 libjnidiagnosticsserver.so \
\libjnidiagnosticsserver.so.1 libjnidiagnosticsserver.so.1.0 dist/

Java 1.4 で動作する場合、最初に jnidiagnosticsserver の依存関係をロードする必要があります。私はなぜなのか理解していない。私は LD_LIBRARY_PATH がこれを処理することを期待していました:

public class JniDiagnostics {

    public native void open(String configurationFile);

    public native void close();

    public native String query(String restfulQueryString);
    private static String[] libraryDependencyList = {"fesdiagnostics", "fesdiagnosticsserver", "jnidiagnosticsserver"};

    private static void libLoad(String libName) {
        System.out.println("Dbg: System.loadLibrary(\"" + libName + "\");");
        System.loadLibrary(libName);
        System.out.println("Dbg: loaded " + libName);
    }

    static //static initializer code
    {
        System.out.println("Dbg: Loading native lib dependencies...");
        for (int i = 0; i < libraryDependencyList.length; i++) {
            libLoad(libraryDependencyList[i]);

        }
    }
}

安全保障問題?Java バージョンの構成の問題?

あらゆる方向性を前もってありがとう、

-エド

CentOS 5.2 32-bit
Netbeans 6.9.1
Java version 1.6.0_26

PS: 私の目標は、Java ソースを Glassfish RESTful Web サービスで実行することです。Java アプリで LD_LIBRARY_PATH を解決できる場合、Glassfish 3 でも同じ解決策が適用されることを期待しています。

4

1 に答える 1

4

問題は、共有ライブラリの依存関係の欠落だと思います。これを理解するには、次のコマンドを実行してみてください。

ldd -d -r /home/esutton/jnidiagnosticsserver/dist/libjnidiagnosticsserver.so.1.0.0

これは、欠落しているシンボルを示しています。

UnsatisfiedLinkError次のように文書化されています。

Thrown if the Java Virtual Machine cannot find an appropriate 
native-language definition of a method declared native. 
于 2012-02-21T16:55:12.543 に答える