简体   繁体   English

MATLAB + JNI =错误?

[英]MATLAB + JNI = error?

Anyone out there used MATLAB's javaObject() function with a JAR file that uses JNI? 有人在那里使用MATLAB的javaObject()函数和使用JNI的JAR文件吗?

I'm trying to get JHDF5 running and it seems like it bombs when it tries to get access using jhdf5.dll so I don't really know what to do next. 我正在尝试使JHDF5运行,当它尝试使用jhdf5.dll进行访问时似乎炸弹,所以我真的不知道下一步该怎么做。 :( :(

edit : I am NOT trying to read basic HDF5 files. 编辑 :我试图读取基本的HDF5文件。 I have my own custom Java code that does something with HDF5 and needs the JHDF5 library. 我有自己的自定义Java代码,该代码可对HDF5执行某些操作,并且需要JHDF5库。 Also, my first question is just whether anyone has used it successfully at all. 另外,我的第一个问题是,是否有人成功使用过它。 If not then I'm probably fighting a losing battle. 如果不是这样的话,我可能正在打一场失败的战斗。 If so then at least it gives me hope. 如果是这样,那么至少它给了我希望。 I'll try to debug, it's very difficult compared to debugging regular Java code under Eclipse. 我将尝试调试,与在Eclipse下调试常规Java代码相比,这非常困难。

update : ok, specifics below. 更新 :好的,详细信息如下。 I made a very short test class and it has the same failure modes as my complicated program. 我做了一个很短的测试课,它的失败模式与我的复杂程序相同。 It looks like my Java classes can't access the HDF5 static constants for some reason. 看来我的Java类由于某种原因无法访问HDF5静态常量。

My MATLAB javaclasspath is set to include my test-hdf5.jar with Test1.java (below), and the files jhdf5.jar, jhdf5.dll, jhdf5obj.jar, and jhdfobj.jar in the same directory. 我的MATLAB javaclasspath设置为将我的test-hdf5.jar与Test1.java(如下)包括在一起,并将文件jhdf5.jar,jhdf5.dll,jhdf5obj.jar和jhdfobj.jar包含在同一目录中。

source file Test1.java: 源文件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);
        }
    }
}

MATLAB error: MATLAB错误:

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

T =

com.example.test.hdf5.Test1@c9a375

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

in case it matters, here's the ant build file I'm using. 万一重要,这是我正在使用的ant构建文件。 The JHDF5 .jar files and .dll are in my lib directory; JHDF5 .jar文件和.dll在我的lib目录中; they get copied to the dist directory where my own .jar file is created. 它们被复制到创建我自己的.jar文件的dist目录中。

<?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>

JHDF5 uses some goofy search logic at the Java side for loading the dll. JHDF5在Java端使用一些愚蠢的搜索逻辑来加载dll。 It works, except when it doesn't, which is often. 它可以正常工作,除非不能正常工作。 And as with many HDF5 details, the underlying logic is undocumented. 与许多HDF5细节一样,底层逻辑也没有记录。

I did this: took JHDF5 Java sources, removed the stupid AI that tries to load the jhdf5.dll (it's in ncsa/hdf/hdf5lib/H5.java file, the static section in about lines 230-290), and replaced it with an explicit System.load("full/path/to/the/jhdf5.dll"); 我这样做了:取得了JHDF5 Java源代码,删除了试图加载jhdf5.dll的愚蠢AI(位于ncsa / hdf / hdf5lib / H5.java文件中,位于第230-290行中的static部分),并替换为一个显式的System.load("full/path/to/the/jhdf5.dll"); statement. 声明。 Then recompiled the jhdf5.jar. 然后重新编译jhdf5.jar。 Maybe not beautiful, but works perfectly. 也许不漂亮,但是效果很好。

Additionally, looking at the source, it seems that if you set an system property called H5_LIBRARY_NAME_PROPERTY_KEY to point at the dll, it might get loaded. 此外,查看源代码,似乎如果设置名为H5_LIBRARY_NAME_PROPERTY_KEY的系统属性以指向dll,则可能会加载它。 You can set system properties for instance by starting jvm with a -D switch, something like: 您可以通过使用-D开关启动jvm来设置系统属性,例如:

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

Didn't try it, though. 不过没有尝试。

Matlab is very complicated about this, the above are correct that the classpath is not used for dlls. Matlab对此非常复杂,上面是正确的,即classpath不用于dll。 You may use an envirnomental solution like the above, but a more MATLAB specific variable is available too. 您可以使用上述环境解决方案,但也可以使用更多MATLAB特定变量。 The file librarypath.txt is able list folders containing any dll's available to MATLAB. 该文件librarypath.txt能够列出包含MATLAB可用的任何dll的文件夹。 It is executed at startup time, so cannot be added to dynamically. 它在启动时执行,因此无法动态添加。 To edit the library path, run edit librarypath.txt on the MATLAB command line. 要编辑库路径,请在MATLAB命令行上运行edit librarypath.txt

The dll is probably not on the java class path. dll可能不在Java类路径上。 Try adding it's directory to the system's PATH environment variable. 尝试将其目录添加到系统的PATH环境变量中。 Or better yet, just use the hd5read/write functions. 或者更好的是,只需使用hd5read / write函数。

The classpath is not used for dlls. 该类路径不用于dll。 They need to be in the PATH environment variable (windows) or LD_LIBRARY_PATH (linux). 它们必须位于PATH环境变量(windows)或LD_LIBRARY_PATH(linux)中。 You might also want to verify that the relative locations and dependencies of the DLLs themselves are correct using Depends (Windows, http://www.dependencywalker.com ) or ldd (linux) 您可能还想使用Depends(Windows, http://www.dependencywalker.com )或ldd(linux)来验证DLL本身的相对位置和依赖性是否正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM