java 使用 System.loadLibrary() 时出现不满意的链接错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3071975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 00:13:28  来源:igfitidea点击:

Unsatisfied Link Error when using System.loadLibrary()?

java

提问by Aaron Hammond

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

出于某种原因,我在我的 Java 应用程序中遇到了令人讨厌的 Unsatisfied Link Error。

This is the offender in question:

这是有问题的罪犯:

System.loadLibrary("psjw");

Despite the library psjw.dll clearly being in the same source package as this class.

尽管库 psjw.dll 显然与此类位于同一源包中。

Please help.

请帮忙。

回答by DeezCashews

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

确保 psjw.dll 位于您的 PATH 或 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

例如:psjw.dll 可能在 /usr/lib 然后你的命令是 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);
    }
}

回答by Petar Minchev

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

尝试在启动 JVM 时显式设置库路径: -Djava.library.path="Directory of DLL"

回答by Alexander C.

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

为了正确查找不同操作系统的库(来自java.library.path)必须具有不同的名称:

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

Than you can call from Java:

比您可以从 Java 调用:

System.loadLibrary( "psjw" );

回答by Funmungus

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

我已经在这个相同的问题上工作了两天,但我最终找到了答案。首先,我为库创建了一个目录,并将 PATH 环境变量设置为该目录。不过,我不喜欢阻塞我的路径,所以现在我给你我在http://blog.cedarsoft.com/2010/11/setting-java-library-path-programmatically/ 上找到的内容。我的演绎如下

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 :

对于上述代码,您的 dll 需要与您的 .java 位于同一文件夹中。如果您从命令行运行,请记住您是从同一目录调用 javac,并从根包目录调用 java。因此,对于 C:\workspace\yourpackage\YourClass.java 的 .java,您可以从命令行调用:

cd "C:\workspace"
java yourpackage.YourClass

回答by Jaydhar

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.

根据我的经验,我可以说的是,如果从 java 类文件中的静态初始化块执行 loadLib(libraryName),则库应该存在于 java.library.path 中。否则无法加载类。但是如果我们将 loadLibrary() 调用移动到其他方法下,例如 Main(),它可以从环境路径中读取。