前一篇文章已经讲了nginx+terracotta集群,但在项目实施时遇到了一些问题,主要是freemarker和webworker版本太低造成的。
type Exceptionreport
message java.io.NotSerializableException:freemarker.ext.servlet.HttpSessionHashModel
description Theserver encountered an internal error that prevented it from fulfilling thisrequest.
exception
java.lang.RuntimeException: java.io.NotSerializableException: freemarker.ext.servlet.HttpSessionHashModel
截图:
在类HttpSessionHashModel增加调试信息,发现session和request都是null,而最初是webwork的FreemarkerServlet调入的,于是想找到webwork 2.1.7的源代码分析,发现时com.opensymphony.webwork.views.freemarker.FreemarkerManager的代码造成的,而webwork 2.2.6版的代码已做了相关调整,于是直接修改了FreemarkerManager类的buildScopesHashModel后集群正常了。
type Exceptionreport
message
description Theserver encountered an internal error that prevented it from fulfilling thisrequest.
exception
java.lang.NullPointerException
freemarker.ext.servlet.HttpSessionHashModel.get(HttpSessionHashModel.java:122)
freemarker.core.DynamicKeyName.dealWithStringKey(DynamicKeyName.java:151)
freemarker.core.DynamicKeyName._eval(DynamicKeyName.java:108)
freemarker.core.Expression.eval(Expression.java:111)
freemarker.core.Dot._eval(Dot.java:74)
freemarker.core.Expression.eval(Expression.java:111)
freemarker.core.Expression.evalAndCoerceToString(Expression.java:115)
freemarker.core.DollarVariable.accept(DollarVariable.java:76)
freemarker.core.Environment.visit(Environment.java:265)
freemarker.core.MixedContent.accept(MixedContent.java:93)
freemarker.core.Environment.visit(Environment.java:265)
freemarker.core.Environment.process(Environment.java:243)
freemarker.template.Template.process(Template.java:277)
com.opensymphony.webwork.views.freemarker.FreemarkerServlet.process(FreemarkerServlet.java:229)
com.opensymphony.webwork.views.freemarker.FreemarkerServlet.doGet(FreemarkerServlet.java:47)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.springframework.orm.hibernate.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:171)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:39)
note The fullstack trace of the root cause is available in the Apache Tomcat/6.0.36 logs.
//新代码
TemplateHashModel sessionModel;
//terracotta集群时,因为terracotta已经Session copy,所以get ATTR_SESSION_MODEL的对象不为空,导致无法初始化HttpSessionHashModel对象,故修改
HttpSession session = request.getSession(false);
if (session != null) {
sessionModel = new HttpSessionHashModel(session, wrapper);
model.put(KEY_SESSION_MODEL, sessionModel);
session.setAttribute(ATTR_SESSION_MODEL, sessionModel);
} else {
// no session means no attributes ???
// model.put(KEY_SESSION_MODEL, new SimpleHash());
}
// 原来的代码
// if (request.getSession(false) != null) {
// HttpSession session = request.getSession();
//
// synchronized (session) {
// sessionModel = (HttpSessionHashModel) session.getAttribute(ATTR_SESSION_MODEL);
// 这里的问题,因为session数据已通过terracotta共享了,所以不能初始化另外一部机器的类HttpSessionHashModel
// if (sessionModel == null) {
// sessionModel = new HttpSessionHashModel(session, wrapper);
// session.setAttribute(ATTR_SESSION_MODEL, sessionModel);
// }
// }
//
// model.put(KEY_SESSION_MODEL, sessionModel);
// }
// else {
// // no session means no attributes ???
// // model.put(KEY_SESSION_MODEL, new SimpleHash());
// }