Java 在WildFly 8上检测webapp时出现VerifyError

Java 在WildFly 8上检测webapp时出现VerifyError,java,jboss,wildfly,instrumentation,Java,Jboss,Wildfly,Instrumentation,我目前正在做一个项目,试图在一个正在运行的webapp中插入额外的Log4j日志语句。为了实现这一点,我通过 启动WildFly时的JVM参数: -javaagent:path/to/agent.jar 代理的premain方法接收检测对象并为远程访问建立MBean。日志插入是使用工具和Javassist实现的。到目前为止,这是完美的。 然而,为了保持这种工作状态,agent.jar还必须在部署时驻留在webapp的WAR文件中,因为用于记录日志的log4j Logger类随此jar一起提供。

我目前正在做一个项目,试图在一个正在运行的webapp中插入额外的Log4j日志语句。为了实现这一点,我通过 启动WildFly时的JVM参数:

-javaagent:path/to/agent.jar
代理的premain方法接收检测对象并为远程访问建立MBean。日志插入是使用工具和Javassist实现的。到目前为止,这是完美的。 然而,为了保持这种工作状态,agent.jar还必须在部署时驻留在webapp的WAR文件中,因为用于记录日志的log4j Logger类随此jar一起提供。如果不是,则当检测API更新类定义时,我会得到一个VerifyError。但是,尝试通过插入“Math.random()”之类的代码从java.lang加载类,效果与预期一致。
需要注意的是,代理类是使用AppClassLoader加载的,AppClassLoader也是应用程序ModuleClassLoader的父级。 因此,我想知道为什么不能通过ModuleClassLoader通过委托加载驻留在agent.jar中的类。 这些观察结果让我认为webapp模块需要声明对外部JAR的显式依赖,即使父AppClassLoader知道这些类。对于安全问题,这对我来说是有意义的

有人能证实这些假设吗?或者有人有其他想法或经历导致这种行为的原因吗

谢谢

----------------编辑---------------------

使用WildFly类加载机制有助于我更详细地描述我的问题。假设我想在属于我的webapp的ManagedBean中使用ModuleClassLoader加载名为com.example.LoggerClass(驻留在agent.jar中!)的类:

Class<?> aClass = this.getClass().getClassLoader().loadClass("com.example.LoggerClass");
Class aClass=this.getClass().getClassLoader().loadClass(“com.example.LoggerClass”);
这将导致ClassNotFoundException! 但是手动将其委托给底层AppClassLoader非常有效:

Class<?> aClass = this.getClass().getClassLoader().getParent().loadClass("com.example.LoggerClass");
Class aClass=this.getClass().getClassLoader().getParent().loadClass(“com.example.LoggerClass”);
现在,关于ModuleClassLoader的loadClass方法的JBoss文档告诉我们:

查找一个类,可能委托给其他加载程序


这可以解释我在上面展示的行为,假设ModuleClassLoader由于安全问题而不委托类加载。在某些情况下,是否有任何方法可以重写此操作并使ModuleClassLoader委托给AppClassLoader?

系统类加载器始终加载Java代理。它的所有依赖项必须在类路径上可用。如果您遇到验证器错误,您的字节码是非法的,因为在加载完成之前进行了验证。这意味着,您的问题与类加载器无关。

Thx Rafael。当我开始寻找这个错误的原因时,我就是这么想的。但它仍然困扰着我,当我的agent.jar出现在WAR的lib目录中时,它可以完美地工作,否则就会失败。我还检查了加载premain类的类加载器,得到的是AppClassLoader。也许系统类加载器适用于SE环境?据我所知,
AppClassLoader
是系统类加载器的实现:-代理的类加载由不知道运行应用程序容器的虚拟机处理。应用程序容器应用子级优先策略以更好地封装webapp。我认为您需要查看modula类加载器的实现以了解发生了什么。ClassLoader.getSystemClassLoader()确认您的建议是正确的,谢谢Rafael!我认为这值得接受你的答案。