Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialization and Deserialization through message queue

I have an Employee class as below:

package com.mypackage.rabbitmq.model
import java.io.Serializable;

import javax.xml.bind.annotation.XmlRootElement;


@XmlRootElement
public class Employee implements Serializable{

    /**
    * 
    */
    private static final long serialVersionUID = -2736911235490297622L;
    private int EmpNo;
    private String FirstName;
    private String LastName;
    private int age;
    private String gender;
    private String skill;
    private long phone;
    private String email;
    private double salary;
    //getters and setters

I published the list of employee in rabbit MQ as below:

package com.mypackage.rabbitmq.client.publisher;

//imports

public class Publisher {

    public static void main(String[] args) throws IOException {
        ConnectionFactory factory = new ConnectionFactory();

        Connection con = factory.newConnection("localhost");
        Channel channel = con.createChannel();

        Gson gson  = new GsonBuilder().create();
        Employee employee = null;

        List<Employee> empList = new ArrayList<>();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);

        String queueName = "TestQueue";
        for(int i=1; i<=10; i++){
            employee = newEmp(i);

            String message =gson.toJson(employee);
            System.out.println("queueName: "+queueName);
            empList.add(employee);

        }
        oos.writeObject(empList);
        channel.basicPublish(1, "", queueName, null, bos.toByteArray());
        System.out.println("[X], sent '"+empList+"'");

        channel.close(0, queueName);
        con.close(0, queueName);
    }

    public static Employee newEmp(int i){

        //logic here
    }
}

From a separate spring boot application I tried to consume the list of employee. In the consumer application I have the same employee class structure. However the package is different.

package org.springboot.consumer.model;

import java.io.Serializable;

public class Employee implements Serializable{
    //fields and getters-setters here
}

In brief consumer code is as bellow:

public class SDPRabbitMQConsumer implements MessageListener {

    @Override
    public void onMessage(Message message) {
        Gson gson  = new GsonBuilder().create();
        try {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            os.write(message.getBody(), 0, message.getBody().length);
            ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
            ObjectInputStream objInputStream = new ObjectInputStream(is);
            System.out.println("objInputStream.readObject().toString()"+objInputStream.readObject().toString());
            Employee[] employeeArray = gson.fromJson(objInputStream.readObject().toString(), Employee[].class);
            List<Employee> employeeList = new ArrayList<Employee>(Arrays.asList(employeeArray));
            for(Employee employee: employeeList){
                System.out.println(employee);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

But I am getting the below exception:

java.lang.ClassNotFoundException: com.mypackage.rabbitmq.model.Employee

It seems it's a Serialization and Deserialization issue.

My questions are:

  1. If I publish Employee instead of List I don't even need to serialize the class. Then why I need to serialize in case of List?
  2. Why this Exception? Do we need to maintain same package structure for a serialized class in both end?
  3. In the consumer side do we need to have serialVersionUID? If yes, should it match with that of publisher's side?

Thanks in advance.

like image 542
Anirban B Avatar asked Oct 24 '25 06:10

Anirban B


1 Answers

1) while java.util.List is not Serializable, all standard implementations are, so you should be able to serialize/deserialize an ArrayList for instance.

2) Yes, you need the same class in the same package, and also..

3) Classes in both ends must have the same serialVersionUID

like image 111
Ulises Avatar answered Oct 26 '25 19:10

Ulises