关键是下面的信息:root cause java.lang.UnsatisfiedLinkError: jCMPP_Connect
at com.haoxi.hainanshow.cnative.JCMPP.jCMPP_Connect(Native Method)
at com.haoxi.hainanshow.test.SMGTest2.doGet(SMGTest2.java:41)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)以前最常见的是(是因为根本找不到.so共享库):
Exception in thread "main" java.lang.UnsatisfiedLinkError: no tssx_cmpp in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491)
        at java.lang.Runtime.loadLibrary0(Runtime.java:788)
        at java.lang.System.loadLibrary(System.java:834)
        at JCMPP.<clinit>(JCMPP.java:27)
        at Test.main(Test.java:3)现在是找到共享库了,但调用不到它的方法?
晕死了!!!

解决方案 »

  1.   

    帖子要沉了,自己再顶一下,我怀疑在servlet中调用jni时,对jni有什么特殊要求,比如在编码上,或是.so库的存放地点上,继续测试中,谁能为我指点迷径呢!!!
      

  2.   

    楼上的兄弟,长归长,有用的就下面几句:
    root cause java.lang.UnsatisfiedLinkError: jCMPP_Connect
    at com.haoxi.hainanshow.cnative.JCMPP.jCMPP_Connect(Native Method)
    at com.haoxi.hainanshow.test.SMGTest2.doGet(SMGTest2.java:41)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
      

  3.   

    把你的库文件放到<TOMCAT_HONE>/bin目录下
      

  4.   

    Does anyone have any idea why I can load the .so but
    can't access the method?
     
      

  5.   

    Thanks for your help anyway!
      

  6.   

    to  usabcd(9号公路上的3名共军) :
    把你的库文件放到<TOMCAT_HONE>/bin目录下我去试试,可这有什么意义呢?另外:
    你的方法里出错了。注意C代码文件路径的使用是否正确。请问出错指的是什么呢,第一次遇到这样的问题,一直找不出原因。我的代码在命令行编译执行都没有问题,但在servlet中引用就不行!
      

  7.   

    我感觉代码出在环境变量上,但找不出具体原因,把变量贴出来,大家帮着看看:[willr@wap lib]$ echo $LD_LIBRARY_PATH
    .:/opt/jakarta-tomcat-4.1.30/webapps/hainanshow/WEB-INF/lib[willr@wap lib]$ echo $PATH
    /usr/kerberos/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/openssh3.8p1/bin:/usr/X11R6/bin:/usr/java/j2sdk1.4.2_04/bin:/opt/mysql/bin:.:/opt/jakarta-tomcat-4.1.30/webapps/hainanshow/WEB-INF/lib:/home/willr/bin[willr@wap lib]$ echo $classpath
    .:/usr/java/j2sdk1.4.2_04/lib:/usr/java/j2sdk1.4.2_04/jre/lib/:/opt/jakarta-tomcat-4.1.30/common/lib/[willr@wap lib]$ echo $CLASSPATH
    .:/usr/java/j2sdk1.4.2_04/lib:/usr/java/j2sdk1.4.2_04/jre/lib/:/opt/jakarta-tomcat-4.1.30/common/lib/
      

  8.   

    写了个小程序在命令行测试java.library.path的值:[willr@wap lib]$ more getLibraryPath.java 
    class getLibraryPath
    {
       public static void main(String[] args)
       {
          String path = System.getProperty("java.library.path");
          System.out.println(path);
       }
    }
    [willr@wap lib]$ java getLibraryPath
    /usr/java/j2sdk1.4.2_04/jre/lib/i386/client:/usr/java/j2sdk1.4.2_04/jre/lib/i386:/usr/java/j2sdk1.4.2_04/jre/../lib/i386:.:/opt/jakarta-tomcat-4.1.30/webapps/hainanshow/WEB-INF/lib
    [willr@wap lib]$
      

  9.   

    应该是设置classpath的问题吧,你在classpath里把那个本地的库指定到具体的文件名,不要指定到目录,试试
      

  10.   

    [willr@wap lib]$ ls /usr/java/j2sdk1.4.2_04/jre/lib/i386/client
    libjsig.so  libjvm.so  libtssx_cmpp.so  Xusage.txtlibtssx_cmpp.so 就是我想要调用的共享库,load成功,但调用其中的函数失败?  
      

  11.   

    CLASSPATH已经写成这样了:[tomcatadmin@wap bin]$ echo $classpath
    /usr/java/j2sdk1.4.2_04/jre/lib/i386/client/libtssx_cmpp.so:./:/usr/java/j2sdk1.4.2_04/lib:/usr/java/j2sdk1.4.2_04/jre/lib/:/opt/jakarta-tomcat-4.1.30/common/lib/[tomcatadmin@wap bin]$ echo $CLASSPATH
    /usr/java/j2sdk1.4.2_04/jre/lib/i386/client/libtssx_cmpp.so:./:/usr/java/j2sdk1.4.2_04/lib:/usr/java/j2sdk1.4.2_04/jre/lib/:/opt/jakarta-tomcat-4.1.30/common/lib/另,本地库的载入用的是用
    System.loadLibrary()或System.load方法,前者是在系统的环境变量LD_LIBRARY_PATH里找(直觉),后者是在指定的绝对路径里找。
    和classpath似乎没有太大关系:(LD_LIBRARY_PATH是操作系统的环境变量,是存放共享库的目录集合,java虚拟机的环境变量java.library.path和它的关系我还没太理清楚。如果不设置任何环境变量,可在命令行加参数指明库路径,如:
    java -Djava.library.path=. ClassName
      

  12.   

    java虚拟机的环境变量java.library.path应该是自己默认的地址列表加上操作系统环境变量LD_LIBRARY_PATH,如:
    java.library.path=$java.library.path:$LD_LIBRARY_PATH当然,这是个比喻,linux下java.library.path并不是个合法的shell变量名
      

  13.   

    to 0210(DBoy) :
    .so要按java规范写的我是按规范写的,为了这个,我研究了一些比较权威的资料。
    既然命令行下编译执行都没有问题,应该可以排除语法问题?public native int jCMPP_Disconnect(int conn_id);
    我的本地方法都是这么声明的,会有问题么?
    比如,在servlet中,只有声明成static才行?:
    public static native int jCMPP_Disconnect(int conn_id);纯属无助之时的呓语,没有根据,做不得书,胡乱猜想,也曾试过,编译执行过,好像问题不在这里
      

  14.   

    轻轻的舒一口气,感觉世界真美好。每每问题的解决,常要一瞬间灵感的闪现这个问题纠缠了我很久,但一开始我就用一个方法绕开了这个问题。
    可最终,当真正的技术问题都解决了之后,又回到了起点,一个不起眼的小问题,不想让我郁闷这么就,每次,想这该是尽头了,却总有新的问题。。这个问题遇到两个障碍,郁闷的是,第一个障碍掩盖了第二个障碍很久,成了盲点不但要对sun的官方文档熟悉,还要对操作系统本身熟悉,语言、一个规则的定义,习惯。。我不是一个c++程序员,更不是一个linux下的c++程序员。所以请大家记住,如果你以前不知道的话回头写篇文档把,感觉经历后,有很多细节的东西是什么狗屁官方文档都不会提到却会郁闷很多人的,我在国外的很多论坛上找到了很多和我同样的问题,可惜没有找到答案。。现在正忙,稍后我会把对jni的一点点心得写出来,供大家分享。感谢XDJM们的帮助!
      

  15.   

    感觉java和其他语言的交互,在掺杂着操作系统的问题,会遇到不少麻烦,
    现在有这样问题的朋友,可以直接发邮件给我,我们一起交流,尽我所能[email protected]