You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Leif Mortenson <le...@silveregg.co.jp> on 2002/01/16 08:18:48 UTC

Defensive Component Question

I was trying to get Logging configured by specifying a Configuration and
a DefaultLogKitManager and ran into a NullPointerException because I had
not called setLogger() on the DefaultLogKitManager before calling
configure(). I figured out the problem after digging around in the code,
but things would have been a lot easier had I gotten an
IllegalStateException describing the problem or something along those lines.

Following the examples in the docs, I have been trying to design my
components to be fairly defensive about their own state by adding checks
to make sure that say configure is not called before setLogger has been
correctly called.

What are peoples thoughts on this? I think that making these classes
more defensive would also really help shorten the learning curve for new
users by pointing out mistakes like mine without requiring the user to
roll up their sleeves and dig into the code.

Here is the exception that I got:
java.lang.NullPointerException
at
org.apache.avalon.excalibur.logger.DefaultLogTargetFactoryManager.configure(DefaultLogTargetFactoryManager.java:144)
at
org.apache.avalon.excalibur.logger.DefaultLogKitManager.setupTargetFactoryManager(DefaultLogKitManager.java:191)
at
org.apache.avalon.excalibur.logger.DefaultLogKitManager.configure(DefaultLogKitManager.java:154)
... rest of stack trace.

Thrown on:
if( getLogger().isDebugEnabled() )

Cheers,
Leif




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Defensive Component Question

Posted by Berin Loritsch <bl...@apache.org>.
Peter Donald wrote:

> On Sat, 19 Jan 2002 01:00, Berin Loritsch wrote:
> 
>>It's a question of what do you make smart, and what are the tradeoffs.
>>Naturally, there is a slight performance hit when you place checking logic
>>in the component itself (very slight).  The ComponentValidator class can
>>be used in either the Container or the Component (or both), and helps
>>newcomers learn the system better with fail-quick messages and helpful
>>exceptions.
>>
>>
>>>What is the coding standard for Avalon code? Are cases like this
>>>considered a problem in the Avalon class? Or are they only required to
>>>not throw NullPointerExceptions etc if the contacts are followed exactly?
>>>
>>If any exception is thrown during the initialization of a Component, that
>>Component is no longer valid.  If a valid component ever throws an
>>exception that is not part of the contract of the Component (like a
>>NullPointerException), then the Component is broken.
>>
> 
> I wouldn't say that. There are some exceptions like InvalidStateException 
> that can effectively indicate "hey you are using me poorly" - especially when 
> the component have no fixed container.


And hence, because the usage contracts have been violated, the Container can
no longer guarantee it is in a consistent state, therefore it is no longer
valid.




-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Defensive Component Question

Posted by Peter Donald <pe...@apache.org>.
On Sat, 19 Jan 2002 01:00, Berin Loritsch wrote:
> It's a question of what do you make smart, and what are the tradeoffs.
> Naturally, there is a slight performance hit when you place checking logic
> in the component itself (very slight).  The ComponentValidator class can
> be used in either the Container or the Component (or both), and helps
> newcomers learn the system better with fail-quick messages and helpful
> exceptions.
>
> > What is the coding standard for Avalon code? Are cases like this
> > considered a problem in the Avalon class? Or are they only required to
> > not throw NullPointerExceptions etc if the contacts are followed exactly?
>
> If any exception is thrown during the initialization of a Component, that
> Component is no longer valid.  If a valid component ever throws an
> exception that is not part of the contract of the Component (like a
> NullPointerException), then the Component is broken.

I wouldn't say that. There are some exceptions like InvalidStateException 
that can effectively indicate "hey you are using me poorly" - especially when 
the component have no fixed container.

-- 
Cheers,

Pete

*------------------------------------------------------*
| "Common sense is the collection of prejudices        |
|  acquired by age 18. " -Albert Einstein              |
*------------------------------------------------------*


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Defensive Component Question

Posted by Berin Loritsch <bl...@apache.org>.
Leif Mortenson wrote:

> 
> Berin Loritsch wrote:
>>
>>There is a utility class in Excalibur's Scratchpad that will help you
>>out.  I am not at the right computer, so I can't give the full
>>class name now.  It should be ComponentValidator or something like
>>that.
>>
>>
> Thanks, yet the class is
> org.apache.avalon.excalibur.util.ComponentStateValidator. But if I am
> not mistaken. That is a class that can be used to track the state of a
> component that you make. It looks like you create an instance of the
> ComponentStateValidator in your component's constructor passing in the
> component's this reference. Then in each of your action methods, call
> the appropriate validator method.
> For example:
> public void compose(ComponentManager manager) throws ComponentException
> {
> m_validator.checkComposed();
> 
> ...user code...
> }
> 
> It appears that this is a utility class to help make it easier for the
> components to protect themself.
> The problem that I ran into was that the DefaultLogKitManager does not
> defend itself from containers which do not follow the contracts
> correctly. In my case, this was caused by me creating a container at the
> same time as I was trying to learn how to do so.


:).  To answer your question of whether it is the responsibility of the
class to protect itself vs. the responsibility of the container--there is
no agreed upon method.  I personally prefer all my code to be checked
explicitly.  Peter, on the other hand, prefers the container to validate
all the contracts.  There are consequences to both of these approaches.
In my approach, the Component itself is protected, and no matter what the
Container does--but at the cost of adding in the explicit checking code.
In Peter's approach, the Component is safe as long as the Container obeys
the lifecycle contracts--but if it's initialization is dependant on the
order of lifecycle contracts and the Component is used in a bad container,
it will malfunction.

It's a question of what do you make smart, and what are the tradeoffs.
Naturally, there is a slight performance hit when you place checking logic
in the component itself (very slight).  The ComponentValidator class can
be used in either the Container or the Component (or both), and helps newcomers
learn the system better with fail-quick messages and helpful exceptions.



> What is the coding standard for Avalon code? Are cases like this
> considered a problem in the Avalon class? Or are they only required to
> not throw NullPointerExceptions etc if the contacts are followed exactly?


If any exception is thrown during the initialization of a Component, that
Component is no longer valid.  If a valid component ever throws an exception
that is not part of the contract of the Component (like a NullPointerException),
then the Component is broken.



> I vote for making the Avalon classes as rugged as possible in cases like
> this. Esp the classes which new users are most likely to be having to
> access directly from their own containers.

I agree, but there are those who hold differing oppinions.  In the end, you
must do what you feel is right.  However, do listen to those who have different
oppinions from you, you might learn something.

-- 

"They that give up essential liberty to obtain a little temporary safety
 deserve neither liberty nor safety."
                - Benjamin Franklin


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: Defensive Component Question

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Leif Mortenson [mailto:leif@silveregg.co.jp]
>
> What is the coding standard for Avalon code? Are cases like this
> considered a problem in the Avalon class? Or are they only required to
> not throw NullPointerExceptions etc if the contacts are followed exactly?
>
> I vote for making the Avalon classes as rugged as possible in cases like
> this. Esp the classes which new users are most likely to be having to
> access directly from their own containers.

Leif,

we (on the list) have been through this before. For some background, check:

http://marc.theaimsgroup.com/?l=avalon-dev&w=2&r=1&s=ComponentValidator&q=b

You may want to know what's already been said if this issue comes up again
(and it will).

/LS


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Defensive Component Question

Posted by Leif Mortenson <le...@silveregg.co.jp>.

Berin Loritsch wrote:

>Leif Mortenson wrote:
>
>>I was trying to get Logging configured by specifying a Configuration and
>>a DefaultLogKitManager and ran into a NullPointerException because I had
>>not called setLogger() on the DefaultLogKitManager before calling
>>configure(). I figured out the problem after digging around in the code,
>>but things would have been a lot easier had I gotten an
>>IllegalStateException describing the problem or something along those lines.
>>
>>Following the examples in the docs, I have been trying to design my
>>components to be fairly defensive about their own state by adding checks
>>to make sure that say configure is not called before setLogger has been
>>correctly called.
>>
>
>
>There is a utility class in Excalibur's Scratchpad that will help you
>out.  I am not at the right computer, so I can't give the full
>class name now.  It should be ComponentValidator or something like
>that.
>
Thanks, yet the class is
org.apache.avalon.excalibur.util.ComponentStateValidator. But if I am
not mistaken. That is a class that can be used to track the state of a
component that you make. It looks like you create an instance of the
ComponentStateValidator in your component's constructor passing in the
component's this reference. Then in each of your action methods, call
the appropriate validator method.
For example:
public void compose(ComponentManager manager) throws ComponentException
{
m_validator.checkComposed();

...user code...
}

It appears that this is a utility class to help make it easier for the
components to protect themself.
The problem that I ran into was that the DefaultLogKitManager does not
defend itself from containers which do not follow the contracts
correctly. In my case, this was caused by me creating a container at the
same time as I was trying to learn how to do so.

What is the coding standard for Avalon code? Are cases like this
considered a problem in the Avalon class? Or are they only required to
not throw NullPointerExceptions etc if the contacts are followed exactly?

I vote for making the Avalon classes as rugged as possible in cases like
this. Esp the classes which new users are most likely to be having to
access directly from their own containers.

Cheers,
Leif

>>What are peoples thoughts on this? I think that making these classes
>>more defensive would also really help shorten the learning curve for new
>>users by pointing out mistakes like mine without requiring the user to
>>roll up their sleeves and dig into the code.
>>
>>Here is the exception that I got:
>>java.lang.NullPointerException
>>at
>>org.apache.avalon.excalibur.logger.DefaultLogTargetFactoryManager.configure(DefaultLogTargetFactoryManager.java:144)
>>at
>>org.apache.avalon.excalibur.logger.DefaultLogKitManager.setupTargetFactoryManager(DefaultLogKitManager.java:191)
>>at
>>org.apache.avalon.excalibur.logger.DefaultLogKitManager.configure(DefaultLogKitManager.java:154)
>>... rest of stack trace.
>>
>>Thrown on:
>>if( getLogger().isDebugEnabled() )
>>




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Defensive Component Question

Posted by Berin Loritsch <bl...@apache.org>.
Leif Mortenson wrote:

> I was trying to get Logging configured by specifying a Configuration and
> a DefaultLogKitManager and ran into a NullPointerException because I had
> not called setLogger() on the DefaultLogKitManager before calling
> configure(). I figured out the problem after digging around in the code,
> but things would have been a lot easier had I gotten an
> IllegalStateException describing the problem or something along those lines.
> 
> Following the examples in the docs, I have been trying to design my
> components to be fairly defensive about their own state by adding checks
> to make sure that say configure is not called before setLogger has been
> correctly called.


There is a utility class in Excalibur's Scratchpad that will help you
out.  I am not at the right computer, so I can't give the full
class name now.  It should be ComponentValidator or something like
that.


> 
> What are peoples thoughts on this? I think that making these classes
> more defensive would also really help shorten the learning curve for new
> users by pointing out mistakes like mine without requiring the user to
> roll up their sleeves and dig into the code.
> 
> Here is the exception that I got:
> java.lang.NullPointerException
> at
> org.apache.avalon.excalibur.logger.DefaultLogTargetFactoryManager.configure(DefaultLogTargetFactoryManager.java:144)
> at
> org.apache.avalon.excalibur.logger.DefaultLogKitManager.setupTargetFactoryManager(DefaultLogKitManager.java:191)
> at
> org.apache.avalon.excalibur.logger.DefaultLogKitManager.configure(DefaultLogKitManager.java:154)
> ... rest of stack trace.
> 
> Thrown on:
> if( getLogger().isDebugEnabled() )
> 
> Cheers,
> Leif
> 
> 
> 
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
> 
> .
> 
> 



----------------------------------------------------
Sign Up for NetZero Platinum Today
Only $9.95 per month!
http://my.netzero.net/s/signup?r=platinum&refcd=PT97

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>