Weeellll....  if you implement StateHolder, this isn't an issue.
The public no-arg constructor will be used, variable initializer
expressions will run, etc.

If you implement Serializable instead, then Craig's totally right -
transient variables will not be re-initialized.   You can deal with
this by adding the log() method, or by providing an implementation
of:

 private void readObject(ObjectInputStream in)

... which can re-initialize any transient values.

I am *so* thankful that java.util.logging doesn't force any of
this pain on its users.

-- Adam



On 2/19/06, Craig McClanahan <[EMAIL PROTECTED]> wrote:
>
>
>
> On 2/19/06, Simon Kitching <[EMAIL PROTECTED]> wrote:
> > On Sun, 2006-02-19 at 17:56 -0800, Craig McClanahan wrote:
> >
> > > Simon,
> > >
> > > Could you do me a favor and publicize this in the Struts community as
> > > well?  The framework code there is littered with static log instances
> > > to.
> >
> > Will do.
> >
> > >  You might also want to add some notes related to using Log instances
> > > in Serializable classes (see below).
> >
> > Will do that also.
> >
> > >
> > > MyFaces folks,
> > >
> > > There *is* a JSF-specific consideration to think about, if you have
> > > classes that implement StateHolder (like a UIComponent
> > > implementation).  Log instances will generally *not* be serializable,
> > > so you will need to deal specially with them in saveState() and
> > > restoreState() methods.  The simplest thing is to just not save them,
> > > and do a "new" operation again in restoreState().
> >
> > Sorry but I don't understand. Why won't the normal approach work?
> >
> >   public class SomeComponent .... {
> >     private Log log = LogFactory.getLog(SomeComponent.class);
> >     ...
> >   }
> >
> > AIUI, the log object won't be saved in the saveState method, but it will
> > be recreated nicely during the RestoreView phase when a new instance is
> > created for the state to be restored into.
> >
> > >
> > > Along the same lines, if your class implements Serializable, you will
> > > need to mark the instance variable transient.  I've started using the
> > > following pattern in my Serializable classes, which would work inside
> > > a StateHolder as well:
> > >
> > >     private transient Log log = null;
> > >
> > >     private Log log() {
> > >         if (log == null) {
> > >             log = LogFactory.getLog(...);
> > >         }
> > >         return log;
> > >     }
> > >
> > > and a typical call looks like:
> > >
> > >     if (log().isDebugEnabled()) {
> > >        log().debug("...");
> > >     }
> >
> > Ok, transient is needed here. But apart from that why won't the standard
> > approach work?
> >
> >   public class SomeThing implements Serializable {
> >     private transient Log log = LogFactory.getLog (SomeThing.class);
> >     ...
> >     if (log.isDebugEnabled()) {
> >       log.debug("...");
> >     }
> >   }
> >
> > Doesn't the log object get recreated when the deserialization occurs?
>
> No, AIUI.  When an object is deserialized, it does *not* execute the
> variable initializer expressions.  Since it was declared transient, there's
> no state for that object to be restored.
>
> > The log() method is quite a lot of boilerplate, and also imposes an
> > additional method call for every isDebugEnabled() call. [The extra call
> > inside the guard is not really relevant as output *is* going to occur at
> > this point which greatly outweighs the price of the method call].
>
> You can reduce that by one call by protecting only the conditional
> expression, because if you get inside you know there's an object ... but
> that means you are relying on the implicit contract between the log instance
> variable and the log() method.
>
> > Cheers,
> >
> > Simon
> >
> >
> Craig
>
>

Reply via email to