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 > >