2017-05-15 4 views
0

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()); 
} 
  1. は「nwMap」メンバ変数をマーシャリングする方法はありますか?
  2. 定義されたユーザに対して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の答えとコメントを参照してください。

答えて

1

まず、エントリの数をintとしてマーシャリングし、次にエントリを反復し、各Address、ScaleInfoエントリを個別にマーシャリングして、ハッシュマップをマーシャリングすることを実装します。

writeAddress()またはwriteAddresses()のように、アドレスまたはアドレスのリストをマーシャリングする方法があります(Util)。

受信側では、int Nを読み取り、ハッシュマップを作成してからN個のエントリを読み込みます。 Util.readAddress()は、byte []配列/入力ストリームからアドレスを作成するために使用できます。シングルトン再

:私は、これは非シングルトンをマーシャリングを異なる方法を見ていない...

+0

私は質問に地図のためのマーシャリングとアンマーシャリングを追加して、それが正常に動作します。しかし、これはアプリケーション内に関数があるので、これは回避策に過ぎません。より深刻な問題は、インスタンスがシングルトンであることです。 Streamable Singletonを使用しているため、私が直面する問題を説明する質問を更新しました。 – kishore

+0

現在、私は 'State'をそのまま送信しないようにし、呼び出し元でマーシャリングした後にバイトバッファを送信するようにコードを修正しました。次に、被呼び出し者は非マーシャリングを実行する(クラスの事前知識はシングルトンである)。これは私のためにうまくいく。私はこれが正しい方法かどうかを知りたいと思います。 – kishore

+0

バイトバッファの送信は常に機能します。おそらくあなたのようなシングルトンのための最良のソリューションです。 –

関連する問題