Results 1 to 12 of 12
Like Tree1Likes
  • 1 Post By pbrockway2

Thread: JNI, Java, Mathematica

  1. #1
    smartin is offline Member
    Join Date
    Jun 2011
    Posts
    4
    Rep Power
    0

    Default JNI, Java, Mathematica

    I am trying to get a Java method to work in Mathematica; Mathematica provides suitable access to a JVM through J/Link. Everything is working great for my own Java classes. The problem is that the method I need calls a JNI (.dll file). Outside of Mathematica from the "cmd" line, all works great. But calling the method within Mathematica, the JVM returns the following:


    Java::excptn: A Java exception occurred: java.lang.UnsatisfiedLinkError: ncsa.hdf.hdf5lib.H5.H5Fcreate(Ljava/lang/String;III)I
    at ncsa.hdf.hdf5lib.H5.H5Fcreate(Native Method)
    at ncsa.hdf.object.h5.H5File.createFile(H5File.java:9 20)
    at H5FileCreateFromMathematica.H5FileCreate(H5FileCre ateFromMathematica.java:38).


    I have spent a lot of time trying to get everything right with the classpath and path environment variables in various permutations. This might still be the problem, though I feel I have worked hard to rule out these possibilities.

    Any insights onto (1) what this message from Java means and even better (2) how to fix it would be much appreciated.

  2. #2
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,305
    Rep Power
    25

    Default

    A guess - is the dll on the OS's path so it can be found?
    The current directory would be on the path when you use a cmd line with the dll being in the current folder.

  3. #3
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    Also at StackOverflow.
    DarrylBurke likes this.

  4. #4
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,188
    Rep Power
    19

    Default

    Thanks Peter

    db

  5. #5
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,337
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by Norm View Post
    A guess - is the dll on the OS's path so it can be found?
    The current directory would be on the path when you use a cmd line with the dll being in the current folder.
    Yep, the library is found (or not loaded yet), otherwise the exception text would've been "no foo.dll in java.library.path"; the JVM can't find method "ncsa.hdf.hdf5lib.H5.H5Fcreate(Ljava/lang/String;III)I" (taking four arguments, returning an int) in the loaded dll files.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  6. #6
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,188
    Rep Power
    19

    Default

    otherwise the exception text would've been "no foo.dll in java.library.path"
    Try this
    Java Code:
    System.loadLibrary(Integer.toString(510 * 619, 29));
    db

  7. #7
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,337
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by DarrylBurke View Post
    Try this
    Java Code:
    System.loadLibrary(Integer.toString(510 * 619, 29));
    I fixed your (obvious) errors and ran this:

    Java Code:
    System.loadLibrary(Long.toString(11431111L*859*29*2*2, 5*7));
    ... and it ran perfectly fine ;-)

    kindest regards,

    Jos
    Last edited by JosAH; 06-26-2011 at 04:52 PM.
    cenosillicaphobia: the fear for an empty beer glass

  8. #8
    smartin is offline Member
    Join Date
    Jun 2011
    Posts
    4
    Rep Power
    0

    Default

    Quote Originally Posted by Norm View Post
    A guess - is the dll on the OS's path so it can be found?
    The current directory would be on the path when you use a cmd line with the dll being in the current folder.
    Thanks for this suggestion. It could be it as I am much more of a Mathematica expert than a Java expert. Nevertheless, I have tried to wrestle this crocodile four ways:
    1. In my system environment variables on Windows7, I have a very nice PATH statement to the dll file. This is what the "cmd" implementation is based on.
    2. When launching Java within mathematica, I tried using: "C:\Program Files\Java\jdk1.6.0_26\bin\javaw.exe -Djava.library.path=C:\MyJava\hdf-java\lib\win\" (*)
    3. Within Mathematica, I called a Java method I made for the purpose at hand (**):

    import ncsa.hdf.object.*; // the common object package
    import ncsa.hdf.object.h5.*; // the HDF5 implementation

    public class SetLibraryPath
    {
    public static String SetPath()
    {
    System.setProperty("ncsa.hdf.hdf5lib.H5.hdf5lib"," C:/Users/smartin/AppData/Roaming/Mathematica/Applications/MyJava/Java/Libraries/Windows-x86-64/jhdf5.dll");
    return "Path Set";
    }
    }

    4. I placed approximately a dozen copies of the "jdhd5.dll" file around my hard drive in various directories that I thought the JVM might be interested in.

    None of efforts #1, #2, #3, or #4 altered the exception report of my original post.

    Any thoughts on what further I might try? As I said, my Mathematica:Java expertise ratio is 100:1.

    Scot

    (*) Technical note to any now or future Mathematica users reading this post. Actually, I used: ReinstallJava[CommandLine->"C:\\Program Files\\Java\\jdk1.6.0_26\\bin\\javaw.exe -Djava.library.path=C:\\MyJava\\hdf-java\\lib\\win\\", ClassPath->"C:\\MyJava\\hdf-java\\lib\\;C:\\MyJava"]

    (**) Technical note to Mathematica users: actual code is as follows:
    LoadJavaClass["SetLibraryPath"];
    SetLibraryPath`SetPath[]

  9. #9
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,305
    Rep Power
    25

    Default

    I have a very nice PATH statement to the dll file
    The path should be to the folder containing the dll file.

  10. #10
    smartin is offline Member
    Join Date
    Jun 2011
    Posts
    4
    Rep Power
    0

    Default

    Quote Originally Posted by JosAH View Post
    Yep, the library is found (or not loaded yet), otherwise the exception text would've been "no foo.dll in java.library.path"; the JVM can't find method "ncsa.hdf.hdf5lib.H5.H5Fcreate(Ljava/lang/String;III)I" (taking four arguments, returning an int) in the loaded dll files.

    kind regards,

    Jos
    Thank you, Jos, for this helpful reply. I am still digesting it. You are saying, if I understand correctly, that the JVM is finding the .dll file but that something else is going wrong (?).

    At the risk of going well beyond your interest in this topic, below seems to be a relevant part of the code based on the error message returned:

    * part 1 *
    Java Code:
        public final static String H5PATH_PROPERTY_KEY = "ncsa.hdf.hdf5lib.H5.hdf5lib";
    
        // add system property to load library by name from library path, via
        // System.loadLibrary()
        public final static String H5_LIBRARY_NAME_PROPERTY_KEY = "ncsa.hdf.hdf5lib.H5.loadLibraryName";
    
        /** logging level: 0 -- information, 1 -- warning message, 2 -- failure */
        public static int LOGGING_LEVEL = 2;
        
        private static Logger s_logger;
        private static String s_libraryName;
        private static boolean isLibraryLoaded = false;
        
        private final static boolean IS_CRITICAL_PINNING = true;
        
        private final static Vector<Integer> OPEN_IDS = new Vector<Integer>();
    
        static {
            loadH5Lib();
        }
    
        public static void loadH5Lib() {
            // Make sure that the library is loaded only once
            if (isLibraryLoaded)
                return;
    
            // use default logger, since spanning sources
            s_logger = Logger.getLogger("ncsa.hdf.hdf5lib"); 
            if (LOGGING_LEVEL == 2)
                s_logger.setLevel(Level.SEVERE);
            else if (LOGGING_LEVEL == 1)
                s_logger.setLevel(Level.WARNING);
            else
                s_logger.setLevel(Level.INFO);
            
            // first try loading library by name from user supplied library path
            s_libraryName = System.getProperty(H5_LIBRARY_NAME_PROPERTY_KEY, null);
            String mappedName = null;
            if ((s_libraryName != null) && (s_libraryName.length() > 0)) {
                try {
                    mappedName = System.mapLibraryName(s_libraryName);
                    System.loadLibrary(s_libraryName);
                    isLibraryLoaded = true;
                }
                catch (Throwable err) {
                    err.printStackTrace();
                    isLibraryLoaded = false;
                }
                finally {
                    s_logger.log(Level.INFO, "HDF5 library: " + s_libraryName
                            + " resolved to: " + mappedName + "; "
                            + (isLibraryLoaded ? "" : " NOT")
                            + " successfully loaded from java.library.path");
    
                }
            }
    
            if (!isLibraryLoaded) {
                // else try loading library via full path
                String filename = System.getProperty(H5PATH_PROPERTY_KEY, null);
                if ((filename != null) && (filename.length() > 0)) {
                    File h5dll = new File(filename);
                    if (h5dll.exists() && h5dll.canRead() && h5dll.isFile()) {
                        try {
                            System.load(filename);
                            isLibraryLoaded = true;
                        }
                        catch (Throwable err) {
                            err.printStackTrace();
                            isLibraryLoaded = false;
                        }
                        finally {
                            s_logger.log(Level.INFO, "HDF5 library: " + filename
                                    + (isLibraryLoaded ? "" : " NOT")
                                    + " successfully loaded.");
    
                        }
                    }
                    else {
                        isLibraryLoaded = false;
                        throw (new UnsatisfiedLinkError("Invalid HDF5 library, "
                                + filename));
                    }
                }
            }
    
            // else load standard library
            if (!isLibraryLoaded) {
                try {
                    s_libraryName = "jhdf5";
                    mappedName = System.mapLibraryName(s_libraryName);
                    System.loadLibrary("jhdf5");
                    isLibraryLoaded = true;
                }
                catch (Throwable err) {
                    err.printStackTrace();
                    isLibraryLoaded = false;
                }
                finally {
                    s_logger.log(Level.INFO, "HDF5 library: " + s_libraryName
                            + " resolved to: " + mappedName + "; "
                            + (isLibraryLoaded ? "" : " NOT")
                            + " successfully loaded from java.library.path");
    
                }
            }
    * part 2 *
    Java Code:
        /**
         * H5Fcreate is the primary function for creating HDF5 files.
         * 
         * @param name
         *            Name of the file to access.
         * @param flags
         *            File access flags. Possible values include:
         *            <UL>
         *            <LI>
         *            H5F_ACC_RDWR Allow read and write access to file.</LI>
         *            <LI>
         *            H5F_ACC_RDONLY Allow read-only access to file.</LI>
         *            <LI>
         *            H5F_ACC_TRUNC Truncate file, if it already exists, erasing all
         *            data previously stored in the file.</LI>
         *            <LI>
         *            H5F_ACC_EXCL Fail if file already exists.</LI>
         *            <LI>
         *            H5F_ACC_DEBUG Print debug information.</LI>
         *            <LI>
         *            H5P_DEFAULT Apply default file access and creation properties.
         *            </LI>
         *            </UL>
         * 
         * @param create_id
         *            File creation property list identifier, used when modifying
         *            default file meta-data. Use H5P_DEFAULT for default access
         *            properties.
         * @param access_id
         *            File access property list identifier. If parallel file access
         *            is desired, this is a collective call according to the
         *            communicator stored in the access_id (not supported in Java).
         *            Use H5P_DEFAULT for default access properties.
         * 
         * @return a file identifier if successful
         * 
         * @exception HDF5LibraryException
         *                - Error from the HDF-5 Library.
         * @exception NullPointerException
         *                - name is null.
         **/
        public static int H5Fcreate(String name, int flags, int create_id,
                int access_id) throws HDF5LibraryException, NullPointerException {
            int id = _H5Fcreate(name, flags, create_id, access_id);
            if (id > 0)
                OPEN_IDS.addElement(id);
            return id;
        }
    
        private synchronized static native int _H5Fcreate(String name, int flags,
                int create_id, int access_id)
                throws HDF5LibraryException, NullPointerException;
    The full source code is here (lines 248-353 (part1) and 1531-1585 (part2)):

    http://www.hdfgroup.org/ftp/HDF5/hdf...df5lib/H5.java

    If you read this far, then I thank you! Hopefully you'll have a suggestion on what I might try.

    Scot
    Last edited by JosAH; 06-27-2011 at 09:06 AM. Reason: added [code] ... [/code] tags

  11. #11
    smartin is offline Member
    Join Date
    Jun 2011
    Posts
    4
    Rep Power
    0

    Default

    Quote Originally Posted by Norm View Post
    The path should be to the folder containing the dll file.
    Thank you, Norm, yes, the entry for the PATH system variable within the Windows7 environment variables is:
    "c:\MyJava\hdf-java\lib\win"
    So that part seems correct to me (?).
    Scot

  12. #12
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,337
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by smartin View Post
    Thank you, Jos, for this helpful reply. I am still digesting it. You are saying, if I understand correctly, that the JVM is finding the .dll file but that something else is going wrong (?).
    When a message like that is issued either the entire library isn't loaded or the (successfully) loaded library doesn't contain the native implementation of the method mentioned in the error message. I'm wondering: does your (extensive) loadH5Lib() method stay completely quiet? If so the lib is loaded ...

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •