我必须将所有依赖的 DLL 放入 JDK 的 bin 文件夹中吗? [英] Must I place all dependent DLLs into the JDK's bin folder?

查看:31
本文介绍了我必须将所有依赖的 DLL 放入 JDK 的 bin 文件夹中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 java 应用程序依赖于一个 DLL,而那个 DLL 进一步依赖于 libstdc++-6.dll.

我试图:

  • libstdc++-6.dll放在一个文件夹中
  • 并将文件夹放入 %PATH%

然后我遇到了java.lang.Unsatisfied LinkError: The specified procedure could not be found 从 Eclipse 启动应用程序时.

但是如果我把 libstdc++-6.dll 放入 JDK 的 bin 文件夹,说 C:Javajdk1.6.0_45_32bitin.它工作正常.

但是我不想污染JDK文件夹.我记得 Windows 会搜索 %PATH% 来定位依赖的 DLL.为什么我在这个问题中不能使用 %PATH%?

更新 1

Windows 中有 2 个不同的 %PATH% 环境变量.

  • 用户变量
  • 系统变量

我只是偶然发现:

  • 如果我将 DLL 的文件夹放在用户 %PATH% 中,则无法找到它.

  • 如果我将 DLL 的文件夹放到系统 %PATH% 中,它就可以工作.

为什么?

更新 2

受此线程启发:系统与用户 PATH 环境变量...只有当我将路径添加到用户 PATH 时,winmerge 才有效

我开始怀疑我的用户 %Path% 是否太长.因此,我将包含我的依赖 DLL 的文件夹路径从用户 %PATH% 的 end 移动到 beginning.它现在有效!

首先,我得出结论,实现 Windows 的 DLL 查找算法的人存在一些截断问题.我几乎认为这是另一个烦人的 Windows 错误.

但我编写了另一个具有类似 DLL 依赖项的 Windows 应用程序来证实我的猜测.该应用程序运行良好!所以我必须回顾我的结论.

我一一检查了我的用户 %PATH% 条目,并将文件夹放置到每个可能的位置.最后,我找到了根本原因.

<块引用>

我在用户 %PATH% 中有一个 C:MinGWin 条目,它恰好包含一个libstdc++-6.dll (977KB) 但不幸的是,它不兼容用我需要的(825KB).仅当我将文件夹放在 MinGW 之前才有效.所以它实际上是 %PATH% 分辨率期间的 DLL 冲突.

现在这个问题似乎解决了.但是又出现了一个,如果我想同时使用我的 DLL 和 MinGW,我需要来回切换吗?

更新 3

请查看@AndyThomas 的评论.他提到对直接和间接 DLL 使用 System.loadLibrary().这样,我们只需要关心 java.library.path 属性.我认为这是一个一劳永逸的解决方案.

解决方案

第一:把你需要的所有DLL文件放在同一个目录下

然后:加载本机库 - 为此,您有 3 个选项:

  1. 在运行应用时设置 VM 选项.

<块引用>

-Djava.library.path="C:Dll 所在的目录礼物"

示例:

<块引用>

java -Djava.library.path="C:Dll 所在的目录呈现"-jar 应用.jar

  1. 从应用内加载特定的原生库:

<块引用>

a) 将包含文件 aaa.dll 的目录直接放在 Java 项目下.

b) 将此行放在您应用的堆栈跟踪顶部:System.loadLibrary("aaa")

  1. 在您的应用中使用 VM 选项:

<块引用>

System.setProperty( "java.library.path", "C:Your Directory where Dll is呈现");

My java application depends on a DLL, and that DLL further depends on libstdc++-6.dll.

I tried to:

  • placed the libstdc++-6.dll in a folder
  • and put the folder in the %PATH%

Then I meet the java.lang.Unsatisfied LinkError: The specified procedure could not be found when launching application from Eclipse.

But if I put the libstdc++-6.dll into the JDK's bin folder, say C:Javajdk1.6.0_45_32bitin. It works fine.

But I don't want to pollute the JDK folder. I remember windows will search %PATH% to locate dependent DLLs. Why can't I use the %PATH% in this issue?

Update 1

There are 2 different %PATH% environment variables in Windows.

  • User variables
  • System variables

I just accidentally find that:

  • If I put the DLL's folder to User %PATH%, it cannot be found.

  • If I put the DLL's folder to System %PATH%, it works.

Why?

Update 2

Inspired by this thread:System versus user PATH environmental variable...winmerge works only if I add the path to the user PATH

I start to wonder maybe my User %Path% is too long. So I moved the folder path containing my dependent DLL from the end of User %PATH% to the beginning. It works now!

At first, I conclude that one who implemented the Windows' DLL lookup algorithm has some truncation issue. And I almost consider it as another annoying Windows Bug.

But I wrote another Windows application which has similar DLL dependencies to confirm my guess. That application works fine! So I have to review my conclusion.

I checked my User %PATH% entry one by one, and place the folder to each possible location. And finally, I find the root cause.

I have a C:MinGWin entry in User %PATH%, which happens to contain a libstdc++-6.dll (977KB) but unfortunately, which isn't compatible with the one I need (825KB). It only works if I place my folder before MinGW. So it's actually DLL collision during %PATH% resolution.

Now this issue seems resolved. But another one comes up, do I need to switch back and forth if I want to use both my DLL and the MinGW?

Update 3

Please check the comment by @AndyThomas. He mentioned using System.loadLibrary() for both direct and indirect DLLs. This way, all we need to care about is the java.library.path property. I think that's a once-for-all solution.

解决方案

First: put all DLL files you need in the same directory

Then: Load native libs - to do so you have 3 options:

  1. Set VM Options while you run your app.

-Djava.library.path="C:Your Directory where Dll is present"

Example:

java -Djava.library.path="C:Your Directory where Dll is present" -jar app.jar

  1. Load specific native library from within the app:

a) Place the directory that contains the file aaa.dll directly under the Java project.

b) And place this line on the top of stack trace of your app: System.loadLibrary("aaa")

  1. Use VM options from within your app:

System.setProperty( "java.library.path", "C:Your Directory where Dll is present" );

这篇关于我必须将所有依赖的 DLL 放入 JDK 的 bin 文件夹中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆