java调用dll异常的处理(UnsatisfiedLinkError)
来源:互联网 发布:tsc g310打印软件 编辑:程序博客网 时间:2024/05/21 01:31
背景描述
因业务需要,java项目需要调用dll进行MD5加密处理。dll是其它项目组提供的,基于64位平台编译的;java项目是基于maven的。我把dll文件放在resources目录下,相关代码如下:
加载dll方法的类:
public class NativeMethod{
public native String getC4MD5(String pwd);
public String getC4MD51(String pwd){
String filePath = this.getClass().getClassLoader().getResource("/").getPath();
filePath +="Md5.dll";
try {
filePath = java.net.URLDecoder.decode(filePath, "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
filePath = filePath.startsWith("/") ? filePath.substring(1) : filePath;
File file=new File(filePath.replaceAll("/", "\\\\"));
System.load(file.toString());
return getC4MD5(pwd);
}
}
调用方式:
public Map<String,Object> doLogin(String userName,String password){Map<String,Object> resultMap = new HashMap<String,Object>();
try {
NativeMethod n = new NativeMethod();
String pwd = n.getC4MD51(password);
System.out.println("pwd:" + pwd);
resultMap.put("pwd", pwd);
} catch (Exception e) {
e.printStackTrace();
resultMap.put("result", false);
resultMap.put("error", e);
}
return resultMap;
}
问题描述
接下来记录调用过程中碰到的两个主要问题:1.JDK版本问题,由于dll是64位的,而我的JDK是32位的,所以会报平台兼容性的错误。解决方案就是把JDK替换成64位版本的。这方面的资料百度上一搜一大堆,这里就不作展开。
2.JDK版本替换成64位之后,通过myeclipse直接部署到tomcat上,可以正常运行,调用加密方法也正常。以为大功告成,于是通过maven打成war,部署到服务器上,结果报错:
2017-04-19 11:37:54 [ http-bio-8080-exec-10:10988 ] - [ DEBUG ] Could not complete request
org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.UnsatisfiedLinkError: D:\Program Files\Apache Software Foundation\Tomcat 7.0\webapps\bss\WEB-INF\classes\Md5.dll: Can't load this .dll (machine code=0xbd) on a AMD 64-bit platform
at org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletionWithError(DispatcherServlet.java:1302)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:977)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
奇怪啊,本地跑的好好的,怎么到服务器上就不行了呢?百思不得其解。
解决方案
折腾了好久,最后在stackoverflow上找到了解决方法。参考链接:http://stackoverflow.com/questions/38244970/running-my-generated-jar-yields-cant-load-this-dll-machine-code-0xbd-on-a
原文如下:
I experienced the same problem when I tried to run the JAR that was built by Maven (but with a 32 bit DLL - Can't load this .dll (machine code=0xbd) on a IA 32-bit platform). Strange thing was: It happened after I moved the DLL in a folder with other resources which have to be copied during the build.
I took me a quite a while to find out that the maven resources plugin was changing the DLL file for some reason (might be a bug?). The original DLL file is 76 kb - the copied DLL in the target folder was 118 kb. Something happened to the file during build.
Adding an extra execution to copy the DLL files without <filtering>true</filtering> solved the problem.
我把war包里的dll文件取出来和原文件一比较,果然如此:原文件123k,war取出来的195k,确实是maven引起的问题。
再查看maven工程的pom.xml,打包相关配置如下:
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.dll</include>
</includes>
</resource>
然后根据这位大神说的,把filtering注释掉,改成如下:
<resource>
<directory>src/main/resources</directory>
<!-- <filtering>true</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.dll</include>
</includes> -->
</resource>
再次编译,问题解决。
或许,如这位大神所说,这真的是maven的一个bug吧。
0 0
- java调用dll异常的处理(UnsatisfiedLinkError)
- JAVA UnsatisfiedLinkError(调用Delphi的DLL)
- java调用dll,报java.lang.UnsatisfiedLinkError错的解决办法
- JNI调用 java.lang.UnsatisfiedLinkError 异常
- java调用DLL库文件。及java.lang.UnsatisfiedLinkError错误!
- JNI调用native方法出现 java.lang.UnsatisfiedLinkError: XXXclass.XXXmethod()异常的解决办法
- JNI调用native方法出现 java.lang.UnsatisfiedLinkError: XXXclass.XXXmethod()异常的解决办法
- [2014.1.31] Eclipse、MinGW、JNI编写C++生成dll, Java端调用的完整示例(附java.lang.UnsatisfiedLinkError解决方法)
- [2014.1.31] Eclipse、MinGW、JNI编写C++生成dll, Java端调用的完整示例(附java.lang.UnsatisfiedLinkError解决方法)
- 关于java.lang.UnsatisfiedLinkError的处理
- 解决 RNI接口调用出现的异常UnsatisfiedLinkError: no jtokyocabinet in java.library.path 及 wrong ELF class: ELFCLASS64问题
- android java.lang.UnsatisfiedLinkError: 异常
- java.lang.UnsatisfiedLinkError异常 (javacv)
- Flex调用Java异常处理
- java中jni调用不需要配置dll的处理代码
- JNI调用Native方法,抛出UnsatisfiedLinkError异常
- 关于Android调用JNI出现的 java.lang.UnsatisfiedLinkError
- java JNI调用C语言动态链接库(java.lang.UnsatisfiedLinkError: no yourClassName in java.library.path 异常的解决方法)
- 大数据概念:史上最全大数据解析
- 机器学习算法笔记之7:模型评估与选择
- 关于SSH
- dns-bind9.3
- C语言函数 判断质数
- java调用dll异常的处理(UnsatisfiedLinkError)
- 算法:按顺时针方向遍历矩阵
- Redis实战之Windows Redis 集群搭建(一)
- 基于docker可使用的api
- 【2017.04.18】完美一面面经
- Linux netstat命令详解
- rails strip
- Nginx相关命令记录
- Elo评分算法原理与实现