Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable Wildfly 9.0.2 trying to serialize certain classes in a clustered application

During the set up of a cluster I'm having an issue with WildFly/Infinispan attempting to serialize a number of classes which are fine to be recreated on each instance - although for whatever reason they seem determined to distribute across the cluster.

Initially I thought that the @Stateless annotation would have the effect I wanted, although it throws an issue from not having the correct constructors, so I don't believe this is what we are looking for.

What is the proper way to disable this, or overwrite the method of serialization, on a per-class basis?

like image 695
William Dunne Avatar asked Jan 28 '16 12:01

William Dunne


1 Answers

The non-answer

Be careful with the approach of disabling serialisation for selected classes. Your application might not need to be 'clustered' and not needing replicated sesssions or stateful entities, when run locally or in some limited development environment. However once deployed to test or production it could be clustered. Then it's going to be broken, if you have prevented serialization.

Therefore the best cause of action is to ensure 'serializability' of your classes, rather than force-preventing it.

Serialization OFF answer

If you insist on disabling serialization, removing <distributable/> from your web.xml should do the trick.

Serializing non-serializables answer

By trying to make some classes serializable sometimes you will find that types of certain class members are simply non-serializable and you cannot swap the type for something similar, which would serialize. Then use the following trick, providing it is applicable:

public class ClassForcedToBeSerializable implements Serializable {

    transient private FileWriter writer; //FileWriter is not serializable!!!
    private final File file;

    public ClassForcedToBeSerializable(File file) throws IOException {
        this.file = file;
        this.writer = new FileWriter(file);
    }

    //FLESH AND BONES HERE

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        if (writer == null) {
            this.writer = new FileWriter(file);
        }
    }
}

As you can see the class includes field of FileWriter type. We ensured the object -> bytes serialization by marking it transient. However on the remote JVM when this class is being brought back from bytes, your FileWriter field field will be null. We avoid this problem by recreating it during deserialization (see readObject() method).

This example works only because the File field carries enough state for FileWriter to be successfully recreated.

like image 177
diginoise Avatar answered Oct 14 '22 00:10

diginoise