JNI可以在所有的Java环境下使用。出了什么错?

解决方案 »

  1.   

    CSDN专家:
            您好:
            我是一名Java程序员,最近在使用JNI时碰到了一个问题,一直无法解决,希望您能给予解答,万分感谢!
            
          问题主要是:在J2SDK环境中(DOS环境下,在J2SDK的bin目录下执行)测试通过的JNI程序,在Tomcat的JSP环境中运行时出错.               我写了一个Test1.java文件,代码如下:
            
      public class Test1 {
      static {
        System.loadLibrary("Test1");
      }  public native static int TestInt(int i);  public Test1() {
      }  public static void main(String[] arg)
      {
        System.out.print(Test1.TestInt(123));
      }
     }
       
        里面包括了一个TestInt(int)的native方法,我将这个.java文件编译成.class文件,然后用javah命令将.class文件编译成.H文件,再用Visual C++编译器创建了一个DLL,实现了.H文件中的方法
    Visual C++中代码如下:
                  
    #include "Test1.h"JNIEXPORT jint JNICALL Java_Test1_TestInt (JNIEnv *env, jclass tclass, jint i)
    {
      return i;
    }        将编译得到的Test1.DLL文件置于System32目录下,在JAVA中System.loadLibrary("Test1")是成功的
            
            在J2SDK1.4.0环境下,运行Java Test1 
            运行结果:123,说明JNI成功 (Java调用DLL成功)        注:
               1. 在J2SDK中运行,需要去掉Test1.Java代码中的"package jnitest"代码,然后保存.
               2. 用javac Test1.java命令得到Test1.class
               3. 用java Test1 即可得到结果为123
                      
           
          
            但在Tomcat环境下运行时,却出错了,出错的页面error.htm我已经保存了,放在附件中,您可以参看
            
            是不是JNI只能运行在J2SDK环境中? 而在JSP环境中不能运行呢?
            
            如有可能,请回复我电子邮件,,万分感谢!
                    代码置于附件中.
      

  2.   

    附件在哪里???不管,我估计你的错误就应该在你的包名上,JNI是根据包名寻址的,也就是说,如果你在生成.h的时候写了包名,如果报名变化和重写,你需要重新生车.h文件。例如现在Java_Test1_TestInt就是一个没有包名的方法,如果加上包再去调用就会出错。
      

  3.   

    我的附件放在这里,http://www.chenbug.com/problem.rar,你可以下载去看看
      

  4.   

    但是所有的测试在J2SDk下用java Test1上可以正确运行的,所以应该不存在包的问题,而且加了包名和不加包名得到的.H文件是一样的,所以我在想是不是Tomcat中需要初始化一些环境变量,或者需要加载一些别的包才能运行JNI呢
      

  5.   

    就是包名的问题,正确的H文件应该是:/* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class Test1 */#ifndef _Included_Test1
    #define _Included_Test1
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     Test1
     * Method:    TestInt
     * Signature: (I)I
     */
    JNIEXPORT jint JNICALL Java_jnitest_Test1_TestInt
      (JNIEnv *, jclass, jint);#ifdef __cplusplus
    }
    #endif
    #endif
      

  6.   

    贴错了,这个:jnitest_Test1.h/* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class jnitest_Test1 */#ifndef _Included_jnitest_Test1
    #define _Included_jnitest_Test1
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     jnitest_Test1
     * Method:    TestInt
     * Signature: (I)I
     */
    JNIEXPORT jint JNICALL Java_jnitest_Test1_TestInt
      (JNIEnv *, jclass, jint);#ifdef __cplusplus
    }
    #endif
    #endif
      

  7.   

    这个问题已经解决了,谢谢,确实是包名的问题,但需要手工编辑.H文件才行现在在运行JNI时,JVM会报错,然后Tomcat就自动关闭了,
    头大,
    System.locadLibrary后需要调用别的方法卸载这个DLL文件吗?
      

  8.   

    1、我给你的h文件就是javah生成的,你把你生成h文件的命令贴上来看看。2、你的JNI调用不标准的话,或者有内存泄漏的话,JVM很容易就死了。3、不用,DLL调入是一次性的。