我正在尝试通过-javaagent:my-agent.jar标志添加到我的应用程序中的javaagent jar中的servlet-api中访问类。我的应用程序在Tomcat上运行。问题是我得到了一个ClassNotFoundException,因为代理jar是由一个无法访问servlet-api类的类加载器加载的。
更具体地说,我想在我的javaagent
中包含一个ServletContainerInitializerpublic class MyInitializer implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
System.out.println(ctx);
}
}
META-INF /服务/ javax.servlet.ServletContainerInitializer
org.example.MyInitializer
结果是ClassNotFoundException,因为找不到ServletContainerInitializer。
有没有办法在javaagent中访问servlet-api?或者更一般地说,是否可以访问通过ApplicationClassLoader加载的任何类,比如spring框架中的类?
答案 0 :(得分:1)
如果您的座席有premain
方法,其签名类似
public static void premain(String agentArgs, Instrumentation inst)
您可以使用Instrumentation
对象,该对象提供方法getAllLoadedClasses()
和getInitiatedClasses(ClassLoader)
。现在每次搜索这些数组并通过反射仅使用Class
实例会很尴尬。但是,您可以使用这些方法来查找所需的API类,确定其运行时ClassLoader
并创建一个新的ClassLoader
,将其用作解析父级并指向需要它们的代理类。
答案 1 :(得分:0)
对我来说有用的是我在ClassPool.insertClassPath中添加了servlet-api.jar文件。这解决了这个问题。
ClassPool $pool = ClassPool.getDefault();
try {
$pool.insertClassPath("/apache-tomcat-7.0.50/lib/servlet-api.jar");
} catch (NotFoundException e) {
throw new RuntimeException(e);
}
return $pool;