Writing async JAX-RS services with Wildfly 11 with weld development mode active
jangerritsen Feb 26, 2018 3:49 PMI started to develop a new JavaEE application where I provide several REST services using JAX-RS
For my experiments I used a simple test Service:
@ApplicationScoped
@Path("service")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class RestService {
@Resource
ManagedExecutorService mes;
@Path("get")
@GET
public void get(@Suspended AsyncResponse ar) {
mes.execute(
() -> {
ar.resume(Response.ok("response").build());
}
);
}
}
Trying to use the async approach, I always got an error in my request:
RESTEASY003320: Failed processing arguments of public void RestService.get(javax.ws.rs.container.AsyncResponse)
Looking in the logs, I saw that the root cause is:
Caused by: java.lang.IllegalStateException: UT010026: Async is not supported for this request, as not all filters or Servlets were marked as supporting async
at io.undertow.servlet//io.undertow.servlet.spec.HttpServletRequestImpl.startAsync(HttpServletRequestImpl.java:961)
at org.jboss.resteasy.resteasy-jaxrs//org.jboss.resteasy.plugins.server.servlet.Servlet3AsyncHttpRequest$Servlet3ExecutionContext.setupAsyncContext(Servlet3AsyncHttpRequest.java:336)
at org.jboss.resteasy.resteasy-jaxrs//org.jboss.resteasy.plugins.server.servlet.Servlet3AsyncHttpRequest$Servlet3ExecutionContext.suspend(Servlet3AsyncHttpRequest.java:324)
at org.jboss.resteasy.resteasy-jaxrs//org.jboss.resteasy.plugins.server.servlet.Servlet3AsyncHttpRequest$Servlet3ExecutionContext.suspend(Servlet3AsyncHttpRequest.java:318)
at org.jboss.resteasy.resteasy-jaxrs//org.jboss.resteasy.plugins.server.servlet.Servlet3AsyncHttpRequest$Servlet3ExecutionContext.suspend(Servlet3AsyncHttpRequest.java:312)
at org.jboss.resteasy.resteasy-jaxrs//org.jboss.resteasy.core.AsynchronousResponseInjector.inject(AsynchronousResponseInjector.java:38)
at org.jboss.resteasy.resteasy-jaxrs//org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:92)
... 59 more
With further debugging I found this code in io.undertow.servlet.handlers.FilterHandler
public FilterHandler(final Map<DispatcherType, List<ManagedFilter>> filters, final boolean allowNonStandardWrappers, final HttpHandler next) {
this.allowNonStandardWrappers = allowNonStandardWrappers;
this.next = next;
this.filters = new EnumMap<>(filters);
Map<DispatcherType, Boolean> asyncSupported = new EnumMap<>(DispatcherType.class);
for(Map.Entry<DispatcherType, List<ManagedFilter>> entry : filters.entrySet()) {
boolean supported = true;
for(ManagedFilter i : entry.getValue()) {
if(!i.getFilterInfo().isAsyncSupported()) {
supported = false; // <-- marked as not supporting async
break;
}
}
asyncSupported.put(entry.getKey(), supported);
}
this.asyncSupported = asyncSupported;
}
Using inspection to find the culprit in the list I found:
i = {ManagedFilter@16278} "ManagedFilter{filterInfo=FilterInfo{filterClass=class org.jboss.weld.probe.ProbeFilter, name='weld-probe-filter'}}"
filterInfo = {FilterInfo@16326} "FilterInfo{filterClass=class org.jboss.weld.probe.ProbeFilter, name='weld-probe-filter'}"
filterClass = {Class@11698} "class org.jboss.weld.probe.ProbeFilter"
name = "weld-probe-filter"
instanceFactory = {UndertowDeploymentInfoService$6@16330}
initParams = {HashMap@16331} size = 0
asyncSupported = false
Using Google and searching around I found this hint:
https://docs.jboss.org/weld/reference/latest/en-US/html/configure.html#config-dev-mode
But setting the filters did not help. I did not investigate why. I guess they are still loaded, not executed for my request but the check for async support is done globally on server initialization.
The only way to get the async mechanism running was to disable the weld development mode globally.
<subsystem xmlns="urn:jboss:domain:weld:4.0" development-mode="false"/>
Having the development mode disabled is not a problem for me at the moment, but it took me several hours to find the cause of my problem and a fitting workaround.
I thought someone here might be interested to find a better solution, or at least, someone else having the same problem can now google the error message and hopefully find my workaround