在设置集群期间,我遇到了 WildFly/Infinispan 尝试序列化许多可以在每个实例上重新创建的类的问题——尽管无论出于何种原因,它们似乎决定在集群中分布。
最初我认为@Stateless 注释会产生我想要的效果,尽管它会因为没有正确的构造函数而引发问题,所以我不相信这就是我们正在寻找的。
在每个类的基础上禁用此功能或覆盖序列化方法的正确方法是什么?
在设置集群期间,我遇到了 WildFly/Infinispan 尝试序列化许多可以在每个实例上重新创建的类的问题——尽管无论出于何种原因,它们似乎决定在集群中分布。
最初我认为@Stateless 注释会产生我想要的效果,尽管它会因为没有正确的构造函数而引发问题,所以我不相信这就是我们正在寻找的。
在每个类的基础上禁用此功能或覆盖序列化方法的正确方法是什么?
小心禁用所选类的序列化方法。当在本地或某些有限的开发环境中运行时,您的应用程序可能不需要“集群”并且不需要复制会话或有状态实体。但是,一旦部署到测试或生产环境,它就可以集群化。如果您阻止了序列化,那么它将被破坏。
因此,最好的行动原因是确保您的类的“可序列化”,而不是强制阻止它。
如果您坚持禁用序列化,<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
成功重新创建。