我有一个小型应用程序,它使用 Attach API 在运行时修改一些第三方类。唉,我遇到了一个大问题:Attach API 仅随 JDK 提供。我可以从 JDK 复制必要的文件并将其添加到我的项目中,但负责此操作的库(attach.(dll|so))我不能。这是因为我必须从 jar 内的资源复制attach.lib,并将其放入 JRE/lib 目录中。
如果用户不是 Linux 计算机上的 root 用户,该操作将不起作用,因此会失去对许多用户的兼容性(因为此应用程序应该在服务器上运行,而大多数服务器都是 Linux,我无法确定所有服务器都是 root 用户)
我查看了所有负责附加 API 的类(VirtualMachine、AttachProvider 等),但没有找到加载库的位置。
可以这样做吗?我的意思是,我可以在 JDK 安装之外使用 Attach API 吗?如果是这样,怎么办?
请您参考如下方法:
您可以通过修改java.library.path
来实现:
static void addToLibPath(String path) throws NoSuchFieldException,
SecurityException,
IllegalArgumentException,
IllegalAccessException
{
if (System.getProperty("java.library.path") != null) {
// If java.library.path is not empty, we will prepend our path
// Note that path.separator is ; on Windows and : on Unix-like,
// so we can't hard code it.
System.setProperty("java.library.path",
path + System.getProperty("path.separator")
+ System.getProperty("java.library.path"));
} else {
System.setProperty("java.library.path", path);
}
// Important: java.library.path is cached
// We will be using reflection to clear the cache
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);
}
调用addToLibPath("path")
会将"path"
添加到java.library.path
。
请注意,java.library.path
已被缓存,需要反射来清除缓存。