[ 
https://issues.apache.org/jira/browse/RIVER-29?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16911840#comment-16911840
 ] 

Peter Firmstone commented on RIVER-29:
--------------------------------------

Rather than using inheritance, which just exposes internal state, I recommend 
that we use a Factory and ServiceProvider instead to allow customization of 
MarshalledInstance.

For example:

/*
 * TODO: ServiceProvider for MarshalFactory, to allow clients to use
 * any Serialization framework for handback objects used in Jini api's,
 * such as events. It isn't appropriate to use subclasses where
 * remote service nodes use a prior version, or don't support dynamic
 * class loading.
 *
 * Service proxy's wishing to utilise different Serialization Frameworks
 * can subclass MarshalledInstance directly to provide their own implementation.
 */
 
 /**
 * Creates a new <code>MarshalledInstance</code> that contains the
 * marshalled representation of the current state of the supplied
 * object. The object is serialized with the semantics defined by
 * <code>MarshalOutput</code>.
 * 
 * This is designed to allow MarshalledInstance to be extensible 
 * and utilize other Serialization Frameworks.
 * 
 * This constructor calls a chain of internal constructors and static
 * methods that prevent finalizer attacks.
 * 
 * It is advisable for overriding classes to be stateless.
 *
 * @param obj The Object to be contained in the new 
 * <code>MarshalledInstance</code>
 * @param context the collection of context information objects or
 * <code>null</code>
 * @param marshalFactory MarshalFactory used to create underlying 
MarshalInstanceInput
 * and MarshalInstanceOutput.
 * @throws IOException if the object cannot be serialized
 * @throws NullPointerException if context or marshalFactory is null.
 */
 protected MarshalledInstance(Object obj, Collection context, MarshalFactory 
marshalFactory) throws IOException{
 this(obj, context, marshalFactory,
 obj != null ? new ByteArrayOutputStream() : null,
 obj != null ? new ByteArrayOutputStream() : null);
 }
 
 private MarshalledInstance(Object obj, Collection context, MarshalFactory 
factory, ByteArrayOutputStream bout,
 ByteArrayOutputStream lout) throws IOException
 {
 this(bout, 
 obj != null ?
 writeOutRetLocAnnotation(obj, context, factory, bout, lout) 
 : null
 );
 }
 
 /**
 * 
 * @param obj Object to be marshaled.
 * @param context
 * @param factory MarshalFactory used to create MarshalIntstanceOutput
 * @param bout ByteArrayOutputStream to write object serial form.
 * @param lout ByteArrayOutputStream to write code-base annotation to.
 * @return byte array of location.
 * @throws IOException 
 */
 private static byte[] writeOutRetLocAnnotation(Object obj, Collection context, 
MarshalFactory factory,
 ByteArrayOutputStream bout, ByteArrayOutputStream lout) throws IOException
 {
 if (context == null) throw new NullPointerException();
 if (factory == null) throw new NullPointerException();
 MarshalInstanceOutput out = null;
 try {
 out = factory.createMarshalOutput(bout, lout, context);
 out.writeObject(obj);
 out.flush();
 // locBytes is null if no annotations
 return out.hadAnnotations() ? lout.toByteArray() : null;
 } finally {
 try {
 if (out != null) out.close();
 } catch (IOException e){} // Ignore
 }
 }

 

/**
 * Allows for alternative serialization implementations of MarshalledInstance.
 * 
 * @author peter
 */
public interface MarshalFactory {
 
 /**
 * 
 * @param objIn InputStream to read serialized objects from.
 * @param locIn InputStream to read codebase annotations from, optional.
 *@param defaultLoader the class loader value (possibly
 * <code>null</code>) to pass as the <code>defaultLoader</code>
 * argument to <code>RMIClassLoader</code> methods
 * @param verifyCodebaseIntegrity if <code>true</code> then
 * codebase integrity is verified, otherwise code base
 * integrity is not verified
 * @param verifierLoader the class loader value (possibly
 * <code>null</code>) to pass to {@link
 * net.jini.security.Security#verifyCodebaseIntegrity
 * Security.verifyCodebaseIntegrity}, if
 * <code>verifyCodebaseIntegrity</code> is <code>true</code>
 * @param context the collection of context information objects or
 * <code>null</code>
 * @return a new MarshalInstanceInput instance.
 * @throws IOException if an 
 * <code>IOException</code> occurs while creating the
 * MarshalInstanceInput.
 */
 MarshalInstanceInput createMarshalInput(InputStream objIn, 
 InputStream locIn,
 ClassLoader defaultLoader,
 boolean verifyCodebaseIntegrity,
 ClassLoader verifierLoader,
 Collection context) throws IOException;
 
 /**
 * 
 * @param objOut the output stream to write objects to.
 * @param locOut the output stream to write annotations to.
 * @param context the collection of context information objects or
 * <code>null</code>
 * @return an instance of MarshalInstanceOutput
 * @throws java.io.IOException if an 
 * <code>IOException</code> occurs while creating the
 * MarshalInstanceOutput.
 */
 MarshalInstanceOutput createMarshalOutput(OutputStream objOut, OutputStream 
locOut, Collection context) throws IOException;
 
}

> Make some of the private fields of MarshalledInstance protected for the 
> purpose of access by subclasses
> -------------------------------------------------------------------------------------------------------
>
>                 Key: RIVER-29
>                 URL: https://issues.apache.org/jira/browse/RIVER-29
>             Project: River
>          Issue Type: Wish
>          Components: net_jini_io
>    Affects Versions: jtsk_2.1
>            Reporter: Mark Brouwer
>            Priority: Minor
>
> {{net.jini.io.MarshalledInstance}} allows for subclassing but some of the 
> fields that might be needed by a subclass can't be accessed as they are 
> declared {{private}}. A subclass has to pass these in to the constructor of 
> the superclass so must have 'access' to them. There seems to be no harm to 
> make them {{protected}}, especially since they are {{final}}. See also this 
> posting on the 
> [river-dev|http://mail-archives.apache.org/mod_mbox/incubator-river-dev/200706.mbox/%[email protected]%3e]
>  mailing list.



--
This message was sent by Atlassian Jira
(v8.3.2#803003)

Reply via email to