gpt4 book ai didi

java - 无法为 tomcat jvm 公开 Java Instrumentation

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:15:37 24 4
gpt4 key购买 nike

我正在使用 tomcat7 实例来运行 Java 应用程序。我的应用程序需要公开 Java 检测。这是通过 javaagent 完成的,我在启动时将代理传递给 setenv.bat 脚本中的 JVM。

set JAVA_OPTS=%JAVA_OPTS% -javaagent:"C:\path\to\agent.jar"

在 list 文件中我有所需的部分:

Premain-Class: package.name.agent.ExposeInstrumentation

在代理类的 premain 方法中,将 JVM 提供的检测分配给可通过静态方法访问的静态变量

public final class ExposeInstrumentation {
private static Instrumentation s_instrumentation;
public static void premain(String arguments, Instrumentation instrumentation) {
s_instrumentation = instrumentation;
}

public static Instrumentation getInstrumentation() {
return s_instrumentation;
}
}

但是当我这样做时在我的代码中:

Instrumentation instrumentation = ExposeInstrumentation.getInstrumentation();

getInstrumentation() 返回空;

问题是什么?

更新

我做了一些进一步的调试并执行了 premain 并且 s_instrumentation 接收了检测,但是当我稍后在我的代码中调用 getInstrumentation 时,s_instrumentation 被设置为 null。这很奇怪,我认为该值在程序的生命周期内仍然有效。

最佳答案

我假设您正在加载类 ExposeInstrumentation 两次。一次是应用程序类加载器 child-first (reverse-order)一次是通过 Java 代理,类由系统类加载器自动加载。因此,ExposeInstrumentation 类被加载两次,您可以从未设置字段的应用程序访问该类。

您可以通过显式访问系统类加载器加载的类来解决这个问题:

class ExposeInstrumentation {

// public to assure accessability
public static Instrumentation s_instrumentation;

public static void premain(String arguments, Instrumentation inst) {
s_instrumentation = inst;
}

public static Instrumentation getInstrumentation() {
try {
return (Instrumentation) ClassLoader.getSystemClassLoader()
.loadClass(ExposeInstrumentation.class.getName())
.getDeclaredField("s_instrumentation")
.get(null);
} catch(Exception e) {
return null;
}
}
}

您还可以查看 Byte Buddy Agent project提供此功能和代理的更多(运行时安装)。使用 Byte Buddy,您只需调用 ByteBuddyAgent.getInstrumentation()

关于java - 无法为 tomcat jvm 公开 Java Instrumentation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36156352/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com