Pregunta

Problema resuelto. libjnidiagnticsserver. So le faltaba el enlace lib y el camino hacia libfesdiagnticsserver.so. Java 1.4 debe ser más liberal para localizar símbolos indefinidos que Java 1.6. Gracias por toda tu ayuda. ¿Alguna sugerencia sobre la etiqueta para cerrar esto de manera equitativa?

(Descargo de responsabilidad: novato de Java)

Escribí una aplicación Java que usa JNI para llamar a mi biblioteca compartida C ++. Imprime la versión Java y obtiene e imprime LD_Library_Path cuando se ejecuta.

Java versión 1.4 - ¡Todo está bien!:

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

Java versión 1.6 - Insatisfecho:

Los "símbolo indefinido" _Zn17DiagnticsServerC1ev se define en libfesdiagnticsserver.So. Java 1.4 lo ve, Java 1.6 ¿No? La llamada System.LoadLibrary ("Fesdiagnticsserver") funciona. Java 1.6 LoadLibrary ¿No sabe dónde buscar?

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

El entorno es el mismo en ambos casos:

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

Opciones nativas de compilación LIB de C ++ compartidas:

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/

Cuando funciona bajo Java 1.4, primero debo cargar las dependencias de Jnidiagnticsserver. No entiendo porque. Esperaba que LD_Library_Path se hubiera encargado de esto:

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

        }
    }
}

¿Problema de seguridad? ¿Problema de configuración de la versión Java?

Gracias de antemano por cualquier dirección,

-En

CentOS 5.2 32-bit
Netbeans 6.9.1
Java version 1.6.0_26

PD: Mi objetivo es hacer que mi fuente de Java se ejecute en un servicio web de Glassfish Restful. Si LD_Library_Path se puede resolver para una aplicación Java, espero que la misma solución se aplique bajo Glassfish 3.

¿Fue útil?

Solución

Supongo que el problema es una dependencia de Missig de su biblioteca compartida. Intente ejecutar el siguiente comando para resolver esto:

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

Esto muestra símbolos faltantes.

UnsatisfiedLinkError está documentado como:

Thrown if the Java Virtual Machine cannot find an appropriate 
native-language definition of a method declared native. 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top