引用kimmking 的
主题:JNI技术实践小结--原理分析和详细步骤截图说明
http://www.iteye.com/topic/304594
现就说明如下,一般新手容易犯的错误
我是将这个类放到了一到eclipes下
一个工程Server
具体的测试类TestHello.java 放在了
E:\workspace\Server\src\test目录下
然后犯了[color=red]第一个[/color]错误
E:\workspace\Server\WebRoot\WEB-INF\classes\test>javah TestHello
错误:无法访问 TestHello
未找到 TestHello 的类文件
javadoc: 错误 - 找不到类 TestHello。
Error: 未在命令行中指定任何类。请尝试使用 -help。
E:\workspace\Server\WebRoot\WEB-INF\classes\test>
正确的做法
E:\>cd E:\workspace\Server\WebRoot\WEB-INF\classes\test
E:\workspace\Server\WebRoot\WEB-INF\classes\test>javah -classpath E:\workspace\Server\WebRoot\WEB-INF\classes test.TestHello
E:\workspace\Server\WebRoot\WEB-INF\classes\test>
[color=red]第二个[/color]错误的地方是在编写dll时我修改了vc编译时引用的目录。但还是有问题。
后来干脆把jni.h,jni_md.h都拷贝到工程目录下。
就不用修改vc的引用目录了。
[color=red]第三个[/color]地方
E:\workspace\Server\WebRoot\WEB-INF\classes\test>java TestHello
Exception in thread "main" java.lang.NoClassDefFoundError: TestHello
Caused by: java.lang.ClassNotFoundException: TestHello
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
Could not find the main class: TestHello. Program will exit.
E:\workspace\Server\WebRoot\WEB-INF\classes\test>
正确的做法
E:\workspace\Server\WebRoot\WEB-INF\classes>java -classpath E:\workspace\Server\
WebRoot\WEB-INF\classes test.TestHello
E:\workspace\Server\WebRoot\WEB-INF\classes>
JNI(Java Native
Interface)应用程序一般是一个Java类,在这个类中定义了几个native方法,并在类的初始化过程中加载动态库,例如下面这个类
public class SystemInfo{
static {
System.loadLibrary("SystemInfo");
}
public static native long getPhysicalMemory();
}
当Web项目用到该类并由于其他类的修改导致项目(context)重新加载,这个时候SystemInfo的初始化就会出异常,直接导致SystemInfo这个不可用,因为JNI中不允许一个动态库被加载两次,而且也没法通过程序来卸载前面所加载的动态库。
怎么来解决因为context重新加载而导致JNI类无法试用的问题呢?
其实这个问题不难,我们只要不让JNI类重新加载即可。但是一般的应用服务器对Web项目中文件都是默认重新加载的,例如WEB-INF/classes以及WEB-INF/lib目录。如此我们便不能将JNI类放在这两个目录下,但是我们又必须保证这个JNI类能被Web项目的其他类引用到,因此这就需要参照不同应用服务器的类路径的说明进行设置,对于Tomcat而言,我们可以把这个JNI类单独打包并放在{tomcat}commonlib目录下,并删除web项目中的这个JNI类即可解决前面提到的问题。
如何在Tomcat下的部署使得java web可以访问此DLL接口
第一步:将生成的文件放在哪里?有两种情况:
如果是java应用程序调用的话,就放置在我的机器是win xp 我就放在system32文件夹下。
如果是java web 开发的话,就是放置在JAVA_HOME的根目录下的bin文件夹下。
第二步:将eclipse下的java web项目,在tomcat下进行部署,并运行.
到此如何用java 调用DLL文件结束。
注:
当类中有package时进行包.类的打包
生成的dll文件要放在%JAVA_HOME%\bin目录下
主题:JNI技术实践小结--原理分析和详细步骤截图说明
http://www.iteye.com/topic/304594
现就说明如下,一般新手容易犯的错误
我是将这个类放到了一到eclipes下
一个工程Server
具体的测试类TestHello.java 放在了
E:\workspace\Server\src\test目录下
然后犯了[color=red]第一个[/color]错误
E:\workspace\Server\WebRoot\WEB-INF\classes\test>javah TestHello
错误:无法访问 TestHello
未找到 TestHello 的类文件
javadoc: 错误 - 找不到类 TestHello。
Error: 未在命令行中指定任何类。请尝试使用 -help。
E:\workspace\Server\WebRoot\WEB-INF\classes\test>
正确的做法
E:\>cd E:\workspace\Server\WebRoot\WEB-INF\classes\test
E:\workspace\Server\WebRoot\WEB-INF\classes\test>javah -classpath E:\workspace\Server\WebRoot\WEB-INF\classes test.TestHello
E:\workspace\Server\WebRoot\WEB-INF\classes\test>
[color=red]第二个[/color]错误的地方是在编写dll时我修改了vc编译时引用的目录。但还是有问题。
后来干脆把jni.h,jni_md.h都拷贝到工程目录下。
就不用修改vc的引用目录了。
[color=red]第三个[/color]地方
E:\workspace\Server\WebRoot\WEB-INF\classes\test>java TestHello
Exception in thread "main" java.lang.NoClassDefFoundError: TestHello
Caused by: java.lang.ClassNotFoundException: TestHello
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
Could not find the main class: TestHello. Program will exit.
E:\workspace\Server\WebRoot\WEB-INF\classes\test>
正确的做法
E:\workspace\Server\WebRoot\WEB-INF\classes>java -classpath E:\workspace\Server\
WebRoot\WEB-INF\classes test.TestHello
E:\workspace\Server\WebRoot\WEB-INF\classes>
JNI(Java Native
Interface)应用程序一般是一个Java类,在这个类中定义了几个native方法,并在类的初始化过程中加载动态库,例如下面这个类
public class SystemInfo{
static {
System.loadLibrary("SystemInfo");
}
public static native long getPhysicalMemory();
}
当Web项目用到该类并由于其他类的修改导致项目(context)重新加载,这个时候SystemInfo的初始化就会出异常,直接导致SystemInfo这个不可用,因为JNI中不允许一个动态库被加载两次,而且也没法通过程序来卸载前面所加载的动态库。
怎么来解决因为context重新加载而导致JNI类无法试用的问题呢?
其实这个问题不难,我们只要不让JNI类重新加载即可。但是一般的应用服务器对Web项目中文件都是默认重新加载的,例如WEB-INF/classes以及WEB-INF/lib目录。如此我们便不能将JNI类放在这两个目录下,但是我们又必须保证这个JNI类能被Web项目的其他类引用到,因此这就需要参照不同应用服务器的类路径的说明进行设置,对于Tomcat而言,我们可以把这个JNI类单独打包并放在{tomcat}commonlib目录下,并删除web项目中的这个JNI类即可解决前面提到的问题。
如何在Tomcat下的部署使得java web可以访问此DLL接口
第一步:将生成的文件放在哪里?有两种情况:
如果是java应用程序调用的话,就放置在我的机器是win xp 我就放在system32文件夹下。
如果是java web 开发的话,就是放置在JAVA_HOME的根目录下的bin文件夹下。
第二步:将eclipse下的java web项目,在tomcat下进行部署,并运行.
到此如何用java 调用DLL文件结束。
注:
当类中有package时进行包.类的打包
生成的dll文件要放在%JAVA_HOME%\bin目录下
本文总结了JNI技术的应用及常见问题,包括类路径配置、动态库加载与编译问题等,并介绍了如何避免因Web应用重新加载导致的JNI类加载失败。
1073

被折叠的 条评论
为什么被折叠?



