Bug 60152

Summary: Allow exceptions from Connector.start() to be caught and handled in code that embeds Tomcat
Product: Tomcat 9 Reporter: Andy Wilkinson <awilkinson>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: enhancement    
Priority: P2    
Version: unspecified   
Target Milestone: -----   
Hardware: All   
OS: All   

Description Andy Wilkinson 2016-09-20 10:48:44 UTC
Currently, when a Connector fails to start, Tomcat logs the exception twice (once in the protocol and once in the service) and then swallows the exception. This isn't very friendly when embedding Tomcat as it means that handling of the exception and reporting it to the user is out of the embedder's control. We'd like a couple of things to be possible:

1. Catching the exception that's thrown when the Connector is started.
2. Tomcat not to log anything

This would allow an embedder to take complete control of how the problem is reported to a user.

In discussing this with Mark Thomas, one possibility that he raised was a Connector equivalent of failCtxIfServletStartFails that both StandardContext and StandardHost have today.
Comment 1 Remy Maucherat 2016-09-20 10:52:13 UTC
+1 for 1) if it's not too hard, however -1 for 2) (Tomcat logs errors and stuff pretty much everywhere, there's no switch for any of them, and it doesn't make sense; please adjust the logging configuration to use some custom logger of your own instead).
Comment 2 Andy Wilkinson 2016-09-20 11:19:38 UTC
>  and it doesn't make sense

The current behaviour makes sense given that Tomcat swallows the exception; otherwise, there'd be no way to see that a problem has occurred. If a change is made such that Tomcat can be configured to throw the exception, then I would argue that it no longer makes sense for Tomcat to also log the exception.

> please adjust the logging configuration to use some custom logger of your own instead

That would only work if it's possible for a logger to distinguish between exceptions that Tomcat is going to swallow and those that it's also going to throw to be caught by embedding code.
Comment 3 Remy Maucherat 2016-09-20 11:39:43 UTC
Ok so basically Tomcat needs to remove all logging I suppose. Nice. I don't think all the necessary information to produce the best logging is contained in the exception, also.
Ex: How do I know if it's a bind exception or a SSL configuration error ? Your solution: dump the exception to the user and he'll figure it out.
So -1, sorry, you'll have to figure things out at the logging layer, even if you don't like it.
Comment 4 Christopher Schultz 2016-09-20 18:46:39 UTC
(Calm down, Rémy.)

I think the proper way to handle this is for Tomcat to change the way the exceptions are handled, here. Instead of introducing a new option (c.f. failCtxIfServletStartFails), why not just move the exception-handling to one layer higher than an embedded controller would see?

That way, standalone Tomcat can still catch and log the exceptions which is appropriate, and embedded controllers can do whatever they like.
Comment 5 Mark Thomas 2016-09-20 18:52:04 UTC
The complication - and I need to dig through the archives to find the details - is that there was a requirement that Tomcat started even if a connector failed.

What we have here is two requirements for exactly opposite behavior. I suspect configuration will have to be part of the solution but if someone can find a way to do this without a new option, great.
Comment 6 Christopher Schultz 2016-09-20 19:08:40 UTC
(In reply to Mark Thomas from comment #5)
> The complication - and I need to dig through the archives to find the
> details - is that there was a requirement that Tomcat started even if a
> connector failed.

I apologize as I'm ignorant of the code in question, but isn't Tomcat's bootstrap process circumvented by an embedded controller? In that case, Tomcat can just try/catch around the Connector.start() calls and log there, no?

> What we have here is two requirements for exactly opposite behavior. I
> suspect configuration will have to be part of the solution but if someone
> can find a way to do this without a new option, great.

It's ugly, but we could also have a callback-registration that would indicate errors for certain components that failed to start. Post-start, the embedded controller could take remunerative action.
Comment 7 Mark Thomas 2016-09-28 12:22:29 UTC
The current behaviour derives to bug 49030 and r752323.

I'm still looking at options for implementing this but it does look like it is going to involve some form of new configuration option.
Comment 8 Mark Thomas 2016-10-07 14:39:57 UTC
Fixed in 9.0.x for 9.0.12 onwards.