日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java.library.path属性在代码中设置不生效问题

發布時間:2024/4/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java.library.path属性在代码中设置不生效问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?http://www.blogjava.net/gembin/archive/2008/10/29/237377.html

from http://daimojingdeyu.blogbus.com/logs/28617218.html



可是在使用上面文章介紹的動態庫時,遇上了加載問題,也就是將動態庫放到什么位置合適?文章中說可以放到System32目錄,但我不想這樣做,我更希望的是可以自己定制dll庫的位置~~

沒有將lib放到System32目錄,而是放到了自己的lib目錄,程序在啟動的過程中會報下面的錯誤:
java.lang.UnsatisfiedLinkError: no JIntellitype in java.library.path

根據上面的提示信息在VM參數處通過-Djava.library.path將加載路徑指定到自己的lib目錄后,程序可以正常啟動。

這種方式不是太好,因為要手動的去指定虛擬機參數,于是想通過System類的setProperty函數來在代碼中動態的改變一下java.library.path的值。
使用

Java代碼
  • System.setProperty("java.library.path",?"./lib");??
  • System.setProperty("java.library.path", "./lib");


    后,啟動程序總是報錯"no JIntellitype in java.library.path"

    想了半天沒有想明白,為什么代碼的設置就不起作用,而在虛擬機參數處指定就是好的?

    Google了半天才知道原因,這里整理一下,以方便以后查找。
    代碼中設置不起作用,主要是因為java.library.path只在jvm啟動時讀取一次,其他情況下的修改不會起作用的。可以參考下面的這個bug:
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4280189

    原因和ClassLoader的實現有關系,
    ClassLoader.loadLibrary() method:

    Java代碼
  • if?(sys_paths?==?null)?{??
  • ????????usr_paths?=?initializePath("java.library.path");??
  • ????????sys_paths?=?initializePath("sun.boot.library.path");??
  • }??
  • if (sys_paths == null) { usr_paths = initializePath("java.library.path"); sys_paths = initializePath("sun.boot.library.path"); }



    系統緩存了java.library.path的值,并且一直都會是第一次加載時的值。有人提到了下面的修改方法,

    Java代碼
  • if?(sys_paths?==?null)?{??
  • ???????sys_paths?=?initializePath("sun.boot.library.path");??
  • }??
  • usr_paths?=?initializePath("java.library.path");??
  • if (sys_paths == null) { sys_paths = initializePath("sun.boot.library.path"); } usr_paths = initializePath("java.library.path");


    但是從2002年到現在Sun一直都沒有改,不知道出于什么原因考慮的。

    有問題,就會有人解決問題,antony_miguel在一篇文章中,使用java的反射機制,完成了對于ClassLoader類中的usr_paths變量的動態修改,

    Java代碼
  • public?static?void?addDir(String?s)?throws?IOException?{??
  • ????try?{??
  • ????????Field?field?=?ClassLoader.class.getDeclaredField("usr_paths");??
  • ????????field.setAccessible(true);??
  • ????????String[]?paths?=?(String[])field.get(null);??
  • ????????for?(int?i?=?0;?i?<?paths.length;?i++)?{??
  • ????????????if?(s.equals(paths[i]))?{??
  • ????????????????return;??
  • ????????????}??
  • ????????}??
  • ????????String[]?tmp?=?new?String[paths.length+1];??
  • ????????System.arraycopy(paths,0,tmp,0,paths.length);??
  • ????????tmp[paths.length]?=?s;??
  • ????????field.set(null,tmp);??
  • ????}?catch?(IllegalAccessException?e)?{??
  • ????????throw?new?IOException("Failed?to?get?permissions?to?set?library?path");??
  • ????}?catch?(NoSuchFieldException?e)?{??
  • ????????throw?new?IOException("Failed?to?get?field?handle?to?set?library?path");??
  • ????}??
  • }??
  • public static void addDir(String s) throws IOException { try { Field field = ClassLoader.class.getDeclaredField("usr_paths"); field.setAccessible(true); String[] paths = (String[])field.get(null); for (int i = 0; i < paths.length; i++) { if (s.equals(paths[i])) { return; } } String[] tmp = new String[paths.length+1]; System.arraycopy(paths,0,tmp,0,paths.length); tmp[paths.length] = s; field.set(null,tmp); } catch (IllegalAccessException e) { throw new IOException("Failed to get permissions to set library path"); } catch (NoSuchFieldException e) { throw new IOException("Failed to get field handle to set library path"); } }


    文章也同時指出了這種實現的局限性,和jvm的實現強關聯,只要jvm實現不是用的變量usr_paths來保存java.library.path的值,這個方法就不能用了。
    但是只要知道源代碼,小小的改動就應該可以實現了。

    總結

    以上是生活随笔為你收集整理的java.library.path属性在代码中设置不生效问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。