Alexander,

Given those constraints, what about simply modify the output string?  As in:
=====
.....
} catch (Exception ex) {
            // Formatting failed: use localized format string.
            return format + " " + toString(record, ex);
}

private String toString(LogRecord record, Exception ex) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        Object[] params = record.getParameters();
        if (params != null) {
           String sep = "";
           for (Object o : params)  {
               pw.append(sep);
               if (o != null) {
                   pw.append(o.getClass().getName());
               } else {
                   pw.append("null");
               }
               pw.println();
               sep = ",";
           }
        }
        ex.printStackTrace(pw);
        return sw.toString();
    }
============================

There is wiggle room in the API docs for modifying the output string which 
would avoid a CCC.


Jason

________________________________________
From: Alexander Fomin <alexander.fo...@oracle.com>
Sent: Monday, November 23, 2015 9:27 AM
To: Jason Mehrens; core-libs-dev@openjdk.java.net; Daniel Fuchs; 
mandy.ch...@oracle.com
Subject: Re: JDK 9 RFR [8137005]: java.util.logging.Formatter#formatMessage() 
swallows Exceptions

Hi Jason

On 20.11.2015 22:15, Jason Mehrens wrote:
> Alexander,
>
> I see your point.  It is also out of spec for Handler.setFormatter to 
> actually call Formatter.setErrorManager.  What if there are subclasses of 
> formatter that exist today with a setErrorManager method?  Also not all 
> handlers have one formatter or actually call super.setFormatter since you 
> can't unseal the super handler (GAE).

Good point. You are right, modifying Handler.setErrorManager and
Handler.setFormatter methods by the way to call
Formatter.setErrorManger() we may introduce  undesirable behavior. For
example, if  Handler is configured with a custom Formatter with a custom
ErrorManger specified, we may spoil the ErrorManager in that Formatter.

Probably the better solution would be to specify the default
ErrorManager for a Formatter in the constructor of specific Handler. But
seems we can't just call getErrorManager() in ConsoleHandler
constructor, for example, as far as the subclass isn't fully initialized
yet.

>
> I still lean toward letting the exceptions fly since there is already an 
> expectation that formatters fail.  Is the concern that the handler will fail 
> or that the program will fail?
Well, actually my initial thought was to let the exceptions to be thrown
from Formatter to corresponding logging Handler where it should be
processed and reported to a registered ErrorManager. But we've given up
from this idea because:
- would require a CCC any way.
- would probably require a release note since it will alter the existing
behavior.
- the current implementation of ErrorManager will cause a
printStackTrace() - but only the first time such an error happens in
Handler. So that, the errors in Formatter will be swallowed any way if
some error happened before.
- this approach may cause an NPE if the concrete Handler subclass has
not installed any ErrorManager and does not override reportError. So,
there's the issue of potentially breaking existing code.

So, I was looking for a solution that shouldn't change any existing
behavior, shouldn't break a code, should work in all cases, should allow
to a Formatter report about its internal errors itself without relay on
the corresponding Handler where the Exception could be intentionally
ignored.

>
> I've recently been tinkering with a custom filter that internally uses a 
> formatter and have prototyped adding get/setErrorManager method to it and it 
> just becomes a mess because to have start thinking about more corner cases 
> and adding more to the spec.
What is wrong with get/serErrorManager for Formatter? It should be just
a way for Formatter to report its internal errors.

> I really think that if you are going to add the 3 ErrorManager methods you 
> should only add them to the LogManager (JDK-6865510) as a way to unify 
> failure reporting in the LogManager itself and to deal with failures inside 
> of error manger.  As in to remove that ugly System.err code in 
> Handler.reportError.  The LogManager would work kind of like 
> Thread.defaultUncaughtExceptionHandler and the Handler.errorManager is kind 
> of like the Thread.uncaughtException handler.
Well. I'm with you on this. I would prefer the fix is a part of more
wider enhancement that unified Logger's inner errors reporting inclusive
redesign for ErrorManager and so on. Probably it's not a big deal, but
it should be some JEP for JDK9. I'm afraid it's too late for 9.

> Then to fix this bug we could report it to via 
> LogManager.getLogManager().reportError.
Well, it's good solution as a default behavior if a user not specified
its own ErrorManager. But, I don't think we have to restrict a user with
what ErrorManager is used in their Formatters. So, set/getErrorManager
for Formatter, Handler and others make sense, i guess.

Ok, I'm still hope on some compromise with the current solution.
The only way to avoid undesirable behavior changes that I see now is
some property in logging.properties that would define if the
ErrorManager in Formatter for a specific Handler must be specified by
default with something. Something like that:

java.util.logging.ConsoleHandler.formatter.ErrorManager = default

If it's set in logging.properties then we are eligible to call
"formatter.setErrorManager(errorManager);" somewhere in Handler
constructor. If not, we have to use Formatter as it has been specified
in specific handler.
Looks ugly, but Let my play with that. If I found it OK, I'll back with
new webrev.

Thanks,
Alexander

Reply via email to