On 7/4/15 11:55 AM, Bryan Pendleton wrote:

I've been digging into o.a.d.iapi.services.i18n.MessageService.java.

Going all the way back to the original code import (revision 37083),
MessageService.getLocalizedMessage() contains this bit of code:

                try {
msg[0] = formatMessage(getBundleForLocale(locale, messageId), messageId, arguments, true);
                        rc[0] = 0;
                        return;
                } catch (MissingResourceException mre) {
                        // message does not exist in the requested locale
// most likely it does exist in our fake base class _en, so try that.
                } catch (ShutdownException se) {
                }
msg[0] = formatMessage(getBundleForLocale(EN, messageId), messageId, arguments, false);
                rc[0] = 0;

I'm wondering specifically about the bit:

                } catch (ShutdownException se) {
                }

Why is this code here? Under what circumstances would we want to
discard the ShutdownException and continue processing like this?

Anybody have any memories of why this code was written this way?

I did spend some time reading DERBY-4920, DERBY-4911, and particularly
the epic DERBY-4741, all of which suggest that the presence of ShutdownException
handling in the code, in general, is due to the fact that when the engine
is being shutdown, there may be multiple threads which are active, and
the engine's shutdown logic uses JDK "interrupt" features to cause those
threads to receive ShutdownException exceptions being thrown.

But those old JIRAs, marvelous as they are, didn't really clarify why
MessageService has any business discarding the exception in this manner.

thanks,

bryan

Hi Bryan,

I don't have any previous experience with how Derby handles ShutdownException. However, I've looked at all the places where we throw and catch this exception. My sense is that ShutdownException is raised when the engine is seriously confused about its internal state, chiefly while handling race conditions during (possibly user-initiated) shutdown. In almost all cases (including the one you're studying) the response to ShutdownException is to silently swallow it and then continue with what you were doing. There is one place where we report this exception--that only happens when the engine is up on the blocks, being examined while debugging a problem.

In the code block which you are studying, the message formatting logic responds to the ShutdownException by falling through to its last chance handler. Do you think it should do something else?

Thanks,
-Rick

--------------------------------------

Here are some notes I jotted down about how ShutdownException is used:


Thrown when context management is confused or interrupted:

    ContextManager.checkInterrupt()
    ContextService.getFactory()

Caught and swallowed:

SystemContext.cleanupOnError() // race conditions during shutdown. just continue shutting down. MessageService.getTextMessage() // fall through to last chance message formatting logic MessageService.getLocalizedMessage() // fall through to last chance message formatting logic
    InterruptStatus.setInterrupted()  // continue interrupt processing
InterruptStatus.restoreIntrFlagIfSeen() // continue interrupt processing InterruptStatus.restoreIntrFlagIfSeen() // continue interrupt processing
    IndexStatisticsDaemonImpl.processingLoop() // continue thread shutdown
    IndexStatisticsDaemonImpl.stop() // continue thread shutdown
    LogToFile.performWork()  // continue winding down a checkpoint

Caught and recorded only if we are tracing while debugging a problem:

    IndexStatisticsDaemonImpl.run()

Caught and handled as a failure:

    BaseMonitor.getBundle()

Reply via email to