【问题标题】:Differences when running Tomcat from within Intellij IDEA?从 Intellij IDEA 中运行 Tomcat 时的差异?
【发布时间】:2023-03-12 17:32:01
【问题描述】:

在 Tomcat (6.0.32) 中运行的 Spring 3.5、Webflow 2.2 应用程序有一个非常奇怪的问题

部分 webflow 调用以检索对象列表。此列表放置在 viewScope 对象中以供 JSP 视图使用。此列表中的每个对象都继承自包含一些公共字段的基类。

然后,webflow 转发到一个 JSP 视图,该视图通过写出所有对象来显示该列表的内容。

当我从独立的 Tomcat 运行它时,基类上的字段都以某种方式设置为 null。我已经调试并确认列表是从 webflow 调用的代码正确构建的。因此,在将列表放入 webflow 视图范围和稍后由 JSP 检索之间的某个位置,基类字段被重置为 null。

问题的真正奇怪的部分是,如果我从 Intellij IDEA 中启动并运行 Tomcat,应用程序会完美运行。我尝试了各种 JDK 和 Tomcat 版本,并且都有相同的问题。

这似乎是一个 webflow 问题(可能是不正确的序列化?),它对 Tomcat 是否从 IntelliJ 中启动很敏感。

IntelliJ 做了什么会导致 Java 序列化行为不端?

【问题讨论】:

  • 另外 - 如果某个善良的灵魂可以指出 Spring Webflow 源代码中的类处理序列化/反序列化对象进出视图范围的处理,那将非常有用。谢谢。
  • 这似乎是一个序列化错误。 Spring SerializedFlowExectionSnapshot 对象包含一个字节数组,其中包含 flowExecutionData - 视图/流范围内所有内容的序列化形式。当错误很明显时,此数组比错误未显示时小。部分数据丢失!

标签: java serialization tomcat intellij-idea spring-webflow


【解决方案1】:

嗯,我还没有找到确切的根本原因,但我确实有一个解决方法。我只是在神秘地没有正确序列化的对象上实现了自定义对象序列化方法 - private void writeObject() 和 readObject(),然后一切都开始工作了。基类中只有几个简单的类型(几个 long 和一个 String),所以并不复杂。

只是为了澄清(以防有人感兴趣)-我的网络应用程序中有一个表单使用的数据对象。该对象包含属性对象的映射,其中每个属性对象都基于类层次结构,如下所示:

属性类->共享基类->根基类

所有这些数据都被 Spring web-flow 持久化到一个字节数组中,然后在 web-flow 调用视图时取消持久化。在我的例子中,根基类的字段没有被默认机制持久化。

我仍然不知道确切的原因。而且我仍然不知道为什么,当我从 IntelliJ 中启动 Tomcat 时,序列化按预期工作。很奇怪。


更新:找到了罪魁祸首。一个非常糟糕的 Ant 构建脚本,隐藏了一个缺失的“可序列化”接口标记。

所讨论的系统实际上相当大,并且有一个讨厌的、难以遵循的 Ant 构建脚本。我以为它正在做一个完整的、适当的干净构建。在我上面展示的类层次结构中,Attribute 类和 Root Base Class 位于不同的 jar 中。包含根基类的 jar 实际上被缓存并且没有正确重建。

正在部署的旧(不正确)版本的基类没有“可序列化”标记接口(Attribute 类有)。所以当然,它的字段没有被序列化。当我在 IntelliJ 中进行测试时,它直接从我的源代码进行构建和部署。

我现在真的很笨。

【讨论】:

    【解决方案2】:

    当我使用 IDE 构建 WAR 时,我已经在各种 IDE 中看到过这种现象,并且在 IDE 中运行时,它使用的缓存类与在 IDE 之外运行时使用的缓存类不同。要缩小现象范围,请尝试以下方法:

    如果您还没有,请为您的项目创建一个 Ant 或 Maven 构建。清理所有 .class 文件和其他工件,关闭 intellij,使用 Ant 或 Maven 构建 WAR,然后尝试将其部署到 Tomcat。看看你是否有奇怪的行为。

    接下来,尝试在 Intellij 中启动 Tomcat 服务器,但不要从 Intellij 中将应用程序部署到它。通过将您的战争放到文件系统上的 Intellij Tomcat 实例中,将您的应用程序从外部部署到它。

    最后,不要从 Intellij 中启动 Tomcat,而是在外部启动它并使用远程调试连接到它,然后查看是否出现问题。远程调试的配置方法如下:http://wiki.apache.org/tomcat/FAQ/Developing

    【讨论】:

    • 感谢 cmets,但问题是什么很清楚 - IntelliJ 似乎神奇地“修复”了这个错误。如果我使用 Ant 脚本进行干净的构建并部署到独立的 Tomcat,我会得到错误(如果我附加远程调试会话,可以看到它本身就显现出来)。如果我从 IntelliJ 中启动 Tomcat,则该错误不会发生。据我所知,IntelliJ 生成了一个新的 CMD.EXE 来启动 Tomcat,唯一的运行时差异是附加的 Groovy jar 作为代理进行热重新部署。我很困惑这会如何影响类的序列化。
    • 不是 IDE 错误地缓存了类,而是一个讨厌的 Ant 构建。否则,你是对的......
    猜你喜欢
    • 2013-08-17
    • 2021-12-16
    • 2016-04-29
    • 2019-05-25
    • 2022-12-22
    • 2017-01-18
    • 2012-04-07
    • 2017-12-24
    • 1970-01-01
    相关资源
    最近更新 更多