开发者

WARN: Could not register destruction callback

开发者 https://www.devze.com 2022-12-17 17:20 出处:网络
15:11:14,676WARN FacesRequestAttributes:121 - Could not register destruction callback [org.springframework.beans.factory.support.DisposableBeanAdapter@1059fd6] for attribute \'purchaseController\' be

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 Spring RequestContextListener 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).


I tried adding

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

as suggested by erhan14 on this forum post.

And that warning disappeared for me. Hope it helps.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号