Overriding class signature in java

227 views Asked by At

I have a class as follows in a .jar file (library file):

class A{
//someimplementation
}

I would like to make it to implements Serializable interface as follows:

class A implements Serializable {
//the same implementation as present in classA
}

I do not want to decompile the jar file, changing the class signature and then archiving it again after compilation.

Is there any way like writing hooks to achieve this? Kindly provide any pointers/suggestions. My ultimate aim is to achieve implementing Serializable interface without modifying the jar file.

1

There are 1 answers

6
dkatzel On

You can probably achieve this using Serialization Proxy Pattern (Effective Java 2nd edition Item 78)

A few links about the Pattern :

http://jtechies.blogspot.com/2012/07/item-78-consider-serialization-proxies.html

http://java.dzone.com/articles/serialization-proxy-pattern

Follow up: instance control in Java without enum

Make a new class that extends A and is Serializable. In order to avoid serialization errors, however, because A isn't serializable, you need to make a SerializationProxy that creates a new instance via constructor or factory method instead of the normal Java Serialization mechanism of explicitly setting the fields outside of any constructor.

public class MySerializableA extends A implements Serializable{
    private final Foo foo;
    private final Bar bar;
   ...

    private Object writeReplace() {
         return new SerializationProxy(this);
    }
    //this forces us to use the SerializationProxy
    private void readObject(ObjectInputStream stream) throws InvalidObjectException {
         throw new InvalidObjectException("Use Serialization Proxy instead.");
    }


   //this private inner class is what actually does our Serialization
   private static class SerializationProxy implements Serializable {
        private final Foo foo;
        private final Bar bar;
   ...

    public SerializationProxy(MySerializableA myA) {
        this.foo = myA.getFoo();
        this.bar = myA.getBar();
        ...//etc
    }

    private Object readResolve() {
        return new MySerializableA(foo, bar,...);
    }

}
} 

The only downside is when you want to serialize an A, you will have to wrap it in a MyA. but when deserializing, the cast to A will work fine.