无法公开tomcat jvm的Java检测
我正在使用tomcat7实例来运行Java应用程序。我的应用程序需要公开Java工具。这是通过javaagent完成的,我在启动时通过setenv.bat脚本将代理传递给JVM无法公开tomcat jvm的Java检测,java,tomcat,instrumentation,javaagents,Java,Tomcat,Instrumentation,Javaagents,我正在使用tomcat7实例来运行Java应用程序。我的应用程序需要公开Java工具。这是通过javaagent完成的,我在启动时通过setenv.bat脚本将代理传递给JVM set JAVA_OPTS=%JAVA_OPTS% -javaagent:"C:\path\to\agent.jar" 在清单文件中,我有必要的部分: Premain-Class: package.name.agent.ExposeInstrumentation 在代理类的premain方法中,将JVM提供的工具分配
set JAVA_OPTS=%JAVA_OPTS% -javaagent:"C:\path\to\agent.jar"
在清单文件中,我有必要的部分:
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()返回null
有什么问题
更新
我做了一些进一步的调试,并执行了premain,s_instrumentation收到了该指令,但是当我稍后在代码中调用getInstrumentation时,s_instrumentation被设置为null。这很奇怪,我认为该值在程序的生命周期内仍然有效。我假设您正在加载类
ExposeInstrumentation
两次。一次由应用程序类加载器加载,一次通过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,您只需调用
ByteBuddyAgent.getInstrumentation()
您的premain
方法是否实际被调用?premain被执行,但我没有得到任何指令……是否有方法阻止应用程序类加载器加载ExposeInstrumentation,使其不会被加载两次?应该是loadClass
而不是findClass
。通过将ExposeInstrumentation类放入其自己的模块中,并为web应用程序声明提供的作用域依赖项,可以防止重复加载。只要附加了代理,这就可以工作。