Search code examples
javachronicle

OpenHFT Chronicle Queue writing fields marked as transient


Ok, so I have a couple of classes that basically look like this.

public class Foo implements Serializable {
    private A a;

    //More code
}

public class A implements Serializable {
    public Vector vector = new Vector();

    //More code
}

public class B implements Serializable {
    private transient A parent;

    //More code
}

public static void main(String[] args) {

    A a = new A();
    a.vector.add(new B(a));

    Foo foo = new Foo(a);
    //More code to write foo with OpenHFT
}

So the oddity here is that A and B point at each other cyclically, where A has B in its attribute vector and B has A as its attribute parent. Normally this would be an issue if you tried to write it since it would result in an infinite loop. Hence the use of the transient keyword on parent.

However, for some reason OpenHFT is not registering the fact that parent is set to be transient and is still trying to write it, resulting in me getting a StackOverflowException (hehe, actually asking about a StackOverflowException on Stack Overflow, that's a first).

Any suggestions as to why this might be happening?

Btw, I'm importing OpenHFT using Maven and I'm using version 5.17.17


Solution

  • I don't know how are you getting StackOverflowException, your code (with some obvious modifications to make it meaningful) works for me:

    public class Test {
        public static class Foo implements Serializable {
            private A a;
    
            public Foo(A a) {
                this.a = a;
            }
    
            //More code
        }
    
        public static class A implements Serializable {
            public Collection<B> vector = new Vector<>();
    
            //More code
        }
    
        public static class B implements Serializable {
            private transient A parent;
            private String name;
    
            public B(A a, String name) {
                this.parent = a;
                this.name = name;
            }
    
            //More code
        }
    
        public static void main(String[] args) {
    
            A a = new A();
            a.vector.add(new B(a, "name"));
    
            Foo foo = new Foo(a);
    
            Bytes bytes = Wires.acquireBytes();
            final ValueOut out = WireType.JSON.apply(bytes).getValueOut();
            out.marshallable(foo);
    
            System.err.println(bytes.toString());
        }
    }
    

    This will output:

    "a":{"vector":[ {"name":"name"} ]
    }
    

    Thus it's clear the transient field is ignored.