Java 我必须将所有依赖DLL放入JDK';垃圾箱文件夹?

Java 我必须将所有依赖DLL放入JDK';垃圾箱文件夹?,java,dll,java-native-interface,Java,Dll,Java Native Interface,我的java应用程序依赖于一个DLL,该DLL进一步依赖于libstdc++-6.DLL 我试图: 将libstdc++-6.dll放在文件夹中 并将文件夹放入%PATH% 然后我遇到了java.lang.Unsatisfied链接错误:从Eclipse启动应用程序时找不到指定的过程 但是如果我将libstdc++-6.dll放入JDK的bin文件夹中,那么就说C:\Java\jdk1.6.0\u 45\u 32bit\bin。它很好用 但我不想污染JDK文件夹。我记得windows将搜索%

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

我试图:

  • libstdc++-6.dll
    放在文件夹中
  • 并将文件夹放入%PATH%
然后我遇到了
java.lang.Unsatisfied链接错误:从Eclipse启动应用程序时找不到指定的过程

但是如果我将
libstdc++-6.dll
放入
JDK的bin文件夹中
,那么就说
C:\Java\jdk1.6.0\u 45\u 32bit\bin
。它很好用

但我不想污染JDK文件夹。我记得windows将搜索%PATH%以查找相关DLL。为什么我不能在此问题中使用%PATH%

更新1 Windows中有2个不同的%PATH%环境变量

  • 用户变量
  • 系统变量
我只是意外地发现:

  • 如果我将DLL的文件夹放到用户%PATH%,则找不到它

  • 如果我将DLL的文件夹放在系统%PATH%,它会工作

为什么?

更新2 灵感来源于这条线索:

我开始怀疑我的用户%Path%是否太长了。因此,我将包含依赖DLL的文件夹路径从用户%path%的结尾移动到开头。现在可以了

首先,我得出结论,实现Windows的DLL查找算法的人有一些截断问题。我几乎把它看作另一个恼人的Windows bug。 但为了证实我的猜测,我编写了另一个具有类似DLL依赖关系的Windows应用程序。该应用程序运行良好!所以我必须回顾我的结论

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

我在用户%PATH%中有一个
C:\MinGW\bin
条目,它恰好包含一个
libstdc++-6.dll(977KB)
但不幸的是,它不兼容 我需要一个
(825KB)
。只有在我将文件夹放在MinGW之前,它才起作用。所以它实际上是在%PATH%解析期间发生的DLL冲突

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

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

首先:将所有需要的DLL文件放在同一目录中

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

  • 运行应用程序时设置VM选项
  • -Djava.library.path=“C:\Dll所在的目录 现在”

    例如:

    java-Djava.library.path=“C:\Dll所在的目录 当前”-jar app.jar

  • 从应用程序中加载特定的本机库:
  • a) 将包含aaa.dll文件的目录直接放在Java项目下

    b) 并将这一行放在应用程序堆栈跟踪的顶部:System.loadLibrary(“aaa”)

  • 在应用程序中使用VM选项:
  • System.setProperty(“java.library.path”,“C:\Dll所在的目录” 出席);


    您确定问题出在路径上吗?错误表明它找不到函数,而不是库,错误消息具有误导性。实际上,我想它说我的DLL依赖于
    libstdc++-6.DLL
    ,而
    libstdc++-6.DLL
    无法找到。因为一旦我把它放到JDK-bin文件夹中,问题就消失了。谢谢。但您的解决方案是让Java定位一个直接依赖的DLL。我的场景是一个间接依赖的DLL。这就是
    myjava应用程序->DLL->libstdc++-6.DLL
    。我的设想是第二步。我认为这一步应该由Windows来完成。我认为Windows应该使用%PATH%作为搜索路径。也许@Igo Kegel的答案可以帮助你:谢谢Karol。你的链接是一篇解释这个概念的好文章。但我已经找到了问题的根源。查看我的更新。@smwikipedia-您也可以使用
    System.load()
    System.loadLibrary()
    来加载这些间接DLL。@smwikipedia-好的,如果您使用
    System.loadLibrary()
    ,则只需配置进程的
    java.library.path
    属性。如果您使用
    System.load(字符串文件名)
    ,您甚至不需要它。