gpt4 book ai didi

java - 重新部署项目后,存储在 session 中的对象将不匹配同一类

转载 作者:行者123 更新时间:2023-11-30 10:47:52 24 4
gpt4 key购买 nike

我有两个扩展 WaterBody 的类 StreamLakeStreamLake 存储在 Apache Shiro 1.2.4 管理的 session 中,以备后用。

WaterBody lake = new Lake();
session.setAttribute("water", lake);`

并通过使用检索它

WaterBody water = (WaterBody) session.getAttribute("water");

在 Wildfly 9.0.2 服务器的全新启动中,我可以将对象存储到 session 中并检索它们。我是否将 LakeStream 存储到 water session 属性并不重要。但是,在不重新启动 Wildfly 服务器的情况下重新部署项目后,我可以将与以前相同的类类型存储到 session 属性 water 即:不能首先存储 Lake 并且重新部署然后存储 Stream。我收到此错误:

 java.lang.ClassCastException: cannot assign instance of [Lfwp.fish.water.HydroUnit; to field fwp.fish.water.WaterBody.hucs of type [Lfwp.fish.water.HydroUnit; in instance of fwp.fish.water.Stream

WaterBody 类具有 HydroUnit 类型的私有(private)字段的 getter 和 setter,因为它由 Stream 继承Lake 这个错误毫无意义。

如果在重新开始时 water session 属性在重新部署之前和之后都分配给了同一个类,它会将值分配给 session 变量就好了,然后在检索时它会抛出这个错误:

java.lang.ClassCastException: fwp.fish.water.Lake cannot be cast to fwp.fish.water.WaterBody

因为 Lake 扩展了 WaterBody 它应该没有问题。

对于 Shiro,我们使用 ehcache 2.9 作为 session 缓存。

似乎 serialVersionUID 被缓存忽略了,或者它在幕后自己生成了一个不同的,它认为类在重新部署之间没有变化时已经发生了变化。

类:

public class WaterBody implements Serializable {
private static final long serialVersionUID = -5481729151007010163L;
private int id;
private HydroUnit[] hucs;

public WaterBody() {
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public HydroUnit[] getHucs() {
return hucs;
}

public void setHucs(HydroUnit[] hucs) {
this.hucs = hucs;
}
}

public class Lake extends WaterBody {
private static final long serialVersionUID = -925557850476426686L;
private String centroidLatitude;
private String centroidLongitude;

public Lake(){
super();
}

public String getCentroidLatitude() {
return centroidLatitude;
}

public void setCentroidLatitude(String centroidLatitude) {
this.centroidLatitude = centroidLatitude;
}

public String getCentroidLongitude() {
return centroidLongitude;
}

public void setCentroidLongitude(String centroidLongitude) {
this.centroidLongitude = centroidLongitude;
}
}

public class Stream extends WaterBody {
private static final long serialVersionUID = 2556033593701784053L;
private String mouthLatitude;
private String mouthLongitude;

public Stream(){
super();
}

public String getMouthLatitude() {
return mouthLatitude;
}

public void setMouthLatitude(String mouthLatitude) {
this.mouthLatitude = mouthLatitude;
}

public String getMouthLongitude() {
return mouthLongitude;
}

public void setMouthLongitude(String mouthLongitude) {
this.mouthLongitude = mouthLongitude;
}
}

最佳答案

在研究这个问题之后,我们发现了这一点。当项目第一次运行时,ClassLoader 在使用类时创建类,然后将对象存储到 session 中。在服务器运行时热重新部署该项目后,当它再次加载 Class 时,ClassLoader 会创建该 Class 的新实例>。然而, session 仍会记住上次存储该 Class 的对象时的 Class,并且有时会让新对象存储在 session 中,显示为同一对象。但是在检索对象时,它仍然由该 Class 的旧实例定义,因此当试图将其转换为该 Class 的当前实例时,它将失败。

我们的解决方案是针对将对象存储在 session 中的项目,将将作为对象存储在 session 中的类分离到一个单独的 .jar 模块中,该模块包含在要重新部署的项目中.这样,如果 Class 文件发生变化,服务器将不得不重新启动,因为模块依赖性发生了变化。现在,如果项目是热重新部署的,类将保持完整,因为它们不在正在刷新的 .war 文件中。

关于java - 重新部署项目后,存储在 session 中的对象将不匹配同一类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36022705/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com