我有一个小应用程序,它使用Attach API在运行时修改某些第三方类。唉,我遇到了一个大问题:Attach API只附带JDK。我可以从JDK复制并添加到我的项目中的必要文件,但负责此的库(附。(dll | so))我不能。这是因为我必须从jar中的资源复制attach.lib,并将其放在JRE / lib目录中。
如果用户不是Linux计算机上的root用户就无法运行的操作,因此失去了对很多用户的兼容性(因为这个应用程序应该在服务器上运行,并且大多数服务器都是Linux,并且我不能确定所有人都是根)
我调查了所有负责附加API的类(VirtualMachine,AttachProvider等),但没有找到加载库的地方。
有可能这样做吗?我的意思是,我可以在JDK安装之外使用Attach API吗?如果是这样,怎么样?
答案 0 :(得分:1)
您可以通过修改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
已缓存,需要反映才能清除缓存。
答案 1 :(得分:0)
据我所知,您需要运行应用程序,以便在JDK(而不是JRE)中执行“附加”操作。通过这样做,您无需担心提供Attach API或其依赖项 - 因为它们都是由JDK提供和管理的。也就是说,这样做不应该有任何“根”问题 - 因为您可以像任何用户一样提取和运行/使用JDK(它不必以“root”身份安装/执行)。也就是说,您只需确保执行附加程序和附加程序的程序作为相同的OS用户运行,以免遇到安全限制。
答案 2 :(得分:0)
我们的经验是,如果没有完整的JDK,就没有可靠的方法来使用attach API。这在Windows上尤其严重。您可能会让它工作,但您可能想要查看普通的旧JMX。