Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #12858 > unrolled thread

Exception Handling

Started byNovice <novice@example..com>
First post2012-03-11 01:51 +0000
Last post2012-03-13 06:05 -0300
Articles 20 on this page of 37 — 8 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Exception Handling Novice <novice@example..com> - 2012-03-11 01:51 +0000
    Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-10 18:39 -0800
      Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-11 11:53 -0300
        Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-11 10:51 -0700
          Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-11 16:35 -0300
      Re: Exception Handling Novice <novice@example..com> - 2012-03-11 17:05 +0000
        Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-11 10:53 -0700
          Re: Exception Handling Novice <novice@example..com> - 2012-03-11 20:36 +0000
        Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-11 11:07 -0700
          Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-11 17:00 -0300
            Re: Exception Handling Novice <novice@example..com> - 2012-03-11 22:02 +0000
          Re: Exception Handling Arivald <NOSPAMarivald@interia.pl> - 2012-03-11 21:03 +0100
            Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-11 18:31 -0300
          Re: Exception Handling Novice <novice@example..com> - 2012-03-11 21:54 +0000
            Re: Exception Handling Patricia Shanahan <pats@acm.org> - 2012-03-11 15:26 -0700
              Re: Exception Handling Novice <novice@example..com> - 2012-03-11 23:23 +0000
                Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-11 16:52 -0700
                  Re: Exception Handling Novice <novice@example..com> - 2012-03-12 17:16 +0000
                    Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-13 08:31 -0700
                Re: Exception Handling Patricia Shanahan <pats@acm.org> - 2012-03-11 17:51 -0700
                  Re: Exception Handling Novice <novice@example..com> - 2012-03-12 17:26 +0000
              Re: Exception Handling Arne Vajhøj <arne@vajhoej.dk> - 2012-03-12 14:49 -0400
            Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-11 20:46 -0300
              Re: Exception Handling Novice <novice@example..com> - 2012-03-12 17:43 +0000
        Re: Exception Handling Patricia Shanahan <pats@acm.org> - 2012-03-11 11:14 -0700
          Re: Exception Handling Novice <novice@example..com> - 2012-03-11 22:35 +0000
            Re: Exception Handling Lew <noone@lewscanon.com> - 2012-03-11 16:58 -0700
              Re: Exception Handling Novice <novice@example..com> - 2012-03-12 15:44 +0000
                Re: Exception Handling Gene Wirchenko <genew@ocis.net> - 2012-03-12 10:34 -0700
        Re: Exception Handling Arivald <NOSPAMarivald@interia.pl> - 2012-03-11 20:34 +0100
          Re: Exception Handling Novice <novice@example..com> - 2012-03-11 22:36 +0000
      Re: Exception Handling Arne Vajhøj <arne@vajhoej.dk> - 2012-03-12 14:41 -0400
    Re: Exception Handling Arne Vajhøj <arne@vajhoej.dk> - 2012-03-12 14:37 -0400
      Re: Exception Handling Novice <novice@example..com> - 2012-03-12 22:43 +0000
        Re: Exception Handling Lew <lewbloch@gmail.com> - 2012-03-12 16:11 -0700
        Re: Exception Handling Arivald <NOSPAMarivald@interia.pl> - 2012-03-13 00:54 +0100
          Re: Exception Handling Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2012-03-13 06:05 -0300

Page 1 of 2  [1] 2  Next page →


#12858 — Exception Handling

FromNovice <novice@example..com>
Date2012-03-11 01:51 +0000
SubjectException Handling
Message-ID<XnsA012D42584994jpnasty@94.75.214.39>
I've been trying to get my head around exception handling for the last 
few days concurrently with my efforts to start doing logging correctly. 

I've re-read the Java Tutorials section on exception handling. I read 
Bloch's remarks on Exception Handling in Effective Java (2nd edition) 
several days ago. I'm working my way through Stelting's Robust Java. 

It's time to ask some questions to make sure I'm on the right track. 

I'm struggling with the best way to revise some of my existing code. 
Let's consider a concrete example and then see if we can generalize to 
come up with a proper error handling strategy.

I have a utility class called LocalizationUtils which basically houses 
convenience methods dealing with i18n/l10n. One of its methods is 
getResources(). It expects two parameters, a String representing the 
"base name" (the leading part of the resource file name) and a locale. 

Here's the code for getResources() with all comments and error handling 
(aside from the empty catch block) stripped out:

====================================================================
static public ResourceBundle getResources(String baseName, Locale locale 
{
  ResourceBundle locList = null;

  try {
    locList = ResourceBundle.getBundle(baseName, locale);
      } 
  catch (MissingResourceException mrExcp) {
    }

  return (locList);
}
====================================================================

The program which is executing is Foo. It has a method called 
getLocalizedText() which is the one executing 
LocalizationUtils.getResources(). The value of the baseName is a constant 
coded in an interface of constants called FooConstants which is 
implemented by Foo. Here's the code for getLocalizedText() without any 
error handling and just one relevant comment: 

====================================================================
private void getLocalizedText() {
		
  Locale locale = Locale.getDefault();
	    
  this.myText = LocalizationUtils.getResources(TEXT_BASE, locale);
  this.myMsg = LocalizationUtils.getResources(MSG_BASE, locale);

  /* Work with the localized resources. */  	
}  		
====================================================================

In terms of trouble spots, I know from experience that getResources() 
will throw a MissingResourceException, which is an unchecked exception, 
if the base name is misspelled. A null value in either parameter is also 
going to make the getResources() method fail: ResourceBundle.getBundle() 
will throw a NullPointerException if either parameter is null. 

My objective is to code getResources() and getLocalizedText() as 
professionally as possible. If the methods fail, I want to write a clear 
message to my log and the log record needs to include a stacktrace. (I'm 
assuming that a console is not necessarily available to the operators 
running this program and I need to know where the error took place. Based 
on an article Arved suggested in another thread, 
http://www.javacodegeeks.com/2011/01/10-tips-proper-application-
logging.html, I'm inclined to minimize "position" information - class 
name, method name, line number - in the log and instead get all of that 
from the stacktrace.) 

Now, finally, here are some questions:

Since the only exceptions I anticipate, MissingResourceException and 
NullPointerException, are unchecked exceptions, I gather than I shouldn't 
really do anything about them aside from logging when they happen. Okay, 
fair enough; I certainly don't want to display the source code to my 
user, make them enter the correct value for the baseName, make them 
recompile the program and then run it again! But when/where should I log 
the error? For instance, if I mess up my coding somehow and inadvertently 
pass a null in the baseName, should getResources() be testing its input 
parameters individually to see if they are null and write a message to 
the log if they are null from within that method? I'm inclined to say yes 
to that but I'm not sure what to do next. It seems pointless to carry on 
with getResources() since ResourceBundle.getBundle(baseName, locale)  
will fail on a NullPointerException with a null in either parameter. I 
could throw a NullPointerException so that getLocalizedText() can deal 
with it. But how do I get a stacktrace into the log if I follow that 
strategy? It's easy enough to get the stacktrace once I've caught an 
exception but I'm just talking about recognizing that an input parameter 
is null; there's no exception at that point to put in my log. 

If I let getResources() throw NullPointerException if either parameter is 
null, then I can let getLocalizedText() catch those NullPointerExceptions 
and get the stacktraces from the exception and write them to the log. In 
that case, I may as well just check the input parameters for nulls, and 
simply throw NullPointerException with a specific message within 
getResources(); then getLocalizedText() can have a try/catch block. The 
try/catch can detect the NullPointerException and write both the message 
and the stacktrace to the log. 

But I gather that you should handle the error as close to where it 
happened as possible when you can. I'd tend to prefer to handle the null 
parameter values in getResources() except that I'm not sure how to write 
the stack trace to the log before any exception has happened.

One other questions. When, if ever, should I execute System.exit() with a 
non-zero integer? In my example, I know that program Foo can't proceed 
without the resources it is trying to get in getResources() so if I 
simply throw exceptions and write to the log and then let the program 
keep going, I'm simply going to get another NullPointerException on the 
first statement that tries to use the resources. I'm thinking that I 
should do a System.exit(1) after I've logged a null parameter or in the 
event of a MissingResourceException in getResources(). But I have yet to 
see System.exit() used in ANY example of error handling in any resource 
I've looked at so far.

-- 
Novice

[toc] | [next] | [standalone]


#12859

FromLew <noone@lewscanon.com>
Date2012-03-10 18:39 -0800
Message-ID<jjh39f$crc$1@news.albasani.net>
In reply to#12858
Novice wrote:
snip
> I have a utility class called LocalizationUtils which basically houses
> convenience methods dealing with i18n/l10n. One of its methods is
> getResources(). It expects two parameters, a String representing the
> "base name" (the leading part of the resource file name) and a locale.
>
> Here's the code for getResources() with all comments and error handling
> (aside from the empty catch block) stripped out:
>
> ====================================================================
> static public ResourceBundle getResources(String baseName, Locale locale
> {
>    ResourceBundle locList = null;

Don't use throwaway initializations, usually.

>    try {
>      locList = ResourceBundle.getBundle(baseName, locale);
>        }
>    catch (MissingResourceException mrExcp) {

Log and return 'null' if that's the recovery strategy for this exception.

>      }
>
>    return (locList);
> }
> ====================================================================
>
> The program which is executing is Foo. It has a method called
> getLocalizedText() which is the one executing
> LocalizationUtils.getResources(). The value of the baseName is a constant
> coded in an interface of constants called FooConstants which is
> implemented by Foo. Here's the code for getLocalizedText() without any
> error handling and just one relevant comment:

Using an interface to define constants is the "Constant Interface 
Antipattern". (Google it.) Use a class to define constants, not an interface.

An interface is there to define a type. Using it merely to define constants 
violates the spirit of interfaces, which is to avoid implementation.

> ====================================================================
> private void getLocalizedText() {
> 		
>    Locale locale = Locale.getDefault();
> 	
>    this.myText = LocalizationUtils.getResources(TEXT_BASE, locale);
>    this.myMsg = LocalizationUtils.getResources(MSG_BASE, locale);
>
>    /* Work with the localized resources. */  	
> }  		
> ====================================================================
>
> In terms of trouble spots, I know from experience that getResources()
> will throw a MissingResourceException, which is an unchecked exception,
> if the base name is misspelled. A null value in either parameter is also
> going to make the getResources() method fail: ResourceBundle.getBundle()
> will throw a NullPointerException if either parameter is null.
>
> My objective is to code getResources() and getLocalizedText() as
> professionally as possible. If the methods fail, I want to write a clear
> message to my log and the log record needs to include a stacktrace. (I'm

example:

   logger.error(message, exception);

> assuming that a console is not necessarily available to the operators
> running this program and I need to know where the error took place. Based
> on an article Arved suggested in another thread,
> http://www.javacodegeeks.com/2011/01/10-tips-proper-application-
> logging.html, I'm inclined to minimize "position" information - class
> name, method name, line number - in the log and instead get all of that
> from the stacktrace.)

I disagree.

I'd keep that class/method info in the log message. Line information is less 
valuable unless your methods are far, far too long.

> Now, finally, here are some questions:
>
> Since the only exceptions I anticipate, MissingResourceException and
> NullPointerException, are unchecked exceptions, I gather than I shouldn't
> really do anything about them aside from logging when they happen. Okay,

I disagree. You should end the program gracefully and get someone to fix the 
programming error right away.

> fair enough; I certainly don't want to display the source code to my
> user, make them enter the correct value for the baseName, make them
> recompile the program and then run it again! But when/where should I log
> the error? For instance, if I mess up my coding somehow and inadvertently

In the log file.

> pass a null in the baseName, should getResources() be testing its input
> parameters individually to see if they are null and write a message to
> the log if they are null from within that method? I'm inclined to say yes

Always check all parameters for validity, either by an explicit check for a 
public or protected method, or by controlling what's passed to package-private 
or private methods.

A normal practice is to have an application-specific checked exception to 
throw, or to throw the standard unchecked exception. For example:

  if (argument == null)
  {
    final String msg = "null argument";
    IllegalArgumentException except = new IllegalArgumentException(msg);
    logger.error(msg, except);
    throw except;
  }

or similarly for application checked exception 'FooException'.

   throw new FooException(new IllegalArgumentException(msg));

Somewhere up the stack you should catch the exception and convert it to valid 
program state"

  catch(RuntimeException except)
  {
    forwardProgramControlToErrorScreen();
  }

> to that but I'm not sure what to do next. It seems pointless to carry on
> with getResources() since ResourceBundle.getBundle(baseName, locale)
> will fail on a NullPointerException with a null in either parameter. I
> could throw a NullPointerException so that getLocalizedText() can deal
> with it. But how do I get a stacktrace into the log if I follow that
> strategy? It's easy enough to get the stacktrace once I've caught an
> exception but I'm just talking about recognizing that an input parameter
> is null; there's no exception at that point to put in my log.

There is if you create one. That's why Java has the 'new' operator.

> If I let getResources() throw NullPointerException if either parameter is

Better, use 'IllegalArgumentException'.

> null, then I can let getLocalizedText() catch those NullPointerExceptions
> and get the stacktraces from the exception and write them to the log. In
> that case, I may as well just check the input parameters for nulls, and
> simply throw NullPointerException with a specific message within

'IllegalArgumentException'.

> getResources(); then getLocalizedText() can have a try/catch block. The
> try/catch can detect the NullPointerException and write both the message
> and the stacktrace to the log.

Write the log at the point where you detect the error, not only further up the 
stack.

> But I gather that you should handle the error as close to where it
> happened as possible when you can. I'd tend to prefer to handle the null
> parameter values in getResources() except that I'm not sure how to write
> the stack trace to the log before any exception has happened.

  IllegalArgumentException exception = new IllegalArgumentException(msg);
  logger.error("Unable to proceed", exception);

> One other questions. When, if ever, should I execute System.exit() with a
> non-zero integer? In my example, I know that program Foo can't proceed

Never. Program exit should be under user control.

> without the resources it is trying to get in getResources() so if I
> simply throw exceptions and write to the log and then let the program
> keep going, I'm simply going to get another NullPointerException on the
> first statement that tries to use the resources. I'm thinking that I
> should do a System.exit(1) after I've logged a null parameter or in the
> event of a MissingResourceException in getResources(). But I have yet to
> see System.exit() used in ANY example of error handling in any resource
> I've looked at so far.

Hmm.

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

[toc] | [prev] | [next] | [standalone]


#12860

FromArved Sandstrom <asandstrom3minus1@eastlink.ca>
Date2012-03-11 11:53 -0300
Message-ID<h%27r.13665$HX7.8681@newsfe11.iad>
In reply to#12859
On 12-03-10 10:39 PM, Lew wrote:
> Novice wrote:
[ SNIP ]

>> My objective is to code getResources() and getLocalizedText() as
>> professionally as possible. If the methods fail, I want to write a clear
>> message to my log and the log record needs to include a stacktrace. (I'm
> 
> example:
> 
>   logger.error(message, exception);
> 
>> assuming that a console is not necessarily available to the operators
>> running this program and I need to know where the error took place. Based
>> on an article Arved suggested in another thread,
>> http://www.javacodegeeks.com/2011/01/10-tips-proper-application-
>> logging.html, I'm inclined to minimize "position" information - class
>> name, method name, line number - in the log and instead get all of that
>> from the stacktrace.)
> 
> I disagree.
> 
> I'd keep that class/method info in the log message. Line information is
> less valuable unless your methods are far, far too long.

We may be talking/thinking at cross-purposes here: you, me, the article
author, and Novice. The logging article author states that you should
never include file name, class name, or line number. To be accurate the
article is an edited compilation of what another fellow (Tomasz
Nurkiewicz) has written about logging: I haven't been able to find the
originals to see what Tomasz put forth as explanation for this stance.

Further, and presumably this also comes from Tomasz, it's stated that
"logging class name, method name and/or line number has a serious
performance impact." Now, to be fair to him this is also still
promulgated by Ceki Gulcu's log4j documentation.

I suspect that in recent years with newer JVMs that the performance
impact of some of the position conversion specifiers is considerably
less than it was when the warnings were first issued.

Having said that, *my* argument against regularly using source position
information is motivated by retaining clarity of logs. Try reading logs
in a text editor or on the console when the first part of every entry is
not only level and timestamp and thread ID but also FQ classname,
methodname, and line number. That positional info is irrelevant almost
all the time, and yet a _default_ decision to include it seriously
clutters logs. The info you really want starts halfway across the editor
window. The human eye is also not that great at differentiating one blob
of letters from another; ignoring the level and timestamp is easy (they
"look" different when scanning), but the positional info easily runs
together with the real message.

My position is, if you need it, include it. Don't default (let's say
through PatternLayout strings) to having it uniformly. Bear in mind (if
performance is still any kind of concern) that the log4j %c conversion
specifier gives you classname for free if you're creating loggers by
class. You don't need it for errors, not if you're dumping stacktraces.
You surely don't need it for info or warnings. Debug may or may not
benefit from positional information, but that should be case by case,
and if you do need a debug statement to include positional info, what's
so tough about putting it in that one, specific debug message?

>> Now, finally, here are some questions:
>>
>> Since the only exceptions I anticipate, MissingResourceException and
>> NullPointerException, are unchecked exceptions, I gather than I shouldn't
>> really do anything about them aside from logging when they happen. Okay,
> 
> I disagree. You should end the program gracefully and get someone to fix
> the programming error right away.
> 
[ SNIP ]

Not often in the real world can you do that, Lew. And you know it. One
source of work like this (fixing errors) for ops support and maintenance
programmers is operational problem reports (trouble tickets etc)
detected and entered by business. Another is ops support monitoring
(Splunk, say) of logs...in which case something they detect may also
enter the ticket/defect tracking systems.

Unless something is truly critical nobody is going to shut down a 24/7
public-facing or partner-supporting (b2b) system just because a
programming error popped up as a runtime exception. In fact, in the
absence of any problem reports from the field an issue like that might
well end up as a low/medium severity, low/medium priority defect - mixed
in with dozens or hundreds of others - that'll get handled a few weeks
or months later.

AHS
-- 
Last week I helped my friend stay put. It's a lot easier'n helpin' 'em
move. I just went over to his house and made sure that he did not start
to load shit into a truck.
-- Mitch Hedberg

[toc] | [prev] | [next] | [standalone]


#12864

FromLew <noone@lewscanon.com>
Date2012-03-11 10:51 -0700
Message-ID<jjionk$l5q$1@news.albasani.net>
In reply to#12860
Arved Sandstrom wrote:
> Lew wrote:
> [ SNIP ]
> We may be talking/thinking at cross-purposes here: you, me, the article
> author, and Novice. The logging article author states that you should
> never include file name, class name, or line number. To be accurate the
> article is an edited compilation of what another fellow (Tomasz
> Nurkiewicz) has written about logging: I haven't been able to find the
> originals to see what Tomasz put forth as explanation for this stance.
>
> Further, and presumably this also comes from Tomasz, it's stated that
> "logging class name, method name and/or line number has a serious
> performance impact." Now, to be fair to him this is also still
> promulgated by Ceki Gulcu's log4j documentation.
>
> I suspect that in recent years with newer JVMs that the performance
> impact of some of the position conversion specifiers is considerably
> less than it was when the warnings were first issued.
>
> Having said that, *my* argument against regularly using source position
> information is motivated by retaining clarity of logs. Try reading logs
> in a text editor or on the console when the first part of every entry is
> not only level and timestamp and thread ID but also FQ classname,
> methodname, and line number. That positional info is irrelevant almost
> all the time, and yet a _default_ decision to include it seriously
> clutters logs. The info you really want starts halfway across the editor
> window. The human eye is also not that great at differentiating one blob
> of letters from another; ignoring the level and timestamp is easy (they
> "look" different when scanning), but the positional info easily runs
> together with the real message.
>
> My position is, if you need it, include it. Don't default (let's say
> through PatternLayout strings) to having it uniformly. Bear in mind (if
> performance is still any kind of concern) that the log4j %c conversion
> specifier gives you classname for free if you're creating loggers by
> class. You don't need it for errors, not if you're dumping stacktraces.
> You surely don't need it for info or warnings. Debug may or may not
> benefit from positional information, but that should be case by case,
> and if you do need a debug statement to include positional info, what's
> so tough about putting it in that one, specific debug message?

I see. Good points.

>> I disagree. You should end the program gracefully and get someone to fix
>> the programming error right away.
>>
> [ SNIP ]
>
> Not often in the real world can you do that, Lew. And you know it. One

At another point in that post, not cited, I talk about not ending the program 
but, "Somewhere up the stack you should catch the exception and convert it to 
valid program state."

You are right that that is often not ending the program. As I also said in 
that post, in answer to when the program should abend, "Never. Program exit 
should be under user control."

So I agree with you.

> source of work like this (fixing errors) for ops support and maintenance
> programmers is operational problem reports (trouble tickets etc)
> detected and entered by business. Another is ops support monitoring
> (Splunk, say) of logs...in which case something they detect may also
> enter the ticket/defect tracking systems.
>
> Unless something is truly critical nobody is going to shut down a 24/7
> public-facing or partner-supporting (b2b) system just because a
> programming error popped up as a runtime exception. In fact, in the
> absence of any problem reports from the field an issue like that might
> well end up as a low/medium severity, low/medium priority defect - mixed
> in with dozens or hundreds of others - that'll get handled a few weeks
> or months later.

As I also stated.

In the cases you state, "exiting gracefully" means "when the operator says 
so". There is nothing in my statements to gainsay your points. /Au contraire/, 
I spoke against exceptions crashing or stopping a program.

And you know it.

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

[toc] | [prev] | [next] | [standalone]


#12868

FromArved Sandstrom <asandstrom3minus1@eastlink.ca>
Date2012-03-11 16:35 -0300
Message-ID<G777r.7791$v11.4979@newsfe20.iad>
In reply to#12864
On 12-03-11 02:51 PM, Lew wrote:
> Arved Sandstrom wrote:
[ SNIP ]

>> Unless something is truly critical nobody is going to shut down a 24/7
>> public-facing or partner-supporting (b2b) system just because a
>> programming error popped up as a runtime exception. In fact, in the
>> absence of any problem reports from the field an issue like that might
>> well end up as a low/medium severity, low/medium priority defect - mixed
>> in with dozens or hundreds of others - that'll get handled a few weeks
>> or months later.
> 
> As I also stated.
> 
> In the cases you state, "exiting gracefully" means "when the operator
> says so". There is nothing in my statements to gainsay your points. /Au
> contraire/, I spoke against exceptions crashing or stopping a program.
> 
> And you know it.
> 
Fair enough: we agree. The point I was making was mostly for the OP, and
really does boil down to making it clear that often "exit gracefully"
means "when the operator says so", not having the application programmed
to automatically exit gracefully. I think it's valid in the OP's case to
make that distinction, seeing as how he's wondering why he hasn't seen
more System.exit calls.

AHS
-- 
Last week I helped my friend stay put. It's a lot easier'n helpin' 'em
move. I just went over to his house and made sure that he did not start
to load shit into a truck.
-- Mitch Hedberg

[toc] | [prev] | [next] | [standalone]


#12862

FromNovice <novice@example..com>
Date2012-03-11 17:05 +0000
Message-ID<XnsA01385245AD09jpnasty@94.75.214.39>
In reply to#12859
Lew <noone@lewscanon.com> wrote in news:jjh39f$crc$1@news.albasani.net:

> Novice wrote:
> snip
>> I have a utility class called LocalizationUtils which basically
>> houses convenience methods dealing with i18n/l10n. One of its methods
>> is getResources(). It expects two parameters, a String representing
>> the "base name" (the leading part of the resource file name) and a
>> locale. 
>>
>> Here's the code for getResources() with all comments and error
>> handling (aside from the empty catch block) stripped out:
>>
>> ====================================================================
>> static public ResourceBundle getResources(String baseName, Locale
>> locale {
>>    ResourceBundle locList = null;
> 
> Don't use throwaway initializations, usually.
> 
Why?

If I omit that line and simply use the following in the try block:

ResourceBundle locList = ResourceBundle.getBundle(baseName, locale);

locList isn't visible after the try/catch so that I can return it.



>>    try {
>>      locList = ResourceBundle.getBundle(baseName, locale);
>>        }
>>    catch (MissingResourceException mrExcp) {
> 
> Log and return 'null' if that's the recovery strategy for this
> exception. 
>
Is that what I should do, return null if there is a problem getting the 
resource?

I'm not sure if I should be returning anything at all. Maybe I should 
just log and stop the program?
 
>>      }
>>
>>    return (locList);
>> }
>> ====================================================================
>>
>> The program which is executing is Foo. It has a method called
>> getLocalizedText() which is the one executing
>> LocalizationUtils.getResources(). The value of the baseName is a
>> constant coded in an interface of constants called FooConstants which
>> is implemented by Foo. Here's the code for getLocalizedText() without
>> any error handling and just one relevant comment:
> 
> Using an interface to define constants is the "Constant Interface 
> Antipattern". (Google it.) Use a class to define constants, not an
> interface. 
> 
> An interface is there to define a type. Using it merely to define
> constants violates the spirit of interfaces, which is to avoid
> implementation. 
>
Fair enough. I've converted each constants interface to a class with a 
private constructor that throws an exception if someone tries to 
instantiate it. 
 
>> ====================================================================
>> private void getLocalizedText() {
>>           
>>    Locale locale = Locale.getDefault();
>>      
>>    this.myText = LocalizationUtils.getResources(TEXT_BASE, locale);
>>    this.myMsg = LocalizationUtils.getResources(MSG_BASE, locale);
>>
>>    /* Work with the localized resources. */       
>> }            
>> ====================================================================
>>
>> In terms of trouble spots, I know from experience that getResources()
>> will throw a MissingResourceException, which is an unchecked
>> exception, if the base name is misspelled. A null value in either
>> parameter is also going to make the getResources() method fail:
>> ResourceBundle.getBundle() will throw a NullPointerException if
>> either parameter is null. 
>>
>> My objective is to code getResources() and getLocalizedText() as
>> professionally as possible. If the methods fail, I want to write a
>> clear message to my log and the log record needs to include a
>> stacktrace. (I'm 
> 
> example:
> 
>    logger.error(message, exception);
> 
Exactly the kind of thing I had in mind.

>> assuming that a console is not necessarily available to the operators
>> running this program and I need to know where the error took place.
>> Based on an article Arved suggested in another thread,
>> http://www.javacodegeeks.com/2011/01/10-tips-proper-application-
>> logging.html, I'm inclined to minimize "position" information - class
>> name, method name, line number - in the log and instead get all of
>> that from the stacktrace.)
> 
> I disagree.
> 
> I'd keep that class/method info in the log message. Line information
> is less valuable unless your methods are far, far too long.
> 
Tip 6 in the article makes the point that it is redundant and expensive 
to get class, method and line information if it is already in the log 
message. A stacktrace will tell me all of that and more so shouldn't I be 
concentrating on getting a stacktrace, plus whatever I'll need that isn't 
in the stacktrace, like the date and time of the problem?

>> Now, finally, here are some questions:
>>
>> Since the only exceptions I anticipate, MissingResourceException and
>> NullPointerException, are unchecked exceptions, I gather than I
>> shouldn't really do anything about them aside from logging when they
>> happen. Okay, 
> 
> I disagree. You should end the program gracefully and get someone to
> fix the programming error right away.
>
But what's the right way to end the program? System.exit()? That seems 
the obvious way but as I've said further down, that doesn't seem to be 
the method used in the books and articles I've been reading. What's the 
better way?
 
>> fair enough; I certainly don't want to display the source code to my
>> user, make them enter the correct value for the baseName, make them
>> recompile the program and then run it again! But when/where should I
>> log the error? For instance, if I mess up my coding somehow and
>> inadvertently 
> 
> In the log file.
> 
Yes, I realize that it goes in the log file. I mean when and where in my 
code do I do that? In getResource() or getLocalizedText()?

>> pass a null in the baseName, should getResources() be testing its
>> input parameters individually to see if they are null and write a
>> message to the log if they are null from within that method? I'm
>> inclined to say yes 
> 
> Always check all parameters for validity, either by an explicit check
> for a public or protected method, or by controlling what's passed to
> package-private or private methods.
> 
> A normal practice is to have an application-specific checked exception
> to throw, or to throw the standard unchecked exception. For example:
> 
>   if (argument == null)
>   {
>     final String msg = "null argument";
>     IllegalArgumentException except = new
>     IllegalArgumentException(msg); logger.error(msg, except);
>     throw except;
>   }
> 
> or similarly for application checked exception 'FooException'.
> 
>    throw new FooException(new IllegalArgumentException(msg));
>
At least one of the articles/books recommended against creating custom 
exceptions unless necessary, preferring to use existing exceptions where 
possible. 

The Java Tutorial puts it this way:

"You should write your own exception classes if you answer yes to any of 
the following questions; otherwise, you can probably use someone else's.

- Do you need an exception type that isn't represented by those in the 
Java platform?
- Would it help users if they could differentiate your exceptions from 
those thrown by classes written by other vendors?
- Does your code throw more than one related exception?
- If you use someone else's exceptions, will users have access to those 
exceptions? A similar question is, should your package be independent and 
self-contained?"
 
I don't _think_ I qualify to create my own exception under any of these 
conditions so I'm inclined to stay with the standard ones. Or am I 
missing something?

Assuming I'm not, I'm inclined to use the first approach you suggested. 
Or perhaps use the technique but throw a NullPointerException. Bloch 
implied that IllegalArgumentException was fine for bad values but that 
NullPointerException was preferred where a parameter had a null value. 
 
> Somewhere up the stack you should catch the exception and convert it
> to valid program state"
> 
>   catch(RuntimeException except)
>   {
>     forwardProgramControlToErrorScreen();
>   }
> 
I went into Eclipse for a minute and amended getResources() to look like 
this:

========================================================================
static public ResourceBundle getResources(String baseName, Locale locale) 
throws NullPointerException, IllegalArgumentException {

if (baseName == null) {
   final String msg = "The base name cannot be null.";
   NullPointerException nullPointerException = new NullPointerException
(msg); 
    Logger logger = Logger.getLogger(CLASS_NAME);
    logger.log(Level.SEVERE, msg, nullPointerException);
    throw nullPointerException;
    }
	    
if (locale == null) {
   final String msg = "The locale cannot be null."; //$NON-NLS-1$
   NullPointerException nullPointerException = new NullPointerException
(msg); 
   Logger logger = Logger.getLogger(CLASS_NAME);
   logger.log(Level.SEVERE, msg, nullPointerException);
   throw nullPointerException;            
   }
        	    
//ResourceBundle resourceFile = null;

try {
  ResourceBundle resourceFile = ResourceBundle.getBundle(baseName, 
locale);
  return(resourceFile);
   } 
catch (MissingResourceException mrExcp) {
  String msg = "Unable to find resources for base name, " + baseName + ", 
and locale, " + locale + ". Check the spelling of the base name."; 
  throw new IllegalArgumentException(msg);
}
}
========================================================================

That works just fine and my exception, with stacktrace, is logged before 
I've left getResources(). But why am I throwing the exception at the end 
of the if (baseName == null) block? Why not just exit the program 
gracefully instead of throwing the exception? If I pass it back up to the 
caller, what is is actually supposed to do, given that the message has 
been logged and recovery is not practical? Am I only passing it up so 
that getLocalizedText() can stop the program? 

>> to that but I'm not sure what to do next. It seems pointless to carry
>> on with getResources() since ResourceBundle.getBundle(baseName,
>> locale) will fail on a NullPointerException with a null in either
>> parameter. I could throw a NullPointerException so that
>> getLocalizedText() can deal with it. But how do I get a stacktrace
>> into the log if I follow that strategy? It's easy enough to get the
>> stacktrace once I've caught an exception but I'm just talking about
>> recognizing that an input parameter is null; there's no exception at
>> that point to put in my log. 
> 
> There is if you create one. That's why Java has the 'new' operator.
> 
Yes, I see that from your technique of creating one. I hadn't anticipated 
that approach.

>> If I let getResources() throw NullPointerException if either
>> parameter is 
> 
> Better, use 'IllegalArgumentException'.
> 
>> null, then I can let getLocalizedText() catch those
>> NullPointerExceptions and get the stacktraces from the exception and
>> write them to the log. In that case, I may as well just check the
>> input parameters for nulls, and simply throw NullPointerException
>> with a specific message within 
> 
> 'IllegalArgumentException'.
> 
I have no strong feelings about this one way or the other but Bloch, on 
page 248 of Effective Java (2nd edition) says: "Arguably, all erroneous 
method invocations boil down to an illegal argument or an illegal state, 
but other exceptions are standardly used for certain kinds of illegal 
arguments and states. If a caller passes null in some parameter for which 
null values are prohibited, convention dictates that NullPointerException 
be thrown rather than IllegalArgumentException."

Can we agree that whether I use IllegalArgumentException or 
NullPointerException in the situation I'm describing in my own code is 
simply a matter of personal style or preference? Or is there a reason to 
prefer IllegalArgumentException that Bloch failed to consider? 

Like I said, I'm fine with either approach.

>> getResources(); then getLocalizedText() can have a try/catch block.
>> The try/catch can detect the NullPointerException and write both the
>> message and the stacktrace to the log.
> 
> Write the log at the point where you detect the error, not only
> further up the stack.
> 
That's what I wanted to do. I just wasn't sure how to get the stacktrace 
into the log until you showed me that technique ;-)

>> But I gather that you should handle the error as close to where it
>> happened as possible when you can. I'd tend to prefer to handle the
>> null parameter values in getResources() except that I'm not sure how
>> to write the stack trace to the log before any exception has
>> happened. 
> 
>   IllegalArgumentException exception = new
>   IllegalArgumentException(msg); logger.error("Unable to proceed",
>   exception); 
> 
>> One other questions. When, if ever, should I execute System.exit()
>> with a non-zero integer? In my example, I know that program Foo can't
>> proceed 
> 
> Never. Program exit should be under user control.
> 
So, given that my application has a GUI, leave the application suspended 
at the exception and make the user click the Close button? Why is that 
better than just exiting given that the program can't proceed without the 
missing resources in this case? 

If this were a batch program rather than one with a GUI, would we close 
with System.exit()? Or wait for the operator to notice the program is 
suspended and make him kill it?

>> without the resources it is trying to get in getResources() so if I
>> simply throw exceptions and write to the log and then let the program
>> keep going, I'm simply going to get another NullPointerException on
>> the first statement that tries to use the resources. I'm thinking
>> that I should do a System.exit(1) after I've logged a null parameter
>> or in the event of a MissingResourceException in getResources(). But
>> I have yet to see System.exit() used in ANY example of error handling
>> in any resource I've looked at so far.
> 
> Hmm.
> 


-- 
Novice

[toc] | [prev] | [next] | [standalone]


#12865

FromLew <noone@lewscanon.com>
Date2012-03-11 10:53 -0700
Message-ID<jjiorj$l5q$2@news.albasani.net>
In reply to#12862
Novice wrote:
> Lew wrote:
>> Novice wrote:
>> [snip]
>>> I have a utility class called LocalizationUtils which basically
>>> houses convenience methods dealing with i18n/l10n. One of its methods
>>> is getResources(). It expects two parameters, a String representing
>>> the "base name" (the leading part of the resource file name) and a
>>> locale.
>>>
>>> Here's the code for getResources() with all comments and error
>>> handling (aside from the empty catch block) stripped out:
>>>
>>> ====================================================================
>>> static public ResourceBundle getResources(String baseName, Locale
>>> locale {
>>>     ResourceBundle locList = null;
>>
>> Don't use throwaway initializations, usually.
>>
> Why?
>
> If I omit that line and simply use the following in the try block:
>
> ResourceBundle locList = ResourceBundle.getBundle(baseName, locale);
>
> locList isn't visible after the try/catch so that I can return it.

Well, I didn't recommend that either. There are so many ways to avoid 
redundant initialization. So - what could avoid the redundant initialization 
without the pitfall you cite?

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

[toc] | [prev] | [next] | [standalone]


#12872

FromNovice <novice@example..com>
Date2012-03-11 20:36 +0000
Message-ID<XnsA013A90663692jpnasty@94.75.214.39>
In reply to#12865
Lew <noone@lewscanon.com> wrote in news:jjiorj$l5q$2@news.albasani.net:

> Novice wrote:
>> Lew wrote:
>>> Novice wrote:
>>> [snip]
>>>> I have a utility class called LocalizationUtils which basically
>>>> houses convenience methods dealing with i18n/l10n. One of its
>>>> methods is getResources(). It expects two parameters, a String
>>>> representing the "base name" (the leading part of the resource file
>>>> name) and a locale.
>>>>
>>>> Here's the code for getResources() with all comments and error
>>>> handling (aside from the empty catch block) stripped out:
>>>>
>>>> ====================================================================
>>>> static public ResourceBundle getResources(String baseName, Locale
>>>> locale {
>>>>     ResourceBundle locList = null;
>>>
>>> Don't use throwaway initializations, usually.
>>>
>> Why?
>>
>> If I omit that line and simply use the following in the try block:
>>
>> ResourceBundle locList = ResourceBundle.getBundle(baseName, locale);
>>
>> locList isn't visible after the try/catch so that I can return it.
> 
> Well, I didn't recommend that either. There are so many ways to avoid 
> redundant initialization. So - what could avoid the redundant
> initialization without the pitfall you cite?
> 

I see that Arivald has answered that already in his contributions to the 
thread ;-)

I'll use one of his approaches.
-- 
Novice

[toc] | [prev] | [next] | [standalone]


#12866

FromLew <noone@lewscanon.com>
Date2012-03-11 11:07 -0700
Message-ID<jjipli$np7$1@news.albasani.net>
In reply to#12862
Novice wrote:
> Lew wrote:
>> Novice wrote:
>> snip
>>>     try {
>>>       locList = ResourceBundle.getBundle(baseName, locale);
>>>         }
>>>     catch (MissingResourceException mrExcp) {
>>
>> Log and return 'null' if that's the recovery strategy for this
>> exception.
>>
> Is that what I should do, return null if there is a problem getting the
> resource?
>
> I'm not sure if I should be returning anything at all. Maybe I should
> just log and stop the program?

I said *if* that's the strategy. What do you think? It may depend on the 
specifics of the case.

> Fair enough. I've converted each constants interface to a class with a
> private constructor that throws an exception if someone tries to
> instantiate it.

How would that exception ever occur? How could "someone" ever try to call a 
private constructor?

Don't throw code into a program that is provably never called.

> Tip 6 in the article makes the point that it is redundant and expensive

We've discussed this before, remember?

It's not expensive. When you're calling a logger statement for an error, the 
cost of the error SWAMPS the time in the logger. Think about it.

> to get class, method and line information if it is already in the log
> message. A stacktrace will tell me all of that and more so shouldn't I be
> concentrating on getting a stacktrace, plus whatever I'll need that isn't
> in the stacktrace, like the date and time of the problem?

There are many who have answered this question, in response to your questions.

The answers covered a lot of approaches. Perhaps you recall them.

>>> Now, finally, here are some questions:
>>>
>>> Since the only exceptions I anticipate, MissingResourceException and
>>> NullPointerException, are unchecked exceptions, I gather than I
>>> shouldn't really do anything about them aside from logging when they
>>> happen. Okay,
>>
>> I disagree. You should end the program gracefully and get someone to
>> fix the programming error right away.
>>
> But what's the right way to end the program? System.exit()? That seems

Under operator control.

> the obvious way but as I've said further down, that doesn't seem to be
> the method used in the books and articles I've been reading. What's the
> better way?

Under operator control.

>>> fair enough; I certainly don't want to display the source code to my
>>> user, make them enter the correct value for the baseName, make them
>>> recompile the program and then run it again! But when/where should I
>>> log the error? For instance, if I mess up my coding somehow and
>>> inadvertently
>>
>> In the log file.
>>
> Yes, I realize that it goes in the log file. I mean when and where in my
> code do I do that? In getResource() or getLocalizedText()?

Wherever you detect the error.

>>> pass a null in the baseName, should getResources() be testing its
>>> input parameters individually to see if they are null and write a
>>> message to the log if they are null from within that method? I'm
>>> inclined to say yes
>>
>> Always check all parameters for validity, either by an explicit check
>> for a public or protected method, or by controlling what's passed to
>> package-private or private methods.
>>
>> A normal practice is to have an application-specific checked exception
>> to throw, or to throw the standard unchecked exception. For example:
>>
>>    if (argument == null)
>>    {
>>      final String msg = "null argument";
>>      IllegalArgumentException except = new
>>      IllegalArgumentException(msg); logger.error(msg, except);
>>      throw except;
>>    }
>>
>> or similarly for application checked exception 'FooException'.
>>
>>     throw new FooException(new IllegalArgumentException(msg));
>>
> At least one of the articles/books recommended against creating custom
> exceptions unless necessary, preferring to use existing exceptions where
> possible.
>
> The Java Tutorial puts it this way:
>
> "You should write your own exception classes if you answer yes to any of
> the following questions; otherwise, you can probably use someone else's.
>
> - Do you need an exception type that isn't represented by those in the
> Java platform?
> - Would it help users if they could differentiate your exceptions from
> those thrown by classes written by other vendors?
> - Does your code throw more than one related exception?
> - If you use someone else's exceptions, will users have access to those
> exceptions? A similar question is, should your package be independent and
> self-contained?"
>
> I don't _think_ I qualify to create my own exception under any of these
> conditions so I'm inclined to stay with the standard ones. Or am I
> missing something?

Yes.

It is common and frequently useful to create an application-specific checked 
exception. Again, and I've said this many times, think about what will be 
useful when troubleshooting a problem. Many times, a custom exception is 
useful. It says that the underlying exception has been caught, logged and wrapped.

Runtime exceptions are dangerous because they slip past you. If you catch them 
in a custom checked exception then code must handle it. All those runtime 
exceptions are related, by dint of being exceptions within the same 
application. BOOM! Qualified.

> Assuming I'm not, I'm inclined to use the first approach you suggested.
> Or perhaps use the technique but throw a NullPointerException. Bloch
> implied that IllegalArgumentException was fine for bad values but that
> NullPointerException was preferred where a parameter had a null value.

That's his opinion.

Many others think that 'IllegalArgumentException' makes more sense if it's an 
argument that has an illegal value.

What do you think?

>> Somewhere up the stack you should catch the exception and convert it
>> to valid program state"
>>
>>    catch(RuntimeException except)
>>    {
>>      forwardProgramControlToErrorScreen();
>>    }
>>
> I went into Eclipse for a minute and amended getResources() to look like
> this:
>
> ========================================================================
> static public ResourceBundle getResources(String baseName, Locale locale)
> throws NullPointerException, IllegalArgumentException {
>
> if (baseName == null) {
>     final String msg = "The base name cannot be null.";
>     NullPointerException nullPointerException = new NullPointerException
> (msg);
>      Logger logger = Logger.getLogger(CLASS_NAME);
>      logger.log(Level.SEVERE, msg, nullPointerException);
>      throw nullPointerException;
>      }
> 	
> if (locale == null) {
>     final String msg = "The locale cannot be null."; //$NON-NLS-1$
>     NullPointerException nullPointerException = new NullPointerException
> (msg);
>     Logger logger = Logger.getLogger(CLASS_NAME);
>     logger.log(Level.SEVERE, msg, nullPointerException);
>     throw nullPointerException;

Kind of a bad name for the variable, there.

What does your log look like with 'msg' printed twice?

>     }
>          	
> //ResourceBundle resourceFile = null;
>
> try {
>    ResourceBundle resourceFile = ResourceBundle.getBundle(baseName,
> locale);
>    return(resourceFile);
>     }
> catch (MissingResourceException mrExcp) {
>    String msg = "Unable to find resources for base name, " + baseName + ",
> and locale, " + locale + ". Check the spelling of the base name.";
>    throw new IllegalArgumentException(msg);
> }
> }
> ========================================================================
>
> That works just fine and my exception, with stacktrace, is logged before
> I've left getResources(). But why am I throwing the exception at the end
> of the if (baseName == null) block? Why not just exit the program
> gracefully instead of throwing the exception? If I pass it back up to the

Why, indeed?

> caller, what is is actually supposed to do, given that the message has
> been logged and recovery is not practical? Am I only passing it up so
> that getLocalizedText() can stop the program?

No, only the operator should stop the program.

The idea is to return to valid program state. RETURN TO VALID PROGRAM STATE.

*RETURN TO VALID PROGRAM STATE.*

>>> to that but I'm not sure what to do next. It seems pointless to carry
>>> on with getResources() since ResourceBundle.getBundle(baseName,
>>> locale) will fail on a NullPointerException with a null in either
>>> parameter. I could throw a NullPointerException so that
>>> getLocalizedText() can deal with it. But how do I get a stacktrace
>>> into the log if I follow that strategy? It's easy enough to get the
>>> stacktrace once I've caught an exception but I'm just talking about
>>> recognizing that an input parameter is null; there's no exception at
>>> that point to put in my log.
>>
>> There is if you create one. That's why Java has the 'new' operator.
>>
> Yes, I see that from your technique of creating one. I hadn't anticipated
> that approach.

That's why Java has the 'new' operator.

>>> If I let getResources() throw NullPointerException if either
>>> parameter is
>>
>> Better, use 'IllegalArgumentException'.
>>
>>> null, then I can let getLocalizedText() catch those
>>> NullPointerExceptions and get the stacktraces from the exception and
>>> write them to the log. In that case, I may as well just check the
>>> input parameters for nulls, and simply throw NullPointerException
>>> with a specific message within
>>
>> 'IllegalArgumentException'.
>>
> I have no strong feelings about this one way or the other but Bloch, on
> page 248 of Effective Java (2nd edition) says: "Arguably, all erroneous
> method invocations boil down to an illegal argument or an illegal state,
> but other exceptions are standardly used for certain kinds of illegal
> arguments and states. If a caller passes null in some parameter for which
> null values are prohibited, convention dictates that NullPointerException
> be thrown rather than IllegalArgumentException."
>
> Can we agree that whether I use IllegalArgumentException or
> NullPointerException in the situation I'm describing in my own code is
> simply a matter of personal style or preference? Or is there a reason to
> prefer IllegalArgumentException that Bloch failed to consider?

What do you think?

[snip]
>>> One other questions. When, if ever, should I execute System.exit()
>>> with a non-zero integer? In my example, I know that program Foo can't
>>> proceed
>>
>> Never. Program exit should be under user control.
>>
> So, given that my application has a GUI, leave the application suspended
> at the exception and make the user click the Close button? Why is that
> better than just exiting given that the program can't proceed without the
> missing resources in this case?

That depends. What constitutes valid program state? Should you just stop, 
leaving the user wondering WTF happened? Should you perhaps come to a screen 
that tells the user something went wrong, and give them some choices?

How do you feel when a program suddenly ends? What if you could've supplied 
the missing "e" in the file name without having to start everything all over 
again?

It all depends on the program, doesn't it?

Programs should really only end under operator control. But hey, do it your 
way. What makes sense? What irritates the user? What's even possible?

> If this were a batch program rather than one with a GUI, would we close
> with System.exit()? Or wait for the operator to notice the program is
> suspended and make him kill it?

You tell me. The questions too vague. Describe the scenario precisely, with 
the advantages and disadvantages of each approach. With more information about 
your particular case, maybe I can advise.

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

[toc] | [prev] | [next] | [standalone]


#12870

FromArved Sandstrom <asandstrom3minus1@eastlink.ca>
Date2012-03-11 17:00 -0300
Message-ID<Dv77r.36154$zD5.32316@newsfe12.iad>
In reply to#12866
On 12-03-11 03:07 PM, Lew wrote:
> Novice wrote:
[ SNIP ]

>> Assuming I'm not, I'm inclined to use the first approach you suggested.
>> Or perhaps use the technique but throw a NullPointerException. Bloch
>> implied that IllegalArgumentException was fine for bad values but that
>> NullPointerException was preferred where a parameter had a null value.
> 
> That's his opinion.
> 
> Many others think that 'IllegalArgumentException' makes more sense if
> it's an argument that has an illegal value.
> 
> What do you think?
[ SNIP ]

StackOverflow has a good thread on this:
http://stackoverflow.com/questions/3881/illegalargumentexception-or-nullpointerexception-for-a-null-parameter.

Main takeaway is, in this case as in many others, as Lew suggests, you
do better to understand *why* people are making certain suggestions, and
then you can make your own choices. Most things in programming aren't
black and white.

Bear in mind, Bloch in "Effective Java" is trying to provide advice.
He's pretty good at it, but he's not infallible. Sometimes it shades a
bit too much over into "I say so...". I find it particularly rich that
he tells us that NPE is to be preferred when a parameter is null and
it's not allowed to be null, and the main reason is "convention
dictates": seeing as how he wrote a lot of JDK classes he had a big hand
in establishing the "convention", so this is quite circular.

Don't get me wrong: ignore Bloch or Goetz or Lea and other people like
that at your peril. But if you're experienced with technology X, and
have in fact been using it as long and probably as thoroughly as some
pundit, and you run across a statement by said pundit that you just
can't see the sense of, don't assume the other guy is right.

FWIW I use IllegalArgumentException in this case myself. I can't help
NPEs that are thrown by JDK classes even when I think they made a
mistake in choosing that exception, but for me an NPE means a
dereferencing failure, and if I've got the choice to create or rethrow,
I'll use IllegalArgumentException.

AHS
-- 
Last week I helped my friend stay put. It's a lot easier'n helpin' 'em
move. I just went over to his house and made sure that he did not start
to load shit into a truck.
-- Mitch Hedberg

[toc] | [prev] | [next] | [standalone]


#12879

FromNovice <novice@example..com>
Date2012-03-11 22:02 +0000
Message-ID<XnsA013B773176E8jpnasty@94.75.214.39>
In reply to#12870
Arved Sandstrom <asandstrom3minus1@eastlink.ca> wrote in
news:Dv77r.36154$zD5.32316@newsfe12.iad: 

> On 12-03-11 03:07 PM, Lew wrote:
>> Novice wrote:
> [ SNIP ]
> 
>>> Assuming I'm not, I'm inclined to use the first approach you
>>> suggested. Or perhaps use the technique but throw a
>>> NullPointerException. Bloch implied that IllegalArgumentException
>>> was fine for bad values but that NullPointerException was preferred
>>> where a parameter had a null value. 
>> 
>> That's his opinion.
>> 
>> Many others think that 'IllegalArgumentException' makes more sense if
>> it's an argument that has an illegal value.
>> 
>> What do you think?
> [ SNIP ]
> 
> StackOverflow has a good thread on this:
> http://stackoverflow.com/questions/3881/illegalargumentexception-or-nul
> lpointerexception-for-a-null-parameter. 
> 
> Main takeaway is, in this case as in many others, as Lew suggests, you
> do better to understand *why* people are making certain suggestions,
> and then you can make your own choices. Most things in programming
> aren't black and white.
> 
> Bear in mind, Bloch in "Effective Java" is trying to provide advice.
> He's pretty good at it, but he's not infallible. Sometimes it shades a
> bit too much over into "I say so...". I find it particularly rich that
> he tells us that NPE is to be preferred when a parameter is null and
> it's not allowed to be null, and the main reason is "convention
> dictates": seeing as how he wrote a lot of JDK classes he had a big
> hand in establishing the "convention", so this is quite circular.
> 
Excellent, excellent point ;-) As someone who still feels like a novice 
about a lot of Java, I'm inclined to ascribe omniscience to the gurus and 
I need to stop doing that. They put their pants on one leg at a time just 
like I do and they are capable of being biased or even flat out wrong, 
although I'm sure I'm wrong a LOT more than they are ;-)

> Don't get me wrong: ignore Bloch or Goetz or Lea and other people like
> that at your peril. But if you're experienced with technology X, and
> have in fact been using it as long and probably as thoroughly as some
> pundit, and you run across a statement by said pundit that you just
> can't see the sense of, don't assume the other guy is right.
>
Excellent advice. And of course you've just restated Lew's advice in your 
own words.

> FWIW I use IllegalArgumentException in this case myself. I can't help
> NPEs that are thrown by JDK classes even when I think they made a
> mistake in choosing that exception, but for me an NPE means a
> dereferencing failure, and if I've got the choice to create or
> rethrow, I'll use IllegalArgumentException.
> 
Like I said, I'm easy with either approach. Perhaps I'll use 
IllegalArgumentException on even-numbered days and NullPointerException 
on odd-numbered days just to show how even-handed I am ;-)

-- 
Novice

[toc] | [prev] | [next] | [standalone]


#12871

FromArivald <NOSPAMarivald@interia.pl>
Date2012-03-11 21:03 +0100
Message-ID<jjj0i8$h2j$1@news.dialog.net.pl>
In reply to#12866
W dniu 2012-03-11 19:07, Lew pisze:
> Novice wrote:
>> }
>>
>> //ResourceBundle resourceFile = null;
>>
>> try {
>> ResourceBundle resourceFile = ResourceBundle.getBundle(baseName,
>> locale);
>> return(resourceFile);
>> }
>> catch (MissingResourceException mrExcp) {
>> String msg = "Unable to find resources for base name, " + baseName + ",
>> and locale, " + locale + ". Check the spelling of the base name.";
>> throw new IllegalArgumentException(msg);
>> }
>> }
>> ========================================================================
>>
>> That works just fine and my exception, with stacktrace, is logged before
>> I've left getResources(). But why am I throwing the exception at the end
>> of the if (baseName == null) block? Why not just exit the program
>> gracefully instead of throwing the exception? If I pass it back up to the
>
> Why, indeed?
>
>> caller, what is is actually supposed to do, given that the message has
>> been logged and recovery is not practical? Am I only passing it up so
>> that getLocalizedText() can stop the program?
>
> No, only the operator should stop the program.
>
> The idea is to return to valid program state. RETURN TO VALID PROGRAM
> STATE.
>
> *RETURN TO VALID PROGRAM STATE.*

Some errors are so bad, so only program termination is applicable. For 
example when there is no valid state to recover.

Novice resource bundles it may be this case. If he have all GUI in XML 
in bundles, or at least all language dependant data (GUI labels, menus, 
etc), there is no valid state to recover. In this case program should 
notify user (message box, with only OK button), and just die.

For console program, there is much more reasons to use exit(). Most 
console programs just exit on error. Very few, usually complex ones, 
try to recover.

Yet another case is server-side applet. In this case exiting on error is 
standard strategy. Although in this case it exits through unhandled 
exception, so server can handle termination reason.

-- 
Arivald

[toc] | [prev] | [next] | [standalone]


#12876

FromArved Sandstrom <asandstrom3minus1@eastlink.ca>
Date2012-03-11 18:31 -0300
Message-ID<jR87r.32506$Ai4.6629@newsfe18.iad>
In reply to#12871
On 12-03-11 05:03 PM, Arivald wrote:
[ SNIP ]

> For console program, there is much more reasons to use exit(). Most
> console programs just exit on error. Very few, usually complex ones, try
> to recover.
[ SNIP ]

I don't believe being a console program has anything to do with the
error handling strategy. If the program can't continue in any useful
form, except for making some last efforts at resource cleanup and some
logging, that's when you exit automatically on error. Console program or
otherwise. Otherwise you try to recover, or at least get to a state
where the operator can make some necessary salvage decisions before
being strongly advised to quit. But you don't automatically exit as a
matter of course.

"Console program" includes not just text-based UI but also CLI
operation. This covers a lot of ground, up to and including servers.
I've deployed and undeployed and bound apps on web and app servers, and
configured the servers, entirely through CLI operations and editing
configuration files, and no doubt so have you. That many of these apps
also have web and desktop GUIs doesn't hide the fact that the core app
is a console program. And you sure aren't going to exit on error with a
server, not unless it's a really serious error.

AHS

-- 
Last week I helped my friend stay put. It's a lot easier'n helpin' 'em
move. I just went over to his house and made sure that he did not start
to load shit into a truck.
-- Mitch Hedberg

[toc] | [prev] | [next] | [standalone]


#12878

FromNovice <novice@example..com>
Date2012-03-11 21:54 +0000
Message-ID<XnsA013B63659242jpnasty@94.75.214.39>
In reply to#12866
Lew <noone@lewscanon.com> wrote in news:jjipli$np7$1@news.albasani.net:

> Novice wrote:
>> Lew wrote:
>>> Novice wrote:
>>> snip
>>>>     try {
>>>>       locList = ResourceBundle.getBundle(baseName, locale);
>>>>         }
>>>>     catch (MissingResourceException mrExcp) {
>>>
>>> Log and return 'null' if that's the recovery strategy for this
>>> exception.
>>>
>> Is that what I should do, return null if there is a problem getting
>> the resource?
>>
>> I'm not sure if I should be returning anything at all. Maybe I should
>> just log and stop the program?
> 
> I said *if* that's the strategy. What do you think? It may depend on
> the specifics of the case.
> 
The bundle being sought is for use on the GUI. Displaying the GUI without 
text is useless.

The nature of the error is a factor. If I'm passing a null for the 
baseName, the program couldn't reasonably work out an alternate resource 
bundle to use, nor could the user of the program. In that case, the 
program should end with a SEVERE error written to the logs. If I'm 
passing in a null locale, getResources() could determine the default 
locale and use it, probably advising the user that it had done so and 
logging that it had made this substitution. If the baseName were present 
but misspelled, I don't see how the program could proceed.

So, in short, I could probably cope with a null locale but not a null or 
misspelled baseName. 

However, if the logic that I messed up in getLocalizedText() was supposed 
to yield a language other than the one returned by Locale.getDefault() 
(my proposed recovery strategy if locale is null in getResources(), the 
GUI would display a different language than the user wanted. That might 
be just as bad as a GUI without text if the user was, say, Japanese and 
didn't know English, assuming English was the default locale. 

>> Fair enough. I've converted each constants interface to a class with
>> a private constructor that throws an exception if someone tries to
>> instantiate it.
> 
> How would that exception ever occur? How could "someone" ever try to
> call a private constructor?
> 
> Don't throw code into a program that is provably never called.
> 
>> Tip 6 in the article makes the point that it is redundant and
>> expensive 
> 
> We've discussed this before, remember?
> 
> It's not expensive. When you're calling a logger statement for an
> error, the cost of the error SWAMPS the time in the logger. Think
> about it. 
> 
I suppose I'm too easily swayed by other opinions. Arved, who seems very 
knowledgeable, cited that article, which seemed to give it his seal of 
approval. I don't know the author of the article but I tend to assume he 
must be an expert to be asked to write about a Java topic. The author 
cites people who he considers experts and the upshot is that the advice 
seems to argue against putting positioning information in the log unless 
its necessary (which it probably isn't if the stacktrace is in the log). 
Now you make a persuasive argument contradicting the article. I'm 
satisfied that you have serious expertise in this area so I have no 
reason to dismiss your argument. But why didn't the experts who wrote the 
article modify their remarks accordingly? 

I am more than happy to include class name, method name and line number 
in a log record. Those three things and the message text are the most 
useful parts of the log record to me. They give me enough information 
that I can find the right spot in the code and start to set up test 
conditions to try to duplicate the error and find out what is causing it. 
The stacktrace gives me that key information too but one of the questions 
I haven't asked yet is whether I should always put a stacktrace in the 
log for every problem situation. I'm inclined to think I should do so for 
errors that get logged as SEVERE but not for FINE/FINER/FINEST messages. 
WARNING and INFO messages are iffier and probably have to be decided on a 
case-by-case basis. If I'm not writing a stacktrace, then I'll want the 
log record to include the message, class name, method name and line 
number at the very least and very likely things like the thread if I'm 
doing multiple threads.

>> to get class, method and line information if it is already in the log
>> message. A stacktrace will tell me all of that and more so shouldn't
>> I be concentrating on getting a stacktrace, plus whatever I'll need
>> that isn't in the stacktrace, like the date and time of the problem?
> 
> There are many who have answered this question, in response to your
> questions. 
> 
> The answers covered a lot of approaches. Perhaps you recall them.
> 
I've had a lot of suggestions over the last few days and, in all honesty, 
they are starting to blur in my mind.... Obviously, I need to reread some 
of those threads....

>>>> Now, finally, here are some questions:
>>>>
>>>> Since the only exceptions I anticipate, MissingResourceException
>>>> and NullPointerException, are unchecked exceptions, I gather than I
>>>> shouldn't really do anything about them aside from logging when
>>>> they happen. Okay,
>>>
>>> I disagree. You should end the program gracefully and get someone to
>>> fix the programming error right away.
>>>
>> But what's the right way to end the program? System.exit()? That
>> seems 
> 
> Under operator control.
> 
>> the obvious way but as I've said further down, that doesn't seem to
>> be the method used in the books and articles I've been reading.
>> What's the better way?
> 
> Under operator control.
> 
>>>> fair enough; I certainly don't want to display the source code to
>>>> my user, make them enter the correct value for the baseName, make
>>>> them recompile the program and then run it again! But when/where
>>>> should I log the error? For instance, if I mess up my coding
>>>> somehow and inadvertently
>>>
>>> In the log file.
>>>
>> Yes, I realize that it goes in the log file. I mean when and where in
>> my code do I do that? In getResource() or getLocalizedText()?
> 
> Wherever you detect the error.
> 
Good. That makes perfect sense to me. 

>>>> pass a null in the baseName, should getResources() be testing its
>>>> input parameters individually to see if they are null and write a
>>>> message to the log if they are null from within that method? I'm
>>>> inclined to say yes
>>>
>>> Always check all parameters for validity, either by an explicit
>>> check for a public or protected method, or by controlling what's
>>> passed to package-private or private methods.
>>>
>>> A normal practice is to have an application-specific checked
>>> exception to throw, or to throw the standard unchecked exception.
>>> For example: 
>>>
>>>    if (argument == null)
>>>    {
>>>      final String msg = "null argument";
>>>      IllegalArgumentException except = new
>>>      IllegalArgumentException(msg); logger.error(msg, except);
>>>      throw except;
>>>    }
>>>
>>> or similarly for application checked exception 'FooException'.
>>>
>>>     throw new FooException(new IllegalArgumentException(msg));
>>>
>> At least one of the articles/books recommended against creating
>> custom exceptions unless necessary, preferring to use existing
>> exceptions where possible.
>>
>> The Java Tutorial puts it this way:
>>
>> "You should write your own exception classes if you answer yes to any
>> of the following questions; otherwise, you can probably use someone
>> else's. 
>>
>> - Do you need an exception type that isn't represented by those in
>> the Java platform?
>> - Would it help users if they could differentiate your exceptions
>> from those thrown by classes written by other vendors?
>> - Does your code throw more than one related exception?
>> - If you use someone else's exceptions, will users have access to
>> those exceptions? A similar question is, should your package be
>> independent and self-contained?"
>>
>> I don't _think_ I qualify to create my own exception under any of
>> these conditions so I'm inclined to stay with the standard ones. Or
>> am I missing something?
> 
> Yes.
> 
> It is common and frequently useful to create an application-specific
> checked exception. Again, and I've said this many times, think about
> what will be useful when troubleshooting a problem. Many times, a
> custom exception is useful. It says that the underlying exception has
> been caught, logged and wrapped. 
> 
But how is a custom FooException better than a good ol' 
IllegalArgumentException? I'm not quite getting that yet. 

Please understand that I have no objection to creating my own exceptions. 
I've actually done it in the past and didn't find it difficult. 

> Runtime exceptions are dangerous because they slip past you. If you
> catch them in a custom checked exception then code must handle it. All
> those runtime exceptions are related, by dint of being exceptions
> within the same application. BOOM! Qualified.
> 
It sounds a little bit like you're saying that RuntimeExceptions should 
be made into chccked exceptions when possible. But I doubt you mean that. 
That seems to contradict what Stelting at least is saying and even the 
API. The spirit of the API seems to be that some things don't lend 
themselves to easy recovery and you shouldn't even try, ergo the 
existence of unchecked exceptions and errors. Naturally, some things DO 
lend themselves to easy recovery by the user so it makes perfect sense 
that if a given file isn't found, the user can be given a chance to 
select a different file with a file chooser, which explains why 
FileNotFoundException is a checked exception. 

>> Assuming I'm not, I'm inclined to use the first approach you
>> suggested. Or perhaps use the technique but throw a
>> NullPointerException. Bloch implied that IllegalArgumentException was
>> fine for bad values but that NullPointerException was preferred where
>> a parameter had a null value. 
> 
> That's his opinion.
> 
> Many others think that 'IllegalArgumentException' makes more sense if
> it's an argument that has an illegal value.
> 
> What do you think?
> 
Like I said, I'm fine with either approach. They're both unchecked 
exceptions and you'd handle them the same way. It feels like a matter of 
personal style to me, meaning I'm free to do what I like on my own code 
and I should follow the shop standard if I'm working for someone else.


>>> Somewhere up the stack you should catch the exception and convert it
>>> to valid program state"
>>>
>>>    catch(RuntimeException except)
>>>    {
>>>      forwardProgramControlToErrorScreen();
>>>    }
>>>
>> I went into Eclipse for a minute and amended getResources() to look
>> like this:
>>
>> ======================================================================
>> == static public ResourceBundle getResources(String baseName, Locale
>> locale) throws NullPointerException, IllegalArgumentException {
>>
>> if (baseName == null) {
>>     final String msg = "The base name cannot be null.";
>>     NullPointerException nullPointerException = new
>>     NullPointerException 
>> (msg);
>>      Logger logger = Logger.getLogger(CLASS_NAME);
>>      logger.log(Level.SEVERE, msg, nullPointerException);
>>      throw nullPointerException;
>>      }
>>      
>> if (locale == null) {
>>     final String msg = "The locale cannot be null."; //$NON-NLS-1$
>>     NullPointerException nullPointerException = new
>>     NullPointerException 
>> (msg);
>>     Logger logger = Logger.getLogger(CLASS_NAME);
>>     logger.log(Level.SEVERE, msg, nullPointerException);
>>     throw nullPointerException;
> 
> Kind of a bad name for the variable, there.
>
You mean nullPointerException? I've gotten into the habit of giving my 
instance names the same name as the class (except for the case of the 
first letter) so I'm used to doing things that way. It seems clearer 
since it avoids any possibly misunderstanding that this isn't just an 
exception but is an instance of NullPointerException. 

> What does your log look like with 'msg' printed twice?
> 
A bit redundant given that the same message appears at the top of the 
stacktrace. But just having "SEVERE" without any other message seems like 
a bad idea. What do you think I should have if in the log record (the 
part that isn't the stacktrace) if not 'msg'? 

>>     }
>>               
>> //ResourceBundle resourceFile = null;
>>
>> try {
>>    ResourceBundle resourceFile = ResourceBundle.getBundle(baseName,
>> locale);
>>    return(resourceFile);
>>     }
>> catch (MissingResourceException mrExcp) {
>>    String msg = "Unable to find resources for base name, " + baseName
>>    + ", 
>> and locale, " + locale + ". Check the spelling of the base name.";
>>    throw new IllegalArgumentException(msg);
>> }
>> }
>> ======================================================================
>> == 
>>
>> That works just fine and my exception, with stacktrace, is logged
>> before I've left getResources(). But why am I throwing the exception
>> at the end of the if (baseName == null) block? Why not just exit the
>> program gracefully instead of throwing the exception? If I pass it
>> back up to the 
> 
> Why, indeed?
> 
>> caller, what is is actually supposed to do, given that the message
>> has been logged and recovery is not practical? Am I only passing it
>> up so that getLocalizedText() can stop the program?
> 
> No, only the operator should stop the program.
>

I think I need to be clear about who the operator is. In the case of a 
game, say, we're talking about the person playing the game (assuming a 
game that has only one player, like a solitaire game). Same kind of 
reasoning for a utility like a program that burns CDs or whatnot. For a 
servlet that is running in a container like Tomcat and may have hundreds 
or thousands of instances running, we'd have both individual users of 
individual copies of the program as well as some kind of admininstrator 
managing the container. Have I got that about right? 

If so, I'm not clear which operator you mean in the case of a servelet. 
Assuming only one instance of an application was having trouble, I'd 
expect the user to be the operator in question. In a case where all 
instances of an application were having problems, I'd expect the 
administrator of the container to shut down all instance of the problem 
program pending a resolution. 

If that's all more-or-less right so far, then what is the operator 
experience going to be when the program has to deal with a null baseName 
and the program is a game or utility? It would seem reasonable to display 
a dialog with a "Sorry, we hit a snag and can't proceed" kind of message 
that includes an okay button. It could go further and advise the user to 
contact Tech Support and even display messages and diagnostics but I 
expect most of that would be over the heads of users and should be 
reserved for the logs. Then, when they press Okay, the program ends.

Is that about what you had in mind?
 
> The idea is to return to valid program state. RETURN TO VALID PROGRAM
> STATE. 
> 
> *RETURN TO VALID PROGRAM STATE.*
> 
I hear you; I'm just not sure what a valid program state would be in my 
case. Honestly, I'm not entirely sure what "valid program state" implies 
in ANY case ;-)  



>>>> to that but I'm not sure what to do next. It seems pointless to
>>>> carry on with getResources() since
>>>> ResourceBundle.getBundle(baseName, locale) will fail on a
>>>> NullPointerException with a null in either parameter. I could throw
>>>> a NullPointerException so that getLocalizedText() can deal with it.
>>>> But how do I get a stacktrace into the log if I follow that
>>>> strategy? It's easy enough to get the stacktrace once I've caught
>>>> an exception but I'm just talking about recognizing that an input
>>>> parameter is null; there's no exception at that point to put in my
>>>> log. 
>>>
>>> There is if you create one. That's why Java has the 'new' operator.
>>>
>> Yes, I see that from your technique of creating one. I hadn't
>> anticipated that approach.
> 
> That's why Java has the 'new' operator.
> 
>>>> If I let getResources() throw NullPointerException if either
>>>> parameter is
>>>
>>> Better, use 'IllegalArgumentException'.
>>>
>>>> null, then I can let getLocalizedText() catch those
>>>> NullPointerExceptions and get the stacktraces from the exception
>>>> and write them to the log. In that case, I may as well just check
>>>> the input parameters for nulls, and simply throw
>>>> NullPointerException with a specific message within
>>>
>>> 'IllegalArgumentException'.
>>>
>> I have no strong feelings about this one way or the other but Bloch,
>> on page 248 of Effective Java (2nd edition) says: "Arguably, all
>> erroneous method invocations boil down to an illegal argument or an
>> illegal state, but other exceptions are standardly used for certain
>> kinds of illegal arguments and states. If a caller passes null in
>> some parameter for which null values are prohibited, convention
>> dictates that NullPointerException be thrown rather than
>> IllegalArgumentException." 
>>
>> Can we agree that whether I use IllegalArgumentException or
>> NullPointerException in the situation I'm describing in my own code
>> is simply a matter of personal style or preference? Or is there a
>> reason to prefer IllegalArgumentException that Bloch failed to
>> consider? 
> 
> What do you think?
> 
I'm easy with either approach. It feels like a personal style thing to 
me. The main thing is that the problem is detected and logged with enough 
information that the operators and/or programmers can figure out what 
went wrong. At the end of the day, the specific exception thrown doesn't 
seem particularly important.

> [snip]
>>>> One other questions. When, if ever, should I execute System.exit()
>>>> with a non-zero integer? In my example, I know that program Foo
>>>> can't proceed
>>>
>>> Never. Program exit should be under user control.
>>>
>> So, given that my application has a GUI, leave the application
>> suspended at the exception and make the user click the Close button?
>> Why is that better than just exiting given that the program can't
>> proceed without the missing resources in this case?
> 
> That depends. What constitutes valid program state? Should you just
> stop, leaving the user wondering WTF happened? Should you perhaps come
> to a screen that tells the user something went wrong, and give them
> some choices? 
>
Aside from not being clear about the meaning of "program state", I see 
your point. 
 
> How do you feel when a program suddenly ends? What if you could've
> supplied the missing "e" in the file name without having to start
> everything all over again?
> 
Absolutely. I think it would be dandy to enlist the user's assistance in 
getting back out of trouble rather than crash the program on him. 

> It all depends on the program, doesn't it?
> 
Yes. 

> Programs should really only end under operator control. But hey, do it
> your way. What makes sense? What irritates the user? What's even
> possible? 
> 
Fair enough. I'm all in favor of the user having a positive experience 
rather than have them scratching their heads and muttering WTF! 

In short, you've won me over. I think displaying a dialog and explaining 
that we have to end is more than reasonable and is better than just 
closing it on the user's behalf without any clear communication. My only 
quibble is that the dialog is a bit of an empty gesture in the sense that 
the user doesn't REALLY have much in the way of control when he gets a 
dialog with only an Okay button on it. The program is already dead in the 
water and his only option is to press Okay to officially kill the 
program. That's not really "control" in a very strong sense. But I agree 
that it is strongly preferable to do that than to just close it without 
telling him what's going on in some way.

>> If this were a batch program rather than one with a GUI, would we
>> close with System.exit()? Or wait for the operator to notice the
>> program is suspended and make him kill it?
> 
> You tell me. The questions too vague. Describe the scenario precisely,
> with the advantages and disadvantages of each approach. With more
> information about your particular case, maybe I can advise.
> 

I didn't really have a specific scenario in mind when I said that. It 
just struck me that the answer would probably be different in a situation 
like that than the case of a standalone utility or game. As you say, a 
good programmer would consider that in devising his strategy for handling 
the problem. 
-- 
Novice

[toc] | [prev] | [next] | [standalone]


#12883

FromPatricia Shanahan <pats@acm.org>
Date2012-03-11 15:26 -0700
Message-ID<S7GdnRomTdoRu8DSnZ2dnUVZ_sWdnZ2d@earthlink.com>
In reply to#12878
On 3/11/2012 2:54 PM, Novice wrote:
> Lew<noone@lewscanon.com>  wrote in news:jjipli$np7$1@news.albasani.net:
...
>> It is common and frequently useful to create an application-specific
>> checked exception. Again, and I've said this many times, think about
>> what will be useful when troubleshooting a problem. Many times, a
>> custom exception is useful. It says that the underlying exception has
>> been caught, logged and wrapped.
>>
> But how is a custom FooException better than a good ol'
> IllegalArgumentException? I'm not quite getting that yet.

Generally, you should use different Exception subclasses for cases that
may need different handling, so that callers can set up appropriate
catch blocks.

Regardless of the conditions under which you choose to generate
IllegalArgumentException, many methods you will be calling use it to
indicate an illegal argument condition that has not yet been logged or
otherwise reported.

If you also use it to indicate exceptions that have already been logged,
you risk either repeated logging of the same issue, or failure to log.

On the other hand, if you create an Exception subclass that you only
throw after logging the underlying problem, there is no ambiguity.
Callers have to deal with the consequences of the failure, but should
only generate log messages if they have something to add. The underlying
problem has already been logged.

Patricia

[toc] | [prev] | [next] | [standalone]


#12888

FromNovice <novice@example..com>
Date2012-03-11 23:23 +0000
Message-ID<XnsA013C5393E0CEjpnasty@94.75.214.39>
In reply to#12883
Patricia Shanahan <pats@acm.org> wrote in 
news:S7GdnRomTdoRu8DSnZ2dnUVZ_sWdnZ2d@earthlink.com:

> On 3/11/2012 2:54 PM, Novice wrote:
>> Lew<noone@lewscanon.com>  wrote in news:jjipli$np7$1
@news.albasani.net:
> ...
>>> It is common and frequently useful to create an application-specific
>>> checked exception. Again, and I've said this many times, think about
>>> what will be useful when troubleshooting a problem. Many times, a
>>> custom exception is useful. It says that the underlying exception has
>>> been caught, logged and wrapped.
>>>
>> But how is a custom FooException better than a good ol'
>> IllegalArgumentException? I'm not quite getting that yet.
> 
> Generally, you should use different Exception subclasses for cases that
> may need different handling, so that callers can set up appropriate
> catch blocks.
> 
> Regardless of the conditions under which you choose to generate
> IllegalArgumentException, many methods you will be calling use it to
> indicate an illegal argument condition that has not yet been logged or
> otherwise reported.
> 
> If you also use it to indicate exceptions that have already been 
logged,
> you risk either repeated logging of the same issue, or failure to log.
> 
> On the other hand, if you create an Exception subclass that you only
> throw after logging the underlying problem, there is no ambiguity.
> Callers have to deal with the consequences of the failure, but should
> only generate log messages if they have something to add. The 
underlying
> problem has already been logged.
> 
I'm sure this will seem like good advice when I understand it but it's 
still vague to me. 

It would really help if you could suggest a concrete example or two that 
show when to use a custom exception and why it's better. 

-- 
Novice

[toc] | [prev] | [next] | [standalone]


#12891

FromLew <noone@lewscanon.com>
Date2012-03-11 16:52 -0700
Message-ID<jjjdsa$984$1@news.albasani.net>
In reply to#12888
Novice wrote:
> Patricia Shanahan :
>> Novice wrote:
>>> Lew wrote:
>> ...
>>>> It is common and frequently useful to create an application-specific
>>>> checked exception. Again, and I've said this many times, think about
>>>> what will be useful when troubleshooting a problem. Many times, a
>>>> custom exception is useful. It says that the underlying exception has
>>>> been caught, logged and wrapped.
>>>>
>>> But how is a custom FooException better than a good ol'
>>> IllegalArgumentException? I'm not quite getting that yet.
>>
>> Generally, you should use different Exception subclasses for cases that
>> may need different handling, so that callers can set up appropriate
>> catch blocks.
>>
>> Regardless of the conditions under which you choose to generate
>> IllegalArgumentException, many methods you will be calling use it to
>> indicate an illegal argument condition that has not yet been logged or
>> otherwise reported.
>>
>> If you also use it to indicate exceptions that have already been
> logged,
>> you risk either repeated logging of the same issue, or failure to log.
>>
>> On the other hand, if you create an Exception subclass that you only
>> throw after logging the underlying problem, there is no ambiguity.
>> Callers have to deal with the consequences of the failure, but should
>> only generate log messages if they have something to add. The
> underlying
>> problem has already been logged.
>>
> I'm sure this will seem like good advice when I understand it but it's
> still vague to me.
>
> It would really help if you could suggest a concrete example or two that
> show when to use a custom exception and why it's better.

This is treading into the matter of art. I can show the idiom, but no way can 
I generate an entire project for you to show the impact of the logging 
strategy across the project, which is the point of the idiom.

Your entire application has layers. The deeper low-level layers are most 
likely to encounter problems first. Runtime exceptions are indicative of 
programming errors, but they're slippery, too. You don't have to catch them, 
which means an unguarded runtime exception can bring your system crashing 
down. That's not something you want to design it to do.

A low-level layer by definition brings some model of the world into 
conformance with your application's model. It might read a file and extract 
data to objects, or persist objects to a database, or transform your 
application's model into and out of XML documents for communication to other 
modules. Whatever the low layer does, the higher-level client code deals with 
abstractions relevant to the program. It's no longer a database record, for 
example, it's a 'Customer' with related 'Order' elements in a collection.

If something goes wrong at a deep layer, the higher-level client must first, 
become aware of it, and second, have some way to handle it. At that level, 
"runtime exception" or 'IOException' are too low-level - they aren't in the 
semantics of the application model. So the lower level, in addition to 
transforming extrinsic models of good stuff into the application domain, also 
must transform bad stuff like exceptions.

One good way to do this is to have an application-specific checked exception 
like 'FooException' for the "Foo" application. As Patricia says, this marks 
for higher-level code that lower-level stuff has done its job. At the higher 
level, we care only that the details are packaged in the exception's 'cause', 
not what the details are. A 'FooException', being checked, must be caught, so 
it cannot accidentally crash the application. Since all higher-level code sees 
'FooException' as a marker for bad stuff, and a black box, they all do the 
same thing with it, more or less. They return the program to valid state

"state" - definable by a quick Google search, for Pete's sake! Come on, man! 
Do a /little/ of the lifting yourself. And no, this isn't "bludgeoning". You 
get your ego in the way and you won't learn. There's a reason we expect you to 
act like a professional.

such as a decision screen or restart position, perhaps extracting standardized 
fields from the 'FooException' for the error message.

Much of programming only makes sense if you think architecturally - that is, 
holistically. Each layer has its own job, and its own vocabulary for that job. 
"Foo" has no business knowing about "I/O" in its Foo-specific logic, and no 
business knowing about "Foo" behavior in its I/O logic.

Separation of concerns.
Law of Demeter.
Object oriented.
Modularity.

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

[toc] | [prev] | [next] | [standalone]


#12901

FromNovice <novice@example..com>
Date2012-03-12 17:16 +0000
Message-ID<XnsA01486FC2B5E8jpnasty@94.75.214.39>
In reply to#12891
Lew <noone@lewscanon.com> wrote in news:jjjdsa$984$1@news.albasani.net:

> Novice wrote:
>> Patricia Shanahan :
>>> Novice wrote:
>>>> Lew wrote:
>>> ...
>>>>> It is common and frequently useful to create an
>>>>> application-specific checked exception. Again, and I've said this
>>>>> many times, think about what will be useful when troubleshooting a
>>>>> problem. Many times, a custom exception is useful. It says that
>>>>> the underlying exception has been caught, logged and wrapped.
>>>>>
>>>> But how is a custom FooException better than a good ol'
>>>> IllegalArgumentException? I'm not quite getting that yet.
>>>
>>> Generally, you should use different Exception subclasses for cases
>>> that may need different handling, so that callers can set up
>>> appropriate catch blocks.
>>>
>>> Regardless of the conditions under which you choose to generate
>>> IllegalArgumentException, many methods you will be calling use it to
>>> indicate an illegal argument condition that has not yet been logged
>>> or otherwise reported.
>>>
>>> If you also use it to indicate exceptions that have already been
>> logged,
>>> you risk either repeated logging of the same issue, or failure to
>>> log. 
>>>
>>> On the other hand, if you create an Exception subclass that you only
>>> throw after logging the underlying problem, there is no ambiguity.
>>> Callers have to deal with the consequences of the failure, but
>>> should only generate log messages if they have something to add. The
>> underlying
>>> problem has already been logged.
>>>
>> I'm sure this will seem like good advice when I understand it but
>> it's still vague to me.
>>
>> It would really help if you could suggest a concrete example or two
>> that show when to use a custom exception and why it's better.
> 
> This is treading into the matter of art. I can show the idiom, but no
> way can I generate an entire project for you to show the impact of the
> logging strategy across the project, which is the point of the idiom.
> 
> Your entire application has layers. The deeper low-level layers are
> most likely to encounter problems first. Runtime exceptions are
> indicative of programming errors, but they're slippery, too. You don't
> have to catch them, which means an unguarded runtime exception can
> bring your system crashing down. That's not something you want to
> design it to do. 
> 
> A low-level layer by definition brings some model of the world into 
> conformance with your application's model. It might read a file and
> extract data to objects, or persist objects to a database, or
> transform your application's model into and out of XML documents for
> communication to other modules. Whatever the low layer does, the
> higher-level client code deals with abstractions relevant to the
> program. It's no longer a database record, for example, it's a
> 'Customer' with related 'Order' elements in a collection. 
> 
> If something goes wrong at a deep layer, the higher-level client must
> first, become aware of it, and second, have some way to handle it. At
> that level, "runtime exception" or 'IOException' are too low-level -
> they aren't in the semantics of the application model. So the lower
> level, in addition to transforming extrinsic models of good stuff into
> the application domain, also must transform bad stuff like exceptions.
> 
> One good way to do this is to have an application-specific checked
> exception like 'FooException' for the "Foo" application. As Patricia
> says, this marks for higher-level code that lower-level stuff has done
> its job. At the higher level, we care only that the details are
> packaged in the exception's 'cause', not what the details are. A
> 'FooException', being checked, must be caught, so it cannot
> accidentally crash the application. Since all higher-level code sees 
> 'FooException' as a marker for bad stuff, and a black box, they all do
> the same thing with it, more or less. They return the program to valid
> state 
> 
> "state" - definable by a quick Google search, for Pete's sake! Come
> on, man! Do a /little/ of the lifting yourself. And no, this isn't
> "bludgeoning". You get your ego in the way and you won't learn.
> There's a reason we expect you to act like a professional.
> 
> such as a decision screen or restart position, perhaps extracting
> standardized fields from the 'FooException' for the error message.
> 
> Much of programming only makes sense if you think architecturally -
> that is, holistically. Each layer has its own job, and its own
> vocabulary for that job. "Foo" has no business knowing about "I/O" in
> its Foo-specific logic, and no business knowing about "Foo" behavior
> in its I/O logic. 
> 
> Separation of concerns.
> Law of Demeter.
> Object oriented.
> Modularity.
> 

I can see why it's hard to be specific about this issue without actually 
building a whole, complex project. I don't want to ask too much of anyone 
on this newsgroup and building a complex project is surely excessive. 
It's just that I really need to hear both principles AND concrete 
examples to be sure I really understand the principles. But let's try to 
keep this at the principle level for the most part.

I see your point about how the low levels of a program are very narrowly 
focused on doing something like finding a resource and don't know - and 
shouldn't care - about the significance of that low level task. Those low 
level methods don't know what the resource bundle is for or what the 
consequences are if the bundle can't be found. It makes sense that the 
decision about what to do if that search fails should be higher up in the 
logic. The higher level will know if that is a show-stopper or is 
recoverable. Some programs may have practical recovery options if the 
bundle is missing while others may not.

I suppose it also makes sense that the higher level logic wants to think 
in terms of "Foo problems" rather than IllegalArgumentExceptions. The 
person writing Foo just wants to know if the problem in the lower level 
method is a show-stopper or is recoverable and probably doesn't care if 
it is a checked or unchecked exception or an error.

But I'm not quite seeing all the implications yet.

Are you envisioning that our hypothetical Foo would have a single 
FooException that it wraps around everything that percolates up from the 
lower levels? Or would there be a bunch of FooExceptions, each handling 
different sorts of problems? 

And what happens with logging? Do we just log the error as an 
IllegalArgumentException (or whatever) when we find it at the low level? 
Or do we also log it again, this time as a FooException, when we deal 
with it at the higher levels? I'm uneasy about writing what are 
effectively redundant messages to the log. 

For what it's worth, I've cobbled together a CrashDialog class which my 
higher level methods, getLocalizedText() for example, displays when it 
handles an IllegalArgumentException() if it is thrown by getResources(). 
(I'm now throwing IllegalArgumentException for nulls in the parameters as 
well as a failed getBundle()). In that case, the CrashDialog class says: 

===================================================================
Foo - Severe Error 

The program has to stop for the following reason: Certain language 
resources were not available.

The problem has been logged and Technical Support will begin resolving 
the error shortly.

          [Okay]
====================================================================

The line about Technical Support resolving the problem shortly is 
somewhat fanciful since I'm the whole development team and the entire 
universe of end users at the moment ;-) I'm just envisioning what I'd say 
in a real production application. 

The bit about the language resources being unavailable is not completely 
satisfactory because it is probably not very helpful to a non-technical 
user but it seemed better to summarize the situation than to use the 
message from the exception; the user is even less likely to comprehend 
"the baseName must not be null" or "Unable to find resources for base 
name, com.novice.foo.FooTextzzz, and locale, jp_JP. Check the spelling of 
the base name". And I certainly don't want to display a stacktrace to the 
user!

I've also logged the fact that the user clicked on okay to end the 
program as another SEVERE error. Mind you, that seems redundant and I'm 
inclined to remove that code again. I'm assuming that in the real world, 
one SEVERE error is going to be enough to get the attention of the 
appropriate people and producing two or three SEVERE errors about the 
same problem is not going to get the problem examined any sooner. Correct 
me if I'm wrong! 

Now, that behavior wouldn't be standard for all cases. If the error is 
recoverable, the user would get different instructions that would lead 
him/her through whatever needs to be done to recover. And some errors 
might not be severe at all and just be informational. In those cases, the 
dialog might say "Information" instead of Severe Error and simply 
describe whatever workaround Foo adopted to get past the problem.

I'm feeling good about the error handling and logging now. It's starting 
to fall into place for me, aside from the whole custom exception 
question. 


-- 
Novice

[toc] | [prev] | [next] | [standalone]


#12956

FromLew <noone@lewscanon.com>
Date2012-03-13 08:31 -0700
Message-ID<jjnp94$5qe$1@news.albasani.net>
In reply to#12901
Novice wrote:
> Are you envisioning that our hypothetical Foo would have a single
> FooException that it wraps around everything that percolates up from the
> lower levels? Or would there be a bunch of FooExceptions, each handling
> different sorts of problems?

Quite often a single exception type suffices. You would only add another if 
there were a crying need for it.

> And what happens with logging? Do we just log the error as an
> IllegalArgumentException (or whatever) when we find it at the low level?

Did you read Patricia's advice on this very matter?

> Or do we also log it again, this time as a FooException, when we deal
> with it at the higher levels? I'm uneasy about writing what are
> effectively redundant messages to the log.

Patricia recommended, and I agree, that the custom exception serve as a signal 
that the lower-level problem has been logged. Remember?

> For what it's worth, I've cobbled together a CrashDialog class which my
> higher level methods, getLocalizedText() for example, displays when it
> handles an IllegalArgumentException() if it is thrown by getResources().
> (I'm now throwing IllegalArgumentException for nulls in the parameters as
> well as a failed getBundle()). In that case, the CrashDialog class says:

Is a failed 'getBundle()' really a programming error? Is it really an illegal 
argument? There was nothing illegal about the argument /per se/ if the 
resource just happened not to be available.

I suggest a checked exception, either 'IOException' or a subtype thereof, for 
a missing bundle, unless it really and truly is completely under programmer 
control. (And deployment-time issues never are.)

> ===================================================================
> Foo - Severe Error
>
> The program has to stop for the following reason: Certain language
> resources were not available.
>
> The problem has been logged and Technical Support will begin resolving
> the error shortly.
>
>            [Okay]
> ====================================================================
>
> The line about Technical Support resolving the problem shortly is
> somewhat fanciful since I'm the whole development team and the entire
> universe of end users at the moment ;-) I'm just envisioning what I'd say
> in a real production application.

Be careful of making promises because you must keep them.

Well, technically you don't have to, but do you want to be that guy?

> The bit about the language resources being unavailable is not completely
> satisfactory because it is probably not very helpful to a non-technical
> user but it seemed better to summarize the situation than to use the
> message from the exception; the user is even less likely to comprehend
> "the baseName must not be null" or "Unable to find resources for base
> name, com.novice.foo.FooTextzzz, and locale, jp_JP. Check the spelling of
> the base name". And I certainly don't want to display a stacktrace to the
> user!
>
> I've also logged the fact that the user clicked on okay to end the
> program as another SEVERE error. Mind you, that seems redundant and I'm

How is that any kind of error?

> inclined to remove that code again. I'm assuming that in the real world,
> one SEVERE error is going to be enough to get the attention of the
> appropriate people and producing two or three SEVERE errors about the
> same problem is not going to get the problem examined any sooner. Correct
> me if I'm wrong!

Don't worry, we will.

But you have a brain. What makes sense there? What would look funny to the ops 
guy?

Are you really thinking like a troubleshooter in the field, or like the 
programmer whose name that troubleshooter will curse?

> Now, that behavior wouldn't be standard for all cases. If the error is
> recoverable, the user would get different instructions that would lead
> him/her through whatever needs to be done to recover. And some errors
> might not be severe at all and just be informational. In those cases, the
> dialog might say "Information" instead of Severe Error and simply
> describe whatever workaround Foo adopted to get past the problem.
>
> I'm feeling good about the error handling and logging now. It's starting
> to fall into place for me, aside from the whole custom exception
> question.

What do you mean by "recoverable"? I mean able to show an error dialog and 
invite the operator to shut down. Is that not a valid program state?

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

[toc] | [prev] | [next] | [standalone]


#12893

FromPatricia Shanahan <pats@acm.org>
Date2012-03-11 17:51 -0700
Message-ID<QdidndGYsfwc1cDSnZ2dnUVZ_tKdnZ2d@earthlink.com>
In reply to#12888
On 3/11/2012 4:23 PM, Novice wrote:
> Patricia Shanahan<pats@acm.org>  wrote in
> news:S7GdnRomTdoRu8DSnZ2dnUVZ_sWdnZ2d@earthlink.com:
>
>> On 3/11/2012 2:54 PM, Novice wrote:
>>> Lew<noone@lewscanon.com>   wrote in news:jjipli$np7$1
> @news.albasani.net:
>> ...
>>>> It is common and frequently useful to create an application-specific
>>>> checked exception. Again, and I've said this many times, think about
>>>> what will be useful when troubleshooting a problem. Many times, a
>>>> custom exception is useful. It says that the underlying exception has
>>>> been caught, logged and wrapped.
>>>>
>>> But how is a custom FooException better than a good ol'
>>> IllegalArgumentException? I'm not quite getting that yet.
>>
>> Generally, you should use different Exception subclasses for cases that
>> may need different handling, so that callers can set up appropriate
>> catch blocks.
>>
>> Regardless of the conditions under which you choose to generate
>> IllegalArgumentException, many methods you will be calling use it to
>> indicate an illegal argument condition that has not yet been logged or
>> otherwise reported.
>>
>> If you also use it to indicate exceptions that have already been
> logged,
>> you risk either repeated logging of the same issue, or failure to log.
>>
>> On the other hand, if you create an Exception subclass that you only
>> throw after logging the underlying problem, there is no ambiguity.
>> Callers have to deal with the consequences of the failure, but should
>> only generate log messages if they have something to add. The
> underlying
>> problem has already been logged.
>>
> I'm sure this will seem like good advice when I understand it but it's
> still vague to me.
>
> It would really help if you could suggest a concrete example or two that
> show when to use a custom exception and why it's better.
>

Using the same exception for "illegal argument" and "already logged and
wrapped" is unlikely to get you into much trouble in a short program
viewed for a few minutes.

The potential trouble comes when you have a large program, too large to
read the whole thing before making a change, and it is being modified by
a programmer who does not know, or does not remember, that the exception
has those two meanings.

That makes it difficult to illustrate in a small example.

Remember that a lot of what you are being told, both in the newsgroup
and in the articles you are reading, is based on experience with
maintaining large programs over many years.

Patricia

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.java.programmer


csiph-web