JGroups 3.6.6を使用するアプリケーションをJGroups 4.0.2に移行しています。 JGroups 3.6.6の 'Address'タイプはシリアライズ可能でしたが、セキュリティ上の理由からJGroups 4.0.2ではStreamableになっています。このため、私は状態転送中に問題に直面しています。ここでは、私が状態転送に使用するクラスを示します。JGroupsのアドレスキーを使用したマップの転送
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)));
}
}
問題は、私はアドレスキーで地図をマーシャリングする方法を見つけることができないということです。私は何が起こっていたのかを見るためにデバッグを試みました。マップがプリミティブ型として扱われ、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());
}
- は「nwMap」メンバ変数をマーシャリングする方法はありますか?
- 定義されたユーザに対してStreamableを実装する方法はありますかシングルトンクラス?この場合の 'State'オブジェクトはシングルトンです。
編集1: 2番目の質問は、シングルトンクラスのケースに重点を置いています。この問題は、内部でUtil.readGenericStreamable
メソッドを呼び出すUtil.objectFromStream
メソッドを呼び出すときに発生します。このメソッド内では、次のコードブロックが実行されます。
{
String classname=in.readUTF();
clazz=ClassConfigurator.get(classname, loader);
retval=(T)clazz.newInstance();
}
シングルトンでnewInstanceを呼び出すと例外が発生します。これは私が質問で伝えようとしたものです "シングルトンクラス?"と定義されたユーザのためにStreamableを実装する方法はありますか?
Util.objectFromStreamメソッドは、RequestCorrelatorにあるreplyFromBufferメソッドとsetStateメソッドのフレーミング中に内部的に呼び出されます。 setStateメソッドでobjectFromStreamを呼び出すことは避けましたが、RequestCorrelatorからの内部呼び出しはまだ問題を引き起こしています。
編集2: 2番目の質問が更新されました。
編集3: 解説については、Bela Banの答えとコメントを参照してください。
私は質問に地図のためのマーシャリングとアンマーシャリングを追加して、それが正常に動作します。しかし、これはアプリケーション内に関数があるので、これは回避策に過ぎません。より深刻な問題は、インスタンスがシングルトンであることです。 Streamable Singletonを使用しているため、私が直面する問題を説明する質問を更新しました。 – kishore
現在、私は 'State'をそのまま送信しないようにし、呼び出し元でマーシャリングした後にバイトバッファを送信するようにコードを修正しました。次に、被呼び出し者は非マーシャリングを実行する(クラスの事前知識はシングルトンである)。これは私のためにうまくいく。私はこれが正しい方法かどうかを知りたいと思います。 – kishore
バイトバッファの送信は常に機能します。おそらくあなたのようなシングルトンのための最良のソリューションです。 –