15:11:14,676 WARN FacesRequestAttributes:121 - Could not register destruction callback [org.springframework.beans.factory.support.DisposableBeanAdapter@1059fd6] for attribute 'purchaseController' because FacesRequestAttributes does not support such callbacks
This warn message appears in my log a lot. For every managed bean whenever it expires. It expires after a given time, because I'm using MyFaces Orchestra.
I have defined the org.springframework.web.context.request.RequestContextListener
in my web.xml
, and I don't have the spring jar only ones on my classpath (i.e. not a class-loading problem)
The docs of FacesRequestAttribute says:
NOTE: In contrast to ServletRequestAttributes, this variant does not support destruction callbacks for scoped attributes, neither for the request scope nor for the session scope. If you rely on such implicit destruction callbacks, consider defining a Spring RequestContextListener in your web.xml.
The purchaseController
is actually a simple managed bean (not extending anything an implementing only Serializable
), annotated with @Controller
.
Update1:
The beans in @Scope("request")
and @Scope("session")
seem to be affected.
So I wanted to know whether this warn poses any danger to the proper flow. I.e. if something really needs those callbacks. If not, I will just skip the warning with the lo4j config.
Update 2:
I digged a little further, and it seems that this happens only sometimes. IF the listener is used, then RequestContextHolder.currentRequestAttributes()
returns the ServletRequestAttributes
, rather than FacesRequestAttributes
. So it appears that sometimes the listener doesn't work and doesn't set the current attributes in the RequestContextHolder
.
Update 3:
I turned debug on for RequestContextListener
, and here's the result:
07:21:31,518 DEBUG RequestContextListener:69 - Bound request context to thread: org.apache.catalina.connector.RequestFacade@1190ae9
07:21:31,518 DEBUG RequestContextListener:89 - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@1190ae9
07:21:31,538 WARN FacesRequestAttributes:121 - Could not register destruction callback [org.springframework.beans.factory.support.DisposableBeanAdapter@11aa152] for attribute 'org.apache.myfaces.orchestra.conversation.AccessScopeManager' because FacesRequestAttributes does not support such callbacks
07:21:31,541 WARN FacesRequestAttributes:121 - Could not register destruction callback [org.springframework.beans.factory.support.DisposableBeanAdapter@1552393] for attribute 'localeController' because FacesRequestAttributes does not support such callbacks
....and so on, other request and session beans
It appears that the request gets destroyed before access to the beans is attempted. Which is very odd. Could this be due to a problem in the servlet container implementation of the listener handling?
In the javadoc of FacesRequestAttributes
, we can read:
Note: In contrast to
ServletRequestAttributes
, this variant does not support destruction callbacks for scoped attributes, neither for the request scope nor for the session scope. If you rely on such implicit destruction callbacks, consider defining a SpringRequestContextListener
in your web.xml.
And, indeed, the registerDestructionCallback()
method of FacesRequestAttributes
doesn't do much things:
public void registerDestructionCallback(String name, Runnable callback, int scope) {
if (logger.isWarnEnabled()) {
logger.warn("Could not register destruction callback [" + callback + "] for attribute '" + name +
"' because FacesRequestAttributes does not support such callbacks");
}
}
But my understanding is that the RequestContextListener
(that you have declared) will take care of this job. Its requestDestroyed(ServletRequestEvent requestEvent)
method is shown below:
public void requestDestroyed(ServletRequestEvent requestEvent) {
ServletRequestAttributes attributes =
(ServletRequestAttributes) requestEvent.getServletRequest().getAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE);
ServletRequestAttributes threadAttributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (threadAttributes != null) {
// We're assumably within the original request thread...
if (attributes == null) {
attributes = threadAttributes;
}
RequestContextHolder.resetRequestAttributes();
LocaleContextHolder.resetLocaleContext();
}
if (attributes != null) {
attributes.requestCompleted();
if (logger.isDebugEnabled()) {
logger.debug("Cleared thread-bound request context: " + requestEvent.getServletRequest());
}
}
}
And if you look at the javadoc of ServletRequestAttributes#requestCompleted()
:
Executes all request destruction callbacks and updates the session attributes that have been accessed during request processing.
So, I think that you can safely skip the WARN with log4j configuration (maybe confirm this with a little debugging session though).