Question

Problème résolu. libjnidiagnosticsserver.so manquait dans l'éditeur de liens lib et chemin vers libfesdiagnosticsserver.so. Java 1.4 doit être plus libéral sur la localisation des symboles non définis que Java 1.6. Merci à tous pour votre aide. Avez-vous des suggestions sur l'étiquette pour clôturer équitablement?

(Clause de non-responsabilité: débutant Java)

J'ai écrit une application Java qui utilise JNI pour appeler ma bibliothèque partagée C ++. Il imprime la version java et obtient et imprime LD_LIBRARY_PATH lorsqu'il est exécuté.

Java version 1.4 - Tout va bien!:

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

Java version 1.6 - UnsatisfiedLinkError :

Le " symbole non défini " _ZN17DiagnosticsServerC1Ev est défini dans libfesdiagnosticsserver.so . Java 1.4 le voit, Java 1.6 ne le voit pas? L'appel System.loadLibrary ("fesdiagnosticsserver") fonctionne. Java 1.6 loadLibrary ne sait pas où chercher?

/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)

L'environnement est le même dans les deux cas:

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

Options de compilation de la bibliothèque partagée native 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/

Quand cela fonctionne sous Java 1.4, je dois d'abord charger les dépendances de jnidiagnosticsserver. Je ne comprends pas pourquoi. Je m'attendais à ce que LD_LIBRARY_PATH s'en soit occupé:

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]);

        }
    }
}

Problème de sécurité? Problème de configuration de la version Java?

Merci d'avance pour toute direction,

-Ed

CentOS 5.2 32-bit
Netbeans 6.9.1
Java version 1.6.0_26

PS: Mon objectif est de faire fonctionner ma source Java dans un site Glassfish RESTful un service. Si LD_LIBRARY_PATH peut être résolu pour une application java, j'espère la même chose la solution s'appliquera sous Glassfish 3.

Était-ce utile?

La solution

Je suppose que le problème est une dépendance manquante de votre bibliothèque partagée.Essayez d'exécuter la commande suivante pour comprendre ceci:

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

Cela montre les symboles manquants.

UnsatisfiedLinkError est documenté comme suit:

Thrown if the Java Virtual Machine cannot find an appropriate 
native-language definition of a method declared native. 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top