zoukankan      html  css  js  c++  java
  • 在tomcat下使用jni加载本地库的问题总结——处理UnsatisfiedLinkError错误

    最近想使用ICTCLAS分词系统,需要在myeclipse中加载dll(本地库),查阅资料使用jni,ICTCLAS官方也提供了很全面的加载方法,虽然在run as java application下运行没有问题,但是在tomcat下报UnsatisfiedLinkError的错误,错误来自System.loadLibrary("ICTCLAS50"),是jni加载本地库的语句。

    之前其实为了省事将dll放在根目录下,显然也不符合tomcat的要求,重新移动到webapps下,想将ICTCLAS.dll所在的目录添加到java.library.path中去:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <span style="font-size:14px;">String path = "";  
    2. try {  
    3.             path = PublicMethod.getAbsolutePath()+"configure";  
    4.         } catch (URISyntaxException e) {  
    5.             e.printStackTrace();  
    6.         }  
    7.   
    8.         path += System.getProperty("java.library.path");  
    9.         System.setProperty("java.library.path", path);  
    10. //      System.out.println(System.getProperty("java.library.path"));  
    11.         System.loadLibrary("ICTCLAS50");</span>  

    同样报错,郁闷(后来得知想代码修改java.library.path是不可实现的 http://blog.csdn.net/xiaolang85/article/details/3604971 )

    然后用过几个小方法,比如修改文件权限、修改路径斜杠。

    大多数情况下tomcat的服务器都是租来的,所以涉及到你能否将你的dll放到tomcat的bin目录下面的问题,大多数情况下是不可能的。

    最后用神奇的System.load(dll的绝地路径):

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <span style="font-size:14px;">String path = "";  
    2.         try {  
    3.             path = PublicMethod.getAbsolutePath()+"configure";  
    4.         } catch (URISyntaxException e) {  
    5.             e.printStackTrace();  
    6.         }  
    7.         System.load(path+"/ICTCLAS50.dll");</span>  

    System.load()是加载dll的另一个方法,避免了查找java.library.path,注意此处的PublicMethod.getAbsolutePath()是自己写的一个获取tomcat运行目录的绝对路径的方法

    值得一提的是如果你想加载jar包中的dll,可以参加以下代码:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
      1. try   
      2. {   
      3. //Finds a stream to the dll. Change path/class if necessary   
      4. InputStream inputStream = getClass().getResource("/jacob.dll").openStream();   
      5. //Change name if necessary   
      6. File temporaryDll = File.createTempFile("jacob", ".dll");   
      7. FileOutputStream outputStream = new FileOutputStream(temporaryDll);   
      8. byte[] array = new byte[8192];   
      9. for (int i = inputStream.read(array); i != -1; i = inputStream.read(array)) {   
      10. outputStream.write(array, 0, i);   
      11. }   
      12. outputStream.close();   
      13. temporaryDll.deleteOnExit();   
      14. System.load(temporaryDll.getPath());   
      15. return true;   
      16. }   
      17. catch(Throwable e)   
      18. {   
      19. e.printStackTrace();   
      20. return false;   
      21. }  
  • 相关阅读:
    常用的学生、课程、成绩、教师表的查询
    flutter 自定义TabBar
    Flutter 设置input边框
    Flutter ReorderableListView 可拖拽的列表
    Flutter NotificationListener 监听列表的滚动
    Flutter 使用Tabbar不要Title
    Nestjs 验证对象数组
    postman 发送数组
    JS面向切面编程AOP
    什么是匿名函数、什么是闭包函数?
  • 原文地址:https://www.cnblogs.com/chbjaycn/p/3840110.html
Copyright © 2011-2022 走看看