2009-07-22 4 views
1

Quelqu'un a-t-il utilisé la fonction javaObject() de MATLAB avec un fichier JAR qui utilise JNI? J'essaye d'obtenir JHDF5 en cours d'exécution et il semble qu'il bombarde quand il essaye d'obtenir l'accès using jhdf5.dll ainsi je ne sais pas quoi faire ensuite. :(MATLAB + JNI = erreur?

modifier:.. Je suis pas essayer de lire les fichiers HDF5 de base que j'ai mon propre coutume code Java qui fait quelque chose avec HDF5 et a besoin de la bibliothèque JHDF5 Aussi, ma première question est juste de savoir si quelqu'un a Si ce n'est pas le cas je combattrai probablement une bataille perdue, si au moins cela me donne de l'espoir, je vais essayer de déboguer, c'est très difficile comparé au débogage du code Java sous Eclipse

mise à jour: ok, les détails ci-dessous J'ai fait une classe de test très courte et il a les mêmes modes de défaillance que mon programme compliqué.Il semble que mes classes Java ne peuvent pas accéder au HDF 5 constantes statiques pour une raison quelconque.

Mon Matlab javaclasspath est paramétrée pour inclure mon test-hdf5.jar avec Test1.java (ci-dessous), et les fichiers jhdf5.jar, jhdf5.dll, jhdf5obj.jar et jhdfobj.jar dans le même répertoire.

fichier source de Test1.java:

package com.example.test.hdf5; 

import ncsa.hdf.hdf5lib.H5; 
import ncsa.hdf.hdf5lib.HDF5Constants; 
import ncsa.hdf.hdf5lib.exceptions.HDF5LibraryException; 
import ncsa.hdf.object.FileFormat; 
import ncsa.hdf.object.h5.H5File; 

public class Test1 { 
    public Test1() {} 

    public static void main(String args[]) 
    { 
     Test1 test = new Test1(); 
     if (args.length < 2) 
     { 

     } 
     else if ("h5file".equals(args[0])) 
     { 
      test.testH5File(args[1]); 
     } 
     else if ("h5f".equals(args[0])) 
     { 
      test.testH5F(args[1]);   
     } 
    } 


    public void testH5File(String filename) { 
     H5File file; 
     try 
     { 
      file = (H5File) new H5File().createFile(
        filename, FileFormat.FILE_CREATE_OPEN); 
      file.close(); 
     } 
     catch (Exception e) 
     { 
      throw new RuntimeException(e); 
     } 
    } 

    public void testH5F(String filename) { 
     try { 
      int id = H5.H5Fopen(filename, 
        HDF5Constants.H5F_ACC_RDONLY, HDF5Constants.H5P_DEFAULT); 
      H5.H5Fclose(id); 
     } 
     catch (HDF5LibraryException e) { 
      throw new RuntimeException(e); 
     } 
     catch (NullPointerException e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

erreur Matlab:

>> T=javaObject('com.example.test.hdf5.Test1') 

T = 

[email protected] 

>> T.testH5F('c:/tmp/espdf/jj11copy.hdf5') 
java.lang.UnsatisfiedLinkError: no jhdf5 in java.library.path 
    at java.lang.ClassLoader.loadLibrary(Unknown Source) 
    at java.lang.Runtime.loadLibrary0(Unknown Source) 
    at java.lang.System.loadLibrary(Unknown Source) 
    at ncsa.hdf.hdf5lib.H5.<clinit>(H5.java:276) 
    at ncsa.hdf.hdf5lib.HDF5Constants.<clinit>(HDF5Constants.java:494) 
    at com.example.test.hdf5.Test1.testH5F(Test1.java:46) 
Jul 23, 2009 10:38:16 AM ncsa.hdf.hdf5lib.H5 <clinit> 

INFO: HDF5 library: jhdf5 resolved to: jhdf5.dll; NOT successfully loaded from java.library.path 

??? Java exception occurred: 
java.lang.UnsatisfiedLinkError: ncsa.hdf.hdf5lib.H5.H5dont_atexit()I 

    at ncsa.hdf.hdf5lib.H5.H5dont_atexit(Native Method) 

    at ncsa.hdf.hdf5lib.H5.<clinit>(H5.java:288) 

    at ncsa.hdf.hdf5lib.HDF5Constants.<clinit>(HDF5Constants.java:494) 

    at com.example.test.hdf5.Test1.testH5F(Test1.java:46) 


>> T.testH5F('c:/tmp/espdf/jj11copy.hdf5') 
??? Java exception occurred: 
java.lang.NoClassDefFoundError: Could not initialize class ncsa.hdf.hdf5lib.HDF5Constants 

    at com.example.test.hdf5.Test1.testH5F(Test1.java:46) 


>> T.testH5File('c:/tmp/espdf/jj11copy.hdf5') 
??? Java exception occurred: 
java.lang.NoClassDefFoundError: Could not initialize class ncsa.hdf.hdf5lib.HDF5Constants 

    at ncsa.hdf.object.h5.H5File.<init>(H5File.java:167) 

    at ncsa.hdf.object.h5.H5File.<init>(H5File.java:106) 

    at com.example.test.hdf5.Test1.testH5File(Test1.java:34) 

dans le cas où il importe, voici le fichier build ant que je utilise. Les fichiers JHDF5 .jar et .dll sont dans mon répertoire lib; ils sont copiés dans le répertoire dist où mon propre fichier .jar est créé.

<?xml version="1.0"?> 
<project default="all" name="test-hdf5"> 
    <description>some libraries to use later</description> 

    <property name="srcDir" location="src"/> 
    <property name="buildDir" location="bin"/> 
    <property name="distDir" location="dist"/> 
    <property name="libDir" location="lib"/> 

    <target name="init"> 
    <tstamp/> 
    <mkdir dir="${buildDir}"/> 
    <mkdir dir="${distDir}"/> 
    </target> 
     <path id="antclasspath"> 
     <fileset dir="${libDir}"> 
      <include name="*.jar"/> 
     </fileset> 
    </path> 

    <target name="compile" depends="init"> 
     <javac srcdir="${srcDir}" 
       destdir="${buildDir}" 
       debug="on" 
       target="1.6" 
       classpathref="antclasspath" 
     /> 
     </target> 

    <target name="dist" depends="compile"> 
    <copy todir="${buildDir}"> 
     <fileset dir="${srcDir}"> 
      <include name="*.properties" /> 
     </fileset> 
    </copy> 
    <copy todir="${distDir}"> 
     <fileset dir="${libDir}"> 
      <include name="*.dll" /> 
      <include name="*.jar" /> 
     </fileset> 
    </copy> 
    <jar destfile="${distDir}/test-hdf5.jar" basedir="${buildDir}" 
     includes="**"> 
     <manifest> 
     <attribute name="Built-By" value="${user.name}"/> 
     <attribute name="Main-Class" value="com.example.test.hdf5.Test1" /> 
     <attribute name="Class-Path" value=". ./jhdf5.jar ./jhdfobj.jar ./jdhf5obj.jar" /> 
     </manifest> 
    </jar> 
    </target> 

    <target name="all" depends="dist" /> 

    <target name="clean" > 
    <delete dir="${buildDir}" /> 
    </target> 
</project> 
+1

Questions courantes: qu'avez-vous fait? À quels résultats vous attendiez-vous? De quelles façons les résultats réels sont-ils en désaccord avec vos attentes? "On dirait que les bombes" ne dit rien au lecteur. –

+0

Le code que vous avez essayé d'exécuter et les messages d'erreur que vous avez obtenu aideraient grandement. – gnovice

+0

Cela ne correspond pas directement à la question JNI, mais vous pouvez attacher le débogueur Eclipse à la JVM intégrée de Matlab pour déboguer le code Java exécuté dans Matlab. Créez un fichier nommé "java.opts" dans le répertoire depuis lequel vous démarrez Matlab et placez-y cette ligne. -agentlib: jdwp = serveur = y, transport = dt_socket, adresse = 9999 Puis allumez Eclipse et Matlab. Matlab bloque au démarrage et attend que vous ajoutiez le débogueur. Aussi, je suis d'accord avec les autres commentateurs. Besoin de plus de détails, de préférence le code exact et les messages d'erreur. –

Répondre

2

JHDF5 utilise une logique de recherche maladroite du côté Java pour charger la DLL. Cela fonctionne, sauf quand ce n'est pas le cas, ce qui est souvent le cas. Et comme pour de nombreux détails HDF5, la logique sous-jacente n'est pas documentée. J'ai fait ceci: pris des sources Java JHDF5, enlevé l'IA stupide qui essaye de charger le fichier jhdf5.dll (c'est dans le fichier ncsa/hdf/hdf5lib/H5.java, la section static dans les lignes 230-290), et l'a remplacé par une instruction explicite System.load("full/path/to/the/jhdf5.dll");. Puis recompilé le jhdf5.jar. Peut-être pas beau, mais fonctionne parfaitement. En outre, en regardant la source, il semble que si vous définissez une propriété système appelée H5_LIBRARY_NAME_PROPERTY_KEY pour pointer sur la DLL, elle peut être chargée. Vous pouvez définir les propriétés du système, par exemple en commençant jvm avec un commutateur -D, quelque chose comme:

java -DH5_LIBRARY_NAME_PROPERTY_KEY=path/to/the/jhdf5.dll -jar yourapp.jar 

n'a pas essayé, cependant.

+0

Malheureusement dans MATLAB vous ne démarrez pas le jvm, il le fait seul. Je ne sais pas comment définir les propriétés du système, si je peux. –

+0

Ah. Duh. Je peux juste faire java.lang.System.setProperty ('ncsa.hdf.hdf5lib.H5.hdf5lib', path_to_jhdf5_dll); Ça marche! –

0

La DLL n'est probablement pas sur le chemin de classe Java. Essayez d'ajouter son répertoire à la variable d'environnement PATH du système. Ou mieux encore, utilisez simplement les fonctions hd5read/write.

+0

Ce n'est pas ça; Je peux exécuter mon fichier .jar à partir d'une invite de commande ou dans le débogueur Eclipse. Et j'ai essayé de mettre une copie de la DLL dans un répertoire sur le chemin, cela n'a rien changé. –

0

Le classpath n'est pas utilisé pour les DLL. Ils doivent être dans la variable d'environnement PATH (windows) ou LD_LIBRARY_PATH (linux). Vous pouvez également vérifier que les emplacements relatifs et les dépendances des DLL elles-mêmes sont corrects en utilisant Depends (Windows, http://www.dependencywalker.com) ou ldd (linux)

+0

Ce n'est pas ça; Je peux exécuter mon fichier .jar à partir d'une invite de commande ou dans le débogueur Eclipse. –

2

Matlab est très compliqué à ce sujet, les précédents sont corrects que le classpath n'est pas utilisé pour les DLL. Vous pouvez utiliser une solution envirnomental comme ci-dessus, mais une variable plus MATLAB spécifique est également disponible. Le fichier librarypath.txt est capable de lister les dossiers contenant toutes les DLL disponibles pour MATLAB. Il est exécuté au démarrage, donc ne peut pas être ajouté dynamiquement. Pour modifier le chemin de la bibliothèque, exécutez edit librarypath.txt sur la ligne de commande MATLAB.