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

翻译 2016年08月31日 10:32:12

先说一下需求吧,

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


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

</pre><pre name="code" class="java">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);
	}
好了,问题完美解决,心中一块石头落地,中午又可以多吃两块肉了,哈哈~~


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

前两天想的屏幕抓图的程序,想给加个系统全局的热键,也就是说,在程序不处于当前激活下也可响应键盘事件。通过java自己应该是实现不了了。 想到使用JNI,还好找到一篇介绍使用JIntellitype...
  • hjxhjh
  • hjxhjh
  • 2013年08月11日 15:43
  • 1851

在java程序中动态设置java.library.path

最近在做一个项目的过程中需要用到第三方的jar包和动态链接库(dll),其中jar包可以直接引入,问题是在开发的时候dll可以放在System32下, 但是当项目完成后build的时候,这种方式就行不...
  • canlets
  • canlets
  • 2014年11月28日 11:01
  • 9199

c#不重启电脑修改环境变量生效

  • 2013年12月30日 10:51
  • 16KB
  • 下载

VC编程获取和修改环境变量,不重启系统即时生效

方法1:getenv,putenv只影响当前进程的环境块。 // 头文件: #include    // 功能: 把字符串加到当前环境中    // 用法: int putenv(char *e...
  • dj0379
  • dj0379
  • 2012年08月29日 16:28
  • 9798

详解Windows不重启使环境变量修改生效(经典)

http://hi.baidu.com/xckouy/item/ff135263dfd92a97c4d2496b 在“我的电脑”->“属性”->“高级”->“环境变量”中增加或修改环...
  • shuixin536
  • shuixin536
  • 2012年10月18日 11:05
  • 36471

修改java 不重启tomcat

  • 2012年03月06日 09:49
  • 2.88MB
  • 下载

Java开发Web程序中修改类文件和配置文件不重启服务器的方法

  • 2012年03月13日 11:19
  • 84KB
  • 下载

Java开发Web程序中修改类文件和配置文件不重启服务器的方法

  • 2010年03月29日 10:45
  • 121KB
  • 下载

maven - java修改 不重启 服务器

java 不重启 服务器          今天发现一个很NB的玩意,让我们在开发的时候修改Java文件,不用重启服务器立刻生效!支持Jetty tomcat jboss等很多服务器...
  • eidolon8
  • eidolon8
  • 2012年03月21日 17:36
  • 1066

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

前两天想的屏幕抓图的程序,想给加个系统全局的热键,也就是说,在程序不处于当前激活下也可响应键盘事件。通过java自己应该是实现不了了。 想到使用JNI,还好找到一篇介绍使用JIntellitype...
  • hjxhjh
  • hjxhjh
  • 2013年08月11日 15:43
  • 1851
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java如何修改java.library.path并且不重启jvm也能生效
举报原因:
原因补充:

(最多只允许输入30个字)