Java - ObjectOutputStream writeClassDescriptor(ObjectStreamClass desc) method



Description

The Java ObjectOutputStream writeClassDescriptor(ObjectStreamClass desc) method writes the specified class descriptor to the ObjectOutputStream. Class descriptors are used to identify the classes of objects written to the stream. Subclasses of ObjectOutputStream may override this method to customize the way in which class descriptors are written to the serialization stream. The corresponding method in ObjectInputStream, readClassDescriptor, should then be overridden to reconstitute the class descriptor from its custom stream representation. By default, this method writes class descriptors according to the format defined in the Object Serialization specification.

  • Called automatically when serializing a Serializable object − it writes metadata about the class (name, serialVersionUID, field info).

  • You can override it to

    • Log class metadata

    • Add extra data (e.g. version tags)

Declaration

Following is the declaration for java.io.ObjectOutputStream.writeClassDescriptor(ObjectStreamClass desc) method.

public void writeClassDescriptor(ObjectStreamClass desc)

Parameters

  • desc − class descriptor to write to the stream.

Return Value

This method does not return a value.

Exception

  • IOException − If I/O errors occur while writing to the underlying stream.

Example - Log the class name and serialVersionUID being serialized

The following example shows the usage of ObjectOutputStream writeClassDescriptor(ObjectStreamClass desc) method.

ObjectOutputStreamDemo.java

package com.tutorialspoint;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.io.Serializable;

public class ObjectOutputStreamDemo {
   public static void main(String[] args) throws IOException {
      try (CustomOOS oos = new CustomOOS(new FileOutputStream("desc1.ser"))) {
         oos.writeObject(new Person("Alice", 28));
      }
   }

   static class CustomOOS extends ObjectOutputStream {
      public CustomOOS(OutputStream out) throws IOException {
         super(out);
      }

      @Override
      protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
         System.out.println("Serializing class: " + desc.getName());
         System.out.println("serialVersionUID: " + desc.getSerialVersionUID());
         super.writeClassDescriptor(desc);
      }
   }

   static class Person implements Serializable {
      private static final long serialVersionUID = 1L;
      String name;
      int age;
      public Person(String name, int age) {
         this.name = name;
         this.age = age;
      }
   }
}

Output

Let us compile and run the above program, this will produce the following result−

Serializing class: com.tutorialspoint.ObjectOutputStreamDemo$Person
serialVersionUID: 1

Explanation

  • We override writeClassDescriptor() to print class name + UID during serialization.

  • Useful for debugging or version tracking.

Example - Tag every class descriptor with a custom version string

The following example shows the usage of ObjectOutputStream writeClassDescriptor(ObjectStreamClass desc) method.

ObjectOutputStreamDemo.java

package com.tutorialspoint;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.io.Serializable;

public class ObjectOutputStreamDemo {
   public static void main(String[] args) throws IOException {
      try (CustomOOS oos = new CustomOOS(new FileOutputStream("desc2.ser"))) {
         oos.writeObject(new Product("Laptop", 1200.0));
      }
   }

   static class CustomOOS extends ObjectOutputStream {
      public CustomOOS(OutputStream out) throws IOException {
         super(out);
   }

   @Override
   protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
      super.writeClassDescriptor(desc);
      writeUTF("custom-version:2.0"); // custom metadata
      System.out.println("Wrote descriptor with version tag for: " + desc.getName());
   }
}

   static class Product implements Serializable {
      private static final long serialVersionUID = 2L;
      String name;
      double price;
      public Product(String name, double price) {
         this.name = name;
         this.price = price;
      }
   }
}

Output

Let us compile and run the above program, this will produce the following result−

Wrote descriptor with version tag for: com.tutorialspoint.ObjectOutputStreamDemo$Product

Explanation

  • Writes class descriptor, then a custom tag "custom-version:2.0".

  • On deserialization, you must read this extra data manually.

  • Great for creating custom serialization formats.

Example - Tag every class descriptor with a custom version string

The following example shows the usage of ObjectOutputStream writeClassDescriptor(ObjectStreamClass desc) method.

ObjectOutputStreamDemo.java

package com.tutorialspoint;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.io.Serializable;

public class ObjectOutputStreamDemo {
   public static void main(String[] args) throws IOException {
      try (CustomOOS oos = new CustomOOS(new FileOutputStream("desc2.ser"))) {
         oos.writeObject(new Product("Laptop", 1200.0));
      }
   }

   static class CustomOOS extends ObjectOutputStream {
      public CustomOOS(OutputStream out) throws IOException {
         super(out);
      }

      @Override
      protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
         super.writeClassDescriptor(desc);
         writeUTF("custom-version:2.0"); // custom metadata
         System.out.println("Wrote descriptor with version tag for: " + desc.getName());
      }
   }

   static class Product implements Serializable {
      private static final long serialVersionUID = 2L;
      String name;
      double price;
      public Product(String name, double price) {
         this.name = name;
         this.price = price;
      }
   }
}

Output

Let us compile and run the above program, this will produce the following result−

Wrote descriptor with version tag for: com.tutorialspoint.ObjectOutputStreamDemo$Product

Explanation

  • Writes class descriptor, then a custom tag "custom-version:2.0".

  • On deserialization, you must read this extra data manually.

  • Great for creating custom serialization formats.

Example - Block serialization of specific classes

The following example shows the usage of ObjectOutputStream writeClassDescriptor(ObjectStreamClass desc) method.

ObjectOutputStreamDemo.java

package com.tutorialspoint;

import java.io.*;

public class ObjectOutputStreamDemo {
   public static void main(String[] args) {
      try (BlockingOOS oos = new BlockingOOS(new FileOutputStream("desc3.ser"))) {
         oos.writeObject(new SecretData("Don't write me!"));
      } catch (IOException e) {
         e.printStackTrace();
      }
   }

   static class BlockingOOS extends ObjectOutputStream {
      public BlockingOOS(OutputStream out) throws IOException {
         super(out);
      }

      @Override
      protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException {
         if (desc.getName().contains("SecretData")) {
            throw new NotSerializableException("Blocked class: " + desc.getName());
         }
         super.writeClassDescriptor(desc);
      }
   }

   static class SecretData implements Serializable {
      private static final long serialVersionUID = 1L;
      String message;
      public SecretData(String message) {
         this.message = message;
      }
   }
}

Output

Let us compile and run the above program, this will produce the following result−

java.io.NotSerializableException: Blocked class: com.tutorialspoint.ObjectOutputStreamDemo$SecretData
	at com.tutorialspoint.ObjectOutputStreamDemo$BlockingOOS.writeClassDescriptor(ObjectOutputStreamDemo.java:28)

Explanation

  • Prevents serialization of classes named SecretData.

  • Useful in secure systems or when writing to untrusted sinks.

  • Raises a NotSerializableException.

java_io_objectoutputstream.htm
Advertisements