Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding class signature in java

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.

like image 876
Arun Avatar asked Mar 08 '26 21:03

Arun


1 Answers

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.

like image 157
dkatzel Avatar answered Mar 10 '26 11:03

dkatzel