【问题标题】:Tomcat running in IntelliJ throws UnmarshalException在 IntelliJ 中运行的 Tomcat 抛出 UnmarshalException
【发布时间】:2021-11-15 00:41:24
【问题描述】:

我已经更改了一个 Java 类,该类作为 *.war 文件部署在 Weblogic Server 内部,以及 Tomcat 内部的 JSP gui 内部(“外部源”部署)。现在这个 Java 类收到了一个新的“serialVersionUID”,因为它是生成的代码。

看起来像这样:

private static final long serialVersionUID = -7417232213234280059L;

我在 maven 构建的 *.war 中发现了相同的生成代码,所以没问题。但是当我运行我的 Tomcat 并且应用程序使用相同的 java 类时,会抛出以下错误:

Caused by: java.io.InvalidClassException: mypackage.MyClass; local class incompatible: stream classdesc serialVersionUID = -7417232213234280059, local class serialVersionUID = -2801645274091928331
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:617)

我知道这听起来像是在 Weblogic 和 Tomcat 中拥有同一个类的两个不同版本,但是我怎样才能告诉我的 Tomcat 使用新类呢?

这些是我已经尝试过的步骤:

  • 全部重建
  • 使缓存无效并重新启动(经典)
  • 重启 IntelliJ(甚至是 Windows)
  • 将 Gui 项目部署为 WAR,我也尝试将其作为“外部源”(应始终使用最新代码)
  • Tomcat 上的“清除内容”(不管是什么,我不知道,没有文档)
  • 在特定项目和其他一切基础上重建
  • 启用设置中的自动构建项目选项
  • 删除了 C:\Users\MyUser\AppData\Local\JetBrains\IntelliJIdea2021.2\tomcat\9256eb14-078c-4ce4-a9fb-835adfd28d66\temp 文件夹,没有成功

即使我进行了新的更改,同一个项目也可以完美地与 Eclipse 配合使用。有没有办法告诉 IntelliJ 使用新代码?正如我已经提到的,“使缓存无效并重新启动”在这种情况下不起作用。

堆栈跟踪:

java.io.InvalidClassException: mypackage.MyClass; local class incompatible: stream classdesc serialVersionUID = -7417232213234280059, local class serialVersionUID = -2801645274091928331
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:617)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1622)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1622)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
    at java.util.ArrayList.readObject(ArrayList.java:771)
    at sun.reflect.GeneratedMethodAccessor64.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
    at weblogic.common.internal.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:120)
    at weblogic.rjvm.MsgAbbrevInputStream.readObject(MsgAbbrevInputStream.java:135)
    at weblogic.rmi.internal.ObjectIO.readObject(ObjectIO.java:56)
    at weblogic.rjvm.ResponseImpl.unmarshalReturn(ResponseImpl.java:164)
    ... 39 more

【问题讨论】:

  • 这只是意味着被序列化并写入磁盘的会话无法恢复。这是很正常的,因为你的一个班级发生了变化。您只需要再次登录您的应用程序。
  • 嗨 Piotr,我每次重新启动 Tomcat 时都会登录我的应用程序。似乎Tomcat在某处存储了与旧serialVersionUID相同的旧类,并在不重新编译的情况下重用它。我什至尝试添加类似于 Eclipse 中的“自动构建”选项的“自动构建项目”选项。没有成功。
  • 能否将错误的完整堆栈跟踪添加到问题中?
  • 当然,我添加了堆栈跟踪。
  • but how can I tell my Tomcat to use the new class? - 在您部署到 Tomcat 服务器的工件中检查此类。

标签: java tomcat intellij-idea


【解决方案1】:

在运行 Tomcat 的 Gui 应用程序内部是一个 WEB-INF/lib 文件夹。应用程序加载的库中仍有旧版本的代码。所以问题是一个遗留部署过程,它将库复制到这个文件夹。它在构建过程中未激活。无论如何,谢谢大家的帮助。

【讨论】:

    猜你喜欢
    • 2019-12-31
    • 2021-12-16
    • 2019-03-16
    • 2012-11-29
    • 2018-08-13
    • 2012-01-15
    • 2013-08-17
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多