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

1

7

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?

Diesel answered 28/1, 2016 at 12:0 Comment(11)
What do you mean by "which are fine to remain completely stateful"? Also, putting the @Stateful turns the class into a stateful EJB, which is then automatically distributed across the cluster to provide fault-tolerance.Hamrnand
You're right, I have been using the wrong annotation, I'll try it again now> I've worded it incorrectly, what I meant was that I don't want it clustered - I want each instance having it's own version.Diesel
You should be able to use @Stateless or @Singleton for this, but in that case you'd need to add a no-args constructor to your class.Hamrnand
Ok, thank you that makes sense. I'll start doing some re-writing to get rid of the constructors. I'll report back with progressDiesel
Didn't have a measurable effect - it's still trying to serialize what is market with the @Stateless annotation.Diesel
Why would you keep state in a @Stateless bean I wonder?Ambiguity
Could you add some details? which classes are being serialized? some EJB? or do you put objects in a clustered cache? maybe with their code?Spout
If you have been writing constructors then that implies that you are managing the object lifecycle for them and not the container. If you mark a class as @Stateless then it will be created by the container when you inject it into some other object.Boiney
You mean Wildfly is serializing instances of the relevant classes, right? Not the class objects themselves?Straticulate
Are you passing bean instances as arguments to other beans' methods? If your beans really are stateless, then that should not be necessary.Straticulate
I dont believe so, they are all either autowired or retrieved by name from the beanmanagerDiesel
E
1

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.

Enamelware answered 9/2, 2016 at 12:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.