7

在设置集群期间,我遇到了 WildFly/Infinispan 尝试序列化许多可以在每个实例上重新创建的类的问题——尽管无论出于何种原因,它们似乎决定在集群中分布。

最初我认为@Stateless 注释会产生我想要的效果,尽管它会因为没有正确的构造函数而引发问题,所以我不相信这就是我们正在寻找的。

在每个类的基础上禁用此功能或覆盖序列化方法的正确方法是什么?

4

1 回答 1

1

不回答

小心禁用所选类的序列化方法。当在本地或某些有限的开发环境中运行时,您的应用程序可能不需要“集群”并且不需要复制会话或有状态实体。但是,一旦部署到测试或生产环境,它就可以集群化。如果您阻止了序列化,那么它将被破坏。

因此,最好的行动原因是确保您的类的“可序列化”,而不是强制阻止它。

序列化关闭答案

如果您坚持禁用序列化,<distributable/>从您web.xml的移除应该可以解决问题。

序列化不可序列化的答案

通过尝试使某些类可序列化,有时您会发现某些类成员的类型只是不可序列化的,并且您无法将类型交换为类似的东西,这将序列化。然后使用以下技巧,只要它适用:

public class ClassForcedToBeSerializable implements Serializable {

    transient private FileWriter writer; //FileWriter is not serializable!!!
    private final File file;

    public ClassForcedToBeSerializable(File file) throws IOException {
        this.file = file;
        this.writer = new FileWriter(file);
    }

    //FLESH AND BONES HERE

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        if (writer == null) {
            this.writer = new FileWriter(file);
        }
    }
}

如您所见,该类包括FileWriter类型字段。我们通过标记来确保对象 -> 字节序列化transient。但是,在远程 JVM 上,当此类从字节中恢复时,您的FileWriter字段字段将为null. 我们通过在反序列化期间重新创建它来避免这个问题(参见readObject()方法)。

此示例之所以有效,是因为该File字段具有足够的状态以便FileWriter成功重新创建。

于 2016-02-09T12:54:50.177 回答