0

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

Erik
  • 293
  • 1
  • 8
  • 1
    Have you read the OpenHFT documentation regarding transient fields? Using `transient` means the default Java serialization mechanism (which you shouldn't use) won't serialize those, but any other serialization libraries don't necessarily do that. They may have their own annotations or ways to prevent serialization of a field. You seem to be using `Vector`. Is that `java.util.Vector` or an OpenHFT class? If the former, you might want to switch to the "new" classes, like `ArrayList`. – Kayaman Sep 05 '19 at 10:16
  • @Kayaman I can't find any documentation for it but I am moderately certain that the `transient` keyword works for OpenHFT, it has worked for me previously at least. Yes, that is `java.util.Vector`. The code above is a very rough re-write of some old legacy code at my company and if they want to use `Vector` then they get to use `Vector`. I'm not planning on touching it. – Erik Sep 05 '19 at 10:35
  • 1
    You do understand that "previously `transient` worked, now it doesn't" isn't an answerable question though. Especially when you show irrelevant code that you don't even run. Provide a [Minimal, Reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) and there may be some hope for this question. – Kayaman Sep 05 '19 at 10:43
  • @Kayaman The question isn't whether or not transient works though, I'm pretty certain it does. If I were to put a `transient` attribute in `Foo` it would not try to write it. I'm asking why it's not recognising the fact that an attribute 2 "levels" down is transient. – Erik Sep 05 '19 at 10:58
  • 1
    So you've compiled and run the exact code in your question and it displays the same behaviour? Then run it with a debugger and see what's going on when those fields are being processed. – Kayaman Sep 05 '19 at 11:08

1 Answers1

2

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.

Dmitry Pisklov
  • 1,196
  • 1
  • 6
  • 16