Runnable Jar中使用jna调用DLL文件,找不到指定模块

松哥B 发布于 2016/05/01 19:50
阅读 9K+
收藏 2

问题描述:

Windows环境,使用tess4j.jar进行OCR识别,tess4j中使用JNA加载gsdll32.dll、liblept171.dll和libtesseract304.dll三个文件。

在Eclipse开发环境下,编译运行没有问题。打包成runnable jar后,运行会有“找不到指定模块”异常,如图

调试过程:

dll文件依赖关系

libtesseract304.dll文件依赖liblept171.dll,另外一个不清楚。

tess4j使用JNA加载DLL过程

分析tess4j使用JNA的源代码,tess4j.jar中包含以上三个dll文件,tess4j将三个dll文件从jar中拷贝到文件系统(C:\Users\songgeb\AppData\Local\Temp\tess4j\win32-x86),然后“jna.library.path”属性设置为以上路径,执行Native.loadLibrary("libtesseract304", TessAPI.class)语句进行加载。

Demo调试

新建工程,使用JNA单独加载“libtesseract304.dll”进行调试。人为设置“jna.library.path”属性的值为本地文件系统某一路径。开启JNA的debug模式(System.setProperty("jna.debug_load","true"))。

1. Eclipse开发环境下运行,能够找到libtesseract304.dll,成功加载。

2. 打包成Runnable Jar后运行,报异常,如图。

疑问:尽管设置了“jna.library.path”,但仍然找不到。

3. 将三个dll文件放入Runnable Jar文件根目录下执行,能够找到libtesseract304.dll,但仍报异常,如图


加载中
1
松哥B

问题已解决,主要原因是在Windows环境下,libtesseract304.dll等三个文件是通过vc2013编译的,所以需要相应地依赖库函数。在这里下载。是知乎上的thom大神帮助解决的,感谢!也感谢三位帮忙解决问题的朋友。

木木月月
太感谢了~捣鼓了半天,症结在这里
松哥B
回复 @行业协汇袁斌 : 有道理,当时怎么就没想到是环境的问题呢。。。。。唉
行业协汇袁斌
行业协汇袁斌
你没有说很关键的一点, 就是你的eclispe环境和发布环境不是同一台机器... 从错误信息上看 dll已经找到 就是无法load进来, 不是路径的问题, 就是环境的问题了... 不过现在说这个已经是事后诸葛亮, 哈哈哈
0
暗影风暴
暗影风暴
把dll放到C:\Windows\System32 下就行了应该
松哥B
经测试还是找不到
0
阿信sxq
阿信sxq

你试过不打包直接运行不没有


松哥B
回复 @阿信sxq : thx
阿信sxq
阿信sxq
回复 @松哥B : 那就应该是路径错误了,我也没有试过那个,所以说帮不上忙了
松哥B
不打包完全没有问题
0
南湖船老大
南湖船老大
jar包里应该有个叫main什么的清单文件
松哥B
manifest,如何配置呢?指定classpath吗?
0
过去现在未来
过去现在未来
松哥, 我在eclipse上就遇到你这样的问题,找不到模块  请问怎么解决呢
松哥B
前面评论里的回复,有帮助吗
0
过去现在未来
过去现在未来
java.lang.UnsatisfiedLinkError: 找不到指定的模块。


at com.sun.jna.Native.open(Native Method)
at com.sun.jna.Native.open(Native.java:1759)
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:260)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
at com.sun.jna.Native.register(Native.java:1396)
at com.sun.jna.Native.register(Native.java:1156)
at net.sourceforge.tess4j.TessAPI1.<clinit>(TessAPI1.java:37)
at com.test.Tesseract1Test.setUp(Tesseract1Test.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:670)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)


0
开源艺龙
开源艺龙
我总结一下吧,最近一直在忙这个问题,首先我们需要确认dll文件的版本(右键属性就可以看到);官方版本地址如下:https://github.com/nguyenq/tess4j 大家选择不同的版本分支下载所需,官方中有一条话需要大家注意:“The following code example shows common usage of the library. Make sure libtesseract302.dllliblept168.dll, and tessdata folder are in the same directory and in the search path, and the .jar files are in the classpath.” 虽然这句话有点问题,大家尽量按文档走吧(按文档走坑少),一般遇到“java.lang.UnsatisfiedLinkError: 找不到指定的模块。”这个问题都是缺少dll文件依赖的类库,需要安装一下Microsoft Visual C++环境,具体版本需要看dll文件是哪个版本编译的(关键我也不知道dll是哪个版本编译的),这个是我目前遇到的问题,希望谁有好的解决方案提供一下,目前我解决方案就是装个visual studio 2012,版本高点东西全
开源艺龙
开源艺龙
@红薯 开源中国评论不知道Markdown么?
返回顶部
顶部