You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Tim Ellison <t....@gmail.com> on 2009/10/08 13:47:03 UTC

[classlib] Looking up exception messages

Part of the patch for HARMONY-6346 includes some improvements to the way
we handle localized exception messages.  That prompted me to write down
a few thoughts...

I don't really like the way we do I18N of exception messages.  We create
message string like this

  throw new IOException(Messages.getString("archive.1E"));

The string "archive.1E" is a key into the resource files loaded by the
Messages class based on the current locale.

1) I have no concrete proof, but I'm prepared to bet that 90% of the
exceptions thrown never get asked for their message string.  Yet we are
setting it eagerly - mainly because there is no mechanism on exceptions
to answer the message lazily.

Simple messages may not be too bad, but we also have formatted messages
where we replace token in the message with actual parameters.  A
particular bad example requires formatting more argument strings, e.g.

  throw new IllegalArgumentException(
      Msg.getString("K031e", new String[] { "query", uri.toString() }));

in this case we format the URI and format the message string, and
probably never use the answer.


2) The use of ResourceBundles for handling the strings seems like
overkill too.

Each time we need a string, we load up the entire set of error messages
for that module into a Properties (i.e. hash table) and hold onto them
forever.

The HARMONY-6346 patch makes the resource file soft referenced so that
may help, but I can't help thinking there is a simpler mechanism for
loading the one or two strings that we need rather than the whole lot +
data structure each time.

Regards,
Tim


Re: [classlib] Looking up exception messages

Posted by Tim Ellison <t....@gmail.com>.
On 08/Oct/2009 23:16, Mark Hindess wrote:
> In message <4A...@googlemail.com>, Oliver Deakin writes:
>> Tim Ellison wrote:
>>> All this is dependent upon the premise that messages are not used
>>> often, I need to check that first.
>> Indeed - this might be overkill if it only has a small impact.
> 
> Yeah.  We really need to confirm/refute this theory.
> 
> Regardless though, I rather like the "no lookups for en/C locale idea"
> because it improves code readability too.

FYI I have a version of the IBM VME that can show when an exception is
thrown (java -Xdump:java:event=throw) and ran it with a simple
HelloWorld example.

I'll admit I was surprised that the Harmony code isn't throwing any
exceptions during start-up, pleasantly surprised that is.  So maybe a
fuss about nothing :-)

Regards,
Tim


Re: [classlib] Looking up exception messages

Posted by Nathan Beyer <nd...@apache.org>.
On Thu, Oct 8, 2009 at 5:16 PM, Mark Hindess
<ma...@googlemail.com> wrote:
>
> In message <4A...@googlemail.com>, Oliver Deakin writes:
>>
>> Tim Ellison wrote:
>> > On 08/Oct/2009 14:21, Oliver Deakin wrote:
>> >
>> >> Tim Ellison wrote:
>> >>
>> >>> Part of the patch for HARMONY-6346 includes some improvements to the way
>> >>> we handle localized exception messages.  That prompted me to write down
>> >>> a few thoughts...
>> >>>
>> >>> I don't really like the way we do I18N of exception messages.  We create
>> >>> message string like this
>> >>>
>> >>>   throw new IOException(Messages.getString("archive.1E"));
>> >>>
>> >>>
>> >> One way to handle this could be to use an exception manager class.
>> >> Rather than carrying out the lookup on the error message at the time the
>> >> exception is thrown, instead associate the exception object with the
>> >> error message key using a exception manager class. Then in the
>> >> getMessage(), getLocalizedMessage() etc. methods the exception will call
>> >> into the exception manager to get it's message (and can cache it locally
>> >> in case of future lookups) if one exists.
>> >>
>> >> So instead of:
>> >> throw new IOException(Messages.getString("archive.1E"));
>> >>
>> >> you might have (here create() returns the exception passed to it as the
>> >> first parameter):
>> >> throw ExceptionManager.create(new IOException(), "archive.1E");
>
> or:
>
>  ExceptionManager.throw(new IOException(), "archive.1E")
>
> and let the Exception manager throw it?  Or maybe that would "ruin"
> the stack trace.

It would ruin the stack trace, we want to leave the throw where it is.

>
>> >> Once the exception is caught and it's message string queried, it will
>> >> call ExceptionManager.getMessage(this) to see if it has an associated
>> >> message available. This way the error message lookup will only happen if
>> >> the message is actually queried. The references in the ExceptionManager
>> >> could be soft so that if the exception is not caught or is discarded,
>> >> then the ExceptionManager does not unnecesarily hang onto it's error
>> >> message.
>> >>
>> >
>> > Yep, so to replay what you just said, the 'guts' of the ExceptionManager
>> > would be a WeakHashMap<Throwable, Object[]> of 'pending' exceptions that
>> > may be asked for their formatted message.
>> >
>> > The Object[] would contain the message id and arguments that only get
>> > looked up and formatted if asked.
>> >
>>
>> Sounds about right to me.
>>
>> >
>> >>> The string "archive.1E" is a key into the resource files loaded by the
>> >>> Messages class based on the current locale.
>> >>>
>> >>> 1) I have no concrete proof, but I'm prepared to bet that 90% of the
>> >>> exceptions thrown never get asked for their message string.  Yet we are
>> >>> setting it eagerly - mainly because there is no mechanism on exceptions
>> >>> to answer the message lazily.
>> >>>
>> >>> Simple messages may not be too bad, but we also have formatted messages
>> >>> where we replace token in the message with actual parameters.  A
>> >>> particular bad example requires formatting more argument strings, e.g.
>> >>>
>> >>>   throw new IllegalArgumentException(
>> >>>       Msg.getString("K031e", new String[] { "query", uri.toString() }));
>> >>>
>> >>> in this case we format the URI and format the message string, and
>> >>> probably never use the answer.
>> >>>
>> >>>
>> >> For this example, the create() method could be made to accept variable
>> >> arguments. It's first argument would be the exception object, the second
>> >> would be the message identifier, and any subsequent arguments would be
>> >> the values to be inserted into tokens in the message string. This would
>> >> mean that in the above example the uri.toString() would still be
>> >> evaluated at the time the exception was created, but the lookup and
>> >> formatting of the error string would only be done when the actual
>> >> exception message was queried. (I havn't looked deeply at this case so
>> >> it may be more complex then that).
>> >>
>> >
>> > ...and if you wanted to be sneaky, you could change the message id to be
>> > the actual string for `you favorite locale` which would mean there was
>> > no loading of message resource bundles if you happened to be running in
>> > the most-favored-locale, e.g.
>> >
>> > throw ExceptionManager.create(new IOException(), "Stream is closed");
>> >
>>
>> True, although I'm not entirely convinced this is a good idea for a
>> couple of reasons:
>>  - Changing all our message files to have "Full English message"="Full
>> translated message" might make them quite cluttered and hard to read.
>
> You read those?  You should get out more. ;-)
>
> Personally I read the code more often and having a meaningful string
> instead of a token definitely makes it easier.  I also think it would
> make mistakes less likely.  Consider my commit r822652 yesterday for
> HARMONY-6347 compared with the original patch.  The original patch
> changed:
>
>  if (len < 0)
>    throw new ArrayIndexOutOfBoundsException(Messages.getString("crypto.36"));
>
> to:
>
>  if (len < 0 || offset < 0)
>    throw new ArrayIndexOutOfBoundsException(Messages.getString("crypto.36"));
>
> which would have given the message "len is negative" for either case.  I
> think this kind of mistake[0] would be less likely with the English text
> present.

I can live without the actual English message, if the resource keys
were semantic - "length_less_than_zero" instead of "crypto.36". I
never thought it saved much to use a hex numbering scheme.

Any possibility to just doing something much more simple, like a
package-scope class named ExceptionMessages with something simple like
String[] constants with semantic names that are offset by locale. If
loading a properties file is expensive, is it any less expensive to
put it in a class file?

>
>>  - Some messages may contain the '=' character (for example, archive.15)
>> which would mess up the parsing of message files.
>
> I'm fairly sure having the same format would not be sensible but that is
> entirely under our control (and Tim already mentioned that Properties/
> ResourceBundles are rather expensive for a lookup mechanism).  However,
> I admit having longer strings probably does tend to make lookups more
> expensive.  In order to avoid duplication you'd probably end up doing
> two lookups:
>
> english -> unique (int?) key (in a common map file)
> unique (int?) key -> nls message (in an nls specific map file)
>
> I guess you'd probably take the pragmatic approach and do:
>
>  throw ExceptionManager.create(new IOException(), "TOKEN: Stream is closed");
>
> and strip the token to either look it up or just print the remainder
> of the message.
>
>> > All this is dependent upon the premise that messages are not used
>> > often, I need to check that first.
>>
>> Indeed - this might be overkill if it only has a small impact.
>
> Yeah.  We really need to confirm/refute this theory.
>
> Regardless though, I rather like the "no lookups for en/C locale idea"
> because it improves code readability too.
>
> -Mark.
>
> [0] This particular example is a variation of a "bad smell in code" that
>    I usual spot that more typically looks like:
>
>      if (A || B)
>        exit_with_error("Failed because of A or B")
>
>    where the error is any string that is independent of A or B.
>
>
>

Re: [classlib] Looking up exception messages

Posted by Mark Hindess <ma...@googlemail.com>.
In message <4A...@googlemail.com>, Oliver Deakin writes:
>
> Tim Ellison wrote:
> > On 08/Oct/2009 14:21, Oliver Deakin wrote:
> >   
> >> Tim Ellison wrote:
> >>     
> >>> Part of the patch for HARMONY-6346 includes some improvements to the way
> >>> we handle localized exception messages.  That prompted me to write down
> >>> a few thoughts...
> >>>
> >>> I don't really like the way we do I18N of exception messages.  We create
> >>> message string like this
> >>>
> >>>   throw new IOException(Messages.getString("archive.1E"));
> >>>   
> >>>       
> >> One way to handle this could be to use an exception manager class.
> >> Rather than carrying out the lookup on the error message at the time the
> >> exception is thrown, instead associate the exception object with the
> >> error message key using a exception manager class. Then in the
> >> getMessage(), getLocalizedMessage() etc. methods the exception will call
> >> into the exception manager to get it's message (and can cache it locally
> >> in case of future lookups) if one exists.
> >>
> >> So instead of:
> >> throw new IOException(Messages.getString("archive.1E"));
> >>
> >> you might have (here create() returns the exception passed to it as the
> >> first parameter):
> >> throw ExceptionManager.create(new IOException(), "archive.1E");

or:

  ExceptionManager.throw(new IOException(), "archive.1E")

and let the Exception manager throw it?  Or maybe that would "ruin"
the stack trace.

> >> Once the exception is caught and it's message string queried, it will
> >> call ExceptionManager.getMessage(this) to see if it has an associated
> >> message available. This way the error message lookup will only happen if
> >> the message is actually queried. The references in the ExceptionManager
> >> could be soft so that if the exception is not caught or is discarded,
> >> then the ExceptionManager does not unnecesarily hang onto it's error
> >> message.
> >>     
> >
> > Yep, so to replay what you just said, the 'guts' of the ExceptionManager
> > would be a WeakHashMap<Throwable, Object[]> of 'pending' exceptions that
> > may be asked for their formatted message.
> >
> > The Object[] would contain the message id and arguments that only get
> > looked up and formatted if asked.
> >   
> 
> Sounds about right to me.
> 
> >   
> >>> The string "archive.1E" is a key into the resource files loaded by the
> >>> Messages class based on the current locale.
> >>>
> >>> 1) I have no concrete proof, but I'm prepared to bet that 90% of the
> >>> exceptions thrown never get asked for their message string.  Yet we are
> >>> setting it eagerly - mainly because there is no mechanism on exceptions
> >>> to answer the message lazily.
> >>>
> >>> Simple messages may not be too bad, but we also have formatted messages
> >>> where we replace token in the message with actual parameters.  A
> >>> particular bad example requires formatting more argument strings, e.g.
> >>>
> >>>   throw new IllegalArgumentException(
> >>>       Msg.getString("K031e", new String[] { "query", uri.toString() }));
> >>>
> >>> in this case we format the URI and format the message string, and
> >>> probably never use the answer.
> >>>   
> >>>       
> >> For this example, the create() method could be made to accept variable
> >> arguments. It's first argument would be the exception object, the second
> >> would be the message identifier, and any subsequent arguments would be
> >> the values to be inserted into tokens in the message string. This would
> >> mean that in the above example the uri.toString() would still be
> >> evaluated at the time the exception was created, but the lookup and
> >> formatting of the error string would only be done when the actual
> >> exception message was queried. (I havn't looked deeply at this case so
> >> it may be more complex then that).
> >>     
> >
> > ...and if you wanted to be sneaky, you could change the message id to be
> > the actual string for `you favorite locale` which would mean there was
> > no loading of message resource bundles if you happened to be running in
> > the most-favored-locale, e.g.
> >
> > throw ExceptionManager.create(new IOException(), "Stream is closed");
> >   
> 
> True, although I'm not entirely convinced this is a good idea for a 
> couple of reasons:
>  - Changing all our message files to have "Full English message"="Full 
> translated message" might make them quite cluttered and hard to read.

You read those?  You should get out more. ;-)

Personally I read the code more often and having a meaningful string
instead of a token definitely makes it easier.  I also think it would
make mistakes less likely.  Consider my commit r822652 yesterday for
HARMONY-6347 compared with the original patch.  The original patch
changed:

  if (len < 0)
    throw new ArrayIndexOutOfBoundsException(Messages.getString("crypto.36"));

to:

  if (len < 0 || offset < 0)
    throw new ArrayIndexOutOfBoundsException(Messages.getString("crypto.36"));

which would have given the message "len is negative" for either case.  I
think this kind of mistake[0] would be less likely with the English text
present.
   
>  - Some messages may contain the '=' character (for example, archive.15) 
> which would mess up the parsing of message files.

I'm fairly sure having the same format would not be sensible but that is
entirely under our control (and Tim already mentioned that Properties/
ResourceBundles are rather expensive for a lookup mechanism).  However,
I admit having longer strings probably does tend to make lookups more
expensive.  In order to avoid duplication you'd probably end up doing
two lookups:

english -> unique (int?) key (in a common map file)
unique (int?) key -> nls message (in an nls specific map file)

I guess you'd probably take the pragmatic approach and do:

  throw ExceptionManager.create(new IOException(), "TOKEN: Stream is closed");

and strip the token to either look it up or just print the remainder
of the message.

> > All this is dependent upon the premise that messages are not used
> > often, I need to check that first.
> 
> Indeed - this might be overkill if it only has a small impact.

Yeah.  We really need to confirm/refute this theory.

Regardless though, I rather like the "no lookups for en/C locale idea"
because it improves code readability too.

-Mark.

[0] This particular example is a variation of a "bad smell in code" that
    I usual spot that more typically looks like:

      if (A || B)
        exit_with_error("Failed because of A or B")

    where the error is any string that is independent of A or B.



Re: [classlib] Looking up exception messages

Posted by Oliver Deakin <ol...@googlemail.com>.
Tim Ellison wrote:
> On 08/Oct/2009 14:21, Oliver Deakin wrote:
>   
>> Tim Ellison wrote:
>>     
>>> Part of the patch for HARMONY-6346 includes some improvements to the way
>>> we handle localized exception messages.  That prompted me to write down
>>> a few thoughts...
>>>
>>> I don't really like the way we do I18N of exception messages.  We create
>>> message string like this
>>>
>>>   throw new IOException(Messages.getString("archive.1E"));
>>>   
>>>       
>> One way to handle this could be to use an exception manager class.
>> Rather than carrying out the lookup on the error message at the time the
>> exception is thrown, instead associate the exception object with the
>> error message key using a exception manager class. Then in the
>> getMessage(), getLocalizedMessage() etc. methods the exception will call
>> into the exception manager to get it's message (and can cache it locally
>> in case of future lookups) if one exists.
>>
>> So instead of:
>> throw new IOException(Messages.getString("archive.1E"));
>>
>> you might have (here create() returns the exception passed to it as the
>> first parameter):
>> throw ExceptionManager.create(new IOException(), "archive.1E");
>>
>> Once the exception is caught and it's message string queried, it will
>> call ExceptionManager.getMessage(this) to see if it has an associated
>> message available. This way the error message lookup will only happen if
>> the message is actually queried. The references in the ExceptionManager
>> could be soft so that if the exception is not caught or is discarded,
>> then the ExceptionManager does not unnecesarily hang onto it's error
>> message.
>>     
>
> Yep, so to replay what you just said, the 'guts' of the ExceptionManager
> would be a WeakHashMap<Throwable, Object[]> of 'pending' exceptions that
> may be asked for their formatted message.
>
> The Object[] would contain the message id and arguments that only get
> looked up and formatted if asked.
>   

Sounds about right to me.

>   
>>> The string "archive.1E" is a key into the resource files loaded by the
>>> Messages class based on the current locale.
>>>
>>> 1) I have no concrete proof, but I'm prepared to bet that 90% of the
>>> exceptions thrown never get asked for their message string.  Yet we are
>>> setting it eagerly - mainly because there is no mechanism on exceptions
>>> to answer the message lazily.
>>>
>>> Simple messages may not be too bad, but we also have formatted messages
>>> where we replace token in the message with actual parameters.  A
>>> particular bad example requires formatting more argument strings, e.g.
>>>
>>>   throw new IllegalArgumentException(
>>>       Msg.getString("K031e", new String[] { "query", uri.toString() }));
>>>
>>> in this case we format the URI and format the message string, and
>>> probably never use the answer.
>>>   
>>>       
>> For this example, the create() method could be made to accept variable
>> arguments. It's first argument would be the exception object, the second
>> would be the message identifier, and any subsequent arguments would be
>> the values to be inserted into tokens in the message string. This would
>> mean that in the above example the uri.toString() would still be
>> evaluated at the time the exception was created, but the lookup and
>> formatting of the error string would only be done when the actual
>> exception message was queried. (I havn't looked deeply at this case so
>> it may be more complex then that).
>>     
>
> ...and if you wanted to be sneaky, you could change the message id to be
> the actual string for `you favorite locale` which would mean there was
> no loading of message resource bundles if you happened to be running in
> the most-favored-locale, e.g.
>
> throw ExceptionManager.create(new IOException(), "Stream is closed");
>   

True, although I'm not entirely convinced this is a good idea for a 
couple of reasons:
 - Changing all our message files to have "Full English message"="Full 
translated message" might make them quite cluttered and hard to read.
 - Some messages may contain the '=' character (for example, archive.15) 
which would mess up the parsing of message files.

>
> All this is dependent upon the premise that messages are not used often,
> I need to check that first.
>   

Indeed - this might be overkill if it only has a small impact.

Regards,
Oliver

> Regards,
> Tim
>
>   
>>> 2) The use of ResourceBundles for handling the strings seems like
>>> overkill too.
>>>
>>> Each time we need a string, we load up the entire set of error messages
>>> for that module into a Properties (i.e. hash table) and hold onto them
>>> forever.
>>>
>>> The HARMONY-6346 patch makes the resource file soft referenced so that
>>> may help, but I can't help thinking there is a simpler mechanism for
>>> loading the one or two strings that we need rather than the whole lot +
>>> data structure each time.
>>>
>>> Regards,
>>> Tim
>>>
>>>
>>>   
>>>       
>
>   

-- 
Oliver Deakin
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 741598. 
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU


Re: [classlib] Looking up exception messages

Posted by Tim Ellison <t....@gmail.com>.
On 08/Oct/2009 14:21, Oliver Deakin wrote:
> Tim Ellison wrote:
>> Part of the patch for HARMONY-6346 includes some improvements to the way
>> we handle localized exception messages.  That prompted me to write down
>> a few thoughts...
>>
>> I don't really like the way we do I18N of exception messages.  We create
>> message string like this
>>
>>   throw new IOException(Messages.getString("archive.1E"));
>>   
> 
> One way to handle this could be to use an exception manager class.
> Rather than carrying out the lookup on the error message at the time the
> exception is thrown, instead associate the exception object with the
> error message key using a exception manager class. Then in the
> getMessage(), getLocalizedMessage() etc. methods the exception will call
> into the exception manager to get it's message (and can cache it locally
> in case of future lookups) if one exists.
> 
> So instead of:
> throw new IOException(Messages.getString("archive.1E"));
> 
> you might have (here create() returns the exception passed to it as the
> first parameter):
> throw ExceptionManager.create(new IOException(), "archive.1E");
> 
> Once the exception is caught and it's message string queried, it will
> call ExceptionManager.getMessage(this) to see if it has an associated
> message available. This way the error message lookup will only happen if
> the message is actually queried. The references in the ExceptionManager
> could be soft so that if the exception is not caught or is discarded,
> then the ExceptionManager does not unnecesarily hang onto it's error
> message.

Yep, so to replay what you just said, the 'guts' of the ExceptionManager
would be a WeakHashMap<Throwable, Object[]> of 'pending' exceptions that
may be asked for their formatted message.

The Object[] would contain the message id and arguments that only get
looked up and formatted if asked.

>> The string "archive.1E" is a key into the resource files loaded by the
>> Messages class based on the current locale.
>>
>> 1) I have no concrete proof, but I'm prepared to bet that 90% of the
>> exceptions thrown never get asked for their message string.  Yet we are
>> setting it eagerly - mainly because there is no mechanism on exceptions
>> to answer the message lazily.
>>
>> Simple messages may not be too bad, but we also have formatted messages
>> where we replace token in the message with actual parameters.  A
>> particular bad example requires formatting more argument strings, e.g.
>>
>>   throw new IllegalArgumentException(
>>       Msg.getString("K031e", new String[] { "query", uri.toString() }));
>>
>> in this case we format the URI and format the message string, and
>> probably never use the answer.
>>   
> 
> For this example, the create() method could be made to accept variable
> arguments. It's first argument would be the exception object, the second
> would be the message identifier, and any subsequent arguments would be
> the values to be inserted into tokens in the message string. This would
> mean that in the above example the uri.toString() would still be
> evaluated at the time the exception was created, but the lookup and
> formatting of the error string would only be done when the actual
> exception message was queried. (I havn't looked deeply at this case so
> it may be more complex then that).

...and if you wanted to be sneaky, you could change the message id to be
the actual string for `you favorite locale` which would mean there was
no loading of message resource bundles if you happened to be running in
the most-favored-locale, e.g.

throw ExceptionManager.create(new IOException(), "Stream is closed");


All this is dependent upon the premise that messages are not used often,
I need to check that first.

Regards,
Tim

>> 2) The use of ResourceBundles for handling the strings seems like
>> overkill too.
>>
>> Each time we need a string, we load up the entire set of error messages
>> for that module into a Properties (i.e. hash table) and hold onto them
>> forever.
>>
>> The HARMONY-6346 patch makes the resource file soft referenced so that
>> may help, but I can't help thinking there is a simpler mechanism for
>> loading the one or two strings that we need rather than the whole lot +
>> data structure each time.
>>
>> Regards,
>> Tim
>>
>>
>>   
> 

Re: [classlib] Looking up exception messages

Posted by Oliver Deakin <ol...@googlemail.com>.
Tim Ellison wrote:
> Part of the patch for HARMONY-6346 includes some improvements to the way
> we handle localized exception messages.  That prompted me to write down
> a few thoughts...
>
> I don't really like the way we do I18N of exception messages.  We create
> message string like this
>
>   throw new IOException(Messages.getString("archive.1E"));
>   

One way to handle this could be to use an exception manager class. 
Rather than carrying out the lookup on the error message at the time the 
exception is thrown, instead associate the exception object with the 
error message key using a exception manager class. Then in the 
getMessage(), getLocalizedMessage() etc. methods the exception will call 
into the exception manager to get it's message (and can cache it locally 
in case of future lookups) if one exists.

So instead of:
throw new IOException(Messages.getString("archive.1E"));

you might have (here create() returns the exception passed to it as the 
first parameter):
throw ExceptionManager.create(new IOException(), "archive.1E");

Once the exception is caught and it's message string queried, it will 
call ExceptionManager.getMessage(this) to see if it has an associated 
message available. This way the error message lookup will only happen if 
the message is actually queried. The references in the ExceptionManager 
could be soft so that if the exception is not caught or is discarded, 
then the ExceptionManager does not unnecesarily hang onto it's error 
message.

> The string "archive.1E" is a key into the resource files loaded by the
> Messages class based on the current locale.
>
> 1) I have no concrete proof, but I'm prepared to bet that 90% of the
> exceptions thrown never get asked for their message string.  Yet we are
> setting it eagerly - mainly because there is no mechanism on exceptions
> to answer the message lazily.
>
> Simple messages may not be too bad, but we also have formatted messages
> where we replace token in the message with actual parameters.  A
> particular bad example requires formatting more argument strings, e.g.
>
>   throw new IllegalArgumentException(
>       Msg.getString("K031e", new String[] { "query", uri.toString() }));
>
> in this case we format the URI and format the message string, and
> probably never use the answer.
>   

For this example, the create() method could be made to accept variable 
arguments. It's first argument would be the exception object, the second 
would be the message identifier, and any subsequent arguments would be 
the values to be inserted into tokens in the message string. This would 
mean that in the above example the uri.toString() would still be 
evaluated at the time the exception was created, but the lookup and 
formatting of the error string would only be done when the actual 
exception message was queried. (I havn't looked deeply at this case so 
it may be more complex then that).

Regards,
Oliver

> 2) The use of ResourceBundles for handling the strings seems like
> overkill too.
>
> Each time we need a string, we load up the entire set of error messages
> for that module into a Properties (i.e. hash table) and hold onto them
> forever.
>
> The HARMONY-6346 patch makes the resource file soft referenced so that
> may help, but I can't help thinking there is a simpler mechanism for
> loading the one or two strings that we need rather than the whole lot +
> data structure each time.
>
> Regards,
> Tim
>
>
>   

-- 
Oliver Deakin
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number 741598. 
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU