このクラスのオブジェクトが異なるプロセスで正しくシリアル化されないのはなぜですか?

ZePotente:

環境

私はJavaアプリケーションを作成し、そのアプリケーションの2つのインスタンスを実行して、変更があるたびにソケットを介してそれらの属性の一部を同期する必要があります。これらの変更を伝えるために、Serializableオブジェクトは、識別子にread / writeUTF()を使用するObjectStreams(入力および出力)を使用し、read / writeObject()およびflush()を使用して、ソケットを通じて送信されます。アプリはまったく同じ.jarであり、異なるポートやIPを使用するなどのいくつかの変更を加えて(必要に応じて)2回実行します。

問題

一部のクラスのオブジェクト(例Notification:)は問題なく送受信されましたが、別のクラス(RegisteredUsers)のオブジェクトは正しく送信(または受信)されていません。したがって、2つのアプリ間でオブジェクトを送信するためにいくつかのテストを実行したところ、オブジェクトが送信されていてnullではないことがわかりました。属性(a HashMap<String,User>)も送信されていて、nullではありませんが、常に空です。
だから私はそれを問題が正確に何であるかにスケールダウンすることにしました:ストリームを介してオブジェクトを書き、同じ.jarの異なるプロセスでそれを読み込もうとしています、そしてほとんどのクラスでそれはうまくいくようですが、それは1つではありません。
オブジェクトが同じプロセスの実行中に書き込まれて読み取られた場合は機能しますが、このオブジェクトが同じアプリの別のインスタンスで読み取られた場合は、このシリアル化プロセスについて私が見逃している、または理解できないものがあるようです。同じ作成プロセスで通知にHashMapを追加しましたが、それでも機能しますが、実際には取得できません。何が欠けていますか?

コード

大きなアプリからいくつかのコードを取得し、テストしたい場合は基本的な問題に切り詰めました。エラーを再現するには、Main1を実行します。Main1を実行すると、それぞれにオブジェクトが永続化された2つのファイル(1つはNotificationオブジェクト、もう1つはRegisteredUsersオブジェクト)が作成され、それらの情報が表示されます。次にMain2がファイルからファイルを読み取り、それらの情報を示し、問題を印刷する必要があります。つまり、reg3のHashMapは空なので、どちらのユーザーも登録されていません。

メイン1

public class Main1 {
    
    public static void main(String[] args) {
        String regFile = "registry.txt";
        String notificationFile = "notification.txt";
        Persistence pers = new Persistence();
        
        RegisteredUsers reg1 = new RegisteredUsers();
        RegisteredUsers reg2 = new RegisteredUsers();
        
        reg1.register("Name1", "127.0.0.1");
        reg1.register("Name2", "127.0.0.1");
        
        try {
            pers.writeReg(reg1, regFile);
        } catch (IOException e) {
            System.out.println("Error writing registry.");
        }
        try {
            reg2 = pers.readReg(regFile);
        } catch (IOException e) {
            System.out.println("Error reading registry.");
        }
        System.out.println("Original registry: ");
        System.out.println(reg1.isRegistered("Name1") + " " + reg1.isRegistered("Name2"));
        System.out.println("Registry read from file: ");
        System.out.println(reg2.isRegistered("Name1") + " " + reg2.isRegistered("Name2"));
        
        Notification noti1 = new Notification("Name", "127.0.0.1");
        Notification noti2 = new Notification(); //not necesary but it's the way it's done in the bigger app.
        try {
            pers.writeNotif(noti1, notificationFile);
        } catch (IOException e) {
            System.out.println("Error writing notification.");
        }
        try {
            noti2 = pers.readNotif(notificationFile);
        } catch (IOException e) {
            System.out.println("Error reading notification.");
        }
        System.out.println("Original notification: ");
        System.out.println(noti1.getAttributes().get(0) + " " + noti1.getAttributes().get(1));
        System.out.println(noti1.getMap());
        System.out.println("Notification read from file: ");
        System.out.println(noti2.getAttributes().get(0) + " " + noti2.getAttributes().get(1));
        System.out.println(noti2.getMap());
    }
}

メイン2

public class Main2 {
    public static void main(String[] args) {
        String regFile = "registry.txt";
        String notificationFile = "notification.txt";
        Persistence pers = new Persistence();
        RegisteredUsers reg3 = new RegisteredUsers();

        try {
            reg3 = pers.readReg(regFile);
        } catch (IOException e) {
            System.out.println("Error reading registry.");
        }
        if (reg3 == null) {
            System.out.println("reg3 is null");
        }
        if (reg3.getMap() == null)
            System.out.println("reg3 has a null map");
        if (reg3.getMap().isEmpty())
            System.out.println("reg3 has an empty map");
        
        System.out.println("Registry read from file on another process: ");
        System.out.println(reg3.isRegistered("Name1") + " " + reg3.isRegistered("Name2"));
        
        Notification noti3 = new Notification(); //not necesary but it's the way it's done in the bigger app.
        try {
            noti3 = pers.readNotif(notificationFile);
        } catch (IOException e) {
            System.out.println("Error reading notification.");
        }
        System.out.println("Notification read from file on another process: ");
        System.out.println(noti3.getAttributes().get(0) + " " + noti3.getAttributes().get(1));
        System.out.println(noti3.getMap());
    }
}

ファイル内のオブジェクトを永続化するクラス:

public class Persistence {
    public void writeReg(RegisteredUsers regus, String file) throws IOException {
        try(FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fos);) {
                oos.writeObject(regus);
                oos.flush();
            }
    }
    
    public RegisteredUsers readReg(String file) throws IOException {
        RegisteredUsers regus = null;
        try(FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis);) {
                regus = (RegisteredUsers) ois.readObject();
        } catch (ClassNotFoundException e) {
        System.out.println("Wrong class.");
        }
        return regus;
    }
    
    public void writeNotif(Notification regus, String file) throws IOException {
        try(FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fos);) {
                oos.writeObject(regus);
                oos.flush();
            }
    }
    
    public Notification readNotif(String file) throws IOException {
        Notification notif = null;
        try(FileInputStream fis = new FileInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(fis);) {
                notif = (Notification) ois.readObject();
        } catch (ClassNotFoundException e) {
        System.out.println("Wrong class.");
        }
        return notif;
    }
}

登録ユーザー

public class RegisteredUsers implements Serializable {
    private static HashMap<String, User> users;
    
    public RegisteredUsers() {
        users = new HashMap<String, User>();
    }
    
    public HashMap<String, User> getMap() {
        return users;   
    }
    
    public boolean isRegistered(String name) {
        User us = users.get(name);
        return us != null;
    }
    
    public void register(String name, String ip) {
        users.put(name, new User(name, ip, false));
    }
}

通知

public class Notification implements Serializable {
    private ArrayList<String> attributes;
    private HashMap<String, User> map = new HashMap<>();
    
    public Notification() {
    }
    
    public Notification(String name, String ip) {
        attributes = new ArrayList<String>();
        attributes.add(0, name);
        attributes.add(1, ip);
        map.put(ip, new User(name, ip, false));
    }

    public ArrayList<String> getAttributes() {
        return attributes;
    }

    public HashMap<String, User> getMap() {
        return map;
    }
}

ユーザー

public class User implements Serializable {
    private String name;
    private String ip;
    private boolean connection_state;

    public User(String name, String ip, boolean connection_state) {
        this.name = name;
        this.ip = ip;
        this.connection_state = connection_state;
    }
}
k1r0:

Javaのstaticフィールドは暗黙的transientにあり、一時フィールドはシリアル化されません。

あなたは、変更した場合RegisterdUsers

public class RegisteredUsers implements Serializable {
    private HashMap<String, User> users; // static modifier is removed
    ...
}

シリアル化は機能します。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

私のBashスクリプトがこのプロジェクトオイラーに正しい答えを返さないのはなぜですか?

分類Dev

計算されたオブジェクト内のオブジェクトプロパティを取得すると、オブジェクト自体ではなく未定義になるのはなぜですか?このコンテキストでは、どちらのアプローチが適していますか?

分類Dev

リストに正しい数のオブジェクトが表示されないのはなぜですか?

分類Dev

Type []がオブジェクトにラップされている場合にのみシリアル化できるのはなぜですか?

分類Dev

チェックされたラジオ入力の値が正しくアクセスされているのに、「for」ループ内でアクセスすると、デフォルトでグループの最初の値になるのはなぜですか。

分類Dev

投稿JSONオブジェクトがシリアル化されないのはなぜですか?

分類Dev

配列のオブジェクトプロパティが値に正しくアクセスするのはなぜですか?

分類Dev

「エラー:アクションはプレーンオブジェクトである必要があります。非同期アクションにはカスタムミドルウェアを使用してください。」というメッセージが表示されるのはなぜですか。エラー?

分類Dev

クラスのサイズがゼロなのはなぜですか?異なるオブジェクトが異なるアドレスを持っていることを確認するにはどうすればよいですか?

分類Dev

クラスのサイズがゼロなのはなぜですか?異なるオブジェクトが異なるアドレスを持っていることを確認するにはどうすればよいですか?

分類Dev

同期:クラスのクラスオブジェクトではなく、プライベートの最終静的オブジェクトをロックすることが望ましいのはなぜですか?

分類Dev

同期:クラスのクラスオブジェクトではなく、プライベートの最終静的オブジェクトをロックすることが望ましいのはなぜですか?

分類Dev

クラスオブジェクト内のtf.Variableが初期化されないのはなぜですか?

分類Dev

Sparkアプリケーションコードがクラスではなくオブジェクトである必要があるのはなぜですか?

分類Dev

JavaScriptでオブジェクトがプログラムでselect要素に正しく追加されないのはなぜですか?

分類Dev

同じタイプのこれら2つのF#クラスオブジェクトが等しくないのはなぜですか?

分類Dev

ブーストラップクラスが正しく解決されないのはなぜですか?

分類Dev

私のクラスが別のオブジェクトの独自に宣言された変数にアクセスできないのはなぜですか

分類Dev

Visual Studio 2013スキーマ比較に各オブジェクト定義のアクセス許可ステートメントが含まれ、プロジェクトとは異なるものとして扱われるのはなぜですか?

分類Dev

オブジェクトリテラルのプロパティに直接アクセスできないのはなぜですか?

分類Dev

タプルのスライスでは、リストのスライスではなく新しいオブジェクトが返されない

分類Dev

シェルスクリプトでプロセス置換が機能しないのはなぜですか?

分類Dev

アクセスが保護されていると、オブジェクトにアクセスできないのはなぜですか?

分類Dev

シェルスクリプトが正しく機能しないのはなぜですか?

分類Dev

この方法でオブジェクトのインスタンスが正しく返されるのに、この方法では返されないのはなぜですか

分類Dev

このグローバル関数がグローバルオブジェクトにアクセスできないのはなぜですか?

分類Dev

オブジェクトのプロパティにアクセスできないのはなぜですか?

分類Dev

オブジェクトがキャメルケースにシリアル化されるのはなぜですか?

分類Dev

これらのクラスが「{}」のjsonにシリアル化されるのはなぜですか

Related 関連記事

  1. 1

    私のBashスクリプトがこのプロジェクトオイラーに正しい答えを返さないのはなぜですか?

  2. 2

    計算されたオブジェクト内のオブジェクトプロパティを取得すると、オブジェクト自体ではなく未定義になるのはなぜですか?このコンテキストでは、どちらのアプローチが適していますか?

  3. 3

    リストに正しい数のオブジェクトが表示されないのはなぜですか?

  4. 4

    Type []がオブジェクトにラップされている場合にのみシリアル化できるのはなぜですか?

  5. 5

    チェックされたラジオ入力の値が正しくアクセスされているのに、「for」ループ内でアクセスすると、デフォルトでグループの最初の値になるのはなぜですか。

  6. 6

    投稿JSONオブジェクトがシリアル化されないのはなぜですか?

  7. 7

    配列のオブジェクトプロパティが値に正しくアクセスするのはなぜですか?

  8. 8

    「エラー:アクションはプレーンオブジェクトである必要があります。非同期アクションにはカスタムミドルウェアを使用してください。」というメッセージが表示されるのはなぜですか。エラー?

  9. 9

    クラスのサイズがゼロなのはなぜですか?異なるオブジェクトが異なるアドレスを持っていることを確認するにはどうすればよいですか?

  10. 10

    クラスのサイズがゼロなのはなぜですか?異なるオブジェクトが異なるアドレスを持っていることを確認するにはどうすればよいですか?

  11. 11

    同期:クラスのクラスオブジェクトではなく、プライベートの最終静的オブジェクトをロックすることが望ましいのはなぜですか?

  12. 12

    同期:クラスのクラスオブジェクトではなく、プライベートの最終静的オブジェクトをロックすることが望ましいのはなぜですか?

  13. 13

    クラスオブジェクト内のtf.Variableが初期化されないのはなぜですか?

  14. 14

    Sparkアプリケーションコードがクラスではなくオブジェクトである必要があるのはなぜですか?

  15. 15

    JavaScriptでオブジェクトがプログラムでselect要素に正しく追加されないのはなぜですか?

  16. 16

    同じタイプのこれら2つのF#クラスオブジェクトが等しくないのはなぜですか?

  17. 17

    ブーストラップクラスが正しく解決されないのはなぜですか?

  18. 18

    私のクラスが別のオブジェクトの独自に宣言された変数にアクセスできないのはなぜですか

  19. 19

    Visual Studio 2013スキーマ比較に各オブジェクト定義のアクセス許可ステートメントが含まれ、プロジェクトとは異なるものとして扱われるのはなぜですか?

  20. 20

    オブジェクトリテラルのプロパティに直接アクセスできないのはなぜですか?

  21. 21

    タプルのスライスでは、リストのスライスではなく新しいオブジェクトが返されない

  22. 22

    シェルスクリプトでプロセス置換が機能しないのはなぜですか?

  23. 23

    アクセスが保護されていると、オブジェクトにアクセスできないのはなぜですか?

  24. 24

    シェルスクリプトが正しく機能しないのはなぜですか?

  25. 25

    この方法でオブジェクトのインスタンスが正しく返されるのに、この方法では返されないのはなぜですか

  26. 26

    このグローバル関数がグローバルオブジェクトにアクセスできないのはなぜですか?

  27. 27

    オブジェクトのプロパティにアクセスできないのはなぜですか?

  28. 28

    オブジェクトがキャメルケースにシリアル化されるのはなぜですか?

  29. 29

    これらのクラスが「{}」のjsonにシリアル化されるのはなぜですか

ホットタグ

アーカイブ