访问javaagent

时间:2015-07-02 17:42:01

标签: java tomcat servlets bytecode javaagents

我正在尝试通过-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 /服务/ javax.servlet.ServletContainerInitializer

org.example.MyInitializer

结果是ClassNotFoundException,因为找不到ServletContainerInitializer。

有没有办法在javaagent中访问servlet-api?或者更一般地说,是否可以访问通过ApplicationClassLoader加载的任何类,比如spring框架中的类?

2 个答案:

答案 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;

https://github.com/presci/MyAgent.git