开发者

Unsatisfied Link Error when using System.loadLibrary()?

For some reason, I'm getting a pesky Unsatisfied Link Error in my java app.

This is the offender in question:

System.loadLibrary("psjw");

Despite the library psjw.dll clearly 开发者_开发问答being in the same source package as this class.

Please help.


Make sure the psjw.dll is either on your PATH or java.library.path.

Ex: psjw.dll may be in /usr/lib then your command would be java -Djava.library.path=/usr/lib ur.package.UrClass

Test your setup using a stripped down class:

public class TestLoadLibrary {

    public static void main(String[] args) {

        String libPath = System.getProperty("java.library.path");
        System.out.println("java.library.path=" + libPath);

        String libraryName = "psjw";
        System.out.println("Trying to load '" + libraryName + "'");
        System.loadLibrary(libraryName);
    }
}


Try to set explicity the library path when starting the JVM: -Djava.library.path="Directory of DLL"


For correct lookup of library (from java.library.path) for different OS's must have different names:

  • Linux: libpsjw.so
  • Windows: psjw.dll

Than you can call from Java:

System.loadLibrary( "psjw" );


What I can say from my experience is that, if the loadLib(libraryName) is performed from static initialization block in java class file, the libraray should be exists in java.library.path. Otherwise class cannot be loaded. But if we are moving the loadLibrary() call to under other methods e.g Main(), it can be read from environment path.


I have been working on this same issue for two days, but I eventually found the answer. First I created a directory for libraries, and set the PATH environment variable to that directory. I don't like clogging up my path though, so now I give you what I found at http://blog.cedarsoft.com/2010/11/setting-java-library-path-programmatically/. My rendition follows

package yourpackage;

import java.io.File;
import java.lang.reflect.Field ;

public class YourClass {
    public native void print () ;
    static
    {
        String mPath = new File (".").getAbsolutePath () ;
        String langKey = "java.library.path" ;
        System.setProperty ( langKey, mPath ) ;

        // Tested both with and without the following, and worked either way.
/*      try
        {
            Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
            fieldSysPath.setAccessible( true );
            fieldSysPath.set( null, null );
        }
        catch ( NoSuchFieldException e )
        {
            System.err.println ( "Unable to reset system path field: \n" + e + '\n' ) ;
        }
        catch ( IllegalAccessException e )
        {
            System.err.println ( "Unable to access system path after reset: \n"
                    + e + '\n' ) ;
        } */

        try
        {
            System.loadLibrary ( "YourLibrary" ) ;
        }
        catch ( UnsatisfiedLinkError e )
        {
            System.err.println ( "Native code library failed to load.\n" + e ) ;
            System.exit ( 1 ) ; 
        }

    }

    public static void main ( String[] args)
    {
        YourClass yc = new YourClass() ;
        yc.print();
    }
}

For the above code your dll needs to be in the same folder as your .java. If you are running from command line, remember you call from the same directory for javac, and root package directory for java calling. Thus for the .java being C:\workspace\yourpackage\YourClass.java, you call from command line :

cd "C:\workspace"
java yourpackage.YourClass
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜