• java如何修改java.library.path并且不重启jvm也能生效


    先说一下需求吧,

    目前在用JCEF实现java程序桌面版包装,源码中需要加载编译好的几个dll文件,而这些文件的路径必然是根据程序安装的路径而变化的,这就需要在程序运行的时候,去动态修改java.library.path来实现dll文件的加载

    最开始的时候,我想到了System.setProperty();但是不管怎么试,都没办法动态加载进来,后来google了一下,发现这个方法需要重启JVM才行,原因看下面这段代码:

    if (sys_paths == null) {
                usr_paths = initializePath("java.library.path");
                sys_paths = initializePath("sun.boot.library.path");
            }

    这段代码在ClassLoader类,loadLibrary方法中,这段代码的意思很好理解,sys_paths为null的时候会去加载一次变量,也就是说JVM启动后就不可能再去加载,既然不能直接用System.setProperty();那就只能另寻他路,我开始在网上找资料,不难找到很多博客(原创或转载)提供了一种方法,代码如下:

     private static void addLibraryDir(String libraryPath) throws Exception {
    	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 (libraryPath.equals(paths[i])) {
    			return;
    		}
    	}
    	String[] tmp = new String[paths.length + 1];
    	System.arraycopy(paths, 0, tmp, 0, paths.length);
    	tmp[paths.length] = libraryPath;
    	field.set(null, tmp);
    }

    我用这种方法,把我的路径加进去了,但是在实际加载的时候,仍然找不到,这就有点尴尬了,我怀疑是不是自己的代码出错了,还是加路径的位置不对,但是尝试了N久,该方法始终无法跑通,也许是小弟资质略差,如有幸有大神看到此处,还望指点迷津


    既然此路不通,咱也不能在一棵树上吊死不是,另寻他路,英文蹩脚的我无奈实处必杀技,在google上开始搜索英文资料,google搜索 “java modify java.library.path at runtime” 没想到第一条搜索就解决了我的问题!!!!!!

    changing-java-library-path-at-runtime

    该博客的第一个方法,还是最上面那两行代码,还是那个位置,该博客博主的方法就是设置sys_paths为null,既然每次只有在null的时候会初始化,那你何不设置路径后,重新置为null,让他下次执行的时候继续初始化呢?年少的我还是有很多路要走啊,这么看似简单的想法,居然一直没有想到,惭愧...

    借鉴该方法,最后代码如下:

    private static void addLibraryDir(String libraryPath) throws Exception {
    	Field userPathsField = ClassLoader.class.getDeclaredField("usr_paths");
    	userPathsField.setAccessible(true);
    	String[] paths = (String[]) userPathsField.get(null);
    	StringBuilder sb = new StringBuilder();
    	for (int i = 0; i < paths.length; i++) {
    		if (libraryPath.equals(paths[i])) {
    			continue;
    		}
    		sb.append(paths[i]).append(';');
    	}
    	sb.append(libraryPath);
    	System.setProperty("java.library.path", sb.toString());
    	final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
    	sysPathsField.setAccessible(true);
    	sysPathsField.set(null, null);
    }

    好了,问题完美解决,心中一块石头落地,中午又可以多吃两块肉了,哈哈~~

     该文章最新发表于CSDN博客,后为推广,在博客园发表一份,文章为原创兼翻译,转载请注明出处,谢谢!

  • 相关阅读:
    python作业堡垒机(第十三周)
    Python的一个BOX
    Nginx (限速)限制并发、限制访问速率、限制流量
    Nginx反向代理维基百科镜像制作全解析
    防盗链测试01
    Pycharm和IntelliJ IDEA激活 2017.3.x版本
    [Openwrt 扩展下篇] Openwrt搭建私有云Owncloud 9
    [Openwrt扩展中篇]添加Aria2和webui
    [Openwrt 扩展上篇]USB挂载&U盘启动&Samba共享
    python作业(第十一周)基于RabbitMQ rpc实现的主机管理
  • 原文地址:https://www.cnblogs.com/minteliu/p/5829061.html
Copyright © 2020-2023  润新知