Details
-
Bug
-
Resolution: Unresolved
-
Critical
-
None
-
3.0.19.Final, 3.6.2.Final
-
None
Description
[I'm relatively new to WildFly/Weld/JAX-RS, so please bear with me. I will try to provide all other information you need, just ask.]
We have a JAX-RS webapp that uses Weld for dependency injection. It doesn't define an explicit Application class, so Weld generates a org.wildfly.swarm.generated.WildFlySwarmDefaultJAXRSApplication$Proxy$_$$_WeldClientProxy instance mapped to the '/' path. Requests get mapped directly to the path defined by resources, e.g. @Path("/api/foo"). So far so good.
I'm now trying to drop a jar with an explicitly defined Application into the mix. This is defined as:
@ApplicationPath("/metrics") @Monitored // A custom JAX-RS name binding annotation public class MetricsApplication extends Application { @Override public Set<Class<?>> getClasses() { Set<Class<?>> resources = new HashSet<>(); // Only export MetricsResource as a resource. resources.add(MetricsResource.class); // Also measure latency for /metrics. resources.add(MonitoringFilter.class); return resources; } }
This second application exports a single resource, annotated with @Path("/"), so it ends up handling the /metrics path. It also registers a request and response filter that measures latency. It should intercept all applications and/or resources annotated with @Monitored and it does it perfectly in another webapp that doesn't use Weld, only WildFly. It looks like this:
@Provider @Monitored public class MonitoringFilter implements ContainerRequestFilter, ContainerResponseFilter { /** The application context, used for retrieving the {@link ApplicationPath} value. */ @Context Application application; // [...] }
In the non-Weld webapp the injected Application instance is always correct (i.e. it's a MetricsApplication for a /metrics request, the webapp's ServiceAplication class for all other requests.
In the Weld-using webapp the injected Application instance is always the same, regardless of request: one of MetricsApplication and the Weld generated proxy. It seems to me that which of the two is injected depends on the hash of the class name, because as soon as I add an explicit Aplication subclass to the app I always get the MetricsApplication injected. Without it, I always get the Weld default application proxy.
Interestingly enough, Weld never generates a proxy for MetricsApplication but it always does for ServiceApplication (if I define one) so I can never retrieve the @ApplicationPath annotation of the ServiceApplication (because the proxy doesn't preserve it).
Help? Please?