我正在尝试从通过 -javaagent:my-agent.jar 标志添加到我的应用程序的 javaagent jar 中的 servlet-api 访问类。我的应用程序在 Tomcat 上运行。问题是我得到了一个 ClassNotFoundException,因为代理 jar 是由一个无法访问 servlet-api 类的类加载器加载的。
更具体地说,我想在我的 javaagent 中包含一个 ServletContainerInitializer
public class MyInitializer implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
System.out.println(ctx);
}
}
META-INF/services/javax.servlet.ServletContainerInitializer
org.example.MyInitializer
结果是 ClassNotFoundException,因为找不到 ServletContainerInitializer。
有什么方法可以在 javaagent 中访问 servlet-api?或者更一般地说,是否可以访问通过 ApplicationClassLoader 加载的任何类,例如来自 spring 框架的类?
最佳答案
如果您的代理有一个 premain
方法,其签名如下
public static void premain(String agentArgs, Instrumentation inst)
你得到一个Instrumentation
提供方法的对象 getAllLoadedClasses()
和 getInitiatedClasses(ClassLoader)
.现在每次都搜索这些数组并仅通过反射使用 Class
实例会很尴尬。但是您可以使用这些方法找到所需的 API 类,确定其运行时 ClassLoader
并创建一个新的 ClassLoader
将其用作解析父级并指向需要的代理类他们。
关于java - 在 javaagent 中访问 servlet-api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31191202/