httpsessionlistener resolved my session persistence issue

August 19, 2008 on 9:16 am | In Technical stuff | 2 Comments

I’ve moved from Resin-3.0 to Tomcat-5.5 for a while now. So far, it’s actually been easier to deploy and run my web applications. However, I started to see some NotSerializableExceptions during shutdowns, and subsequent startups. After some research, it became clear that I was inadvertently storing Spring-proxied items into http sessions. If they still existed during serialization of the current session, Tomcat would complain, being that Tomcat actually expects truly serializable items in its sessions - how dare they :)

I knew the item being placed in the http session held a reference to a spring-wrapped DAO (the item’s a data view helper). So, after some cups of coffee it finally came to me: have my custom listener defined in the web.xml, which currently only implements ServletContextListener, also implement HttpSessionListener. With that, I was able clear out the culprit on sessionDestroyed(…). I wish all my technical problems were this straight forward.

Update: Anjan, in response to your question, I’m embedding the web.xml declaration and the actual Listener code. Hope this helps.

web.xml listener declaration


   <!--    Our custom system initializing listener     -->
   <listener>
      <listener-class>com.some.company.SomeInitListener</listener-class>
   </listener>

Listener Implementations


public class SomeInitListener extends BosenInitListener {

	private static final Logger LOG = Logger.getLogger(SomeInitListener.class);

	@Override
	protected void customInitForServlet(ServletContextEvent event) {
		super.customInitForServlet(event);

		ServletContext servletContext = event.getServletContext();
		SomeResourceInitializer resourceInitializer = (SomeResourceInitializer) getBean(servletContext, "resourceInitializer");

		// Make default menus
		String menuConfig = servletContext.getInitParameter(AppConstants.MENU_CONFIG);
		if (null != menuConfig) {
                    ...
		} else {
			LOG.warn("Could not find a menu configuration.");
		}

		resourceInitializer.init();
	}
}

public abstract class BosenInitListener implements ServletContextListener, HttpSessionListener {

	private static final Logger LOG = Logger.getLogger(BosenInitListener.class);

	public final void contextInitialized(final ServletContextEvent event) {
		String servletContextName = event.getServletContext().getServletContextName();
		if (LOG.isInfoEnabled()) {
			LOG.info("Initializing [ " + servletContextName + " ]");
		}

		customInitForServlet(event);

		if (LOG.isInfoEnabled()) {
			LOG.info("Initialized [ " + servletContextName + " ]nn");
		}
	}

	public final void contextDestroyed(final ServletContextEvent event) {
		String servletContextName = event.getServletContext().getServletContextName();
		if (LOG.isInfoEnabled()) {
			LOG.info("Destroying [ " + servletContextName + "]");
		}

		customDestroyForServlet(event);

		if (LOG.isInfoEnabled()) {
			LOG.info("Destroyed [ " + servletContextName + "]nn");
		}
	}

	protected void customInitForServlet(final ServletContextEvent event) {
		ServletContext servletContext = event.getServletContext();
		String appContextName = WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;
		Object webCtxAttribute = servletContext.getAttribute(appContextName);
		if (null != webCtxAttribute) {
			if (webCtxAttribute instanceof Exception) {
				LOG.error(webCtxAttribute);
			}

		} else {
			throw new IllegalStateException("Could not read applicationContext.xml.");
		}
	}

	protected void customDestroyForServlet(final ServletContextEvent event) {
		//no-op
	}

	public final void sessionCreated(final HttpSessionEvent event) {
		String sessionId = event.getSession().getId();
		if (LOG.isDebugEnabled()) {
			LOG.debug("Initializing a new Session [" + sessionId + "]");
		}

		customInitForSession(event);

		if (LOG.isDebugEnabled()) {
			LOG.debug("Initialized a new Session [" + sessionId + "]");
		}
	}

	public final void sessionDestroyed(final HttpSessionEvent event) {
		String sessionId = event.getSession().getId();
		if (LOG.isDebugEnabled()) {
			LOG.debug("Destroying an existing Session [" + sessionId + "]");
		}

		customDestroyForSession(event);

		if (LOG.isDebugEnabled()) {
			LOG.debug("Destroyed an existing Session [" + sessionId + "]nn");
		}
	}

	protected void customInitForSession(final HttpSessionEvent event) {
		//no-op
	}

	protected void customDestroyForSession(final HttpSessionEvent event) {
		HttpSession session = event.getSession();
		session.removeValue(BosenConstants.SESSION_PAGINATED_SEARCH_RESULTS);
		session.removeAttribute(BosenConstants.SESSION_PAGINATED_SEARCH_RESULTS);
	}

	protected static ApplicationContext getApplicationContext(ServletContext servletContext) {
		String appContextName = WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;
		return (ApplicationContext) servletContext.getAttribute(appContextName);
	}

	protected static Object getBean(ServletContext servletContext, String name) {
		return getApplicationContext(servletContext).getBean(name);
	}

openspaces developer challenge winners…

May 28, 2008 on 11:51 am | In Technical stuff | 3 Comments

Kudos to Jason Carreira! His DomainProxy entry to the OpenSpaces Developer Challenge earned him a finalist position.

One to watch: Leonardo Goncalves’ Goods Donation System great idea that also made it to the finals. This could be a great help to many non-profits in the near future. Congrats to everyone who had the creativity and drive to submit anything to the challenge. I’ll be watching to see who gets 1st…

See here for more info.

JFrets…

May 7, 2008 on 9:14 am | In Technical stuff | 1 Comment

I’ve always thought about something like this, but never made a move. Here’s to Matt Warman going from clouds to code!

JFrets…

next…

April 25, 2008 on 9:23 am | In Technical stuff | 5 Comments

Tonight I start my first GigaSpaces project. It’s been on my mind since last November, and it’s been building steam. Why do I need a JavaSpaces/OpenSpaces framework? This project is supposed to be for a larger user base (500+ to start), and based on my academic distributed computing experience, and the excellent posts on highscalability.com, I know I need to upgrade some of my current 3rd party libraries. For performance reasons, of course.

So, I’m going with Spring-2.5.3 for my AOP and DI needs; easy choice. Hibernate-3.2.6 for ORM (I’m staving off JPA, for as long as I can!). MySql-5.0 for database. The UI… Well, I haven’t decided. I know I have to start moving away from WebWork-2. This isn’t up for debate. But I’m torn between moving to Struts-2 (familiarity) or JSF (component-based). I read this FAQ entry for the differences between Struts-2 and JSF.

Ehh… here’s to new things: I’m going with JSF. I’ll take a serious look at Seam and MyFaces.

*****

Update: After some discussion, and further research, I’ve decided to hold off on using JSF. Since it’s a fairly mature, event-based API, I definitely see myself using it in the near future. However, since scalability is the currently highest priority, I’m compelled to go with Struts-2. This also allows me to upgrade all my existing WebWork-2 projects…

caucho’s got a facelift

April 7, 2008 on 12:29 pm | In Technical stuff | No Comments

You may, or may not know that I’m still a Resin user. Hence, every now and then I hit the Caucho site for documentation, mailing list archives, etc. Well today I decided to do just that; it had been at least a month since my last visit. I was pleased to see and cleaner and brighter interface, and even a blog. I’m taking this to mean there’s some new life in the Caucho’s/Resin’s development group (or at least their marketing). I for one am happy to see it!

Next Page »

Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds. Valid XHTML and CSS. ^Top^