gpt4 book ai didi

java - 使用 java RMI 传递复合对象

转载 作者:行者123 更新时间:2023-12-01 19:28:20 24 4
gpt4 key购买 nike

我需要使用 RMI 为客户发送药物计划。服务器和客户端位于不同的项目中,都定义了这些类(实体和远程接口(interface)):

public class Plan implements Serializable {
private Integer id;
private Date periodStart;
private Date periodEnd;
private Integer patientId;
private Medication medications;
}

public class Medication implements Serializable {
private Integer id;
private String name;
private Integer dosage;
private Integer intakeInterval;
}

public interface PillService extends Remote {
public Plan getPlan(int id) throws RemoteException;
}

上面的代码工作正常,但我需要在Plan中有一个药物列表。像这样:

 public class Plan implements Serializable {
...
private List<Medication> medications;
}

如果我用这个 Plan 运行类,我得到这个异常:

Client exception: java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
java.lang.ClassNotFoundException: org.hibernate.collection.internal.PersistentBag (no security manager: RMI class loader disabled)

在此之后我添加了 SecutiryManagerSystem我收到错误:

java.security.AccessControlException: access denied ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)

所以,没有 List<Medication> 就可以正常工作在 Plan 。 RMI 不喜欢复合对象吗?我应该定义一个新的远程方法来单独获取药物列表吗?

最佳答案

问题似乎是 List 的运行时类型。该类无法从客户端获得,因此 RMI 尝试从远程代码库下载代码。这已被相当合理地禁用。

最简单的解决方法是使用众所周知的List实现。将列表复制到 Plan 中设置的位置或自定义 writeObject 方法中。

this.medications = new ArrayList<>(medications);

或者

  private void writeObject(
ObjectOutputStream out
) throws IOException {
this.medications = new ArrayList<>(this.medications);
out.defaultWriteObject();
}

看起来你的List是一个延迟加载实现,所以这将强制它完全加载。您也许可以简单地使用预先加载。

理想情况下,不要使用 RMI,包括 Java 序列化部分。

关于java - 使用 java RMI 传递复合对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59286798/

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