Java - ObjectInputStream resolveClass(ObjectStreamClass desc) method



Description

The Java ObjectInputStream resolveClass(ObjectStreamClass desc) method loads the local class equivalent of the specified stream class description. Subclasses may implement this method to allow classes to be fetched from an alternate source.

Declaration

Following is the declaration for java.io.ObjectInputStream.resolveClass(ObjectStreamClass desc) method.

protected Class<?> resolveClass(ObjectStreamClass desc)

Parameters

desc − An instance of class ObjectStreamClass.

Return Value

This method returns a Class object corresponding to desc.

Exception

  • ClassNotFoundException − If class of a serialized object cannot be found.

  • IOException − Any of the usual Input/Output exceptions.

Example - Usage of ObjectInputStream resolveClass(ObjectStreamClass desc) method

The following example shows the usage of Java ObjectInputStream resolveClass(ObjectStreamClass desc) method.

ObjectInputStreamDemo.java

package com.tutorialspoint;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;

public class ObjectInputStreamDemo extends ObjectInputStream {

   public ObjectInputStreamDemo(InputStream in) throws IOException {
      super(in);
   }

   public static void main(String[] args) {
      String s = "Hello World";
      
      try {
         // create a new file with an ObjectOutputStream
         FileOutputStream out = new FileOutputStream("test.txt");
         ObjectOutputStream oout = new ObjectOutputStream(out);

         // write something in the file
         oout.writeUTF(s);
         oout.flush();

         // create an ObjectInputStream for the file we created before
         ObjectInputStreamDemo ois = new ObjectInputStreamDemo(new FileInputStream("test.txt"));

         // read and print an object and cast it as string
         System.out.println("" + (String) ois.readUTF());

         // get the class for string and print the name
         ObjectStreamClass streamClass = ObjectStreamClass.lookup(Integer.class);
         System.out.println("" + ois.resolveClass(streamClass).getName());
      } catch (Exception ex) {
         ex.printStackTrace();
      }
   }
}

Output

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

Hello World
java.lang.Integer

Example - Resolving a Renamed Class

The following example shows the usage of Java ObjectInputStream resolveClass(ObjectStreamClass desc) method.

Scenario

  • We serialized an object of OldClass in a file (data.ser).

  • Later, the class was renamed to NewClass, which normally causes a ClassNotFoundException during deserialization.

  • To fix this, we override resolveClass() to map the old class name to the new class.

ObjectInputStreamDemo.java

package com.tutorialspoint;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.Serializable;

public class ObjectInputStreamDemo {
   public static void main(String[] args)throws IOException, ClassNotFoundException {

      try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.ser"))) {
         oos.writeObject(new OldClass("Hello from OldClass!"));
         System.out.println("OldClass object serialized.");
      } catch (IOException e) {
         e.printStackTrace();
      }

      CustomObjectInputStream ois = new CustomObjectInputStream(new FileInputStream("data.ser"));

      OldClass obj = (OldClass) ois.readObject();
      if (obj instanceof OldClass oldObj) {
         // Manually convert OldClass to NewClass
         NewClass newObj = new NewClass(oldObj.getMessage());
         System.out.println("Deserialized and converted to: " + newObj.getMessage());
      }
   }
   static class NewClass implements Serializable {  // Old class before renaming
      private static final long serialVersionUID = 1L;
      private String message;

      public NewClass(String message) {
         this.message = message;
      }

      public String getMessage() {
         return message;
      }
   }

   static class OldClass implements Serializable {  // Old class before renaming
      private static final long serialVersionUID = 1L;
      private String message;

      public OldClass(String message) {
         this.message = message;
      }
      public String getMessage() {
         return message;
      }
   }

   static class CustomObjectInputStream extends ObjectInputStream {
      public CustomObjectInputStream(InputStream in) throws IOException {
         super(in);
      }

      @Override
      protected Class<?> resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException {
         System.out.println("inside resolveclass....");
         return super.resolveClass(osc);
      }
   }
}

Output

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

OldClass object serialized.
inside resolveclass....
Deserialized and converted to: Hello from OldClass!

Key Points

  • Without resolveClass(), deserialization would fail (ClassNotFoundException).

  • Solution

    • We override resolveClass().

    • If the ObjectStreamClass name is "OldClass", we manually return NewClass.class.

    • This allows deserialization to succeed even though the class was renamed.

Example - Use of Custom ObjectInputStream

The following example shows the usage of Java ObjectInputStream resolveClass(ObjectStreamClass desc) method.

CustomObjectInputStream.java

package com.tutorialspoint;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.Serializable;

public class CustomObjectInputStream extends ObjectInputStream {
   public CustomObjectInputStream(InputStream in) throws IOException {
      super(in);
   }

   @Override
   protected Class<?> resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException { 
      // Get the class name from the stream
      String className = osc.getName();
      // Log class loading for debugging
      System.out.println("Attempting to resolve class: " + className);
      // Default behavior - use the parent class loader
      return super.resolveClass(osc);
   }

   public static void main(String[] args) {
      try (ObjectOutputStream oos = new ObjectOutputStream(new  
         FileOutputStream("object.ser"))) {  
         oos.writeObject(new MyClass("Hello from MyClass!"));
         System.out.println("MyClass object serialized.");
      } catch (IOException e) {
         e.printStackTrace();
      }
      try {
         // Example usage
         FileInputStream fis = new FileInputStream("object.ser");
         CustomObjectInputStream ois = new CustomObjectInputStream(fis);           
         Object obj = ois.readObject();
         System.out.println("Deserialized object: " + obj);            
         ois.close();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   static class MyClass implements Serializable {
      private static final long serialVersionUID = 2L; 
      String name;
      public MyClass(String name) {
         this.name = name; 
      }
      @Override
      public String toString() {
         return "MyClass: { name='" + name + "'}";
      }
   }
}

Output

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

MyClass object serialized.
Attempting to resolve class: CustomObjectInputStream$MyClass
Deserialized object: MyClass: { name='Hello from MyClass!'}

Explanation

This method (resolveClass) is overridden to

  • Add custom class loading behavior

  • Implement security checks

  • Log class resolution for debugging

java_io_objectinputstream.htm
Advertisements
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy