Deserialization of java serialized object

Deserialize of Java Serialized object

If you want to save any (active) Java instance, you must first serialize the object instance before you can save it to a file. This file is now a serialized Java object file. And if you want to " revive " this serialized object, you must first read it from the file and then deserialize it. It’s a reverse process and is called deserialization. For this Object-saving purpose, JAVA provides you with a tool with 2 APIs:

  • ObjectOutputStream for serializing an object instance
  • ObjectInputStream for the reverse process

The serialization process is a straightforward one. An object you want to store just needs to be an “implementation” of the Serializable interface. Example:

import java.util.ArrayList;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class MyList implements java.io.Serializable {
  public static final long serialVersionUID = 1L; 
  ArrayList<String> list;
  public MyList(String[] mylist) {
    list = new ArrayList<>(mylist.length);
    for (String s:mylist) list.add(s);
  }
  public void print() {
    System.out.println(list);
  }
  //
  public static void main(String... a) throws Exception {
    MyList ml = new MyList(a.length == 0? new String[] { "Hello", "World" }:a);
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serobj/MyList.txt"));
    oos.writeObject(ml);
    oos.flush();
    oos.close();
  }
}

And the file MyList.txt looks as following (in plain text)

  • Invocation with 3 parameters: java MyList joe T schwarz
¬í #sr #MyList ## #L #listt #Ljava/util/ArrayList;xpsr #java.util.ArrayListxÒ#™Ça# #I #sizexp #w# #t #joet #Tt #schwarzx
  • Invocation without parameter: java MyList
¬í #sr #MyList ## #L #listt #Ljava/util/ArrayList;xpsr #java.util.ArrayListxÒ#™Ça# #I #sizexp #w# #t #Hellot #Worldx

If you dump these files as hex-content, you will see: (MyList.txt with 3 parameters)

0        4        8        C        10
ACED0005 73720006 4D794C69 73740000 00000000   |.... sr.. MyLi st.. .... 0
00010200 014C0004 6C697374 7400154C 6A617661   |.... .L.. list t..L java 1
2F757469 6C2F4172 7261794C 6973743B 78707372   |/uti l/Ar rayL ist; xpsr 2
00136A61 76612E75 74696C2E 41727261 794C6973   |..ja va.u til. Arra yLis 3
747881D2 1D99C761 9D030001 49000473 697A6578   |tx.. ...a .... I..s izex 4
70000000 03770400 00000374 00036A6F 65740001   |p... .w.. ...t ..jo et.. 5
54740007 73636877 61727A78                     |Tt.. schw arzx           6

It looks quite confusing. Both processes ALWAYS require that the binary bytecode class of the serialized object exists and is known via CLASSPATH. Otherwise a " ClassNotFoundException " is thrown. Ugly, isn’t it? Now, let’s start the reverse process.

import java.util.ArrayList;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class DeMyList {
  public static void main(String... a) throws Exception {
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(a[0]));
    MyList ml = (MyList) ois.readObject( );
    ois.close();
    ml.print();
  }
}

If you rename the class MyList.class to any name and run the MyList and this little app, you will get this famous ClassNotFoundException . Example:

C:\JoeApp\ODB\examples\Test\examples>java MyList joe T schwarz
Error: Could not find or load main class MyList
Caused by: java.lang.ClassNotFoundException: MyList
C:\JoeApp\ODB\examples\Test\examples>j ava DeMyList serobj/mylist.txt
Exception in thread "main" java.lang. ClassNotFoundException: MyList
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)

Let’s rename it back to MyList.class and rerun DeMyList.

C:\JoeApp\ODB\examples\Test>java ViewObject examples/serobj/MyList.txt
Class Name: MyList
SerID: 1
Number of Fields: 1
Field: list, type: java.util.ArrayList, value/Reference: [joe, T, schwarz]

What I am showing you here is a trivial work with Java Serializable Object. You might be wondering what all this effort is for? Well, it is probably desirable when you need to send a serialized object instance over a network and there are no binary bytecodes available for that object on the other side. Trying to do this with URLClassLoader or Java Reflection ends with ClassNotFoundException. The only option is to send a bytecode class along with the serialized object instance and make it known via CLASSPATH . And that is virtually impossible. Since the serialized object contains valid data (except codes for the methods), the question arises: is there a way to work with the serialized objects (or files)? If you search the internet, you won’t find any. The only package I found is the Github jdeserialize . This package reads a serialized object file and dumps the layout of the serialized data structure (reverse engineering?) with all the data initialized. Since there is no access to every field, working with this outputted object requires additional hard work.
…more click this GITHUB here.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?