Hi Peter: I must have missed the discussion on the original change to the API (RemoteEvent is intended for extension, so it’s part of the public API).
What’s the reasoning on making the fields immutable? It would seem simpler to undo the change and make the fields ‘protected’ again, rather than force every subclass to implement the readObject/writeObject mechanism. RemoteEvent is pretty core to the usage of Jini. it seems like a pretty onerous requirement, plus I have a feeling that new users would find it awfully confusing. Cheers, Greg Trasuk > On Apr 9, 2016, at 9:57 PM, peter_firmst...@apache.org wrote: > > Author: peter_firmstone > Date: Sun Apr 10 01:57:46 2016 > New Revision: 1738402 > > URL: http://svn.apache.org/viewvc?rev=1738402&view=rev > Log: > Critical patch: > > This patch provides a compatible upgrade path for existing mutable subclasses > of RemoteEvent. > > Modified: > river/jtsk/trunk/src/net/jini/core/event/RemoteEvent.java > > Modified: river/jtsk/trunk/src/net/jini/core/event/RemoteEvent.java > URL: > http://svn.apache.org/viewvc/river/jtsk/trunk/src/net/jini/core/event/RemoteEvent.java?rev=1738402&r1=1738401&r2=1738402&view=diff > ============================================================================== > --- river/jtsk/trunk/src/net/jini/core/event/RemoteEvent.java (original) > +++ river/jtsk/trunk/src/net/jini/core/event/RemoteEvent.java Sun Apr 10 > 01:57:46 2016 > @@ -18,6 +18,8 @@ > > package net.jini.core.event; > > +import java.io.ObjectOutputStream.PutField; > +import java.io.ObjectStreamField; > import java.rmi.MarshalledObject; > > /** > @@ -81,6 +83,14 @@ import java.rmi.MarshalledObject; > public class RemoteEvent extends java.util.EventObject { > > private static final long serialVersionUID = 1777278867291906446L; > + > + private static final ObjectStreamField[] serialPersistentFields = > + { > + new ObjectStreamField("source", Object.class), > + new ObjectStreamField("eventID", long.class), > + new ObjectStreamField("seqNum", long.class), > + new ObjectStreamField("handback", MarshalledObject.class) > + }; > > /** > * The event source. > @@ -188,4 +198,39 @@ public class RemoteEvent extends java.ut > stream.defaultReadObject(); > super.source = source; > } > + > + /** > + * In River 3.0.0, RemoteEvent became immutable and all state made > private, > + * previously all fields were protected and non final. > + * <p> > + * This change breaks compatibility for subclasses that access these > fields > + * directly. For other classes, all fields were accessible > + * via public API getter methods. > + * <p> > + * To allow an upgrade path for subclasses that extend RemoteEvent and > + * provide public setter methods for these fields, it is recommended to > + * override all public methods and maintain state independently using > + * transient fields. The subclass should also use RemoteEvent getter > + * methods to set these transient fields during de-serialization. > + * <p> > + * writeObject, instead of writing RemoteEvent fields, writes the > + * result of all getter methods to the ObjectOutputStream, during > serialization, > + * preserving serial form compatibility wither earlier versions, while > + * also allowing mutable subclasses to maintain full serial > compatibility. > + * <p> > + * Mutable subclasses honoring this contract will be compatible with all > + * versions since Jini 1.0. > + * > + * @param stream > + * @throws java.io.IOException > + */ > + private void writeObject(java.io.ObjectOutputStream stream) throws > java.io.IOException > + { > + PutField fields = stream.putFields(); > + fields.put("source", getSource()); > + fields.put("eventID", getID()); > + fields.put("seqNum", getSequenceNumber()); > + fields.put("handback", getRegistrationObject()); > + stream.writeFields(); > + } > } > >