javaserializationanylogic

Cannot override writeObject (Serializable model) method in AnyLogic


I have a model based on AnyLogic and tried to serialize it, but receive an StackOverflow error. As I understand the main reason is a circular agent reference. I can't find it however. I tried to override AnyLogic writeObject method in my function on the main agent to find the last serializing Agent.

try {
        FileOutputStream fos = new FileOutputStream("t.tmp");
        ObjectOutputStream out = new ObjectOutputStream(fos) {
            @Override
            protected void writeObjectOverride(Object obj) {
                System.out.println("Serializing: " + obj.getClass().getName() + " - " + obj);
                super.writeObjectOverride(obj);
            }
        };
        
        out.writeObject(this);
        out.close();
        System.out.println("Serialization completed successfully");
        
    } catch (IOException e) {
        System.err.println("Serialization error: " + e.getMessage());
        e.printStackTrace();
    }

I run my model in debug mode with breakpoints on the overriding method, but nothing happened. Model starts and when I call this function it executes an Anylogic writeObjectOverride method (i don't see any messages in console and my breakpoins didn't work) Whats happened?


Solution

  • From the documentation of writeObjectOverride

    This method is called by trusted subclasses of ObjectOutputStream that constructed ObjectOutputStream using the protected no-arg constructor.

    This does not fit your use case.

    Instead, you should override replaceObject(Object). But don’t forget to invoke enableReplaceObject(true) in the constructor to enable this feature.

    try(FileOutputStream fos = new FileOutputStream("t.tmp");
        ObjectOutputStream out = new ObjectOutputStream(fos) {
            { enableReplaceObject(true); }
            @Override
            protected Object replaceObject(Object obj) throws IOException {
                System.out.println("Serializing: " + obj.getClass().getName() + " - " + obj);
                return obj;
            }
          }) {
    
        out.writeObject(this);
        System.out.println("Serialization completed successfully");
    } catch (IOException e) {
        System.err.println("Serialization error: " + e.getMessage());
        e.printStackTrace();
    }