Week 2 — What is meant by serialization?

Question of the Week #2
What is meant by serialization?
12 Replies
Eric McIntyre
Eric McIntyre2y ago
In general, serialization is used to facilitate the transfer of data between different systems or to store data in a persistent format. (for example, in a file or memory buffer, or transmitted across a network connection link) and reconstructed later in the same or another computer environment. import json Define a class for a person class Person: def init(self, name, age, gender): self.name = name self.age = age self.gender = gender Create an instance of the Person class person = Person("John", 35, "male") Serialize the object to a JSON string json_string = json.dumps(person.dict) Output the JSON string print(json_string) Output: {"name": "John", "age": 35, "gender": "male"}
Submission from Cream#5750
Eric McIntyre
Eric McIntyre2y ago
a process converts objects into bytes so you can store it into database or files or whatever
Submission from Al3mid3x#4454
Eric McIntyre
Eric McIntyre2y ago
Serialization is the process of converting an object to a different format (e.g. a binary or text representation) where it can be restored. There are multiple ways to achieve this. One possibility to serialize object (graphs) is binary serialization:
record SomeRecord(int i, String s) implements Serializable{};
class SomeSerializableClass implements Serializable{
private int i;
private String s;
private SomeRecord r;
public SomeSerializableClass(int i, String s, SomeRecord r){
this.i=i;
this.s=s;
this.r=r;
}
public int getI(){
return i;
}
public String getS(){
return s;
}
public SomeRecord getR(){
return r;
}
}
record SomeRecord(int i, String s) implements Serializable{};
class SomeSerializableClass implements Serializable{
private int i;
private String s;
private SomeRecord r;
public SomeSerializableClass(int i, String s, SomeRecord r){
this.i=i;
this.s=s;
this.r=r;
}
public int getI(){
return i;
}
public String getS(){
return s;
}
public SomeRecord getR(){
return r;
}
}
SomeSerializableClass someObject=new SomeSerializableClass(123,"Hello", new SomeRecord(456,"World"));
try(ObjectOutputStream oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("object.dat")))){//save it to a file
oos.writeObject(someObject);
}
SomeSerializableClass someObject=new SomeSerializableClass(123,"Hello", new SomeRecord(456,"World"));
try(ObjectOutputStream oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("object.dat")))){//save it to a file
oos.writeObject(someObject);
}
The whole object graph can be easily reconstructed:
SomeSerializableClass reconstructed;
try(ObjectInputStream oos=new ObjectInputStream(new BufferedInputStream(new FileInputStream("object.dat")))){//save it to a file
reconstructed=(SomeSerializableClass)oos.readObject();
}
SomeSerializableClass reconstructed;
try(ObjectInputStream oos=new ObjectInputStream(new BufferedInputStream(new FileInputStream("object.dat")))){//save it to a file
reconstructed=(SomeSerializableClass)oos.readObject();
}
However, as noted in the Javadocs of Serializable (<Warning: Deserialization of untrusted data is inherently dangerous and should be avoided. Untrusted data should be carefully validated according to the "Serialization and Deserialization" section of the Secure Coding Guidelines for Java SE. Serialization Filtering describes best practices for defensive use of serial filters.>):
Warning: Deserialization of untrusted data is inherently dangerous and should be avoided. Untrusted data should be carefully validated according to the "Serialization and Deserialization" section of the Secure Coding Guidelines for Java SE. Serialization Filtering describes best practices for defensive use of serial filters.
When deserializing (converting the binary representation back to the object graph) malicious code using binary deserialization, it is possible that the program is stuck in an infinite loop (denial of service) or that the attacker even gets full control over the program (remote code execution). While denial of service can be achieved easily when untrusted code is deserialized (e.g. by deserializing multiple nested HashSets), Remote Code Executions are more difficult to exploit. Aside from that, binary deserialization is an extralinguistic mechanism which bypasses the the constructor. It is possible to deserialize invalid object even though the constructor would prohibit that (this is different for records).
Eric McIntyre
Eric McIntyre2y ago
Instead of binary serialization, one could also use custom serialization (define a custom data format and write fields manually) or use libraries for serializing data for a commonly known format (e.g. JSON with libraries like Jackson or GSON).
⭐ Submission from dan1st#7327
Eric McIntyre
Eric McIntyre2y ago
In this example, we have a MyObject class that implements the Serializable interface. This interface is a marker interface, which means it has no methods. It simply indicates that an object of a class that implements Serializable can be serialized. The main method first serializes an instance of MyObject and writes it to a file called "object.ser". It then reads the serialized object from the file and deserializes it, creating a new instance of MyObject. Finally, it prints the deserialized object to the console. When an object is serialized, the object's state is saved by writing the object's field values to a stream. The object's class, its superclass, and any implemented interfaces are also saved in the stream, so that the object can be reconstructed when it is deserialized. There are some limitations to serialization in Java. For example, static fields are not serialized, because they are not part of an object's state. Also, objects that are not serializable cannot be serialized, even if they are part of a serializable object. In such cases, you can use the transient keyword to indicate that a particular field should not be serialized.
⭐ Submission from Liquid#2980
Eric McIntyre
Eric McIntyre2y ago
In Java, serialization is the process of converting an object into a stream of bytes in order to store the object or transmit it over a network. The reverse process, reconstructing the object from the stream of bytes, is called deserialization. Here is an example of how to serialize and deserialize an object in Java:
import java.io.*;

public class SerializationExample {
public static void main(String[] args) {
// Serialize the object
try {
FileOutputStream fos = new FileOutputStream("object.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(new MyObject("Hello", 123));
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}

// Deserialize the object
try {
FileInputStream fis = new FileInputStream("object.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
MyObject obj = (MyObject) ois.readObject();
ois.close();
fis.close();
System.out.println(obj);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}

class MyObject implements Serializable {
String message;
int value;

public MyObject(String message, int value) {
this.message = message;
this.value = value;
}

@Override
public String toString() {
return "MyObject{" +
"message='" + message + '\'' +
", value=" + value +
'}';
}
}
import java.io.*;

public class SerializationExample {
public static void main(String[] args) {
// Serialize the object
try {
FileOutputStream fos = new FileOutputStream("object.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(new MyObject("Hello", 123));
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}

// Deserialize the object
try {
FileInputStream fis = new FileInputStream("object.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
MyObject obj = (MyObject) ois.readObject();
ois.close();
fis.close();
System.out.println(obj);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}

class MyObject implements Serializable {
String message;
int value;

public MyObject(String message, int value) {
this.message = message;
this.value = value;
}

@Override
public String toString() {
return "MyObject{" +
"message='" + message + '\'' +
", value=" + value +
'}';
}
}
Eric McIntyre
Eric McIntyre2y ago
Serialization is when you convert an object's state into something that can be stored/sent over a network. You can do this with the Serializable interface in java:
public class Employee implements Serializable{

// Needed to remember the serialized object is the same as the loaded one
private static long serialVersionUID =1L;
private String firstName;
private String lastName;
private int salary;

//Use transient to prevent it from being serialized
transient String job;
public Employee(String firstN, String lastN, int salary){
this.firstName = firstN;
this.lastName = lastN;
this.salary = salary
}
public Employee() {}
}
class SerializeObject{
public static void main(String[] args){
Employee e = new Employee("Mark","Zuckerberg",100000);
try(FileOutputStream fOut= new FileOutputStream(new File("SerializableFile");
ObjectOutputStream o = new ObjectOututStream(fOut){
o.writeObject(e)
}catch(IOException e){}

}
}
public class Employee implements Serializable{

// Needed to remember the serialized object is the same as the loaded one
private static long serialVersionUID =1L;
private String firstName;
private String lastName;
private int salary;

//Use transient to prevent it from being serialized
transient String job;
public Employee(String firstN, String lastN, int salary){
this.firstName = firstN;
this.lastName = lastN;
this.salary = salary
}
public Employee() {}
}
class SerializeObject{
public static void main(String[] args){
Employee e = new Employee("Mark","Zuckerberg",100000);
try(FileOutputStream fOut= new FileOutputStream(new File("SerializableFile");
ObjectOutputStream o = new ObjectOututStream(fOut){
o.writeObject(e)
}catch(IOException e){}

}
}
Submission from Prismoid#3448
Eric McIntyre
Eric McIntyre2y ago
Serialization is the act of transforming objects into bits(Numbers), using the objectinputstream and objectoutputstream class
Submission from JChrist#8013
Eric McIntyre
Eric McIntyre2y ago
To serialize an object of this class in code we can use an ObjectOutputStream
private static void write (Serializable obj, String path) {
try (var fos = new FileOutputStream(path);
var oos = new ObjectOutputStream(fos)) {
oos.writeObject(obj);
oos.flush();
} catch (IOException ignored) {}
}
private static void write (Serializable obj, String path) {
try (var fos = new FileOutputStream(path);
var oos = new ObjectOutputStream(fos)) {
oos.writeObject(obj);
oos.flush();
} catch (IOException ignored) {}
}
which if used with
UserDTO jade = new UserDTO("Jade", "Foo", LocalDate.of(2004, 11, 16));
write(jade, "out");
UserDTO jade = new UserDTO("Jade", "Foo", LocalDate.of(2004, 11, 16));
write(jade, "out");
writes a file out with the contents
java.time.Ser�]��H�n$UserDTO,LdobtLjava/time/LocalDate;L firstNametLjava/lang/String;lastNameq~xpsr
xpw�
xtJadetFoo
java.time.Ser�]��H�n$UserDTO,LdobtLjava/time/LocalDate;L firstNametLjava/lang/String;lastNameq~xpsr
xpw�
xtJadetFoo
Which might be barely- to unreadable for humans but is able to be deserialized from another process, provided they know about the UserDTO class As a real world example we will use a simple user data-class
@Data
class UserDTO {
private String firstName;
private String lastName;
private LocalDate dob;
}
@Data
class UserDTO {
private String firstName;
private String lastName;
private LocalDate dob;
}
To serialize objects of this class we will need to mark this class as serializable using the interface of the same name. This is purely symbolic and to annotate the class can be serialized without needing to provide any implementation. Additionally one can add a private final static field with a serial version id which (although weakly) ensures that the deserializing code uses the same class
@Data
class UserDTO implements Serializable {
@Serial
private final static long serialVersionUID = 69420L;

private String firstName;
private String lastName;
private LocalDate dob;
}
@Data
class UserDTO implements Serializable {
@Serial
private final static long serialVersionUID = 69420L;

private String firstName;
private String lastName;
private LocalDate dob;
}
Eric McIntyre
Eric McIntyre2y ago
A few additional noteworthy information in no particular order include that you can mark a field as transient which will make the serialization process ignore this field. Furthermore the entire dependency (as in composition) tree of the serialized class needs to be serializable. That means if a class has a non-transient reference to an object that is not serializable the process will fail with a NotSerializableException. This also applies to collections of items such as arrays or lists. Lastly it is important to notice that a Serial version UID, if not present, is automatically generated by the runtime which can lead to errors as changes in the class may lead to unexpected deserialization exceptions
⭐ Submission from jade#9418
Eric McIntyre
Eric McIntyre2y ago
In code we can read this data using a similar method to the one above, namely
private static Object read (String path) {
try (var fis = new FileInputStream(path);
var ois = new ObjectInputStream(fis)) {
return ois.readObject();
} catch (IOException | ClassNotFoundException ignored) {
return null;
}
}
private static Object read (String path) {
try (var fis = new FileInputStream(path);
var ois = new ObjectInputStream(fis)) {
return ois.readObject();
} catch (IOException | ClassNotFoundException ignored) {
return null;
}
}
which deserializes our object. Applying this in the following way
UserDTO isItJade = (UserDTO) read(out);
System.out.println("Is this Jade?");
if ("Jade".equals(isItJade.getFirstName())) {
System.out.printf("%s is Jade!");
}
UserDTO isItJade = (UserDTO) read(out);
System.out.println("Is this Jade?");
if ("Jade".equals(isItJade.getFirstName())) {
System.out.printf("%s is Jade!");
}
yields
Is this Jade?
UserDTO{firstName='Jade', lastName='Foo', dob=2004-11-16} is Jade!
Is this Jade?
UserDTO{firstName='Jade', lastName='Foo', dob=2004-11-16} is Jade!
Serialization refers to translating a java object to a bytestream which can be stored in memory or a database or sent to another JVM which can apply the inverse of serialization, namely deserialize the bytestream and recieve back the original object, provided an identical class to that of the sent object exists for the recipient.
Eric McIntyre
Eric McIntyre2y ago
Serialization is a process of converting some sort of data structure to binary representation for transmitting, storing, etc. The inverse process is called "deserialization" (when binary representation converts back to original data).
Submission from Tapeline#8009
Want results from more Discord servers?
Add your server