JBoss 类加载 IncompatibleClassChangeError

JBoss classloading IncompatibleClassChangeError

我正在将一个项目从 JBoss 5 迁移到 6.4。在此过程中,我更新了构建中的几个 jar 文件。我有几个 ClassCastExceptions,我通过从 JBoss 系统模块中的 jar 中获取特定 classes 的版本并在我的应用程序构建中使用它来解决这些异常。我用两个罐子 jbossweb-7.5.26.Final-redhat-1.jarjboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar 完成了此操作,它们分别包含 classes org.apache.catalina.connector.Requestjavax.servlet.http.HttpServletRequest。我在我的应用程序构建中将这两个 jar 用作库,并且所有编译都没有错误或警告。我已经确认,当我删除这些库时,应用程序无法编译,因为它找不到包含的引用 classes,所以我知道我实际上并没有引用那些 class 的其他副本es 在我的构建中。该应用程序部署正常,但当我尝试点击它时出现异常

JBWEB001018: An exception or error occurred in the container during the request processing: java.lang.IncompatibleClassChangeError: Class org.apache.catalina.connector.Request does not implement the requested interface javax.servlet.http.HttpServletRequest

当我在编辑器 (JDeveloper 12c) 中查看 jars 中的 class 定义时,我可以看到 jbossweb-7.5.26.Final-redhat-1 中定义的 org.apache.catalina.connector.Request 实际上实现了 javax.servlet.http.HttpServletRequestjboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar 中所定义。

我打开了 class 加载的详细日志记录(JAVA_OPT -verbose:class),并确认 JBoss 正在加载这两个 class 是的,它们实际上是从这两个 jar 文件中加载的,而不是我不知道的其他文件。我可以在我的开发人员工具中看到我在我的项目中包含的 .class 文件来自这两个相同的 jar 文件。

可能相关,class加载日志显示 JBoss 正在从 RedHat/JBoss/EAP-6.4.0/modules/system/layers/base/.overlays/layer-base-jboss-eap-6.4.18.CP/org/jboss/as/web/main/ 加载 org.apache.catalina.connector.Request。我不确定为什么它使用 copy/location 而不是 RedHat\JBoss\EAP-6.4.0\modules\system\layers\base\org\jboss\as\web\main.

那么是什么原因呢?我在错误中读到的内容向我表明 jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar 是针对与 jbossweb-7.5.26.Final-redhat-1 包含的不同版本的 HttpServletRequest 编译的。

这种解释或错误是正确的吗? JBoss 6.4 是否真的在其系统模块中附带了不兼容的 jar 文件?如果是这样,我需要这些罐子的什么版本以及如何检查兼容性?我可以安全地切换到不同的 jar 文件而不引入更多与其他 jar 的不兼容性吗?我可能会遗漏哪些其他原因?非常感谢任何帮助。

1/ 你不应该依赖 servlet API 实现 2 / 你不应该在你的应用程序中包含那些实现 类 它们是由服务器本身提供的 3/ 你不应该在你的应用程序中放置 API 罐子或它们的实现,或者如果你这样做你需要使用 jboss-deployment.xml[=10= 从你的应用程序中排除这些模块]

看来问题是我没有正确使用 modules.xml。我需要在 module.xml 文件

中为这两个包添加依赖项
   <dependencies>
      <module name="org.jboss.as.web"/>
      <module name="javax.servlet.api"/>
   </dependencies>

我之前已将这些模块添加到我的 war 文件的 jboss-deployment-structure.xml 中,但这并没有起到作用,给我留下了 ClassNotFoundExceptions。我的 Jboss-deployment-structure.xml 现在只引用我自己的自定义模块作为依赖项,而后者又具有自己的依赖项。

我仍然不明白是什么导致了之前的错误,因为它们都是有问题的 jar 文件的相同版本,所以我不知道冲突在哪里,但这让错误消失了并且不再有 ClassNotFoundExceptions。