Class ServerStartupWaiter
ExoContainer started, then a JMX-managed HTTP connector in STARTED
state. Tomcat starts its connectors only once every webapp is deployed and
every container is started, and their 'stateName' JMX attribute switches to
STARTED as the last server startup step — so that state is the one signal
that the server can answer the HTTP requests startup-time work may need to
send to itself (OAuth/OIDC discovery, token issuance, MCP, REST).
Degrades to the container-startup-only wait when no JMX-managed HTTP connector exists (unit tests, embedded runs, AJP-only servers) or when the JMX read fails, escapes with a warning when every HTTP connector reached a terminal state without starting (e.g. port already bound), and gives up with a warning past "exo.server.startup.wait.timeoutSeconds" seconds (600L by default) — the timeout is the safety net for any thread the server startup transitively depends on that this class cannot recognize (see below), turning a potential boot deadlock into a bounded delay.
The server startup thread itself is refused with an
IllegalStateException: the connector starts only after that thread
finishes the startup, so waiting there can never end. That detection is by
thread name ("main") — the reliable signal for the standard Tomcat
bootstrap, but blind to renamed bootstrap threads and to the
catalina-utility-* threads Tomcat uses when startStopThreads
> 1; those cases are what the timeout bounds instead.
-
Method Summary
Modifier and TypeMethodDescriptionstatic voidawaitServerStartup(ExoContainer container, String subject) Waits until the container is started and one HTTP connector is up, per the class contract above.static booleanisHttpConnectorPending(ExoContainer container, String subject) Whether an HTTP connector exists and has not started yet — i.e.
-
Method Details
-
awaitServerStartup
public static void awaitServerStartup(ExoContainer container, String subject) throws InterruptedException Waits until the container is started and one HTTP connector is up, per the class contract above.- Parameters:
container- the container whose startup ends the first wait phasesubject- what is being held, for the wait logs and the startup-thread error message (e.g. "Quartz scheduled jobs", "MCP client OAuth registrations")- Throws:
InterruptedException- when the wait is interrupted (server shutdown)IllegalStateException- when called on the server startup thread while a wait is actually needed — waiting there would deadlock the boot, the work must move to an async-init or request thread
-
isHttpConnectorPending
Whether an HTTP connector exists and has not started yet — i.e. whetherawaitServerStartup(org.exoplatform.container.ExoContainer, java.lang.String)would actually have something to wait for beyond the container startup. Lets a caller keep its legacy synchronous path when there is nothing observable to wait for (unit tests, embedded runs, AJP-only servers) and pay the asynchronous wait only when the wait is real.- Parameters:
container- the container providing the JMX serversubject- what would be held, for the degrade-path logs- Returns:
truewhen an HTTP connector is observable and not STARTED
-