今天,使用JNative遇到了一些小问题,郁闷是我,弄了很久才发现问题的所在:
先说一下JNative的使用吧(JNative是封装了访问动态库的相关东西,方便java访问动态库的一个jar包):
首先:下载JNative(http://sourceforge.net/projects/jnative/)又是sourceforge的东西;
其次:将你需要调用的的动态库放到系统系统盘下的system32或者其他地方(这些其他地方你可以查一下,WEB 项目则将动态库拷贝到容器的bin目录下,如tomcat的bin下 );
再次: 建立一个java项目,在项目中调用动态库,我这里粘贴一个我的例子供参考:
package com.gxmis.password;
import org.jasig.cas.authentication.handler.PasswordEncoder;
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.MemoryBlock;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;
//这是CAS里要使用的一个加密类,我实现了PasswordEncoder 的接口
public class AccPasswordEncoder implements PasswordEncoder {
public AccPasswordEncoder(){
}
//重写的加密方法
public String encode(String pass) {
//定义JNative
JNative jn = null;
//返回密码的长度
int retInt ;
//返回的密码字符串
String retPass = "";
try {
//申请一个内存块,因为要将加密后的数据取回来用,所以将加密后的数据放在这个内存块,方便返回的时候取出
MemoryBlock m = MemoryBlockFactory.createMemoryBlock(1024);
//指向内存块的指针
Pointer pp = new Pointer(m);
//设置日志记录的开启,方便跟踪JNative的运行过程
JNative.setLoggingEnabled(true);
//加载系统system32目录下的动态库
System.loadLibrary("encrypt");
//将动态库的名字和方法传递给JNative
jn= new JNative ("encrypt","encrypttext");
//设置调用动态库的方法后的返回类型(即encrypttext方法的返回类型)
jn.setRetVal(Type.INT);
int passLen = pass.length();
int intOut = 2 * passLen + 16;
//注意,我的encrypttext方法是有4个参数的,返回值为整型,第0,2个参数是字符串,第1,3个是整形
jn.setParameter(0, pass);
jn.setParameter(1, passLen);
jn.setParameter(2, pp);
jn.setParameter(3, intOut);
//调用encrypttext方法
jn.invoke();
//获得返回值
intOut = Integer.parseInt(jn.getRetVal());
if (intOut == -1){
jn.dispose();
retPass = "";
}
else{
jn.dispose();
//取得加密数据
retPass = pp.getAsString().substring(0,6);
}
} catch (NativeException e) {
System.out.println("NativeException异常:");
e.printStackTrace();
} catch (IllegalAccessException e) {
System.out.println("IllegalAccessException异常:");
e.printStackTrace();
}finally{
try {
jn.dispose();
} catch (NativeException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return retPass;
}
}
我自己是调用动态库进行加密的操作:
遇到的问题1:
这个问题是找不到日志文件的异常,但是加密已经完成,从数据可以看出来:
2009-11-5 10:43:01, [DEBUG] [org.xvolks.jnative.JNative] [loadLibrary]: Successfully loaded library 'encrypt', functionName = encrypttext: hModule = 268435456
1af154(这个是加密后出现的数据)java.lang.NoSuchFieldError: lastError
at org.xvolks.jnative.JNative.nInvoke(Native Method)
at org.xvolks.jnative.JNative.invoke(JNative.java:807)
at com.passkey.AccPasswordEncoder.encode(AccPasswordEncoder.java:50)
at com.passkey.test.main(test.java:10)
2009-11-5 10:43:01, [DEBUG] [org.xvolks.jnative.JNative] [unLoad]: Unloading native library 'encrypt'
ccx_jni_utils.c.writeLog : can't get a Java Logger instance.
Exception in thread "main"
解决办法:这个问题是jar包的原因,更新新版本的JNative.jar包就可以解决
遇到的问题2:
JVM的问题:
#
# An unexpected error has been detected by Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x02e37b1a, pid=4008, tid=456
#
# Java VM: Java HotSpot(TM) Client VM (1.6.0-beta2-b86 mixed mode, sharing)
# Problematic frame:
# C [IC_WS_CPU.dll+0x7b1a]
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
#
解决办法:是JDK版本的原因,注意要更新JDK的版本,1.5以下的可能会出现一些异常,更新到1.6的正式发布版本(尽量不使用测试版本)就好了
遇到的问题3:
我看网上还有个问题是:
开发一个web的时候,一个类用了JNative,JNativeCpp.dll文件发到了windows/system32下面,
junit 也测试通过了,实际调用的时候报了个
java.lang.IllegalStateException: JNative library not loaded, sorry !
at org.xvolks.jnative.JNative. <init>(JNative.java:337)
at org.xvolks.jnative.JNative. <init>(JNative.java:269)
....
的错误,
后来把JNativeCpp.dll拷到tomcat的bin下面就解决了。
不过,不知道了解里面的机制。
我也试了一下不用将JNativeCpp.dll拷贝到相应的目录,因为最新的JNative.jar包里面是打包了JNativeCpp.dll文件,所以这个问题在新版本我是没有遇到
以上的是鄙人遇到的一些东西,记录下来方便查找,若有错误之处忘回帖指教,若你也遇到了问题,也麻烦你写下问题和问题的解决办法,大家共同学习进步,谢谢.
分享到:
相关推荐
在Java程序中调用DLL(动态链接库)文件通常是通过JNI(Java Native...然而,这也意味着一旦遇到问题,可能需要对JNI有一定的了解才能有效地排查和解决。在实际开发中,应谨慎使用,确保调用的本地方法安全且性能高效。
通过阅读文档,开发者可以快速上手,避免在使用过程中遇到困扰。 在使用JNative时,你需要按照以下步骤操作: 1. **引入库**:确保你的Java项目正确地引用了JNative的库文件,这通常通过设置Java的类路径或者系统...
在Java程序中,我们通常使用Java语言编写大部分逻辑,但有时会遇到需要调用非Java代码的情况,例如利用C/C++库提供的高性能计算功能。这时,JNI提供了一种方式,让我们可以在Java代码中直接调用本地方法,这些方法...
如果遇到jnative报错,可以尝试将dll动态库文件放入system32中,或者直接把dll放入jdk/bin目录下和jdk/jre/bin目录下,或者把jNative放入jdk/jre/lib/ext目录下,或者把Termb.dll和JNativeCpp.dll放在桌面
如果遇到处理结构体(如`out`参数)的问题,可以参考[JNative文档](http://jnative.free.fr/SPIP-v1-8-3/article.php3?id_article=10)。对于检测系统用户权限,可以查看[XP系统用户权限检测]...
描述中的问题 "64和32位不同" 暗示用户可能遇到了兼容性问题。Windows 系统有 32 位和 64 位两种版本,每种版本需要对应位数的 DLL 文件。如果将 32 位应用程序安装在 64 位系统上,或者反之,可能会导致 DLL 文件不...
5. **C++ 使用 ShellExecute**:如果是在编程中遇到此问题,特别是使用 C++ 的 `ShellExecute` 函数,确保添加了适当的参数。例如,可以使用 `ShellExecute(NULL, "runas", "path_to_your_executable", NULL, NULL, ...
6. **异常处理**:由于涉及底层系统调用,务必添加适当的错误处理机制,以确保程序在遇到问题时能够正常运行。 在描述中还提到了“原来的串口要改USB”。这表明原本的系统可能是通过串口(COM口)与硬件通信的,...
5. **错误处理**:添加适当的错误处理机制,确保在遇到问题时能够正确地反馈和处理。 为了成功实现Java对接LED屏,开发者需要对以下知识有深入理解: - Java语言基础 - JNI原理及使用 - Windows系统上的动态链接库...
一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...
EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件...
一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...
一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...
一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...
一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...
一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...
一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...
一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...
一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...
一个Java的类库,用于异步输出记录的简单小框架用于高并发下数据输出使用。 Java转C++代码工具 J2C J2C 将 Java 代码转成 C++ 代码,这是源码级别的转换,输出的 C++ 代码是有效的代码。 OSGi 分布式通讯组件 R-...