首页 > 解决方案 > 类 MyClass 不能转换为类 MyClass(MyClass 位于加载器 org.glassfish.[...].WebappClassLoader@1 的未命名模块中)

问题描述

为什么 Glassfish / Payara 应用程序服务器中有时会在部署阶段出现此错误?我可以猜测应用程序服务器正在尝试使用两个不同类加载器的两个不同类,但是有没有办法阻止它执行这种行为?

我试图在网上查找一些来源,但一无所获。

编辑:这在重新部署时发生在同一个应用程序上。它可以通过重新启动应用程序服务器来解决,但不知不觉这不是解决方案

java.lang.ClassCastException: class com.MyClass cannot be cast to class com.MyClass (com.MyClass is in unnamed module of loader org.glassfish.web.loader.WebappClassLoader@1, com.MyClass is in unnamed module of loader org.glassfish.web.loader.WebappClassLoader@2)

最后编辑,在斯蒂芬 C 的巨大反应之后。有什么工具可以理解为什么 Payara/GC 不破坏旧对象?

标签: javaclassloaderprofilerpayaraglassfish-5

解决方案


我可以猜测应用程序服务器正在尝试使用两个不同类加载器的两个不同类,但是有没有办法阻止它执行这种行为?

是的,这就是我认为正在发生的事情。如果相同.class的文件由不同的类加载器加载,则生成的运行时类型是不同的,并且不能通过强制转换。

有三种方法可以避免这种情况:

  1. 不要在不同的 webapps 之间传递或共享这些对象。

  2. 将定义需要共享的类的 JAR 移动到 Web 容器的共享库区域……以便它们由 Web 容器的类加载器而不是 Web 应用类加载器加载。

  3. 如果类需要由多个 webapp 类加载器加载(例如,因为它们具有相同的名称但实现不同),您可能需要重新架构您的应用程序,以便类实现由单个类加载器加载的公共接口。如果你的 webapp 代码只转换到共享接口,你就不会遇到这个问题。


如果 Web 应用程序相同怎么办?(所以当应用重新部署同一个应用时)

如果是这种情况,那么听起来问题在于您的 webapp 的关闭代码没有做正确的事情。由早期部署的 webapp 创建的 Java 对象正在泄漏到后面的部署中。

  • 检查某些东西是否没有缓存应用程序对象。
  • 检查应用程序对象是否没有隐藏在会话状态或线程本地,或类似的东西中。

推荐阅读