2

我有一个小应用程序,它使用 Attach API 在运行时修改一些第三方类。唉,我遇到了一个大问题:Attach API 只随 JDK 一起提供。我可以从 JDK 复制必要的文件并添加到我的项目中,但是负责这个的库(附加。(dll|so))我不能。这是因为我必须从 jar 内的资源中复制 attach.lib,并将其放在 JRE/lib 目录中。

如果用户不是 Linux 机器上的 root 用户,则该操作将不起作用,因此失去对许多用户的兼容性(因为该应用程序应该在服务器上运行,并且大多数服务器都是 Linux,我不能确定都是root)

我查看了所有负责附加 API 的类(VirtualMachine、AttachProvider 等),但没有找到加载库的地方。

是否有可能做到这一点?我的意思是,我可以在 JDK 安装之外使用 Attach API 吗?如果是这样,怎么做?

4

3 回答 3

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是缓存的,需要反射才能清除缓存。

于 2012-09-09T22:53:27.510 回答
0

据我所知,您需要运行希望从 JDK(而不是 JRE)中执行“附加”的应用程序。通过这样做,您无需担心提供 Attach API 或其依赖项——因为它们都是由 JDK 提供和管理的。也就是说,您不应该对此有任何“root”问题 - 因为您可以以任何用户身份提取和运行/使用 JDK(不必以“root”身份安装/执行)。也就是说,您只需要确保执行附加的程序和所附加的程序以相同的操作系统用户身份运行,以免遇到安全限制。

于 2012-09-08T02:28:28.617 回答
0

我们的经验是,如果没有完整的 JDK,就没有可靠的方法来使用附加 API。这在 Windows 上尤其严重。您可能会让它工作,但您可能想要查看普通的旧 JMX。

于 2012-09-09T22:56:57.730 回答