early adopter…

March 28, 2009 on 4:18 pm | In Technical stuff | No Comments

Since I’ve been introduced to WebWork, I was a serious proponent. It was built on some interesting technologies. Implemented some great concepts. Things that are now considered standard for any self-respecting web-mvc framework. After some evolution, WebWorkis now Struts2. Since I considered myself a proponent, I’ve followed most releases. Especially the security-related items.

Recently I decided to leave the 2.0.x series, and upgrade to the 2.1.x path. After a little work, you can piece together the major changes you need to adhere. For me, the biggest change was the built-in Dojo support. As of 2.1, it’s an optional, external module, which is fine. I went about making the changes. Things like changing my theme from Ajax to XHtml. Importing the Dojo taglibs into the necessary pages. Nothing too complicated. More time-consuming than anything.

OK, so I ran into a problem. I worked at it for a good weekend. After banging my head against this one, with no resolution, I sought help on the user-list. No response. None of this really bothered me. What really bothered me was my naiveté.

The affected projects are all on svn. For some reason, I did the upgrade on HEAD. So, after no resolution, I had to revert. Since the upgrade included some other libs (Hibernate-3.3, some Commons modules, etc), I actually had to revert and then reapply some other upgrades.

Regardless of your personal feelings for a framework/library, don’t ever assume it’s going to be that easy! If you have a source control tool, use it. A branch for these upgrades would have made things a bit easier. I used to think branches were for teams larger than 2-3. Yeah, not so much. It’s not a problem to adopt a release/technology early, it’s all in how you do it. Ugh, lesson learned.

ehcache-1.6

March 15, 2009 on 1:23 pm | In Technical stuff | 3 Comments

OK, no one should have to tell an engineer to use caching. If you’re dealing with non-trivial amounts of data, and have a reasonable requirement for availability, you’ll need caching. The real issue is what, and how. The what depends on your situation. The how? Well, I’ve always thought it was obvious: ehcache. I’ve been using it as my 2nd-level cache provider for years. As cache providers go, it’s done well by me.

Well, now Greg Luck’s taking it to the next level. By moving to a minimum JDK of 1.5, he’ll be able to remove all dependencies. Also, ehcache-1.5 was a performant module. Now, if his figures are right, ehcache-1.6 will truly obliterate its peers. It’s still in beta, 1.6 that is, but check it out.

fonts and stuff…

October 1, 2008 on 8:35 pm | In Technical stuff | No Comments

Eric Burke’s Blog has a post talking about finding the best font for his comics. OK, One comment brought a superior tool to light: typetester.org. Honestly, I’ve needed this thing for years.

t-mobile g1

September 23, 2008 on 8:07 pm | In Technical stuff | No Comments

Finally, if you were looking for a actual piece of hardware for your Android apps, here it goes: the T-Mobile G1. It’s not too shabby.

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);
	}

Next Page »

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