Hi all,

I agree with Joe's remark too. I have made the change locally to the
Resource and Handler classes. I will check that in when I'm done with the
Resource refactoring.

We won't port that change back to 1.0 as it slightly modifies the API
contract.

Best regards,
Jerome  

> -----Message d'origine-----
> De : Thierry Boileau [mailto:[EMAIL PROTECTED] 
> Envoyé : mardi 23 octobre 2007 17:09
> À : [email protected]
> Objet : Re: When and when not to override Resource.init
> 
> Thanks a lot Joe for this nice demonstration!
> I'm totally convinced. I think also the init method must be removed
> from the "normal" constructor.
> 
> best regards,
> Thierry Boileau
> 
> On 10/22/07, Joe Nellis <[EMAIL PROTECTED]> wrote:
> > Ok, well I just want to make sure you know what I'm talking about. I
> > understand the need to have a default constructor for 
> injection purposes but
> > that is not the issue.  The issue is with the "normal" 
> constructor calling
> > init.  It should not call init. It might be convenient to 
> put all the
> > context, request, response object assignments in init for 
> the Spring folk
> > but it needs to be duplicated in the "normal" constructor 
> also, instead of
> > just calling init. You must never call non-final methods inside a
> > constructor.. Here is some test code that explains the bug.
> >
> > package test;
> >
> > import org.restlet.Context;
> > import org.restlet.data.MediaType;
> > import org.restlet.data.Request;
> > import org.restlet.data.Response;
> > import org.restlet.resource.Representation;
> > import org.restlet.resource.Resource;
> > import org.restlet.resource.StringRepresentation;
> > import org.restlet.resource.Variant;
> >
> > /**
> >  *
> >  * @author jnellis
> >  */
> > public class MyResource extends Resource{
> >   // These variables get initialized AFTER init is called!
> >   private String something  =  "default-value";
> >   private String other;   // no default initializer, the 
> default is null.
> >
> >   public MyResource(){
> >     // You can provide this constructor but a Finder won't 
> look at it
> >     // because of the "normal" constructor.
> >   }
> >
> >   public MyResource(Context context, Request request, 
> Response response){
> >     // The call to super happens before the construction of 
> THIS subclass
> >     // object and so when it calls init, it is really 
> calling a method
> >     // of an object that has not been initialized.
> >     super(context,request,response);
> >   }
> >
> >   @Override
> >   public void init(Context context, Request request, 
> Response response){
> >     // call first as Resource.init documentation says.
> >     super.init(context,request,response);
> >
> >     // Now do our initialization stuff.
> >     // The only safe operations are on direct members of 
> the Resource
> >     // class itself, mainly, it seems, to be able to add 
> Variants this
> >     // resource handles.
> >     getVariants().add(new Variant(MediaType.TEXT_PLAIN));
> >
> >     /* The developer says to himself, "oh hey, this is a 
> nice place to
> >      * put my subclass specific stuff too!"  BAM! problems 
> start here.
> >      */
> >     this.something = "apples";
> >     this.other = "oranges";
> >   }
> >
> >   @Override
> >   public Representation getRepresentation(Variant variant){
> >     Representation result = null;
> >     // One would think this prints "apples or oranges" but 
> on my machine
> >     // it prints out "default-value or oranges".
> >     result = new StringRepresentation(something + " or " + other);
> >     // ANY subclass variable with a default initializer will end up
> >     // re-initializing that variable after it has been set in
> >     // the init method.
> >     return result;
> >   }
> > }
> >
> >
> >
> >
> >
> > ----- Original Message -----
> > From: "Thierry Boileau" <[EMAIL PROTECTED]>
> > To: <[email protected]>
> > Sent: Monday, October 22, 2007 5:02 AM
> > Subject: Re: When and when not to override Resource.init
> >
> >
> > > Hello Joe,
> > >
> > > The "init" method has been introduced in order to satisfy 
> recurrent
> > > requests made by Spring users of the Restlet framework. There is a
> > > need to create resources with the default constructor, 
> instead of the
> > > "normal" one (the one with the 3 parameters). On the other hand
> > > resources need to be instantiated with their context plus 
> the request
> > > and response objects. That's why the Finder tries to invoke the 3
> > > parameters constructor, and if it doesn' exist, invokes 
> the default
> > > constructor then the "init" method.
> > > Having said that, I'm conscious that I've uncompletely answered to
> > > your question... But I've a meeting right now.
> > >
> > > best regards,
> > > Thierry Boileau
> > >
> > > On 10/22/07, Joe Nellis <[EMAIL PROTECTED]> wrote:
> > >> Greetings,
> > >>
> > >> This purposefully overridable method is called from the 
> Resource(Context,
> > >> Request, Response) constructor and therefore subclasses 
> that override
> > >> init(Context, Request, Response) are in for a big 
> suprise if they try to
> > >> do
> > >> operations on their own fields in the init method.  At 
> this point in
> > >> execution, the subclass of Resource has not been 
> initialized and so
> > >> default
> > >> field intializers have not been called, not even fields 
> declared final.
> > >> The
> > >> default initializers will be called after init finishes 
> and any subclass
> > >> fields set during the init method call will be 
> overwritten with defaults.
> > >> This is a gotcha in Joshua Blochs Effective Java pg 80.  
> Constructors of
> > >> classes intended to be subclassed should not call 
> overridable methods.
> > >>
> > >> So I think some clarification on when to override init 
> when your class
> > >> also
> > >> supports the three argument resource constructor 
> (assuming you call
> > >> super(context,request,response) first in the 
> constructor.)  Why is there
> > >> a
> > >> three argument constructor?  The Finder.createResource 
> calls the default
> > >> constructor then calls init afterwards which is ok 
> because all subclasses
> > >> have been initialized by then.
> > >>
> > >> Perhaps there is a way with annotations to convey 
> Variants a resource has
> > >> representations for as this is what the init method 
> seems to be of value
> > >> for, adding variants to the list.
> > >>
> > >> -Joe
> > >>
> >

Reply via email to