我正在将使用JGroups 3.6.6的应用程序迁移到JGroups 4.0.2。地址' JGroups 3.6.6中的类型是可序列化的,但由于安全原因,它已在JGroups 4.0.2中成为Streamable。由于这个原因,我在国家转移期间遇到了问题。这是我用于状态转移的类。
public class State implements Streamable {
/**
*
*/
private static final Logger log = LogManager.getLogger(State.class);
private Map<Address, ScaleInfo> nwMap = new ConcurrentHashMap<>();
private Set<Address> listOfSyncedMastersInCluster = Collections
.newSetFromMap(new ConcurrentHashMap<Address, Boolean>());
private boolean hasMasterMajorityInCluster = false;
private Address prevCoordAddress = null;
private Address currentCoordAddress = null;
private static final State instance = new State();
private State() {
}
public static State getInstance() {
return instance;
}}
状态转移逻辑,
@Override
public void getState(OutputStream output) throws Exception {
State state = State.getInstance();
synchronized (state) {
Util.objectToStream(state, new DataOutputStream(output));
}
}
@Override
public void setState(InputStream input) throws Exception {
State state = State.getInstance();
synchronized (state) {
state.setInstance((State) Util.objectFromStream(new DataInputStream(input)));
}
}
问题在于我无法找到一种方法来编组Map with Address键。我尝试调试以查看发生了什么,我可以看到Map被视为基本类型,JGroups尝试序列化它。这会导致异常。这是我用于实现Streamable的代码,
@Override
public void writeTo(DataOutput out) throws Exception {
Util.writeObject(networkMap, out);
Util.writeAddresses(listOfSyncedMastersInCluster, out);
out.writeBoolean(hasMasterMajorityInCluster);
Util.writeAddress(prevCoordAddress, out);
Util.writeAddress(currentCoordAddress, out);
out.writeUTF(Util.objectToByteBuffer(this).toString());
}
@Override
public void readFrom(DataInput in) throws Exception {
nwMap = (Map<Address, ScaleInfo>) Util.readObject(in);
listOfSyncedMastersInCluster = (Set<Address>) Util.readObject(in);
hasMasterMajorityInCluster = in.readBoolean();
prevCoordAddress = Util.readAddress(in);
currentCoordAddress = Util.readAddress(in);
instance = Util.objectFromByteBuffer(in.readUTF().getBytes());
}
编辑1:
第二个问题强调了单例类的情况。调用内部调用Util.objectFromStream
方法的Util.readGenericStreamable
方法时会发生此问题。在此方法中,执行以下代码块。
{
String classname=in.readUTF();
clazz=ClassConfigurator.get(classname, loader);
retval=(T)clazz.newInstance();
}
在单例上调用newInstance会导致异常。这是我在我的问题中尝试传达的内容&#34; 有没有办法为用户定义的单例类实现Streamable?&#34;。
在构造replyFromBuffer方法(在RequestCorrelator中找到)以及setState方法时,内部调用Util.objectFromStream方法。虽然我避免在setState方法中调用objectFromStream,但来自RequestCorrelator的内部调用仍然会导致问题。
编辑2: 更新了第二个问题。
编辑3: 请参阅Bela Ban的答案以及解决方案的以下评论。
答案 0 :(得分:1)
我通过首先将条目数量编组为int来实现编组散列映射,然后迭代条目并分别编组每个Address,ScaleInfo条目。
Util
中有一些方法,例如writeAddress()
或writeAddresses()
,它们会封送地址或地址列表。
在接收方,读取int N并创建一个hashmap,然后读取N个条目。 Util.readAddress()
可用于从byte []数组/输入流创建地址。
单身人士:我不知道这与编组非单身人士有何不同......