Where shoul I throw RuntimeException

D

dimka

Hi all!
I want to know, where can I use runtime exceptions?
For example, I have method like this:
public String getNameById(long id) {
Connection connection = null;
Statement st = null;
try {
connection = getConnection();
st = connection.createStatement();
ResultSet rs = st.executeQuery("SELECT NAME WHERE id=" + id);
if (!rs.next()) {
//--->Here, I can return null, throw RuntimeException, throw
catched exception<---
}
return rs.getString(1);
} catch (SQLException e) {
//--->Here, I can return null, throw RuntimeException, throw
catched exception<---
} finally {
closeConnectionAndStatement(st, connection);
}
}

In this example, I can return null and describe this in javadoc for
method. But, when other developer use this method, he cann't get id
from somewhere, he must know that object with this id exist...
Ever, when I should make a choice, I cann't choose right answer :(
What do you think about this?
 
A

Antti Järvinen

dimka said:
Hi all!
I want to know, where can I use runtime exceptions?
For example, I have method like this:
public String getNameById(long id) { ....
In this example, I can return null and describe this in javadoc for
method. But, when other developer use this method, he cann't get id
from somewhere, he must know that object with this id exist...
Ever, when I should make a choice, I cann't choose right answer :(
What do you think about this?

This is c++ -paper but applies well here too:

http://chaos.troll.no/~shausman/api-design/api-design.pdf

About the actual question about if you should communicate nonexistence
via
- null pointer returning
- checked exception
- unchecked (runtime) exception
is your choise and all are technically possible. I'd say it more depends
on how your api will be used by others ; you could actually ask the
end users what they want. My personal preference here would be
the first option, null pointer but the checked exception is good candidate
also if you like writing try/catch blocks instead of if() statements.
I'd say that unchecked exceptions are a no-no because they're not
self-documenting as checked exceptions that you either need to catch
or pass to upper level (again as checked exceptions). For really
unexpected situations go on with unchecked exceptions, I've used them
in situations where the whole application is in such a state that
it needs to be killed due to big internal mess.. :)
 
C

charlesbos73

Hi all!
I want to know, where can I use runtime exceptions?

If it's "where can I use unchecked exception versus
instead of checked exception?" the answer is "mostly
everywhere". Note the "mostly". Hard to argue with
that ;)

What do you think about this?

Take a look at how other have "solved" that problem
instead of re-inventing another broken "I query my
SQL DB by hand" piece of code.

I'd start with Spring's very cleanly designed
JDBC abstraction layer.

The amazing Spring framework's philosophy explicitely
states the following:

- "OO design is more important than any implementation
technology, such as J2EE"

- "Checked exceptions are overused in Java. A framework
shouldn't force you to catch exceptions you're unlikely to
be able to recover from."

Instead of diving into a code-writing frenzy, read on
how others have dealt with that exact same issue.

To me using Java's null as a return value from a method
and using checked exception are basically the anti-thesis
of OO.

That's what I think about this, but it's unlikely to
be an appreciated view on this newsgroup by those
who worship every piece of crap that made it into
Java and who affectionate passionately the GOTO-style
programming provided by checked exceptions, etc.

Once again, I'm the lucky one happening to be using
Java to do real OOP (as in "translating a wonderful
OOD into Java") while most people are using it as
a glorified hybrid between Visual Basic and PHP
(to query relational DBs of course... Mindboggling :)
 
A

Arved Sandstrom

charlesbos73 wrote:
[ SNIP ]
To me using Java's null as a return value from a method
and using checked exception are basically the anti-thesis
of OO.

Would you care to point out why you believe that returning a null from a
method is an anti-OOP thing to do? I've run across articles where people
express that viewpoint, but I don't know what your reason is.

If nothing else, null expresses the concept of no object. If a method is
being asked to return a reference to an object, and there is no object
that can be returned, guess what? You return null. There is nothing more
appropriate to return. I imagine you probably have some system where you
avoid doing this, but it'll be artificial and clumsy.

Checked exceptions have problems, sure. The biggest problem is that bad
programmers swallow them, and the program breaks. Are checked exceptions
an _antithesis_ of OOP? Hardly. Reputable commentators who argue against
having checked exceptions don't go so far as to say that - they just say
they don't much like checked exceptions.
That's what I think about this, but it's unlikely to
be an appreciated view on this newsgroup by those
who worship every piece of crap that made it into
Java and who affectionate passionately the GOTO-style
programming provided by checked exceptions, etc.

Here's a newsflash. If you had uniformly unchecked exceptions, and you
therefore were able to choose when and where to deal with them, how is
this not GOTO-style programming?

As for folks on this NG "worshipping every piece of crap" that is in
Java, you must be reading threads very selectively. Not one frequent
poster has failed to point out, from time to time, features of the
language that they don't like, that they think can be improved, or
features that they think should be added.
Once again, I'm the lucky one happening to be using
Java to do real OOP (as in "translating a wonderful
OOD into Java") while most people are using it as
a glorified hybrid between Visual Basic and PHP
(to query relational DBs of course... Mindboggling :)

I'm happy for you that you are able to do "real" OOP in Java and the
rest of us cannot. I'll have to revisit all the Java coding I've done
since 1998 and examine it closely to see why it isn't object-oriented.
Perhaps if you posted some code snippets for us we'd be able to see what
we've been doing wrong.

As far as accessing RDBMS's goes, I guarantee you that if you post
typical code that you use in an OODBMS environment to manipulate
persistent objects, it'll look very similar to the code _I_ use to
manipulate persistent objects in a JPA environment. So please tell me
what's better about what you are doing.

AHS
 
L

Lew

dimka said:
I want to know, where can I use runtime exceptions?

Runtime exceptions - trap conditions the client programmer should have
known better than to cause. Example - NullPointerException for a null
argument. The programmer should not pass a null argument, and will
fix the code if they discover this exception.

Checked exceptions - trap conditions in order to force the client code
to deal with it, usually not due to misuse of the call but to
situations outside of the client code's control. Example -
SQLException for an unexpected database state. There really is
nothing wrong with the code, the database just happened to be in a
different state this time. The API writer anticipated this, and put
the exception into the method signature to make sure that the client
code handles these "expected exceptions". It is unlikely that such
code will be rewritten just because this exception happens, and
there's no need or desire to halt the program for it.

Return a default value such as 'null' - when it makes sense in the
business logic that the condition is not exceptional but maps cleanly
to the range of the method. Example - returning 'null' if a record is
not found. "Not found" is a normal and expected result of a search,
and the client code will have conditional logic for this eventuality.
In this example, I can return null and describe this in javadoc [sic] for
method. But, when other developer use this method, he cann't get id
from somewhere, he must know that object with this id exist...

One period suffices to end a sentence.

If the method returns 'null' for an ID, doesn't that mean that no
object with this ID exists?
Ever, when I should make a choice, I cann't choose right answer :(

The right answer is the one you decide is right.

The Zen answer is, "Do what makes sense for the situation." It might
be different each time.

Part of the business of the API writer, even for use in one's own
client code, is to determine how clients will use the API, and prevent
abuse of the API.
 
L

Lew

charlesbos73 said:
To me using Java's null as a return value from a method
and using checked exception are basically the anti-thesis [sic]
of OO.

Arved said:
Would you care to point out why you believe that returning a null from a
method is an anti-OOP thing to do? I've run across articles where people
express that viewpoint, but I don't know what your reason is.

If that were true, wouldn't returning any value be antithetical to
OOP?
If nothing else, null expresses the concept of no object. If a method is
being asked to return a reference to an object, and there is no object
that can be returned, guess what? You return null. There is nothing more
appropriate to return. I imagine you probably have some system where you
avoid doing this, but it'll be artificial and clumsy.

'null' is sometimes used to signify something like "UNKNOWN" in a
three-valued logic, and often as a sentinel value. I agree that
there's nothing inherently un-OOPish about sentinel values. Their
signal characteristic is that they be out of band for the range of the
method; 'null' fulfills that condition sweetly.
Checked exceptions have problems, sure. The biggest problem is that bad
programmers swallow them, and the program breaks. Are checked exceptions
an _antithesis_ of OOP? Hardly. Reputable commentators who argue against
having checked exceptions don't go so far as to say that - they just say
they don't much like checked exceptions.

I assess that people who dislike checked exceptions are those who
write client code that is forced to handle them. That is, of course,
the reason why checked exceptions exist - to force client code to deal
with them. Checked exceptions are an API writer's friend.

Client-code authors should embrace checked exceptions; when they're
defined appropriately, they strongly assist client code in anticipated
and handling certain conditions.

Begging the question, straw-man argument and ad hominem remarks.
Here's a newsflash. If you had uniformly unchecked exceptions, and you
therefore were able to choose when and where to deal with them, how is
this not GOTO-style programming?

As for folks on this NG "worshipping every piece of crap" that is in
Java, you must be reading threads very selectively. Not one frequent
poster has failed to point out, from time to time, features of the
language that they don't like, that they think can be improved, or
features that they think should be added.

One of the distinguishing aspects of the Java programmers' culture is
that we don't drink the Kool-Aid. We're a curmudgeonly lot, all of us
convinced we could have designed it better and vocal in our opinions
of how to improve it. I know of few if any other programming
languages with a more devotedly whiny constituency.
I'm happy for you that you are able to do "real" OOP in Java and the
rest of us cannot. I'll have to revisit all the Java coding I've done
since 1998 and examine it closely to see why it isn't object-oriented.
Perhaps if you posted some code snippets for us we'd be able to see what
we've been doing wrong.

As far as accessing RDBMS's goes, I guarantee you that if you post
typical code that you use in an OODBMS environment to manipulate
persistent objects, it'll look very similar to the code _I_ use to
manipulate persistent objects in a JPA environment. So please tell me
what's better about what you are doing.

The short answer is that what he's doing isn't actually better, just
another way.
 
R

Roedy Green

Hi all!
I want to know, where can I use runtime exceptions?
For example, I have method like this:
public String getNameById(long id) {
Connection connection = null;
Statement st = null;
try {
connection = getConnection();
st = connection.createStatement();
ResultSet rs = st.executeQuery("SELECT NAME WHERE id=" + id);
if (!rs.next()) {
//--->Here, I can return null, throw RuntimeException, throw
catched exception<---
}
return rs.getString(1);
} catch (SQLException e) {
//--->Here, I can return null, throw RuntimeException, throw
catched exception<---
} finally {
closeConnectionAndStatement(st, connection);
}
}

In this example, I can return null and describe this in javadoc for
method. But, when other developer use this method, he cann't get id
from somewhere, he must know that object with this id exist...
Ever, when I should make a choice, I cann't choose right answer :(
What do you think about this?

see http://mindprod.com/jgloss/exception.html

You can throw them anywhere, so you might as well throw them as soon
as you discover the trouble.
--
Roedy Green Canadian Mind Products
http://mindprod.com

"If people become accustomed to lying, they will unconsciously commit every possible wrong deed. Before they can act wickedly, they must lie, and once they begin to lie they will act wickedly without concern."
~ Gautama Buddha
 
L

Lew

I said:
I'm kind of theoretically skeptical about Java's checked exceptions,
although the problem isn't the checking, but having to specify them,
which forces code that otherwise doesn't need to know about exceptions to
deal with them.

That makes exactly as much sense as complaining that 'Baz foo( Bar
arg )' forces client code to use an argument of type 'Bar' and to deal
with a return type of 'Baz' when it otherwise wouldn't have to deal
with them.

The whole *point* of checked exceptions is to force client code to
deal with them.
The fact that exceptions propagate through layers until
they reach the appropriate level at which to handle them is one of their
advantages; forcing the author to specify exceptions at every level gets
in the way of that, cluttering the intermediate layers. The compiler

But that is the point of checked exceptions. If the API writer didn't
want the client to deal with them, he'd have used a runtime exception.

Checked exceptions exist for the very purpose of making client code
deal with them. Complaining that they do what they're designed to do
is very strange.
knows (or, could work out) what exceptions a method could throw, and it
could check they get handled without requiring they are specified
explicitly.

That is a simplistic suggestion. The compiler cannot know what
subtypes' overrides might throw, and this suggestion wouldn't let the
API writer control exceptions as part of the method signature.
Remember that one of the design principles of Java is to support
strong typing and the concomitant type safety. Checked exceptions are
representative of that philosophy.
Having said that, I haven't actually found specifying exceptions to be as
much as a problem as I would have imagined. I'm coming round to the view
that the distinction between checked and unchecked exceptions reflects a
pretty real distinction between those exceptions that should be handled
close to where they occur, and those that don't.

This is a false dichotomy.

The difference isn't where they're handled but whether the client code
should be forced to handle them. The rule of thumb is that runtime
exceptions require a code change in the client to eliminate them,
checked exceptions do not.
 
T

Tom Anderson

I want to know, where can I use runtime exceptions?
For example, I have method like this:
public String getNameById(long id) {
Connection connection = null;
Statement st = null;
try {
connection = getConnection();
st = connection.createStatement();
ResultSet rs = st.executeQuery("SELECT NAME WHERE id=" + id);
if (!rs.next()) {
//--->Here, I can return null, throw RuntimeException, throw
catched exception<---
}
return rs.getString(1);
} catch (SQLException e) {
//--->Here, I can return null, throw RuntimeException, throw
catched exception<---
} finally {
closeConnectionAndStatement(st, connection);
}
}

In this example, I can return null and describe this in javadoc for
method. But, when other developer use this method, he cann't get id
from somewhere, he must know that object with this id exist...
Ever, when I should make a choice, I cann't choose right answer :(
What do you think about this?

I think that method should throw SQLException.

It definitely should not return null - that's almost never a good idea. It
shouldn't throw a RuntimeException, because that won't force the callers
to face up to the possiblity of failure. It could throw another checked
exception, perhaps a domain-specific one like DimkaDataLayerException,
rather an an SQLException. But what is certain - although others, who
labour in ignorance or sin, may disagree - is that it should throw a
checked exception. If there is a real possibility of failure, callers
should be made aware of it, and be made to prepare for it.

tom
 
L

Lew

Tom said:
...
But what is certain
- although others, who labour in ignorance or sin, may disagree - is
that it should throw a checked exception.
Amen.

If there is a real possibility
of failure, callers should be made aware of it, and be made to prepare
for it.

Spoken like a good API designer.
 
K

Karl Uppiano

I V said:
I'm kind of theoretically skeptical about Java's checked exceptions,
although the problem isn't the checking, but having to specify them,
which forces code that otherwise doesn't need to know about exceptions to
deal with them. The fact that exceptions propagate through layers until
they reach the appropriate level at which to handle them is one of their
advantages; forcing the author to specify exceptions at every level gets
in the way of that, cluttering the intermediate layers. The compiler
knows (or, could work out) what exceptions a method could throw, and it
could check they get handled without requiring they are specified
explicitly.

If you don't know how to deal with a checked exception, then you ignore it,
and declare that your method might "throw" it. Or you catch it, and re-throw
it as something that you want your API to throw. How else will you tell
*your* callers about it?
Having said that, I haven't actually found specifying exceptions to be as
much as a problem as I would have imagined. I'm coming round to the view
that the distinction between checked and unchecked exceptions reflects a
pretty real distinction between those exceptions that should be handled
close to where they occur, and those that don't.

Yes, the Java designers were very thoughtful in realizing that there are
situations where you want checked exceptions, and ones where you don't. My
quibble is in the choice of the Java API making some exceptions checked that
I think should be unchecked, and vice versa -- e.g., we had a discussion
here about InterruptedException a while back. Not everyone agreed with me.
Most peculiar, mama!
 
G

Giovanni Azua

Hi Dimka,

Some time ago I came across a quote that said something like "if your
country is ruled by a committee, be in that committee" being an expat from a
communist country this quote sounded very unpleasant to me but I think it
fits your question very well. Whenever I find myself in this same kind
dilemma I many times just dive into the Sun JDK API looking for similar
contexts and patterns to resolve the very same problem, they are the
"committee". You might also decide not to comply with the committee e.g. I
don't think that IllegalArgumentException should be used in the JDK in the
way it does now, the right tool should be assertions, because assertions
were added later to the language, I think from 1.4.x most likely this is a
backward compatibility issue.

dimka said:
public String getNameById(long id) {
If there would be anything to throw even if it is a RuntimeException
subclass, you should make it explicit in the method declaration as "throws
XXXException" this will get documented in the javadocs and give your clients
some clue of what could go wrong.
Connection connection = null;
Statement st = null;
try {
connection = getConnection();
st = connection.createStatement();
ResultSet rs = st.executeQuery("SELECT NAME WHERE id=" + id);
if (!rs.next()) {
//--->Here, I can return null, throw RuntimeException, throw
catched exception<---
See how Sun's JPA API resolves a similar issue:
http://java.sun.com/javaee/5/docs/a....html#find(java.lang.Class, java.lang.Object)

In this case they just return null. Now, beware that returning null is one
of the main causes of the very profane NullPointerException. There are ways
around it e.g. using the NullObject pattern but in this case that you return
a String the most sensitive thing to do would be returning null.
http://en.wikipedia.org/wiki/Null_Object_pattern
}
return rs.getString(1);
} catch (SQLException e) {
//--->Here, I can return null, throw RuntimeException, throw
If you see a catch, it is not a good idea to firstly just think what to
re-throw. You should rather first think hard what can you do at that point
to recover to fulfill the client's request. This is precisely the definition
of "Robustness" in Software Engineering "Robustness is the ability of
software systems to react appropriately to abnormal conditions" abnormal
conditions being Exceptions see Object Oriented Software Construction by
Bertrand Meyer.

Now, if there is nothing you can really do and you must really throw or
re-throw an exception, then from the design prospective it is not a good
idea to let the client of this code deal with inners of the persistence API,
the SQLException. You should rather throw to the client a more "service"
level-like exception e.g. PersonNotFoundException or at most DaoException

More on checked vs unchecked:

In EJB 3.0 the choice of checked vs. unchecked exceptions has strong
semantics compared to how it was before i.e. checked exceptions are assumed
by the EJB 3 specification to be "application exceptions" and when thrown
they will not rollback the transaction. Unchecked exceptions are assumed
"system exceptions" and when thrown they will cause the transaction to
rollback and even get the container to discard the Bean instance without not
even chance for disposal lifecycle callbacks i.e. @PreDestroy

I am not particularly fond of checked exceptions but I think this would be a
valid strategy to decide what the type of an exception should be. In a
"design by contract" approach a method would look like:

pre-conditions: conditions that the client must respect for the method to
fulfill its service e.g. arg1 must not be null
Method(arg1)
class-invariants: conditions that should be invariant during the lifetime of
an instance of the class
post-conditions: conditions or guarantees of the service offered by the
method e.g. in the case above that the name was found and is a valid name
not an empty string

Checked exceptions: because they force the client of the routine to handle
it, I would only make the client handle situations that they have control of
i.e. the pre-condition. The client is responsible for passing valid input,
so if they do not, they must be ready to fix it and retry. But notice that
the committee in this case decided IllegalArgumentException should be
unchecked and I don't blame them for that.

Unchecked exceptions: to signal that the Method could not fulfill its
promise, the client can do little about this, exactly the situation depicted
above. What can the client of "getNameById" possibly do with a SQLException?
nothing! If the client tried to fix it that would mean that the client would
be trying to do "getNameById"'s job in some way and this would break the
clean distribution of concerns leading to:

- tangled code: the client will not only implement business logic but also
low level persistence non-functional concerns
- scattered code: the same non functional concern is spread across many
disparate parties: Client, Dao, etc the right recipe for a nice spaghetti.

HTH,
Best regards,
Giovanni
 
L

Lew

Giovanni said:
Some time ago I came across a quote that said something like "if your
country is ruled by a committee, be in that committee" being an expat from a
communist country this quote sounded very unpleasant to me but I think it
fits your question very well. Whenever I find myself in this same kind
dilemma I many times just dive into the Sun JDK API looking for similar
contexts and patterns to resolve the very same problem, they are the
"committee". You might also decide not to comply with the committee e.g. I
don't think that IllegalArgumentException should be used in the JDK in the
way it does now, the right tool should be assertions, because assertions
were added later to the language, I think from 1.4.x most likely this is a
backward compatibility issue.

That is very wrong. Assertions are not exceptions and cannot nor should not
be used for argument checking on public methods.
If there would be anything to throw even if it is a RuntimeException
subclass, you should make it explicit in the method declaration as "throws
XXXException" this will get documented in the javadocs and give your clients
some clue of what could go wrong.

No. It is useless to declare runtime exceptions in the signature, though it's
wise to Javadoc them.

Null makes sense in this particular case.
In this case they just return null. Now, beware that returning null is one
of the main causes of the very profane NullPointerException.
"Profane"?

There are ways
around it e.g. [sic] using the NullObject pattern but in this case that you return
a String the most sensitive thing to do would be returning null.
Sometimes.
....
I am not particularly fond of checked exceptions but I think this would be a

I am particularly fond of checked exceptions.
valid strategy to decide what the type of an exception should be. In a
"design by contract" approach a method would look like:

pre-conditions: conditions that the client must respect for the method to
fulfill its service e.g. arg1 must not be null
Method(arg1)
class-invariants: conditions that should be invariant during the lifetime of
an instance of the class
post-conditions: conditions or guarantees of the service offered by the
method e.g. in the case above that the name was found and is a valid name
not an empty string

These are enforced by exception, proven by assertion.
 
G

Giovanni Azua

Lew said:
That is very wrong. Assertions are not exceptions and cannot nor should
not be used for argument checking on public methods.
because ... ?
No. It is useless to declare runtime exceptions in the signature, though
it's wise to Javadoc them.
That must be why it is the standard in the JDK, see e.g. this same method
declares throws IllegalArgumentException and IllegalStateException both
RuntimeExceptions
http://java.sun.com/javaee/5/docs/a....html#find(java.lang.Class, java.lang.Object)

Giovanni
 
G

Giovanni Azua

Hi Eric,

Eric Sosman said:
because ... ?
Because they [assertions] can be turned off at run-time, leaving you with
no validity-checking at all.
In general I disagree with this rule "do not use assertions to check the
parameters of a public method":
http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html#usage-conditions

These would be the possible scenarios interacting with an API:

1-. Human to software interaction: end-user enters data
2-. External system to software interaction: binary interoperability of
separate components e.g. MOM
3-. Software to software interaction: a library e.g. JDK is being used to
develop some application

In cases #1 and #2 it is necessary to use exceptions e.g.
IllegalArgumentException to deal with *Input Validation*. This is because #1
and #2 are the front-line layers that deal with input outside the control of
the application. These are the "filter modules" to the outside world. Using
assertions to deal with Input Validation indeed would be wrong and "wishful
thinking" as Bertrand Meyer calls it.

Now point #3 is the case of application interacting with a library e.g. JDK.
There is no external wrong input to deal with but only programming errors, a
precondition violation is a programming error in the client of the routine
or class. Programming errors must be discovered during testing and debugging
cycles when assertions are enabled and not in production.

I just want to stress that there is a difference between Input Validation
and preconditions checks (assertions):
"Object Oriented Software Construction 2nd Edition" Bertrand Meyer, page 345
"Assertions are not an input checking mechanism".

I also included a note on this, see "Defensive Programming Approach":
http://perfectjpattern.sourceforge.net/design-notes.html

Best regards,
Giovanni
 
G

Giovanni Azua

Hello Eric,

Eric Sosman said:
Thought experiment: Should the array-accessing operation treat
the index value as an input to be validated, or as a precondition
whose validity has been established during the testing phase and
need not be checked thereafter? That is, would you be in favor of
checking indices with an assert-like mechanism that could be turned
off once the code had passed enough tests? Surely it's a programming
error if the code generates an invalid index; should the detection
of that error be suppressable?
To be honest I'd personally prefer to spare all the worthless and expensive
validations and hence the [substantial?] performance overhead resulting from
this Defensive Programming approach when I know my code is throughly tested.
I really prefer here the C++ way, they assume you know what you are doing.
On the other hand, If you know your Java code is not well tested then you
would still have the choice to run it -ea in production ... though it would
be a very lame acknowledgement.
Your distinction between validation and precondition checking
is, I think, a reasonable one to draw in private and package-
private methods. But a public or protected method is too "exposed"
to take advantage of such a distinction, and should IMHO treat all
inputs as coming from "the outside."
I believe this is a decision of the API or public method designer to make,
of whether the API in question is supposed to be exposed to "the outside" or
not. I find that the decision made in JDK to go for the defensive
programming approach is by all means very pragmatic but hinders those who
actually know what they are doing.

Best regards,
Giovanni
 
L

Lew

Eric said:
Because they [assertions] can be turned off at run-time, leaving you with
no validity-checking at all.

Because, also, that is not the purpose of assertions. Assertions do
not validate, they prove that validation has been done.
In general I disagree with this rule "do not use assertions to check the
parameters of a public method":http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html#usage-...

Then you are mistaken, and are completely misusing assertions.

Assertions exist to prove invariants. They are to prove that things
under the API writer's control have been handled, e.g., that an
exception has been thrown to prevent a bad parameter. They do not and
cannot substitute as public variable validators.

Giovanni said:
These would be the possible scenarios interacting with an API:

1-. Human to software interaction: end-user enters data
2-. External system to software interaction: binary interoperability of
separate components e.g. MOM
3-. Software to software interaction: a library e.g. JDK is being used to
develop some application

In cases #1 and #2 it is necessary to use exceptions e.g.
IllegalArgumentException to deal with *Input Validation*. This is because #1
and #2 are the front-line layers that deal with input outside the control of
the application. These are the "filter modules" to the outside world. Using
assertions to deal with Input Validation indeed would be wrong and "wishful
thinking" as Bertrand Meyer calls it.

Now point #3 is the case of application interacting with a library e.g. JDK.
There is no external wrong input to deal with but only programming errors, a
precondition violation is a programming error in the client of the routine
or class. Programming errors must be discovered during testing and debugging
cycles when assertions are enabled and not in production.

While the principle is true, that does not change the fact that
assertions are not the right way to validate input. Exceptions
validate, assertions prove.
I just want to stress that there is a difference between Input Validation
and preconditions checks (assertions):
"Object Oriented Software Construction 2nd Edition" Bertrand Meyer, page 345
"Assertions are not an input checking mechanism".

I also included a note on this, see "Defensive Programming Approach":http://perfectjpattern.sourceforge.net/design-notes.html

If that note promotes the same misconception about assertions that you
are spreading here, then you should study up on them and revise your
note.

Read and study Sun's little tutorial on the matter:
<http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html>

Among other things, it teaches:
There are also a few situations where you should not use them:
* Do not use assertions for argument checking in public methods.
Argument checking is typically part of the published specifications
(or contract) of a method, and these specifications must be obeyed
whether assertions are enabled or disabled. Another problem with
using assertions for argument checking is that erroneous arguments
should result in an appropriate runtime exception (such as
IllegalArgumentException, IndexOutOfBoundsException, or NullPointerException).
An assertion failure will not throw an appropriate exception.

* Do not use assertions to do any work that your application
requires for correct operation.
Because assertions may be disabled, programs must not assume that the
boolean expression contained in an assertion will be evaluated.
Violating this rule has dire consequences.

Suggesting otherwise does a huge disservice to anyone who believes
you.
 
L

Lew

Giovanni said:
To be honest I'd personally prefer to spare all the worthless and expensive
validations and hence the [substantial?] performance overhead resulting from
this Defensive Programming approach when I know my code is throughly tested.
I really prefer here the C++ way, they assume you know what you are doing.
On the other hand, If you know your Java code is not well tested then you
would still have the choice to run it -ea in production ... though it would
be a very lame acknowledgement.

This is an erroneous argument. No matter how well tested your code
is, you cannot test other people's code that they haven't yet
written. All you can do is put in validation checks, using exceptions
or default return values. You use assertions to prove that your
validation checks are correct, as part of your thorough testing, not
as a replacement for validation checks.

Calling someone's code "lame" because they programmed against someone
else's future misuse is in itself quite lame.
I believe this is a decision of the API or public method designer to make,
of whether the API in question is supposed to be exposed to "the outside" or
not. I find that the decision made in JDK to go for the defensive
programming approach is by all means very pragmatic but hinders those who
actually know what they are doing.

An API writer has the responsibility to enforce proper use of the code
in the public, your disingenuous redefinition of the word "public"
notwithstanding. Structure does not "hinder" those who "know what
they are doing", a set one excludes oneself from by misrepresenting
the purpose of assertions. On the contrary, structure supports those
who know what they're doing by providing guarantees of certain
behaviors, sparing the client code from having to do such thing on the
API's behalf.

Also, merely characterizing argument checking and such techniques as
"defensive programming" and then disparaging it by arrogating some
special knowledge to oneself puts the cart before the horse. Properly-
written APIs are pre-emptive programming, not defensive - they rigidly
enforce a contract on which client code can then rely. This is not
some psychological condescension to less-experienced programmers, as
you falsely present it. It's rigorous coding to prevent bugs as a
safety guarantee to all future use of the API, even if it is strictly
within a single project. It is properly the province of a method or
class to enforce its own invariants, and not be all loosey-goosey on
the client code only then to blame the other programmer in the event
of error. It is the proper allocation of responsibility to do what
you so disparagingly call "defensive programming".

As those who actually know what they are doing well know.
 
L

Lew

Side note: in my earlier poast the single-">" quote are from Giovanni
Azua, not Eric Sosman unless specified to be from the Sun document on
assertions.


I was astounded to realize that you were citing the same document that
disproves your comments about assertions that I cited via a different
link. Your link is the more modern one. You should read that
document again until you realize why they say what they say.
Then you are mistaken, and are completely misusing assertions.

Based on what you write here, and on a few things I read on that site,
I am going to keep a good healthy distance from the "Perfect
JPattern".
 
G

Giovanni Azua

Lew said:
This is an erroneous argument. No matter how well tested your code
is, you cannot test other people's code that they haven't yet written.
LOL indeed you can't, they should test it themselves :)
All you can do is put in validation checks, using exceptions
or default return values. You use assertions to prove that your
validation checks are correct, as part of your thorough testing, not
as a replacement for validation checks.
I think this is wrong. Besides, assertions were introduced in Java as an
"informal" design by contract:
"While the assert construct is not a full-blown design-by-contract facility,
it can help support an informal design-by-contract style of programming."
http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html

You need to understand design-by-contract and judging by your explanations I
think you don't.
Calling someone's code "lame" because they programmed against someone
else's future misuse is in itself quite lame.
No. I said lame because enabling -ea in production would mean that the code
was not tested well and would be quality-wise inadequate to roll into
production. It is in fact not uncommon to see projects rolled into
production with -ea enabled and it is always rooted by concerns about the
lack of quality.
An API writer has the responsibility to enforce proper use of the code
in the public, your disingenuous redefinition of the word "public"
[snip]
"defensive programming" and then disparaging it by arrogating some
special knowledge to oneself puts the cart before the horse. Properly-
[snip]
Fallacies, you are a notorious master in this area. It is a pity because you
keep undermining what would otherwise be very interesting discussions. I
don't mind if you don't understand some of the arguments, I am happy to
clarify and help but your rhetorical behavior is far from useful.
Based on what you write here, and on a few things I read on that site,
I am going to keep a good healthy distance from the "Perfect
JPattern".
I don't think you even read properly what I wrote, because the design notes
explain that PerfectJPattern complies to the JDK design principles explained
under http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html
therefore if you are saying that because of what I wrote there you don't
want to use it, it does not really make much sense.

Another very different thing is how I believe validation and assertions
should be used based on what I know about design-by-contract and this was
the main topic being discussed.

Best regards,
Giovanni
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top