You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by __matthewHawthorne <mh...@alumni.pitt.edu> on 2003/08/26 21:01:28 UTC

[all] RuntimeExceptions, assertions, and pluggable validation

I've been thinking about RuntimeExceptions and assertions...


--------------------------------
Intro
--------------------------------
A RuntimeException is typically thought of as a way to indicate misuse of a
particular method.  As I've always seen it, it is not meant to be caught.

The majority of methods that I write include an initial block which 
validates
the arguments, such as:

    public void doSomethingWith(Object o) {
        if(o == null) {
            throw new IllegalArgumentException("Object cannot be null.");
        }
    }

I think this is OK, but there are some people who believe that even this is
overkill.  If I were to abandon the null check, a NullPointerException 
would be
thrown which would indicate the same thing - programmer error.

The flaw that I see in this is the lack of details about the error.  A
NullPointerException with a line number is useless to somebody who does 
not have
access to the source code.  There is also a certain degree of confusion 
as to
where the error lies.  If my code calls apache code which calls sun 
code, who is
responsible?


--------------------------------
Idea
--------------------------------
I like Java 1.4's assertion system, especially the ability the turn the
assertions on or off for certain packages.  I would like to be able to 
provide
similar functionality that allows for more flexibility in the error 
handling,
which could be especially useful in pre-1.4 code.

Here's a rough idea:


class AsserterFactory
    Asserter getAsserter(String name)

interface Asserter
    void assertTrue(boolean condition, String message)

    class Java14Asserter
        void assertTrue(boolean condition, String message)
            assert condition : message;

    class StandardAsserter
        void assertTrue(boolean condition, String message)
            if(!condition) {
                throw new IllegalArgumentException(message)
        }

    class PassiveAsserter
        void assertTrue(boolean condition, String message) {
            // Does nothing
        }


The asserter name could be a package name, a class name, or some other 
type of
identifier.  The configuration of these details may require system 
properties
or a default asserter.properties file to set up different asserters.

I can think of 2 difficulties presented by this approach, more specifically,
with the dynamic nature of the RuntimeExceptions that a method may throw.

    1) Unit tests catch RuntimeExceptions to validate method behavior, 
if assertions
    were pluggable, switching them would cause a lot of tests to fail.

    2) The RuntimeExceptions that a method throws could not be documented.


--------------------------------
Conclusion
--------------------------------
Any thoughts or ideas?  Repetitive coding of validation and
exception handling is starting to make me think that there is a better way.
There are even similar examples in [lang], where null-handling had to be
updated for tens of methods at a time.


Imagine a similar concept, such as

    Validator
        validate(Object o)

    StringValidator
        validate(Object o) {
            String s = (String)o
            // Validate s
        }


Where users could supply their own validator:

    StringUtils.setValidator(StringValidator v)

and be guaranteed that the validate method would be called on any String 
that is
passed in.

Thanks in advance for any replies, my apologies for the chaos.



Re: [all] RuntimeExceptions, assertions, and pluggable validation

Posted by Stephen Colebourne <sc...@btopenworld.com>.
I am also from the school of IAE for invalid null arguments. NPE reserved
for library bugs.

The original question was about standard validation techniques. Perhaps the
[lang] Validate class is what you are looking for. Its not pluggable, but it
does the job.

Stephen


----- Original Message -----
From: "Michael Heuer" <he...@acm.org>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>;
<dg...@apache.org>
Sent: Tuesday, August 26, 2003 10:16 PM
Subject: Re: [all] RuntimeExceptions, assertions, and pluggable validation


>
> On Tue, 26 Aug 2003, David Graham wrote:
>
> > --- __matthewHawthorne <mh...@alumni.pitt.edu> wrote:
> > > I've been thinking about RuntimeExceptions and assertions...
> > >
> > >
> > > --------------------------------
> > > Intro
> > > --------------------------------
> > > A RuntimeException is typically thought of as a way to indicate misuse
> > > of a
> > > particular method.  As I've always seen it, it is not meant to be
> > > caught.
> > >
> > > The majority of methods that I write include an initial block which
> > > validates
> > > the arguments, such as:
> > >
> > >     public void doSomethingWith(Object o) {
> > >         if(o == null) {
> > >             throw new IllegalArgumentException("Object cannot be
> > > null.");
> > >         }
> > >     }
> > >
> > > I think this is OK, but there are some people who believe that even
this
> > > is
> > > overkill.  If I were to abandon the null check, a NullPointerException
> > > would be
> > > thrown which would indicate the same thing - programmer error.
> >
> > NPE exists so that you don't have to code those boring null checks in
all
> > your code.  It is indeed overkill to throw IllegalArgumentException for
> > null parameters.  Further, the standard Java classes use NPE to indicate
> > programmer error.
>
> I don't agree with this -- there are often conditions where passing in
> null for one method will not throw an NPE until it is accessed in a
> different method.  This can be difficult to track down, especially in a
> third party library.
>
> I think IAE, or better yet o.a.c.l.NullArgumentException is useful in
> many cases.
>
>    michael
>
> >
> > >
> > > The flaw that I see in this is the lack of details about the error.  A
> > > NullPointerException with a line number is useless to somebody who
does
> > > not have
> > > access to the source code.
> >
> > The stack trace provides enough details to debug the source of the
error.
> > It is not useless to someone without the source because their offending
> > method call will be somewhere in the trace, instantly locating the
> > problem.
> >
> > > There is also a certain degree of confusion
> > > as to
> > > where the error lies.  If my code calls apache code which calls sun
> > > code, who is
> > > responsible?
> >
> > You are.  If you pass null to a method that doesn't explicitly state
that
> > null is allowed it's your error.
> >
> > >
> > >
> > > --------------------------------
> > > Idea
> > > --------------------------------
> > > I like Java 1.4's assertion system, especially the ability the turn
the
> > > assertions on or off for certain packages.  I would like to be able to
> > > provide
> > > similar functionality that allows for more flexibility in the error
> > > handling,
> > > which could be especially useful in pre-1.4 code.
> > >
> > > Here's a rough idea:
> > >
> > >
> > > class AsserterFactory
> > >     Asserter getAsserter(String name)
> > >
> > > interface Asserter
> > >     void assertTrue(boolean condition, String message)
> > >
> > >     class Java14Asserter
> > >         void assertTrue(boolean condition, String message)
> > >             assert condition : message;
> > >
> > >     class StandardAsserter
> > >         void assertTrue(boolean condition, String message)
> > >             if(!condition) {
> > >                 throw new IllegalArgumentException(message)
> > >         }
> > >
> > >     class PassiveAsserter
> > >         void assertTrue(boolean condition, String message) {
> > >             // Does nothing
> > >         }
> > >
> > >
> > > The asserter name could be a package name, a class name, or some other
> > > type of
> > > identifier.  The configuration of these details may require system
> > > properties
> > > or a default asserter.properties file to set up different asserters.
> > >
> > > I can think of 2 difficulties presented by this approach, more
> > > specifically,
> > > with the dynamic nature of the RuntimeExceptions that a method may
> > > throw.
> > >
> > >     1) Unit tests catch RuntimeExceptions to validate method behavior,
> > > if assertions
> > >     were pluggable, switching them would cause a lot of tests to fail.
> > >
> > >     2) The RuntimeExceptions that a method throws could not be
> > > documented.
> > >
> > >
> > > --------------------------------
> > > Conclusion
> > > --------------------------------
> > > Any thoughts or ideas?  Repetitive coding of validation and
> > > exception handling is starting to make me think that there is a better
> > > way.
> >
> > The better (and standard) way is to utilize NPE.
> >
> > > There are even similar examples in [lang], where null-handling had to
be
> > > updated for tens of methods at a time.
> >
> > This is a known drawback in libraries that choose to check for null
> > instead of allowing the runtime to throw NPE.
> >
> > >
> > >
> > > Imagine a similar concept, such as
> > >
> > >     Validator
> > >         validate(Object o)
> > >
> > >     StringValidator
> > >         validate(Object o) {
> > >             String s = (String)o
> > >             // Validate s
> > >         }
> > >
> > >
> > > Where users could supply their own validator:
> > >
> > >     StringUtils.setValidator(StringValidator v)
> > >
> > > and be guaranteed that the validate method would be called on any
String
> > >
> > > that is
> > > passed in.
> > >
> > > Thanks in advance for any replies, my apologies for the chaos.
> >
> > The proposed solution is much worse than the perceived problem.  Java
> > programmers instantly know how to debug a NPE in a stack trace.  Adding
> > some convoluted validation/assertion scheme puts an undue burden on the
> > library code and is likely to confuse the developer.
> >
> > David
> >
> > >
> > >
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > > For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> > >
> >
> >
> > __________________________________
> > Do you Yahoo!?
> > Yahoo! SiteBuilder - Free, easy-to-use web site design software
> > http://sitebuilder.yahoo.com
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>


Re: [all] RuntimeExceptions, assertions, and pluggable validation

Posted by Michael Heuer <he...@acm.org>.
On Tue, 26 Aug 2003, David Graham wrote:

> --- __matthewHawthorne <mh...@alumni.pitt.edu> wrote:
> > I've been thinking about RuntimeExceptions and assertions...
> >
> >
> > --------------------------------
> > Intro
> > --------------------------------
> > A RuntimeException is typically thought of as a way to indicate misuse
> > of a
> > particular method.  As I've always seen it, it is not meant to be
> > caught.
> >
> > The majority of methods that I write include an initial block which
> > validates
> > the arguments, such as:
> >
> >     public void doSomethingWith(Object o) {
> >         if(o == null) {
> >             throw new IllegalArgumentException("Object cannot be
> > null.");
> >         }
> >     }
> >
> > I think this is OK, but there are some people who believe that even this
> > is
> > overkill.  If I were to abandon the null check, a NullPointerException
> > would be
> > thrown which would indicate the same thing - programmer error.
>
> NPE exists so that you don't have to code those boring null checks in all
> your code.  It is indeed overkill to throw IllegalArgumentException for
> null parameters.  Further, the standard Java classes use NPE to indicate
> programmer error.

I don't agree with this -- there are often conditions where passing in
null for one method will not throw an NPE until it is accessed in a
different method.  This can be difficult to track down, especially in a
third party library.

I think IAE, or better yet o.a.c.l.NullArgumentException is useful in
many cases.

   michael

>
> >
> > The flaw that I see in this is the lack of details about the error.  A
> > NullPointerException with a line number is useless to somebody who does
> > not have
> > access to the source code.
>
> The stack trace provides enough details to debug the source of the error.
> It is not useless to someone without the source because their offending
> method call will be somewhere in the trace, instantly locating the
> problem.
>
> > There is also a certain degree of confusion
> > as to
> > where the error lies.  If my code calls apache code which calls sun
> > code, who is
> > responsible?
>
> You are.  If you pass null to a method that doesn't explicitly state that
> null is allowed it's your error.
>
> >
> >
> > --------------------------------
> > Idea
> > --------------------------------
> > I like Java 1.4's assertion system, especially the ability the turn the
> > assertions on or off for certain packages.  I would like to be able to
> > provide
> > similar functionality that allows for more flexibility in the error
> > handling,
> > which could be especially useful in pre-1.4 code.
> >
> > Here's a rough idea:
> >
> >
> > class AsserterFactory
> >     Asserter getAsserter(String name)
> >
> > interface Asserter
> >     void assertTrue(boolean condition, String message)
> >
> >     class Java14Asserter
> >         void assertTrue(boolean condition, String message)
> >             assert condition : message;
> >
> >     class StandardAsserter
> >         void assertTrue(boolean condition, String message)
> >             if(!condition) {
> >                 throw new IllegalArgumentException(message)
> >         }
> >
> >     class PassiveAsserter
> >         void assertTrue(boolean condition, String message) {
> >             // Does nothing
> >         }
> >
> >
> > The asserter name could be a package name, a class name, or some other
> > type of
> > identifier.  The configuration of these details may require system
> > properties
> > or a default asserter.properties file to set up different asserters.
> >
> > I can think of 2 difficulties presented by this approach, more
> > specifically,
> > with the dynamic nature of the RuntimeExceptions that a method may
> > throw.
> >
> >     1) Unit tests catch RuntimeExceptions to validate method behavior,
> > if assertions
> >     were pluggable, switching them would cause a lot of tests to fail.
> >
> >     2) The RuntimeExceptions that a method throws could not be
> > documented.
> >
> >
> > --------------------------------
> > Conclusion
> > --------------------------------
> > Any thoughts or ideas?  Repetitive coding of validation and
> > exception handling is starting to make me think that there is a better
> > way.
>
> The better (and standard) way is to utilize NPE.
>
> > There are even similar examples in [lang], where null-handling had to be
> > updated for tens of methods at a time.
>
> This is a known drawback in libraries that choose to check for null
> instead of allowing the runtime to throw NPE.
>
> >
> >
> > Imagine a similar concept, such as
> >
> >     Validator
> >         validate(Object o)
> >
> >     StringValidator
> >         validate(Object o) {
> >             String s = (String)o
> >             // Validate s
> >         }
> >
> >
> > Where users could supply their own validator:
> >
> >     StringUtils.setValidator(StringValidator v)
> >
> > and be guaranteed that the validate method would be called on any String
> >
> > that is
> > passed in.
> >
> > Thanks in advance for any replies, my apologies for the chaos.
>
> The proposed solution is much worse than the perceived problem.  Java
> programmers instantly know how to debug a NPE in a stack trace.  Adding
> some convoluted validation/assertion scheme puts an undue burden on the
> library code and is likely to confuse the developer.
>
> David
>
> >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> >
>
>
> __________________________________
> Do you Yahoo!?
> Yahoo! SiteBuilder - Free, easy-to-use web site design software
> http://sitebuilder.yahoo.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>


Re: [all] RuntimeExceptions, assertions, and pluggable validation

Posted by David Graham <gr...@yahoo.com>.
--- __matthewHawthorne <mh...@alumni.pitt.edu> wrote:
> I've been thinking about RuntimeExceptions and assertions...
> 
> 
> --------------------------------
> Intro
> --------------------------------
> A RuntimeException is typically thought of as a way to indicate misuse
> of a
> particular method.  As I've always seen it, it is not meant to be
> caught.
> 
> The majority of methods that I write include an initial block which 
> validates
> the arguments, such as:
> 
>     public void doSomethingWith(Object o) {
>         if(o == null) {
>             throw new IllegalArgumentException("Object cannot be
> null.");
>         }
>     }
> 
> I think this is OK, but there are some people who believe that even this
> is
> overkill.  If I were to abandon the null check, a NullPointerException 
> would be
> thrown which would indicate the same thing - programmer error.

NPE exists so that you don't have to code those boring null checks in all
your code.  It is indeed overkill to throw IllegalArgumentException for
null parameters.  Further, the standard Java classes use NPE to indicate
programmer error.

> 
> The flaw that I see in this is the lack of details about the error.  A
> NullPointerException with a line number is useless to somebody who does 
> not have
> access to the source code.  

The stack trace provides enough details to debug the source of the error. 
It is not useless to someone without the source because their offending
method call will be somewhere in the trace, instantly locating the
problem.

> There is also a certain degree of confusion 
> as to
> where the error lies.  If my code calls apache code which calls sun 
> code, who is
> responsible?

You are.  If you pass null to a method that doesn't explicitly state that
null is allowed it's your error.

> 
> 
> --------------------------------
> Idea
> --------------------------------
> I like Java 1.4's assertion system, especially the ability the turn the
> assertions on or off for certain packages.  I would like to be able to 
> provide
> similar functionality that allows for more flexibility in the error 
> handling,
> which could be especially useful in pre-1.4 code.
> 
> Here's a rough idea:
> 
> 
> class AsserterFactory
>     Asserter getAsserter(String name)
> 
> interface Asserter
>     void assertTrue(boolean condition, String message)
> 
>     class Java14Asserter
>         void assertTrue(boolean condition, String message)
>             assert condition : message;
> 
>     class StandardAsserter
>         void assertTrue(boolean condition, String message)
>             if(!condition) {
>                 throw new IllegalArgumentException(message)
>         }
> 
>     class PassiveAsserter
>         void assertTrue(boolean condition, String message) {
>             // Does nothing
>         }
> 
> 
> The asserter name could be a package name, a class name, or some other 
> type of
> identifier.  The configuration of these details may require system 
> properties
> or a default asserter.properties file to set up different asserters.
> 
> I can think of 2 difficulties presented by this approach, more
> specifically,
> with the dynamic nature of the RuntimeExceptions that a method may
> throw.
> 
>     1) Unit tests catch RuntimeExceptions to validate method behavior, 
> if assertions
>     were pluggable, switching them would cause a lot of tests to fail.
> 
>     2) The RuntimeExceptions that a method throws could not be
> documented.
> 
> 
> --------------------------------
> Conclusion
> --------------------------------
> Any thoughts or ideas?  Repetitive coding of validation and
> exception handling is starting to make me think that there is a better
> way.

The better (and standard) way is to utilize NPE.  

> There are even similar examples in [lang], where null-handling had to be
> updated for tens of methods at a time.

This is a known drawback in libraries that choose to check for null
instead of allowing the runtime to throw NPE.

> 
> 
> Imagine a similar concept, such as
> 
>     Validator
>         validate(Object o)
> 
>     StringValidator
>         validate(Object o) {
>             String s = (String)o
>             // Validate s
>         }
> 
> 
> Where users could supply their own validator:
> 
>     StringUtils.setValidator(StringValidator v)
> 
> and be guaranteed that the validate method would be called on any String
> 
> that is
> passed in.
> 
> Thanks in advance for any replies, my apologies for the chaos.

The proposed solution is much worse than the perceived problem.  Java
programmers instantly know how to debug a NPE in a stack trace.  Adding
some convoluted validation/assertion scheme puts an undue burden on the
library code and is likely to confuse the developer.

David

> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
> 


__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com