Search code examples
eclipseemf

EMF NotSerializableException


I build application in Java using EMF.
I use Java8 JDK.
All I need is persist instance of my model's class.
I run the code in debug mode on WildFly 10 server, remotely from Eclipse.

private String getXml(Audit audit) throws NeoflexException {
    XMLResource res = new XMLResourceImpl();        
    res.getContents().add(audit);       
    StringWriter sw = new StringWriter();

    try {
        res.save(sw, null);
    } catch (IOException e) {
        throw new NeoflexException(e);
    }

    return sw.toString();   
}

On serialization I get a NotSerializableException.
I see that generated Audit class isn't marked as Serializable.
I can not edit generated code, how ever, I also don't have option to mark this class in diagram as serializable.
As described here: https://www.eclipse.org/forums/index.php/t/261475/
I need to create an interface and derive it from serializable, but I don't have such option. See screenshot attached.

Serializable


Solution

  • In general, EMF serializability is not bound to the ISerializable interface, but a containment hierarchy formed between the model elements. Furthermore, you should not make EMF interfaces extend the ISerializable inferface at all, as it is misleading (EMF model objects are not supposed to be serializable using the basic Java serialization).

    Basically, the instances of your classes should for a containment tree: one object should be the root of the tree, and all other instances should be contained in it. Then you could save this entire containment hierarchy into a file by adding the model root into the resource.

    Without knowing the concrete error message in the exception, my first tip would be to check whether the Audit element references some other model element, because if that element is referenced in a non-containment relation, than the serialization will fail.

    To set a relation containment, edit your metamodel (Audit.ecore file) and set the property called containment true for the reference. However, you have to make sure that the containment subtree can be set up correctly: there is only a single model root element; all other elements can be reached by exactly one path of containment references from the model root. If an element is referenced by a cross-reference, it must also be included in the containment hierarchy in order for the EMF serialization (Resource.save) to work.

    A further issue I see that you create the EMF Resource file manually, without any URI (that determines where you want to save your model) and without any resourceset (that is used to split your models into multiple files/resources with separate containment hierarchies).

    In other words, you should create a ResourceSet instance, and use that to create your model Resource instances.

    For more details, I suggest to check the basic and serialization specific tutorial at vogella.com.