Java 对于绑定到会话的对象,是否允许applicationserver在会话失效期间两次调用`valueUnbound(..)`方法?
我有一个web应用程序(Servlet2.4规范),它在WebSphere8.0、8.5和Tomcat8.5上运行良好。现在我们想评估应用程序是否可以在WebSphereLiberty下运行 Websphere日志文件在启动期间提供以下版本号:Java 对于绑定到会话的对象,是否允许applicationserver在会话失效期间两次调用`valueUnbound(..)`方法?,java,session,jakarta-ee,websphere-liberty,Java,Session,Jakarta Ee,Websphere Liberty,我有一个web应用程序(Servlet2.4规范),它在WebSphere8.0、8.5和Tomcat8.5上运行良好。现在我们想评估应用程序是否可以在WebSphereLiberty下运行 Websphere日志文件在启动期间提供以下版本号: product = WebSphere Application Server 17.0.0.2 (wlp-1.0.17.cl170220170523-1818) 通过在浏览器中发送启动URL启动应用程序期间,某些对象将绑定到会话。例如,通过以下代码:
product = WebSphere Application Server 17.0.0.2 (wlp-1.0.17.cl170220170523-1818)
通过在浏览器中发送启动URL启动应用程序期间,某些对象将绑定到会话。例如,通过以下代码:
(...)
GwgImpl gwg = (GwgImpl)session.getAttribute(WEBKEY);
if (gwg == null) {
gwg = new GwgImpl();
session.setAttribute(WEBKEY, gwg);
}
(...)
GwgImpl
对象由以下内容定义:
public class GwgImpl implements HttpSessionBindingListener {
List<String> list = new ArrayList<String>();
(...)
public void valueBound(HttpSessionBindingEvent ev) {
}
public void valueUnbound(HttpSessionBindingEvent ev) {
list.clear();
list = null;
(...)
}
(...)
}
对象GwgImpl
中的方法valueUnbound()
被调用两次。由于该方法的第一次调用将变量list
设置为null
,因此第二次调用将导致NullPointerException
我知道我可以通过添加if语句轻松解决此问题,但由于没有其他applicationserver存在此问题,因此我有以下问题:
对于绑定到会话的对象,是否允许applicationserver在会话失效期间调用valueUnbound(..)
方法两次?(我还没有从servlet规范中找到明确的答案)
或者这是WebSphereApplicationServer中的一个bug
编辑
我修改了valueUnbound(..)
方法,以查看两个调用的调用堆栈和HttpSessionBindingEvent的值
public void valueUnbound(HttpSessionBindingEvent ev) {
logger.info("Stacktrace:");
for (StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
logger.info(" " + stackTraceElement.toString());
}
logger.info("HttpSessionBindingEvent:");
logger.info(" SessionID='" + ev.getSession().getId() + "'");
logger.info(" Name='" + ev.getName() + "'");
logger.info(" Value='" + ev.getValue() + "'");
(...)
}
在我的Websphere日志文件中,我现在可以找到以下行:
Stacktrace:
java.lang.Thread.getStackTrace(Unknown Source)
com.mycorp.gwg.dao.GwgImpl.valueUnbound(GwgImpl.java:130)
com.ibm.ws.session.http.HttpSessionObserver.sessionDestroyed(HttpSessionObserver.java:231)
com.ibm.ws.session.SessionEventDispatcher.sessionDestroyed(SessionEventDispatcher.java:167)
com.ibm.ws.session.StoreCallback.sessionInvalidated(StoreCallback.java:129)
com.ibm.ws.session.store.memory.MemorySession.invalidate(MemorySession.java:236)
com.ibm.ws.session.http.HttpSessionImpl.invalidate(HttpSessionImpl.java:317)
com.ibm.ws.session.SessionData.invalidate(SessionData.java:256)
com.ibm.ws.session.HttpSessionFacade.invalidate(HttpSessionFacade.java:197)
com.mycorp.login.client.LogoutHandler.doLogout(LogoutHandler.java:154)
(...)
HttpSessionBindingEvent:
SessionID='X_AmenZHphA-DBkNRoOeWZu'
Name='gwg'
Value='null'
(...)
Stacktrace:
java.lang.Thread.getStackTrace(Unknown Source)
com.mycorp.gwg.dao.GwgImpl.valueUnbound(GwgImpl.java:130)
com.ibm.ws.session.http.HttpSessionAttributeObserver.sessionAttributeRemoved(HttpSessionAttributeObserver.java:160)
com.ibm.ws.session.SessionStateEventDispatcher.sessionAttributeRemoved(SessionStateEventDispatcher.java:142)
com.ibm.ws.session.StoreCallback.sessionAttributeRemoved(StoreCallback.java:196)
com.ibm.ws.session.store.memory.MemorySession.removeAttribute(MemorySession.java:537)
com.ibm.ws.session.store.memory.MemorySession.invalidate(MemorySession.java:253)
com.ibm.ws.session.http.HttpSessionImpl.invalidate(HttpSessionImpl.java:317)
com.ibm.ws.session.SessionData.invalidate(SessionData.java:256)
com.ibm.ws.session.HttpSessionFacade.invalidate(HttpSessionFacade.java:197)
com.mycorp.login.client.LogoutHandler.doLogout(LogoutHandler.java:154)
(...)
HttpSessionBindingEvent:
SessionID='X_AmenZHphA-DBkNRoOeWZu'
Name='gwg'
Value='com.mycorp.gwg.dao.GwgImpl@b294b7c'
你有没有发现这一点很清楚。我观察到WAS 9的类似模式,这给我们带来了一个问题,并试图找到确定在sessionDestroyed与SessionDistributereMoved期间调用valueUnbound的最佳方法。想法?@b科尼:不幸的是没有。我最终接受了这种(对我来说)奇怪的行为,并强化了我的valueUnbound()
方法。
Stacktrace:
java.lang.Thread.getStackTrace(Unknown Source)
com.mycorp.gwg.dao.GwgImpl.valueUnbound(GwgImpl.java:130)
com.ibm.ws.session.http.HttpSessionObserver.sessionDestroyed(HttpSessionObserver.java:231)
com.ibm.ws.session.SessionEventDispatcher.sessionDestroyed(SessionEventDispatcher.java:167)
com.ibm.ws.session.StoreCallback.sessionInvalidated(StoreCallback.java:129)
com.ibm.ws.session.store.memory.MemorySession.invalidate(MemorySession.java:236)
com.ibm.ws.session.http.HttpSessionImpl.invalidate(HttpSessionImpl.java:317)
com.ibm.ws.session.SessionData.invalidate(SessionData.java:256)
com.ibm.ws.session.HttpSessionFacade.invalidate(HttpSessionFacade.java:197)
com.mycorp.login.client.LogoutHandler.doLogout(LogoutHandler.java:154)
(...)
HttpSessionBindingEvent:
SessionID='X_AmenZHphA-DBkNRoOeWZu'
Name='gwg'
Value='null'
(...)
Stacktrace:
java.lang.Thread.getStackTrace(Unknown Source)
com.mycorp.gwg.dao.GwgImpl.valueUnbound(GwgImpl.java:130)
com.ibm.ws.session.http.HttpSessionAttributeObserver.sessionAttributeRemoved(HttpSessionAttributeObserver.java:160)
com.ibm.ws.session.SessionStateEventDispatcher.sessionAttributeRemoved(SessionStateEventDispatcher.java:142)
com.ibm.ws.session.StoreCallback.sessionAttributeRemoved(StoreCallback.java:196)
com.ibm.ws.session.store.memory.MemorySession.removeAttribute(MemorySession.java:537)
com.ibm.ws.session.store.memory.MemorySession.invalidate(MemorySession.java:253)
com.ibm.ws.session.http.HttpSessionImpl.invalidate(HttpSessionImpl.java:317)
com.ibm.ws.session.SessionData.invalidate(SessionData.java:256)
com.ibm.ws.session.HttpSessionFacade.invalidate(HttpSessionFacade.java:197)
com.mycorp.login.client.LogoutHandler.doLogout(LogoutHandler.java:154)
(...)
HttpSessionBindingEvent:
SessionID='X_AmenZHphA-DBkNRoOeWZu'
Name='gwg'
Value='com.mycorp.gwg.dao.GwgImpl@b294b7c'