Skip to content

TOMEE-4716 - deploy MicroProfile Health at the context root regardless of declared JAX-RS applications - #2960

Open
jungm wants to merge 3 commits into
apache:mainfrom
jungm:TOMEE-4716
Open

jungm wants to merge 3 commits into
apache:mainfrom
jungm:TOMEE-4716

Conversation

@jungm

@jungm jungm commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Fixes TOMEE-4716: with the MicroProfile distribution, a webapp that declares a JAX-RS Application listing its classes has no /health, /health/live, /health/ready or /health/started (all 404); an Application listing nothing gets them under its own path, e.g. /api/health.

MicroProfileHealthChecksEndpoint only reached a webapp through class scanning (WebAppInfo.restClass), and RESTService only deploys scanned classes into the default application (no Application declared) or into an Application that lists nothing. Since TOMEE-3729 a declared Application deploys exactly the classes it lists, so the endpoint went with the rest of the scanned classes. MicroProfile Health 4.0.1 describes the endpoints as representing the entire runtime, not one JAX-RS application.

TomEEMicroProfileListener now registers the endpoint in a new WebAppInfo.containerRestClass set, and RESTService deploys those classes at the context root: as their own internal application when the webapp declares Application subclasses, as part of the default application otherwise, and in the per-class fallback deployment. CXF runs one server per address, so an application mapped to the context root gets them instead of a separate internal application. RsHttpListener.deployApplication takes them next to the application, so the application instance stays as it is and its name bindings don't apply to them. TOMEE-3729's rule is unchanged, and the existing removal of the endpoint when a servlet is mapped to /* still applies.

New HealthEndpointTest in tomee-microprofile-itests covers an @ApplicationPath("/api") application listing its resource and listing nothing (both 404 on /test/health without the fix), applications at / listing their resource, listing nothing and declaring a name binding, and two applications. The rest of tomee-microprofile-itests, itests/jaxrs, openejb-cxf-rs (115 tests) and the MicroProfile Health TCK (28 tests) pass.

…t regardless of declared JAX-RS applications
…t root and with multiple applications

The test with an application at the context root fails: the application is deployed, but the health endpoint is not available.
@rzo1

rzo1 commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

@jungm I pushed cc6f875 with two more cases for HealthEndpointTest:

  • multipleApplications (two applications at /api and /other): passes
  • applicationAtTheContextRoot (@ApplicationPath("/"), listing its classes): fails, /test/hello answers 200 but /test/health is a 404

So the additional container application at /* collides with a user application, which is mapped to the context root as well. RESTService#afterApplicationCreated always deploys it with the prefix "/" + wildcard, which is the same address as the one of the user application.

An idea would be to add the containerRestClass classes to the user application, if it is mapped to the context root, instead of deploying a second application. Can you have a look?

Two more things I noticed, but did not verify:

  • The new block is guarded by deploymentWithApplication, so with the old deployment (pojo configuration for a listed class or openejb.jaxrs.application=false) and an application listing its classes, the health endpoint might still be missing.
  • For an application listing nothing, the endpoint moves from <context>/<application path>/health to <context>/health. This is intended as far as I understand, but it is worth a note in the release notes.

…he context root

CXF runs one server per address, so a separate container application at the context root clashes with an application mapped to /. The container resources are deployed with that application instead. They are passed to the listener next to the application, so the application instance stays as it is and its name bindings don't apply to them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants