class MyClass 无法转换为 class MyClass(MyClass 在加载器 org.glassfish.[...].WebappClassLoader@1 的未命名模块中)

class MyClass cannot be cast to class MyClass (MyClass is in unnamed module of loader 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)

最后一次编辑,在 Stephen C. 有什么工具可以理解为什么 Payara/GC 不破坏旧对象?

I can guess that the application server is trying to use two different classes of two different classloaders but is there a way to prevent it to do this behavior?

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

可以通过三种方式避免这种情况:

  1. 不要在不同的网络应用程序之间传递或共享这些对象。

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

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


What if the web app is the same? (so when the application redeploy the same app)

如果是这样,那么问题似乎出在您的网络应用程序的关闭代码没有做正确的事情。 Java 较早部署的 webapp 创建的对象正在泄漏到较晚的部署中。

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