Folks, Currently BinaryMarshaller works in a very non-trivial way: 1) If class is Serializable or Binarylizable, it is written in binary format and can be used without deserialization. 2) If class implements Externalizable, it is written in binary format, but without fields metadata. 3) If class has writeObject/readObject methods, it is written with OptimizedMarshaller, also without fields metadata.
Class from p.2 and p.3 must always be deserialized on server side to allow queries. There was an idea to ignore Externalizable/writeObject/readObject and always write object fields directly with binary format and metadata. And let user fallback to default Java logic if needed. I tried this approach today and it appears to be very unstable. Lots of classes from JDK and other libraries has custom serialization logic. As we ignore it, it produces weird exceptions (such as NPE) which we cannot handle and cannot give user any advice on what is going on. I think we should resolve this problem as follows: 1) Both Externalizable and writeObject/readObject cases *by default* are handled in a similar way - with OptimizedMarshaller. *I.e. they are deserialized on server by default.* 2) User can optionally fallback to binary format if he thinks it is safe. But he must do it explicitly via configuration. 3) When we met such classes for the first time, a warning is printed to the user. Something like: "Binary format cannot be applied to the [class] because it implements Externalizable interface; instances will be deserialized on server (to enable binary format please implement Binarylizable interface, or enable [property] or define custom serializer)". 4) Only one exception class is possible on the server - ClassNotFound. We will throw it with sensible error message as well. Thoughts? Vladimir.