指纹仪
小弟的最近在JavaEE项目中用到了中控指纹仪(UareU4000B,ZKOnline SDK)通过指纹验证来实现身份验证,在做服务器端身份验证时,采用JNative(JNative-1.3.2,JNative-1.4均试过)方式来调用SDK中的Match.dll文件来实现指纹对比,虽然实现了,可以对比成功,但极不稳定,验证几次后Tomcat服务器就挂了,控制台提示如下:
2011-7-28 18:26:17, [DEBUG] [org.xvolks.jnative.JNative] [loadLibrary]: Reusing cached handle 1236533248 for function 'Process' in library 'Match.dll'
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d9a8504, pid=3360, tid=5820
#
# JRE version: 6.0_22-b04
# Java VM: Java HotSpot(TM) Client VM (17.1-b03 mixed mode windows-x86 )
# Problematic frame:
# V [jvm.dll+0x108504]
#
# An error report file with more information is saved as:
# D:ServerTomcat 6.0inhs_err_pid3360.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
不知问题出在哪?请指点,不胜感激,附代码如下:
package com.pilotexam.util;
import org.apache.struts2.ServletActionContext;
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
/**
*
* @param regFinger 采集注册的指纹
* @param verFinger 待验证的指纹
* @return 返回结果(true:验证通过,false:验证失败)
*/
public class MatchClassLoader {
public static boolean verFinger(String regFinger,String verFinger){
System.load(ServletActionContext.getServletContext().getRealPath("/Match.dll"));
boolean flag = false;
JNative jna = null;
try {
if(jna == null){
jna = new JNative("Match.dll","Process");//调用Mathc中的Process方法
jna.setRetVal(Type.INT);
JNative.setLoggingEnabled(true);
}
jna.setParameter(0,Type.STRING,regFinger);//设置Process方法中的第一个参数
jna.setParameter(1,Type.STRING,verFinger);//设置Process方法中的第二个参数
jna.invoke();
String val = jna.getRetVal();//获取Process方法的返回值
if("65535".equals(val))
flag = true;
} catch (Exception e) {
// TODO: handle exception
System.out.println("JNative调用Match.dll失败!");
e.printStackTrace();
}finally{
if(jna!=null){
try{
jna.dispose();
}catch(Exception e){
System.out.println("JNative注销失败!");
}
}
}
return flag;
}
}
问题补充:小卓SUN 写道把loadLibrary()加上static放在方法外面
Java代码
publicclass MatchClassLoader {
static{
System.loadLibrary(ServletActionContext.getServletContext().getRealPath("/Match.dll"));
}
public staticboolean verFinger(String regFinger,String verFinger){ //其他代码 }
这样系统在整个运行过程中只会加载一次
不会出现reuse重复使用现象
出现错误取决于是否第一次测试还没有完全结束第2次就开始了
如果没有释放,就load新的,有的系统会说reuse,有的会说load不到
话说,一个是你的verFinger最好不要同一个名字定义2变量
还有既然已经jna.setRetVal(Type.INT);
String val = jna.getRetVal();最好用ParseInt不要强制转换
谢谢你的解答啊,最初我也是把 System.loadLibrary(ServletActionContext.getServletContext().getRealPath("/Match.dll")); 放到静态块里写,但是很奇怪的是这样在执行的时候,执行完这句就没响应了,根本执行不到后面具体验证的那个方法里去,控制台也没输出任何异常信息,服务器状态也仍然是运行状态。
我是在一个Struts2.0的Action中调用这个方法的
MatchClassLoader.verFingerByZKOnline(person.getFigure(),fingureTemplate);
//第一个参数是人员注册的指纹模板,第二个参数是前台传过来的指纹验证信息
另后来我索性不用动态加载dll文件,把System.loadLibrary(ServletActionContext.getServletContext().getRealPath("/Match.dll"));这句去掉,直接把Match.dll拷贝到Tomcat的bin目录下,但在执行指纹对比的方法时Tomcat就停掉了,控制台没任何异常信息,另外附上D:ServerTomcat 6.0inhs_err_pid3360.log (见附件),请指点了谢谢!!
修改后的代码Java代码
package com.pilotexam.util;
import org.apache.struts2.ServletActionContext;
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
public class MatchClassLoader {
/** * 加载库文件 */
static {
System.loadLibrary(ServletActionContext.getServletContext().getRealPath("/Match.dll"));
}
/**
* * @param regFinger 采集注册的指纹
*
* @param verFinger 待验证的指纹 *
* @return 返回结果(true:验证通过,false:验证失败)
*/
public staticboolean verFingerByZKOnline(String regFinger, String verFinger) {
boolean flag = false;
JNative jna = null;
try {
if (jna == null) {
jna = new JNative("Match.dll", "Process");
//调用Mathc中的Process方法
jna.setRetVal(Type.STRING);
JNative.setLoggingEnabled(true);
}
jna.setParameter(0, Type.STRING, regFinger);//设置Process方法中的第一个参数
jna.setParameter(1,Type.STRING,verFinger);//设置Process方法中的第二个参数
jna.invoke();
String val = jna.getRetVal();//获取Process方法的返回值
if ("65535".equals(val))
flag = true;
} catch (Exception e) { // TODO: handle exception
System.out.println("JNative调用Match.dll失败!");
e.printStackTrace();
} finally {
if (jna != null) {
try {
jna.dispose();
} catch (Exception e) {
System.out.println("JNative注销失败!");
}
}
}
return flag;
}
}
问题补充:小卓SUN 写道引用(见附件)
木有看见
话说,你直接把dll文件放在systm32下
Java代码 System<pre name="code"class="java"></pre>.loadLibrary("/Match.dll")
第一种情况我觉得是动态load时候你servlet action那边阻塞造成的
你这里的代码没有什么问题,点击到load后,你用get step in看下
它怎么获取当前路径的,在什么地方阻塞的
第2种情况本身就有问题,dll文件你一定要加载才可以用啊
我单步Debug,程序在执行Java代码
static{
System.loadLibrary("/Match.dll");
} 时最后断点进了Runtime.class,执行到下面这一行挂掉的(走了方法的第二个if判断)
Java代码
synchronizedvoid loadLibrary0(Class fromClass, String libname) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkLink(libname);
}
if (libname.indexOf((int)File.separatorChar) != -1)
{ thrownew UnsatisfiedLinkError( "Directory separator should not appear in library name: " + libname);
}
ClassLoader.loadLibrary(fromClass, libname, false);
} ,另重新上传了一下hs_err_pid3360.log问题补充:Java代码
static{
System.loadLibrary(ServletActionContext.getServletContext().getRealPath("/Match.dll"));
} 也是在debug到那一步挂的,但是要是把加载动态库的那一句从静态块拿出来放在静态方法里是可以验证指纹成功的只是不稳定,单连续验证不了几次就挂了,这样应该是你说的阻塞了吧问题补充:能验证成功证明Java代码 System.loadLibrary(ServletActionContext.getServletContext().getRealPath("/Match.dll")); 是可以取到库的啊,为什么移到静态块里就不行了呢,请指点谢谢~Java综合2011年7月28日 19:05yingqiao
0
002hs_err_pid3360.rar (5.5 KB)下载次数: 13添加评论关注(0)
4个答案按时间排序按投票排序00引用时最后断点进了Runtime.class,执行到下面这一行挂掉的(走了方法的第二个if判断)
对不起啊,是我笔误了,没有前面那个斜杠/
汗。。。
你就没有加载成功,你所谓的验证成功肯定是个假象
2011年7月29日 17:33小卓SUN
497
000添加评论00引用(见附件)
木有看见
话说,你直接把dll文件放在systm32下
Java代码 System.loadLibrary("/Match.dll")
第一种情况我觉得是动态load时候你servlet action那边阻塞造成的
你这里的代码没有什么问题,点击到load后,你用get step in看下
它怎么获取当前路径的,在什么地方阻塞的
第2种情况本身就有问题,dll文件你一定要加载才可以用啊
2011年7月29日 15:56小卓SUN
497
000添加评论00把loadLibrary()加上static放在方法外面
Java代码 publicclass MatchClassLoader { static{ System.loadLibrary(ServletActionContext.getServletContext().getRealPath("/Match.dll")); } public staticboolean verFinger(String regFinger,String verFinger){ //其他代码 }
这样系统在整个运行过程中只会加载一次
不会出现reuse重复使用现象
出现错误取决于是否第一次测试还没有完全结束第2次就开始了
如果没有释放,就load新的,有的系统会说reuse,有的会说load不到
话说,一个是你的verFinger最好不要同一个名字定义2变量
还有既然已经jna.setRetVal(Type.INT);
String val = jna.getRetVal();最好用ParseInt不要强制转换