java.lang.UnsatisfiedLinkError 在 java.library.path 中没有 *****.dll
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1403788/
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
java.lang.UnsatisfiedLinkError no *****.dll in java.library.path
提问by Ketan Khairnar
How can I load a custom dll file in my web application? I tried following ways but its failing.
如何在我的 Web 应用程序中加载自定义 dll 文件?我尝试了以下方法,但失败了。
- copied all required dlls in
system32
folder and tried to load one of them inServlet
constructorSystem.loadLibrary
- Copied required dlls in
tomcat_home/shared/lib
andtomcat_home/common/lib
- all these dlls are in
WEB-INF/lib
of the web-application
- 复制
system32
文件夹中所有必需的 dll并尝试在Servlet
构造函数中加载其中之一System.loadLibrary
- 将所需的 dll 复制到
tomcat_home/shared/lib
和tomcat_home/common/lib
- 所有这些 dll 都在
WEB-INF/lib
Web 应用程序中
采纳答案by Adam Batkin
In order for System.loadLibrary()
to work, the library (on Windows, a DLL) must be in a directory somewhere on your PATH
oron a path listed in the java.library.path
system property (so you can launch Java like java -Djava.library.path=/path/to/dir
).
为了System.loadLibrary()
工作,库(在 Windows 上,DLL)必须位于您PATH
或java.library.path
系统属性中列出的路径上的某个目录中(因此您可以像 一样启动 Java java -Djava.library.path=/path/to/dir
)。
Additionally, for loadLibrary()
, you specify the base name of the library, without the .dll
at the end. So, for /path/to/something.dll
, you would just use System.loadLibrary("something")
.
此外,对于loadLibrary()
,您指定库的基本名称,.dll
末尾不带。因此,对于/path/to/something.dll
,您只需使用System.loadLibrary("something")
.
You also need to look at the exact UnsatisfiedLinkError
that you are getting. If it says something like:
您还需要查看UnsatisfiedLinkError
您获得的确切信息。如果它说的是:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
then it can't find the foolibrary (foo.dll) in your PATH
or java.library.path
. If it says something like:
那么它在您的或.dll 文件中找不到foo库 (foo.dll) 。如果它说的是:PATH
java.library.path
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
then something is wrong with the library itself in the sense that Java is not able to map a native Java function in your application to its actual native counterpart.
那么库本身就有问题,因为 Java 无法将应用程序中的原生 Java 函数映射到其实际的原生对应物。
To start with, I would put some logging around your System.loadLibrary()
call to see if that executes properly. If it throws an exception or is not in a code path that is actually executed, then you will always get the latter type of UnsatisfiedLinkError
explained above.
首先,我会在您的System.loadLibrary()
呼叫周围放置一些日志,以查看它是否正确执行。如果它抛出异常或不在实际执行的代码路径中,那么您将始终得到UnsatisfiedLinkError
上面解释的后一种类型。
As a sidenote, most people put their loadLibrary()
calls into a static initializer block in the class with the native methods, to ensure that it is always executed exactly once:
作为旁注,大多数人将他们的loadLibrary()
调用放入具有本机方法的类中的静态初始化块中,以确保它始终只执行一次:
class Foo {
static {
System.loadLibrary('foo');
}
public Foo() {
}
}
回答by Mangesh M. Kulkarni
For those who are looking for java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
对于那些正在寻找 java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
I was facing same exception; I tried everything and important things to make it work are:
我面临着同样的例外;我尝试了一切,使其工作的重要事情是:
- Correct version of pdf lib.jar ( In my case it was wrong version jar kept in server runtime )
- Make a folder and keep the pdflib jar in it and add the folder in your PATH variable
- pdf lib.jar 的正确版本(在我的情况下,它是服务器运行时中保存的错误版本 jar)
- 创建一个文件夹并将 pdflib jar 保存在其中,并将该文件夹添加到您的 PATH 变量中
It worked with tomcat 6.
它适用于 tomcat 6。
回答by sayannayas
Poor me ! spent a whole day behind this.Writing it down here if any body replicates this issue.
可怜的我 !在这后面花了一整天。如果有任何机构复制了这个问题,就把它写在这里。
I was trying to load as Adam suggested but then got caught with AMD64 vs IA 32 exception.If in any case after working as per Adam's(no doubt the best pick) walkthrough,try to have a 64 bit version of latest jre.Make sure your JRE AND JDK are 64 bit and you have correctly added it to your classpath.
我试图按照 Adam 的建议进行加载,但随后遇到了 AMD64 vs IA 32 异常。您的 JRE 和 JDK 是 64 位,并且您已将其正确添加到类路径中。
My working example goes here:unstatisfied link error
我的工作示例在这里:未统计的链接错误
回答by Philip Whitehouse
You can use System.load()
to provide an absolute path which is what you want, rather than a file in the standard library folder for the respective OS.
您可以使用System.load()
提供您想要的绝对路径,而不是相应操作系统的标准库文件夹中的文件。
If you want native applications that already exist, use System.loadLibrary(String filename)
. If you want to provide your own you're probably better with load().
如果您想要已经存在的本机应用程序,请使用System.loadLibrary(String filename)
. 如果你想提供你自己的,你可能会更好地使用 load()。
You should also be able to use loadLibrary
with the java.library.path
set correctly. See ClassLoader.java
for implementation source showing both paths being checked (OpenJDK)
您还应该能够正确使用loadLibrary
该java.library.path
套装。请参阅ClassLoader.java
显示正在检查的两个路径的实现源(OpenJDK)
回答by Matt M
The original answer by Adam Batkin will lead you to a solution, but if you redeploy your webapp (without restarting your web container), you should run into the following error:
Adam Batkin 的原始答案将引导您找到解决方案,但如果您重新部署您的 web 应用程序(不重新启动您的 web 容器),您应该遇到以下错误:
java.lang.UnsatisfiedLinkError: Native Library "foo" already loaded in another classloader
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1715)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1646)
at java.lang.Runtime.load0(Runtime.java:787)
at java.lang.System.load(System.java:1022)
This happens because the ClassLoader that originally loaded your DLL still references this DLL. However, your webapp is now running with a new ClassLoader, and because the same JVM is running and a JVM won't allow 2 references to the same DLL, you can't reloadit. Thus, your webapp can't access the existing DLL and can't load a new one. So.... you're stuck.
发生这种情况是因为最初加载您的 DLL 的 ClassLoader 仍然引用此 DLL。但是,您的 web 应用程序现在正在使用新的 ClassLoader 运行,并且由于正在运行相同的 JVM,并且 JVM 不允许对同一个 DLL 进行 2 次引用,因此您无法重新加载它。因此,您的 web 应用程序无法访问现有的 DLL,也无法加载新的 DLL。所以......你被卡住了。
Tomcat's ClassLoader documentationoutlines why your reloaded webapp runs in a new isolated ClassLoader and how you can work around this limitation (at a very high level).
Tomcat 的 ClassLoader 文档概述了为什么重新加载的 web 应用程序在新的隔离 ClassLoader 中运行以及如何解决此限制(在非常高的级别)。
The solution is to extend Adam Batkin's solution a little:
解决方案是稍微扩展 Adam Batkin 的解决方案:
package awesome;
public class Foo {
static {
System.loadLibrary('foo');
}
// required to work with JDK 6 and JDK 7
public static void main(String[] args) {
}
}
Then placing a jar containing JUST this compiled class into the TOMCAT_HOME/lib folder.
然后将一个只包含这个编译类的 jar 放入 TOMCAT_HOME/lib 文件夹中。
Now, within your webapp, you just have to force Tomcat to reference this class, which can be done as simply as this:
现在,在你的 webapp 中,你只需要强制 Tomcat 引用这个类,这可以像这样简单地完成:
Class.forName("awesome.Foo");
Now your DLL should be loaded in the common classloader, and can be referenced from your webapp even after being redeployed.
现在您的 DLL 应该被加载到公共类加载器中,并且即使在重新部署之后也可以从您的 web 应用程序中引用。
Make sense?
有道理?
A working reference copy can be found on google code, static-dll-bootstrapper.
可以在谷歌代码static-dll-bootstrapper上找到工作参考副本。
回答by Rick C. Hodgin
If you need to load a file that's relative to some directory where you already are (like in the current directory), here's an easy solution:
如果您需要加载一个与您所在目录相关的文件(例如在当前目录中),这里有一个简单的解决方案:
File f;
if (System.getProperty("sun.arch.data.model").equals("32")) {
// 32-bit JVM
f = new File("mylibfile32.so");
} else {
// 64-bit JVM
f = new File("mylibfile64.so");
}
System.load(f.getAbsolutePath());
回答by Ian Emmons
In the case where the problem is that System.loadLibrary cannot find the DLL in question, one common misconception (reinforced by Java's error message) is that the system property java.library.path is the answer. If you set the system property java.library.path to the directory where your DLL is located, then System.loadLibrary will indeed find your DLL. However, if your DLL in turn depends on other DLLs, as is often the case, then java.library.path cannot help, because the loading of the dependent DLLs is managed entirely by the operating system, which knows nothing of java.library.path. Thus, it is almost always better to bypass java.library.path and simply add your DLL's directory to LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS), or Path (Windows) prior to starting the JVM.
如果问题是 System.loadLibrary 找不到相关的 DLL,一个常见的误解(由 Java 的错误消息强化)是系统属性 java.library.path 是答案。如果您将系统属性 java.library.path 设置为您的 DLL 所在的目录,那么 System.loadLibrary 确实会找到您的 DLL。但是,如果您的 DLL 又依赖于其他 DLL(通常是这种情况),那么 java.library.path 将无济于事,因为依赖 DLL 的加载完全由操作系统管理,而操作系统对 java.library 一无所知。小路。因此,在启动 JVM 之前绕过 java.library.path 并简单地将 DLL 的目录添加到 LD_LIBRARY_PATH (Linux)、DYLD_LIBRARY_PATH (MacOS) 或 Path (Windows) 几乎总是更好。
(Note: I am using the term "DLL" in the generic sense of DLL or shared library.)
(注意:我在 DLL 或共享库的一般意义上使用术语“DLL”。)
回答by Alexandre
Changing 'java.library.path' variable at runtime is not enough because it is read only once by JVM. You have to reset it like:
在运行时更改 'java.library.path' 变量是不够的,因为它只被 JVM 读取一次。你必须像这样重置它:
System.setProperty("java.library.path", path);
//set sys_paths to null
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);
Please, take a loot at: Changing Java Library Path at Runtime.
请查看:在运行时更改 Java 库路径。
回答by Dan Carte
For windows I found that when i loaded the filles(jd2xsx.dll calls & ftd2xx.dll) into the windowws/system32 folder this resolved the issues. I then had an issue with my newer fd2xx.dll having to do with parameters which is why I had to load the older version of this dll. I will have to ferrit this out later.
对于 Windows,我发现当我将填充物(jd2xsx.dll 调用和 ftd2xx.dll)加载到 windowws/system32 文件夹时,这解决了问题。然后我遇到了我的新 fd2xx.dll 与参数有关的问题,这就是为什么我必须加载这个 dll 的旧版本。稍后我将不得不解决这个问题。
Note: the jd2xsx.dll calls the ftd2xx.dll so just setting the path for the jd2xx.dll might not work.
注意:jd2xsx.dll 调用 ftd2xx.dll,所以只设置 jd2xx.dll 的路径可能不起作用。
回答by alexventuraio
I'm using Mac OS X Yosemite and Netbeans 8.02, I got the same error and the simple solution I have found is like above, this is useful when you need to include native library in the project. So do the next for Netbeans:
我正在使用 Mac OS X Yosemite 和 Netbeans 8.02,我遇到了同样的错误,我找到的简单解决方案与上面类似,当您需要在项目中包含本机库时,这很有用。为 Netbeans 做下一个:
1.- Right click on the Project
2.- Properties
3.- Click on RUN
4.- VM Options: java -Djava.library.path="your_path"
5.- for example in my case: java -Djava.library.path=</Users/Lexynux/NetBeansProjects/NAO/libs>
6.- Ok
I hope it could be useful for someone. The link where I found the solution is here: java.library.path – What is it and how to use
我希望它对某人有用。我找到解决方案的链接在这里: java.library.path – What is it and how to use