<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Pragmatic Coder : Java, Wicket and the Web</title>
	
	<link>http://www.richardnichols.net</link>
	<description>The blog of Richard Nichols.</description>
	<lastBuildDate>Tue, 31 Aug 2010 16:00:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<meta xmlns="http://www.w3.org/1999/xhtml" name="robots" content="noindex,follow" />
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PragmaticCoder" /><feedburner:info uri="pragmaticcoder" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Clustering Guice Java Web Applications</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/nxr4e8Cyu74/</link>
		<comments>http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/#comments</comments>
		<pubDate>Tue, 31 Aug 2010 16:00:48 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[guice]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=662</guid>
		<description><![CDATA[Considering the origin of Guice (it&#8217;s use in Google Adwords, one of the largest apps on the Internet), it&#8217;s fair to say it should support clustering / session replication. There&#8217;s not much in the way of documentation around that aspect &#8230; <a href="http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/05/aop-annotation-based-caching-solution-for-guice-projects/' rel='bookmark' title='Permanent Link: AOP, Annotation-based caching solution for Guice projects&#8230;'>AOP, Annotation-based caching solution for Guice projects&#8230;</a></li>
<li><a href='http://www.richardnichols.net/2009/06/the-5-minute-guice-primer/' rel='bookmark' title='Permanent Link: The 5 Minute Guice Primer'>The 5 Minute Guice Primer</a></li>
<li><a href='http://www.richardnichols.net/2010/08/5-minute-guide-clustering-apache-tomcat/' rel='bookmark' title='Permanent Link: 5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat'>5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Considering the origin of Guice (it&#8217;s use in Google Adwords, one of the largest apps on the Internet), it&#8217;s fair to say it should support clustering / session replication.</p>
<p>There&#8217;s not much in the way of documentation around that aspect of it.</p>
<p>As it turns out, there&#8217;s a good reason for that &#8211; clustering and session replication with Guice are mind-numbingly simple. In fact, if you&#8217;re doing session replication / fail-over, you probably already have it working.</p>
<p>This is because, @SessionScoped objects in Guice are stored in HttpSession, and with consistent internal keys.</p>
<p>That might be obvious to some people, but it wasn&#8217;t to me. I thought that Guice used&#8230; well&#8230; MAGIC or something to keep track of objects in session scope.</p>
<p>Actually, delving into the <a href="http://code.google.com/p/google-guice/source/browse/trunk/extensions/servlet/src/com/google/inject/servlet/ServletScopes.java" target="_blank">Guice internals</a>, here&#8217;s the &#8220;magical&#8221; code -</p>
<pre class="prettyprint">
  public static final Scope SESSION = new Scope() {
    public <T> Provider<T> scope(Key<T> key, final Provider<T> creator) {
      final String name = key.toString();
      return new Provider<T>() {
        public T get() {
          HttpSession session = GuiceFilter.getRequest().getSession();
          synchronized (session) {
            Object obj = session.getAttribute(name);
            if (NullObject.INSTANCE == obj) {
              return null;
            }
            @SuppressWarnings("unchecked")
            T t = (T) obj;
            if (t == null) {
              t = creator.get();
              session.setAttribute(name, (t != null) ? t : NullObject.INSTANCE);
            }
            return t;
          }
        }
        public String toString() {
          return String.format("%s[%s]", creator, SESSION);
        }
      };
    }
</pre>
<p>So the GuiceFilter servlet filter is actually what provides the magic for this functionality. The actual objects are stored in the HttpSession as attributes.</p>
<p>So in order to support session replication you just need to make sure that your session scoped objects are Serializable, and everything is good. Normal HttpSession replication across your cluster will mean everything works as expected.</p>
<p>Of course, what if you have non-serializable dependencies? </p>
<p>Well they can be @Inject&#8217;ed into a static member variable to get around that, though I&#8217;d suggest a better solution would be to refactor the code such that the data (Serializable) component is kept in session scope, but the functional (non-serializable) part is split out into a @Singleton service class.</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F09%2Fsession-replication-with-guice-java-web-applications%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F09%2Fsession-replication-with-guice-java-web-applications%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=cluster,guice,Java,tips" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/05/aop-annotation-based-caching-solution-for-guice-projects/' rel='bookmark' title='Permanent Link: AOP, Annotation-based caching solution for Guice projects&#8230;'>AOP, Annotation-based caching solution for Guice projects&#8230;</a></li>
<li><a href='http://www.richardnichols.net/2009/06/the-5-minute-guice-primer/' rel='bookmark' title='Permanent Link: The 5 Minute Guice Primer'>The 5 Minute Guice Primer</a></li>
<li><a href='http://www.richardnichols.net/2010/08/5-minute-guide-clustering-apache-tomcat/' rel='bookmark' title='Permanent Link: 5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat'>5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=nxr4e8Cyu74:_-FcuJpNd4U:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=nxr4e8Cyu74:_-FcuJpNd4U:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=nxr4e8Cyu74:_-FcuJpNd4U:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=nxr4e8Cyu74:_-FcuJpNd4U:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=nxr4e8Cyu74:_-FcuJpNd4U:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=nxr4e8Cyu74:_-FcuJpNd4U:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=nxr4e8Cyu74:_-FcuJpNd4U:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=nxr4e8Cyu74:_-FcuJpNd4U:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=nxr4e8Cyu74:_-FcuJpNd4U:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=nxr4e8Cyu74:_-FcuJpNd4U:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=nxr4e8Cyu74:_-FcuJpNd4U:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=nxr4e8Cyu74:_-FcuJpNd4U:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/</feedburner:origLink></item>
		<item>
		<title>Setting Up Memcached As A Windows Service</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/bPA833D_y4c/</link>
		<comments>http://www.richardnichols.net/2010/08/install-memcached-on-windows-server/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 04:57:39 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[guides]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=668</guid>
		<description><![CDATA[Memcached is an in-memory, distributed key-value store for random pieces of application data. It is useful for clustering and distributed caching and it (and similar tools) are becoming an increasingly common feature of large Web-based apps. I don&#8217;t like Windows &#8230; <a href="http://www.richardnichols.net/2010/08/install-memcached-on-windows-server/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2009/09/1-minute-guide-installing-redmine-on-windows/' rel='bookmark' title='Permanent Link: 1 Minute Guide &#8211; Installing Redmine on Windows'>1 Minute Guide &#8211; Installing Redmine on Windows</a></li>
<li><a href='http://www.richardnichols.net/2010/08/5-minute-guide-clustering-apache-tomcat/' rel='bookmark' title='Permanent Link: 5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat'>5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><em>Memcached </em>is an in-memory, distributed key-value store for random pieces of application data. It is useful for clustering and distributed caching and it (and similar tools) are becoming an increasingly common feature of large Web-based apps.</p>
<p>I don&#8217;t like Windows any more than the next guy when it comes to using it as a Server OS, but sometimes you&#8217;ve got no choice &#8211; maybe you work in an environment where <em>Windows Server</em> is the only option. *sigh*</p>
<p>Memcached is not something that you would generally install on Windows, (not for production anyhow), but it is possible to have it running happily as a native Windows service.</p>
<p>Here&#8217;s how -</p>
<ol>
<li>Download either the 32-bit or 64-bit Windows builds of <a href="http://labs.northscale.com/memcached-packages/">Memcached from NorthScale</a></li>
<li>Unzip the memcached build into a server folder, say <em>&#8220;C:\memcached&#8221;</em></li>
<li>Run <em>memcached.exe</em> and ensure it starts. You should get a blank console window. Ctrl+C will close it, assuming all is well.</li>
<li>To set it up as a native service we will download the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&amp;displaylang=en">Windows Server 2003 Resource Kit</a></li>
<li>Install the Windows Resource Kit.<br />
For clarity I&#8217;ll refer to the install location as <em>&#8220;C:\Program Files\Windows Resource Kits\Tools&#8221;</em>, in reality it may be different. Substitute your install location as needed.</li>
<li>Open a command prompt and change to your resource kit folder e.g. <em>C:\Program Files\Windows Resource Kits\Tools</em></li>
<li>At the prompt:
<pre>instsrv Memcached "C:\Program Files\Windows Resource Kits\Tools\SRVANY.EXE"</pre>
</li>
<li>Open Notepad and paste the following into it -
<pre>Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Memcached\Parameters]
"Application"="c:\\memcached\\memcached.exe"
"AppParameters"="-m 1024"</pre>
<p>Adjust the path as necessary. You can add (or remove) <em>memcached</em> command line options with the &#8220;AppParameters&#8221; option.</p>
<p>The &#8220;-m 1024&#8243; creates 1024MB (1 GB) memcache. You can get a list of other options with <em>&#8220;memcached -h&#8221;</em> or on <a href="http://memcached.org/" target="_blank">memcached.org</a></li>
<li>Save the file as <em>&#8220;c:\memcached\configservice.reg&#8221; </em><em><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/configservice.png"><img class="alignnone size-full wp-image-676" title="configservice" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/configservice.png" alt="" width="566" height="462" /></a><br />
</em></li>
<li>Double click the file in Windows Explorer and merge the settings into the Registry.<br />
<a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Registry-Editor_2010-08-27_14-39-31.png"><img class="alignnone size-medium wp-image-677" title="Registry Editor_2010-08-27_14-39-31" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Registry-Editor_2010-08-27_14-39-31-300x64.png" alt="" width="300" height="64" /></a></li>
<li>Start the service, e.g. <em>&#8220;net start Memcached&#8221;</em> at the command prompt<a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Administrator-Command-Prompt_2010-08-27_14-43-03.png"><img class="alignnone size-medium wp-image-678" title="Administrator Command Prompt_2010-08-27_14-43-03" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Administrator-Command-Prompt_2010-08-27_14-43-03-300x83.png" alt="" width="300" height="83" /></a></li>
<li>You&#8217;re done!</li>
</ol>
<p>Also, there is an alternative option &#8211; you can use the Java based clone of <em>memcached</em>, (the intuitively/unimaginatively) named <a rel="nofollow" href="http://code.google.com/p/jmemcache-daemon/" target="_blank">jmemcached</a>.</p>
<p>This can be used in conjunction with <a rel="nofollow" href="http://wrapper.tanukisoftware.com/doc/english/download.jsp" target="_blank">Java Service Wrapper</a> to create Java-based Windows service which operates like the native memcached.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F08%2Finstall-memcached-on-windows-server%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F08%2Finstall-memcached-on-windows-server%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=cluster,guides,memcached,servers,windows" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2009/09/1-minute-guide-installing-redmine-on-windows/' rel='bookmark' title='Permanent Link: 1 Minute Guide &#8211; Installing Redmine on Windows'>1 Minute Guide &#8211; Installing Redmine on Windows</a></li>
<li><a href='http://www.richardnichols.net/2010/08/5-minute-guide-clustering-apache-tomcat/' rel='bookmark' title='Permanent Link: 5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat'>5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=bPA833D_y4c:cZWQk5tcFpg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=bPA833D_y4c:cZWQk5tcFpg:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=bPA833D_y4c:cZWQk5tcFpg:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=bPA833D_y4c:cZWQk5tcFpg:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=bPA833D_y4c:cZWQk5tcFpg:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=bPA833D_y4c:cZWQk5tcFpg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=bPA833D_y4c:cZWQk5tcFpg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=bPA833D_y4c:cZWQk5tcFpg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=bPA833D_y4c:cZWQk5tcFpg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=bPA833D_y4c:cZWQk5tcFpg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=bPA833D_y4c:cZWQk5tcFpg:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=bPA833D_y4c:cZWQk5tcFpg:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/08/install-memcached-on-windows-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/08/install-memcached-on-windows-server/</feedburner:origLink></item>
		<item>
		<title>Where Does Wicket Store It’s DiskPageStore Files?</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/fBQryvZZNoc/</link>
		<comments>http://www.richardnichols.net/2010/08/where-does-wicket-store-its-diskpagestore-files/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 00:26:06 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Wicket]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[wicket]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=659</guid>
		<description><![CDATA[Wicket stores everything other than the current Page for a given user&#8217;s session (by default) in a second-level disk-based session cache. I&#8217;d never looked much into how it worked, until I wanted to know where these files were located. The &#8230; <a href="http://www.richardnichols.net/2010/08/where-does-wicket-store-its-diskpagestore-files/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2009/11/announcing-visural-wicket/' rel='bookmark' title='Permanent Link: Announcing &#8211; visural-wicket'>Announcing &#8211; visural-wicket</a></li>
<li><a href='http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/' rel='bookmark' title='Permanent Link: Clustering Guice Java Web Applications'>Clustering Guice Java Web Applications</a></li>
<li><a href='http://www.richardnichols.net/2010/06/less-css-in-wicket-using-mozilla-rhino/' rel='bookmark' title='Permanent Link: LessCSS available in Java and Wicket &#8211; less.js'>LessCSS available in Java and Wicket &#8211; less.js</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Wicket stores everything other than the current Page for a given user&#8217;s session (by default) in a second-level disk-based session cache.</p>
<p>I&#8217;d never looked much into how it worked, until I wanted to know where these files were located.</p>
<p>The answer as it turns out makes a lot of sense &#8211; here&#8217;s the method that does the work in the <em>DiskPageStore.java</em> -</p>
<pre class="prettyprint"> private static File getDefaultFileStoreFolder()
    {
        final File dir = (File)((WebApplication)Application.get()).getServletContext()
            .getAttribute("javax.servlet.context.tempdir");
        if (dir != null)
        {
            return dir;
        }
        else
        {
            try
            {
                return File.createTempFile("file-prefix", null).getParentFile();
            }
            catch (IOException e)
            {
                throw new WicketRuntimeException(e);
            }
        }
    }</pre>
<p>So by default it tries to use the servlet container&#8217;s local context&#8217;s temporary location, in a Wicket folder underneath. If that fails it attempts to grab the system&#8217;s temporary folder.</p>
<p>For Apache Tomcat, that means a folder under your webapps context in <em>apache-tomcat/work/Catalina/</em>&#8230; e.g.</p>
<p><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/WicketApplication-filestore_2010-08-23_10-17-47.png"><img class="alignnone size-full wp-image-660" title="WicketApplication-filestore_2010-08-23_10-17-47" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/WicketApplication-filestore_2010-08-23_10-17-47.png" alt="" width="550" height="490" /></a>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F08%2Fwhere-does-wicket-store-its-diskpagestore-files%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F08%2Fwhere-does-wicket-store-its-diskpagestore-files%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=Java,web,wicket" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2009/11/announcing-visural-wicket/' rel='bookmark' title='Permanent Link: Announcing &#8211; visural-wicket'>Announcing &#8211; visural-wicket</a></li>
<li><a href='http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/' rel='bookmark' title='Permanent Link: Clustering Guice Java Web Applications'>Clustering Guice Java Web Applications</a></li>
<li><a href='http://www.richardnichols.net/2010/06/less-css-in-wicket-using-mozilla-rhino/' rel='bookmark' title='Permanent Link: LessCSS available in Java and Wicket &#8211; less.js'>LessCSS available in Java and Wicket &#8211; less.js</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fBQryvZZNoc:-7Tutme-lbA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fBQryvZZNoc:-7Tutme-lbA:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=fBQryvZZNoc:-7Tutme-lbA:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fBQryvZZNoc:-7Tutme-lbA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=fBQryvZZNoc:-7Tutme-lbA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fBQryvZZNoc:-7Tutme-lbA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=fBQryvZZNoc:-7Tutme-lbA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fBQryvZZNoc:-7Tutme-lbA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=fBQryvZZNoc:-7Tutme-lbA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fBQryvZZNoc:-7Tutme-lbA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fBQryvZZNoc:-7Tutme-lbA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=fBQryvZZNoc:-7Tutme-lbA:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/08/where-does-wicket-store-its-diskpagestore-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/08/where-does-wicket-store-its-diskpagestore-files/</feedburner:origLink></item>
		<item>
		<title>5 Minute Guide to Clustering – Java Web Apps in Tomcat</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/D01SbRCiC-o/</link>
		<comments>http://www.richardnichols.net/2010/08/5-minute-guide-clustering-apache-tomcat/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 01:08:10 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[guides]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=625</guid>
		<description><![CDATA[I&#8217;ve been taking a break from posting for the last couple of weeks. I was starting to get a bit run down, and feel like burn out was about to set in. The kind of blog posts I do take &#8230; <a href="http://www.richardnichols.net/2010/08/5-minute-guide-clustering-apache-tomcat/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/' rel='bookmark' title='Permanent Link: Clustering Guice Java Web Applications'>Clustering Guice Java Web Applications</a></li>
<li><a href='http://www.richardnichols.net/2010/03/1-second-guide-enabling-gzip-compression-in-apache-tomcat/' rel='bookmark' title='Permanent Link: 1 second guide &#8211; enabling gzip compression in Apache Tomcat'>1 second guide &#8211; enabling gzip compression in Apache Tomcat</a></li>
<li><a href='http://www.richardnichols.net/2010/08/where-does-wicket-store-its-diskpagestore-files/' rel='bookmark' title='Permanent Link: Where Does Wicket Store It&#8217;s DiskPageStore Files?'>Where Does Wicket Store It&#8217;s DiskPageStore Files?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div>
<p>I&#8217;ve been taking a break from posting for the last couple of weeks. I was starting to get a bit run down, and feel like burn out was about to set in. The kind of blog posts I do take quite a bit of time, both in terms of the technical background work and the time to write and proof read the posts. Balancing that with work, plus personal projects, family life something had to take a break, and it&#8217;s not going to be work or family life <img src='http://d3araz99qvcc8b.cloudfront.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Anyhow, I&#8217;m back with another 5 minute guide. This time, how to set up clustering with Apache Web Server and Apache Tomcat.</p>
<p>For the purposes of the rest of this article, when I say &#8220;Apache&#8221; I mean the web server, and when I say &#8220;Tomcat&#8221; I mean Tomcat.</p>
<p>There are pretty much two ways to set up basic clustering, which use two different Apache modules. The architecture for both, is the same. Apache sits in front of the Tomcat nodes and acts as a load balancer.</p>
<p><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Tomcat-cluster-diagram.png"><img class="alignnone size-full wp-image-637" title="Tomcat cluster diagram" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Tomcat-cluster-diagram.png" alt="Architecture of Apache and Tomcat cluster, protocols and connectivity" width="563" height="547" /></a></p>
<p>Traffic is passed between Apache and Tomcat(s) using the binary AJP 1.3 protocol. The two modules are <em>mod_jk </em>and <em>mod_proxy</em>.</p>
<p><strong>mod_jk</strong> stands for &#8220;<em>jakarta</em>&#8221; the original project under which Tomcat was developed. It is the older way of setting this up, but still has some advantages.</p>
<p><strong>mod_proxy</strong> is a newer and more generic way of setting this up. The rest of this guide will focus on <strong>mod_proxy</strong>, since it ships &#8220;out of the box&#8221; with newer versions of Apache.</p>
<p>You should be able to follow this guide by downloading Apache and Tomcat default distributions and following the steps. No funny business required.</p>
<h2>Clustering Background</h2>
<p>You can cluster at the request or session level. Request level means that each request may go to a different node &#8211; this is the ideal since the traffic would be balanced across all nodes, and if a node goes down, the user has no idea. Unfortunately this requires session replication between all nodes, not just of HttpSession, but ANY session state. For the purposes of this article I&#8217;m going to describe Session level clustering, since it is simpler to set up, and works regardless of the dynamics of your application.<br />
&#8230;&#8230;.  After all we only have 5 minutes! <img src='http://d3araz99qvcc8b.cloudfront.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Session level clustering means if your application is one that requires a login or other forms of session-state, and one or more your Tomcat nodes goes down, on their next request, the user will be asked to log in again, since they will hit a different node which does not have any stored session data for the user.</p>
<p>This is still an improvement on a non-clustered environment where, if your node goes down, you have no application at all!</p>
<p>And we still get the benefits of load balancing across nodes, which allows us to scale our application out horizontally across many machines.</p>
<p>Anyhow without further ado, let&#8217;s get into the how-to.</p>
<h2>Setting Up The Nodes</h2>
<p>In most situations you would be deploying the nodes on physically separate machines, but in this example we will set them up on a single machine, but on different ports. This allows us to easily test this configuration.</p>
<p>Nothing much changes for the physically separate set up &#8211; just the Hostnames of the nodes as you would expect.</p>
<p>Oh and I&#8217;m working on Windows &#8211; but aside from the installation of Apache and Tomcat nothing is different between platforms since the configuration files are standard on all platforms.</p>
<ol>
<li>Download <a href="http://tomcat.apache.org/download-60.cgi" target="_blank">Tomcat .ZIP distribution</a>, e.g.<br />
<a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Apache-Tomcat-Apache-Tomcat-6-Downloads-Google-Chrome_2010-08-21_09-05-31.png"><img class="size-medium wp-image-635 alignnone" title="Apache Tomcat - Apache Tomcat 6 Downloads" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Apache-Tomcat-Apache-Tomcat-6-Downloads-Google-Chrome_2010-08-21_09-05-31-300x157.png" alt="Image showing download package" width="300" height="157" /></p>
<p></a></li>
<li>We&#8217;ll use a folder to install all this stuff in. Let&#8217;s say it&#8217;s &#8220;C:\cluster&#8221; for the purposes of the article.</li>
<li>Unzip the Tomcat distro twice, into two folders -<br />
<em>C:\cluster\tomcat-node-1</em><br />
<em>C:\cluster\tomcat-node-2<br />
</em></li>
<li>Start up each of the nodes, using the bin/startup.bat / bin/startup.sh scripts. Ensure they start. If they don&#8217;t you may need to point Tomcat to the JDK installation on your machine.</li>
<li>Open up the server.xml configuration on<br />
<em> c:\cluster\tomcat-node-1\conf\server.xml<br />
</em></li>
<li>There are two places we need to (potentially) configure -<a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/server.xml-engine-and-connector.png"><img class="alignnone size-full wp-image-642" title="server.xml engine and connector" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/server.xml-engine-and-connector.png" alt="screenshot of where these lines are in server.xml" width="634" height="305" /><br />
</a><br />
The first line is the connector for the AJP protocol. The &#8220;port&#8221; attribute is the important part here. We will leave this one as is, but for our second (or subsequent) Tomcat nodes, we will need to change it to a different value.</p>
<p>The second part is the &#8220;engine&#8221; element. The &#8220;jvmRoute&#8221; attribute has to be added &#8211; this configures the name of this node in the cluster. The &#8220;jvmRoute&#8221; must be unique across all your nodes. For our purposes we will use &#8220;node1&#8243; and &#8220;node2&#8243; for our two node cluster.</li>
<li>This step is optional, but for production configs, you may want to remove the HTTP connector for Tomcat &#8211; that&#8217;s one less port to secure, and you don&#8217;t need it for the cluster to operate. Comment out the following lines of the server.xml -<br />
<a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/http-connector.png"><img class="alignnone size-medium wp-image-641" title="http connector" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/http-connector-300x144.png" alt="" width="300" height="144" /></p>
<p></a></li>
<li>Now repeat this for <em>C:\cluster\tomcat-node-2\conf\server.xml<br />
<span style="font-style: normal;">Change the jvmRoute to &#8220;node2&#8243; and the AJP connector port to &#8220;8019&#8243;.</span></em></li>
</ol>
</div>
<p>We&#8217;re done with Tomcat. Start each node up, and ensure it still works.</p>
<div>
<h2>Setting Up The Apache Cluster</h2>
<p>Okay, this is the important part.</p>
<ol>
<li>Download and install <a href="http://httpd.apache.org/download.cgi" target="_blank">Apache HTTP Server</a>.
<p><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Download-The-Apache-HTTP-Server-Project-Google-Chrome_2010-08-21_10-19-16.png"><img class="alignnone size-medium wp-image-643" title="Download - The Apache HTTP Server Project" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Download-The-Apache-HTTP-Server-Project-Google-Chrome_2010-08-21_10-19-16-300x124.png" alt="" width="300" height="124" /></a></p>
<p>Use the custom option to install it into <em>C:\cluster\apache2.2</em>
</li>
<li>Now open up c:\cluster\apache2.2\conf\httpd.conf in your favourite text editor.
</li>
<li>Firstly, we need to uncomment the following lines (delete the &#8216;#&#8217;) -<br />
<a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/httpd.conf-mod_proxy-lines.png"><img class="alignnone size-full wp-image-646" title="httpd.conf - mod_proxy lines" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/httpd.conf-mod_proxy-lines.png" alt="mod_proxy lines in httpd.conf to be uncommented" width="605" height="175" /><br />
</a><br />
These enable the necessary <strong>mod_proxy</strong> modules in Apache.
</li>
<li>Finally, go to the end of the file, and add the following:
<pre>&lt;Proxy balancer://testcluster stickysession=JSESSIONID&gt;
BalancerMember ajp://127.0.0.1:8009 min=10 max=100 route=node1 loadfactor=1
BalancerMember ajp://127.0.0.1:8019 min=20 max=200 route=node2 loadfactor=1
&lt;/Proxy&gt;

ProxyPass /examples balancer://testcluster/examples</pre>
<p>The above is the actual clustering configuration.</p>
<p>The first section configures a load balancer across our two nodes. The <em>loadfactor </em>can be modified to send more traffic to one or the other node. i.e. how much load can this member handle compared to the others?</p>
<p>This allows you to balance effectively if you have multiple servers which have different hardware profiles.</p>
<p>Note also the &#8220;route&#8221; setting which must match the names of the &#8220;<em>jvmRoutes</em>&#8221; in the Tomcat server.xml for each node. This in conjunction with the &#8220;<em>stickysession</em>&#8221; setting is key for a Tomcat cluster, as this configures the session management. It tells <em>mod_proxy</em> to look for the node&#8217;s <em>route</em> in the given session cookie to determine which node that session is using. This allows all requests from a given client to go to the node which is holding the session state for the client.</p>
<p>The <em>ProxyPass </em>line configures the actual URL from Apache to the load balanced cluster. You may want this to be &#8220;/&#8221;<br />
e.g. &#8220;<em>ProxyPass /balancer://testcluster/&#8221;<br />
</em><br />
In our case we&#8217;re just configuring the Tomcat /<strong>examples </strong>application for our test.</li>
<li>Save it, and restart your Apache server.</li>
</ol>
</div>
<h2>Test It Out</h2>
<p>With your Apache server running you should be able to go to <a href="http://localhost/examples" target="_blank">http://localhost/examples</a></p>
<p>You should get a 503 error page as per below -</p>
<p><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/503-Service-Temporarily-Unavailable-Google-Chrome_2010-08-21_10-37-44.png"><img class="alignnone size-medium wp-image-648" title="503 Service Temporarily Unavailable" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/503-Service-Temporarily-Unavailable-Google-Chrome_2010-08-21_10-37-44-300x32.png" alt="" width="300" height="32" /></a></p>
<p>This is because both Tomcat nodes are down.</p>
<p>Start up <em>node1 </em>(<em>c:\cluster\tomcat-node-1\bin\startup</em>) and reload <a href="http://localhost/examples" target="_blank">http://localhost/examples</a></p>
<p>You should see the examples application from the default Tomcat installation -</p>
<p><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Apache-Tomcat-Examples.png"><img class="alignnone size-full wp-image-649" title="Apache Tomcat Examples" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Apache-Tomcat-Examples.png" alt="" width="345" height="160" /></a></p>
<p>Shut down <strong>node1</strong>, and then start up <strong>node2. </strong>Repeat the test. You should see the same page as above. We have transparently moved from node1 to node2 since node1 went down.</p>
<p>Start both nodes up and your cluster is now working.</p>
<p>You&#8217;re done!</p>
<div>
<h2>Optional: Set Up Apache Balancer Manager</h2>
<p><em>mod_proxy </em>has an additional &#8220;balancer manager&#8221; component which provides a nice web interface to the load balanced cluster. It&#8217;s worthwhile setting this up if you want to remotely administer / monitor the cluster.</p>
<p>To do so is easy -</p>
<ol>
<li>Add the following to the bottom of your <em>C:\cluster\apache2.2\conf\httpd.conf</em>
<pre>&lt;Location /balancer-manager&gt;
SetHandler balancer-manager
AuthType Basic
AuthName "Balancer Manager"
AuthUserFile "C:/cluster/apache2.2/conf/.htpasswd"
Require valid-user
&lt;/Location&gt;</pre>
<p>This configures the balancer manager at <a href="http://localhost/balancer-manager">http://localhost/balancer-manager</a></li>
<li>We need to create a password file to secure it. At the command prompt you can use -
<pre>c:\cluster\apache2.2\bin\htpasswd -c c:\cluster\apache2.2\conf\.htpasswd admin</pre>
<p>Then set a password when prompted. This password would be used by the balancer-manager URL to authenticate.</li>
</ol>
<p>Restart your Apache web server, and go to <a href="http://localhost/balancer-manager">http://localhost/balancer-manager</a></p>
<p>You should be prompted for a username/password as you set before, and see the balancer manager tool as below:</p>
<p><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Balancer-Manager.png"><img class="alignnone size-full wp-image-652" title="Balancer Manager" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/08/Balancer-Manager.png" alt="" width="553" height="336" /></a></p>
</div>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F08%2F5-minute-guide-clustering-apache-tomcat%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F08%2F5-minute-guide-clustering-apache-tomcat%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=apache,cluster,guides,Java,open-source,performance,web" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/' rel='bookmark' title='Permanent Link: Clustering Guice Java Web Applications'>Clustering Guice Java Web Applications</a></li>
<li><a href='http://www.richardnichols.net/2010/03/1-second-guide-enabling-gzip-compression-in-apache-tomcat/' rel='bookmark' title='Permanent Link: 1 second guide &#8211; enabling gzip compression in Apache Tomcat'>1 second guide &#8211; enabling gzip compression in Apache Tomcat</a></li>
<li><a href='http://www.richardnichols.net/2010/08/where-does-wicket-store-its-diskpagestore-files/' rel='bookmark' title='Permanent Link: Where Does Wicket Store It&#8217;s DiskPageStore Files?'>Where Does Wicket Store It&#8217;s DiskPageStore Files?</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=D01SbRCiC-o:Wi3IG_nYuLY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=D01SbRCiC-o:Wi3IG_nYuLY:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=D01SbRCiC-o:Wi3IG_nYuLY:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=D01SbRCiC-o:Wi3IG_nYuLY:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=D01SbRCiC-o:Wi3IG_nYuLY:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=D01SbRCiC-o:Wi3IG_nYuLY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=D01SbRCiC-o:Wi3IG_nYuLY:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=D01SbRCiC-o:Wi3IG_nYuLY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=D01SbRCiC-o:Wi3IG_nYuLY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=D01SbRCiC-o:Wi3IG_nYuLY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=D01SbRCiC-o:Wi3IG_nYuLY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=D01SbRCiC-o:Wi3IG_nYuLY:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/08/5-minute-guide-clustering-apache-tomcat/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/08/5-minute-guide-clustering-apache-tomcat/</feedburner:origLink></item>
		<item>
		<title>ResourceTransformFilter – DataUris, LessCSS, Javascript and CSS Compression Made Easy!</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/1qJFzDGTdp0/</link>
		<comments>http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 12:52:40 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[visural-common]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=522</guid>
		<description><![CDATA[ResourceTransformFilter is a swiss-army-knife for HTML/CSS/Javascript transformation in Java web applications. It&#8217;s a new addition to the visural-common Apache 2.0 licensed project. Apply this filter in your Java webapp to get - Automatic CSS DataURI image inlining for supported browsers Automatic &#8230; <a href="http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2009/07/automatic-javascript-and-css-compression-for-java-webapps/' rel='bookmark' title='Permanent Link: Automatic Javascript and CSS Compression For Java Webapps'>Automatic Javascript and CSS Compression For Java Webapps</a></li>
<li><a href='http://www.richardnichols.net/2010/07/mhtml-browser-compatibility-css-inlining/' rel='bookmark' title='Permanent Link: MHTML Browser Compatibility &#8211; CSS Inlining'>MHTML Browser Compatibility &#8211; CSS Inlining</a></li>
<li><a href='http://www.richardnichols.net/2010/06/301-redirects-made-easy-in-java/' rel='bookmark' title='Permanent Link: 301 Redirects Made Easy In Java'>301 Redirects Made Easy In Java</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><em>ResourceTransformFilter</em> is a swiss-army-knife for HTML/CSS/Javascript transformation in Java web applications.</p>
<p>It&#8217;s a new addition to the <a href="http://code.google.com/p/visural-common">visural-common</a> Apache 2.0 licensed project.</p>
<p>Apply this filter in your Java webapp to get -</p>
<ul>
<li>Automatic CSS DataURI image inlining for supported browsers</li>
<li>Automatic CSS MHTML image inlining for supported IE browsers</li>
<li><a href="http://lesscss.org/">LessCSS </a>compilation for <em>.less</em> files</li>
<li>Automatic<a href="http://developer.yahoo.com/yui/compressor/"> YUI compression</a> of <em>.css &amp; .js</em> resources</li>
<li><strong>Optional:</strong> DataURI inlining of &lt;img&gt; tags in HTML responses</li>
</ul>
<p>So as you can see, the primary purpose of this filter is web app resource optimization.</p>
<h2>DataURIs and MHTML?</h2>
<p><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/07/2983149263_ae3daa555d1.jpg"><img class="alignright size-thumbnail wp-image-542" title="http://www.flickr.com/photos/andresrueda/" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/07/2983149263_ae3daa555d1-150x150.jpg" alt="by http://www.flickr.com/photos/andresrueda/" width="150" height="150" /></a>One of the most effective ways of improving website performance is to reduce the number of HTTP requests required for the page to fully load.</p>
<p>Typically you&#8217;ll have a bunch of small icons used for buttons, panels, links etc. in your CSS, as well as small background graphics here and there. These all add us to a significant number of HTTP requests, each one for only a couple of kilobytes of data.</p>
<p>&#8220;CSS Sprites&#8221; have often been used as a way of overcoming this issue, however two newer techniques (data URIs and MHTML)  are starting to become a more common way to address the problem.</p>
<p>The idea of data URIs and MHTML are the same &#8211; inline the image data into the actual CSS (or HTML) as base64-encoded text.</p>
<p>Data URIs are the preferred way of doing this, however they are not supported in older browsers, specifically IE6 and IE7. Also, IE7 on Windows Vista has problems, and <a href="http://www.richardnichols.net/2010/07/mhtml-browser-compatibility-css-inlining/" target="_blank">I&#8217;ve talked about this in more detail recently</a>. MHTML can be used reliably in IE6/7 on Windows XP, and so the filter will apply it for those clients.</p>
<h2>Applying the Filter</h2>
<p>I&#8217;ll cut right to the chase &#8211; here&#8217;s how you can apply this to your Java web-application in <strong>two simple steps</strong>:</p>
<ol>
<li>Add <a href="http://code.google.com/p/visural-common/downloads/list">visural-common</a> to your projects set of libraries, or adding it as a dependency (<a href="http://code.google.com/p/visural-common/wiki/MavenSupport">Maven</a>). You will also need to add the <a href="http://visural-common.googlecode.com/svn/trunk/visural-common/lib/yuicompressor/yuicompressor-2.4.2.jar">YUI Jar</a> to your project to use CSS / JS compression.</li>
<li>Add <em>com.visural.common.web.transform.<em>ResourceTransformFilter </em></em>to your your <em>web.xml</em> as a standard servlet filter, matched to the URLs of your resource file(s)</li>
</ol>
<p>For example you might add the following XML your <em>web.xml</em>:</p>
<pre>    &lt;filter&gt;
        &lt;filter-name&gt;ResourceTransformFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;com.visural.common.web.transform.ResourceTransformFilter&lt;/filter-class&gt;
    &lt;/filter&gt;
...
    &lt;filter-mapping&gt;
        &lt;filter-name&gt;ResourceTransformFilter&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
    &lt;/filter-mapping&gt;</pre>
<p>And you&#8217;re done.</p>
<h2>Default Configuation</h2>
<p>The default configuration works as follows -</p>
<ul>
<li>Supported features will be detected by using visural-common&#8217;s <a href="http://www.richardnichols.net/2010/07/detecting-which-browser-in-java-servlet-filter/">built in WebClient detector</a> (based on User-Agent)</li>
<li>Resource URLs ending in <strong>.less</strong> will be compiled through the LessCSS compiler</li>
<li>Resources ending in <strong>.less</strong> or <strong>.css</strong> will have DataURIs or MHTML applied, but only if the client supports them, otherwise the original image references will be left untouched.<br />
By default, only <strong>images &lt; 50kb</strong> in size will be inlined, any larger images will be left as url(..) references. <em>This is configurable.</em></li>
<li>Resources ending in <strong>.less</strong> or <strong>.css</strong> will be compressed through the Yahoo YUI CSS Compressor</li>
<li>Resources ending in <strong>.js</strong> will be compressed through the Yahoo YUI Javascript Compressor</li>
</ul>
<p>Transformed responses will be automatically cached, so any additional overhead to generate these responses will be a one-time only cost. Note that any response headers you set will also be cached, and <em>the filter does not affect the detection and dynamic behaviour based on the client browser/OS</em>.</p>
<h2>Custom Configuation</h2>
<p>You can customise the behaviour of the filter by extending the filter&#8217;s class <em>com.visural.common.web.transform.ResourceTransformFilter</em> and overriding the protected &#8220;over-ride points&#8221; to change the classes behaviour.</p>
<p>Use <a href="http://code.google.com/p/visural-common/source/browse/trunk/visural-common/src/com/visural/common/web/transform/ResourceTransformFilter.java">the source</a> as the starting point.</p>
<h2>Optional .html DataURI Conversion</h2>
<p>The default configuration does not do auto-conversion of HTML &lt;img&gt; tags to DataURI&#8217;s.</p>
<p>The reason for this is, that it is not always possible to reliably detect HTML responses, without a performance cost, and additionally, the CPU, memory and bandwidth overhead to doing this can be undersirable.</p>
<p>Unlike .CSS files, HTML responses are typically dynamic and can&#8217;t be cached. Additionally, images in the response may be from external servers, and may be larger than the types of image typically referenced from CSS.</p>
<p>For this reason, you will need to evaluate your circumstances to determine if enabling HTML inlining is a good idea in your application.</p>
<p>If you do want to enable it, you could do so like in the following example -</p>
<pre class="prettyprint">import com.visural.common.web.client.WebClient;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;

public class MyResourceTransformFilter extends com.visural.common.web.transform.ResourceTransformFilter {
    @Override
    protected List<Transform> getTransforms(HttpServletRequest req, WebClient client) {
        String url = req.getRequestURI();
        String last = url.substring(url.lastIndexOf('/'));
        if (last.contains(".")) {
            return super.getTransforms(req, client);
        } else if (client.supportsDataUris()) {
            return Arrays.asList(Transform.HTML_DATAURI);
        } else {
            return null;
        }
    }
}</pre>
<p>There are several other override points, included in the filter, so consult <a href="http://code.google.com/p/visural-common/source/browse/trunk/visural-common/src/com/visural/common/web/transform/ResourceTransformFilter.java">the source</a> or drop me an email if you&#8217;d like to customise further.</p>
<h2>Summary</h2>
<p>So with this one simple addition we get framework-agnostic image inlining, compilation and compression which responds intelligently to the user&#8217;s choice of browser.</p>
<p>This has been live on <a href="http://www.onmydoorstep.com.au/">onmydoorstep.com.au</a> for a week or two is working out well thus far.</p>
<h2>Great, I don&#8217;t use servlet filters!</h2>
<p>There is also a command-line version of the DataURI and MHTML converters which you can apply to non-JVM based projects as part of a build-script or manual process.</p>
<p>If you&#8217;ve downloaded the commandline version you can run it by:</p>
<pre>  java -cp visural-common.jar com.visural.common.web.css.CSSDataUri [input-file.css] [output-file.css]</pre>
<p>This will convert the<em> [input-file.css] </em>and inline the image data into the output. Note that the relative URLs are assumed to be resolvable relative the location of the CSS on disk. Mostly this will work just fine, and it will even attempt to resolve http:// urls.</p>
<p>The one thing that won&#8217;t work with the command line version is root-relative urls, e.g. url(&#8220;/folder/myimage.png&#8221;), since there&#8217;s no way to know what the root is, in the context of the disk. I could fix this is a future version by adding another command line option, so if you need it, let me know.</p>
<p>Similarly, you can run the MHTML converter from the command-line as so:</p>
<pre>  java -cp visural-common.jar com.visural.common.web.css.CSSMHTML [input-file.css] [output-file.css] [http://serverurl/for/css]</pre>
<p>For this one, you need to supply the additional server URL for the CSS file. This is because MHTML file references need the full URL to the defining CSS file (relative URLs don&#8217;t work).</p>
<p>This is one of the reasons that I chose to implement the solution as a filter.</p>
<p>Anyhow, given the simplicity of this filter, there&#8217;s pretty much no reason not to use this in your Java web app and improve those YSlow / PageSpeed results and rating without very little effort <img src='http://d3araz99qvcc8b.cloudfront.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Fjava-web-datauris-lesscss-javascript-css-compression%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Fjava-web-datauris-lesscss-javascript-css-compression%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=automation,css,Java,javascript,open-source,tips,visural-common,web" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2009/07/automatic-javascript-and-css-compression-for-java-webapps/' rel='bookmark' title='Permanent Link: Automatic Javascript and CSS Compression For Java Webapps'>Automatic Javascript and CSS Compression For Java Webapps</a></li>
<li><a href='http://www.richardnichols.net/2010/07/mhtml-browser-compatibility-css-inlining/' rel='bookmark' title='Permanent Link: MHTML Browser Compatibility &#8211; CSS Inlining'>MHTML Browser Compatibility &#8211; CSS Inlining</a></li>
<li><a href='http://www.richardnichols.net/2010/06/301-redirects-made-easy-in-java/' rel='bookmark' title='Permanent Link: 301 Redirects Made Easy In Java'>301 Redirects Made Easy In Java</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=1qJFzDGTdp0:3_lYW1FSMo0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=1qJFzDGTdp0:3_lYW1FSMo0:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=1qJFzDGTdp0:3_lYW1FSMo0:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=1qJFzDGTdp0:3_lYW1FSMo0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=1qJFzDGTdp0:3_lYW1FSMo0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=1qJFzDGTdp0:3_lYW1FSMo0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=1qJFzDGTdp0:3_lYW1FSMo0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=1qJFzDGTdp0:3_lYW1FSMo0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=1qJFzDGTdp0:3_lYW1FSMo0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=1qJFzDGTdp0:3_lYW1FSMo0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=1qJFzDGTdp0:3_lYW1FSMo0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=1qJFzDGTdp0:3_lYW1FSMo0:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/</feedburner:origLink></item>
		<item>
		<title>Thoughts on the WordPress &amp; Thesis GPL hoo-haa</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/9frDi7v-Ee0/</link>
		<comments>http://www.richardnichols.net/2010/07/thoughts-on-the-wordpress-thesis-gpl-hoo-haa/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 22:35:44 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[IT]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[soap-box]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=591</guid>
		<description><![CDATA[The blogosphere has been railing back and forth the past week about the assertion made by Matt Mullenweg that themes are covered by the GPL, as is WordPress. This post is a pretty good jumping off point if you need &#8230; <a href="http://www.richardnichols.net/2010/07/thoughts-on-the-wordpress-thesis-gpl-hoo-haa/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/07/facelift-time-and-on-to-wordpress-3/' rel='bookmark' title='Permanent Link: Facelift time and on to WordPress 3'>Facelift time and on to WordPress 3</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>The blogosphere has been railing back and forth the past week about the assertion made by Matt Mullenweg that themes are covered by the GPL, as is WordPress.</p>
<p>This <a href="http://ma.tt/2010/07/theme-are-gpl-too/">post</a> is a pretty good jumping off point if you need to get up to speed.</p>
<p>It appears in the context of the for-pay Thesis theme which is the primary issue in the discussion, there are a few points worth pointing out -</p>
<ul>
<li>The issue of whether it&#8217;s a derivative work is moot since it has been clearly noted that it contains code from the original WordPress base theme, ergo even by the legal definition (as compared with the GPL&#8217;s), it is a derivative work.</li>
<li>The GPL only covers code that is executed. This means that the Thesis developer is obligated to only distribute the .php source under the GPL, while the other theme assets may be proprietary.</li>
</ul>
<p>So with that in mind, the real question is &#8211; does the GPL apply to a non derivative work (in the legal, copyright sense) that is executed in the same process as the core GPL WordPress code?</p>
<p>Yes it does.</p>
<p>At least, the GPL says it does &#8211; it&#8217;s yet to be tested in a meaningful way. So whether that&#8217;s a legally enforceable statement, remains to be seen, but the license is pretty clear on that matter.</p>
<p>My feelings about this issue in general are -</p>
<ul>
<li>The key issue here is that WordPress is mostly an end-user product, and a very popular one. This means there are a lot of people in the WordPress community with no understanding of GPL or licensing in general. The GPL enforces Freedom, and that&#8217;s with a capital &#8216;F&#8217; &#8211; but the community around WordPress isn&#8217;t necessarily unanimously aware of this goal.<br/><br/>Actually, that&#8217;s precisely why Stallman wrote the GPL as such. To ensure that his vision of community (and its efforts) were maintained despite any community that latched on to it down the road.<br/><br/></li>
<li> People have a choice when they choose GPL licensed code.<br/><br/>When you pick something that&#8217;s GPL&#8217;ed, you accept that other people have put a lot of effort into building it. You reciprocate that effort by providing any effort that you choose to add, to others. It&#8217;s a one good turn obliges another type philosophy.<br/><br/>You may disagree with it &#8211; it goes too far!<br/><br/>Well that&#8217;s no problem &#8211; just don&#8217;t use or modify GPL&#8217;ed software. There are plenty of other more permissive licenses.</li>
</ul>
<p>I actually think this debate is a good thing for the WordPress&#8217;s community. A bunch of people who previously didn&#8217;t care about licensing and software freedom have now been pulled kicking and screaming into the debate.</p>
<p>And that can only be a good thing, if only a small step.</p>
<p>(For my general position on open-source licensing, have a read of my <a href="http://www.richardnichols.net/open-source/">open-source page</a>)
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Fthoughts-on-the-wordpress-thesis-gpl-hoo-haa%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Fthoughts-on-the-wordpress-thesis-gpl-hoo-haa%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=open-source,soap-box" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/07/facelift-time-and-on-to-wordpress-3/' rel='bookmark' title='Permanent Link: Facelift time and on to WordPress 3'>Facelift time and on to WordPress 3</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=9frDi7v-Ee0:81WOYJGXKoA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=9frDi7v-Ee0:81WOYJGXKoA:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=9frDi7v-Ee0:81WOYJGXKoA:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=9frDi7v-Ee0:81WOYJGXKoA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=9frDi7v-Ee0:81WOYJGXKoA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=9frDi7v-Ee0:81WOYJGXKoA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=9frDi7v-Ee0:81WOYJGXKoA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=9frDi7v-Ee0:81WOYJGXKoA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=9frDi7v-Ee0:81WOYJGXKoA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=9frDi7v-Ee0:81WOYJGXKoA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=9frDi7v-Ee0:81WOYJGXKoA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=9frDi7v-Ee0:81WOYJGXKoA:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/07/thoughts-on-the-wordpress-thesis-gpl-hoo-haa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/07/thoughts-on-the-wordpress-thesis-gpl-hoo-haa/</feedburner:origLink></item>
		<item>
		<title>Detecting Which Browser In Java Servlet/Filter</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/sTxDxZ_mv0M/</link>
		<comments>http://www.richardnichols.net/2010/07/detecting-which-browser-in-java-servlet-filter/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 09:22:28 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[visural-common]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=549</guid>
		<description><![CDATA[The newest version of my open source tools project, visural-common &#8211; 0.4, includes a new feature the com.visural.web.client.WebClient class. The purpose of this class is simple - User-Agent string goes in -&#62; Browser, version and platform comes out. The &#8220;User-Agent&#8221; string &#8230; <a href="http://www.richardnichols.net/2010/07/detecting-which-browser-in-java-servlet-filter/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/' rel='bookmark' title='Permanent Link: ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!'>ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!</a></li>
<li><a href='http://www.richardnichols.net/2010/06/301-redirects-made-easy-in-java/' rel='bookmark' title='Permanent Link: 301 Redirects Made Easy In Java'>301 Redirects Made Easy In Java</a></li>
<li><a href='http://www.richardnichols.net/2010/03/apache-wicket-force-page-reload-to-fix-ajax-back/' rel='bookmark' title='Permanent Link: Wicket &#8211; forcing page reload on browser back button&#8230;'>Wicket &#8211; forcing page reload on browser back button&#8230;</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/07/browsericons.png"><img class="alignright size-thumbnail wp-image-568" title="Which web browser?" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/07/browsericons-150x150.png" alt="" width="150" height="150" /></a>The newest version of my open source tools project, <a href="http://code.google.com/p/visural-common/">visural-common</a> &#8211; 0.4, includes a new feature the <strong>com.visural.web.client.WebClient</strong> class.</p>
<p>The purpose of this class is simple -</p>
<p><em>User-Agent string goes in -&gt; Browser, version and platform comes out.</em></p>
<p>The &#8220;User-Agent&#8221; string is a HTTP header property that is sent as part of the HTTP request. All common web browsers (and other HTTP clients, such as search engine crawlers) send predictable user agent strings which allow detection of the browser and operating system being used.</p>
<p>This makes it very easy to add conditional code to your server-side logic (in servlet filters or otherwise), such that you can customise the web experience for each platform and browser.</p>
<p>The usage of the class is very simple -</p>
<pre class="prettyprint">import com.visural.web.client.*;

class MyFilter implements Filter {
    ...
    public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc)
            throws IOException, ServletException
    {
        HttpServletRequest req = (HttpServletRequest) sr;
        WebClient client = WebClient.detect(req);
        if (client.getUserAgent().equals(UserAgent.IE)) {
            // do something for IE only
        } else if (client.getUserAgent().equals(UserAgent.FIREFOX) &amp;&amp;
                 client.getPlatform().equals(Platform.LINUX)) {
            // etc.
        }
    }
    ...
}</pre>
<p>Currently it supports the detection of the following browsers, including version number -</p>
<pre>    IE,
    FIREFOX,
    CHROME,
    OPERA,
    SAFARI,
    GOOGLEBOT,
    YAHOO_SLURP,
    MSNBOT</pre>
<p>And will detect the following operating systems -</p>
<pre>    MACOSX,
    WIN95,
    WIN98,
    WINNT,
    WIN2K,
    WINXP,
    WINVISTA,
    WIN7,
    LINUX,
    IOS, (iPhone, iPad, iPod Touch)
    ANDROID</pre>
<p>There are certainly other solutions for this, but I wanted a simple, elegant implementation, that is optimised for the typical sort of logic that you want this for on the server side.</p>
<p>You can download version 0.4 of <a href="http://code.google.com/p/visural-common/">visural-common</a> at google code and get started right away. It is licensed under the Apache 2.0 License.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Fdetecting-which-browser-in-java-servlet-filter%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Fdetecting-which-browser-in-java-servlet-filter%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=Java,open-source,visural-common" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/' rel='bookmark' title='Permanent Link: ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!'>ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!</a></li>
<li><a href='http://www.richardnichols.net/2010/06/301-redirects-made-easy-in-java/' rel='bookmark' title='Permanent Link: 301 Redirects Made Easy In Java'>301 Redirects Made Easy In Java</a></li>
<li><a href='http://www.richardnichols.net/2010/03/apache-wicket-force-page-reload-to-fix-ajax-back/' rel='bookmark' title='Permanent Link: Wicket &#8211; forcing page reload on browser back button&#8230;'>Wicket &#8211; forcing page reload on browser back button&#8230;</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=sTxDxZ_mv0M:tUSRyoXYeMQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=sTxDxZ_mv0M:tUSRyoXYeMQ:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=sTxDxZ_mv0M:tUSRyoXYeMQ:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=sTxDxZ_mv0M:tUSRyoXYeMQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=sTxDxZ_mv0M:tUSRyoXYeMQ:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=sTxDxZ_mv0M:tUSRyoXYeMQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=sTxDxZ_mv0M:tUSRyoXYeMQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=sTxDxZ_mv0M:tUSRyoXYeMQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=sTxDxZ_mv0M:tUSRyoXYeMQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=sTxDxZ_mv0M:tUSRyoXYeMQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=sTxDxZ_mv0M:tUSRyoXYeMQ:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=sTxDxZ_mv0M:tUSRyoXYeMQ:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/07/detecting-which-browser-in-java-servlet-filter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/07/detecting-which-browser-in-java-servlet-filter/</feedburner:origLink></item>
		<item>
		<title>Facelift time and on to WordPress 3</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/oZuIrqdwjmI/</link>
		<comments>http://www.richardnichols.net/2010/07/facelift-time-and-on-to-wordpress-3/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 03:53:52 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[off-topic]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=579</guid>
		<description><![CDATA[Well I finally upgraded to the new WordPress. To be honest there&#8217;s not really a great deal I was interested in, although the new Twenty-Ten theme is nice. I took the opportunity to the give the site a bit of &#8230; <a href="http://www.richardnichols.net/2010/07/facelift-time-and-on-to-wordpress-3/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/07/thoughts-on-the-wordpress-thesis-gpl-hoo-haa/' rel='bookmark' title='Permanent Link: Thoughts on the WordPress &#038; Thesis GPL hoo-haa'>Thoughts on the WordPress &#038; Thesis GPL hoo-haa</a></li>
<li><a href='http://www.richardnichols.net/2010/05/onmydoorstep-com-au-officially-launched/' rel='bookmark' title='Permanent Link: onmydoorstep.com.au &#8211; officially launched!'>onmydoorstep.com.au &#8211; officially launched!</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/07/4470976294_c98f0cbceb_z1.jpg"><img class="alignright size-thumbnail wp-image-581" title="By herbm http://www.flickr.com/photos/herbrm/4470976294/sizes/z/in/photostream/" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/07/4470976294_c98f0cbceb_z1-150x150.jpg" alt="" width="150" height="150" /></a>Well I finally upgraded to the new WordPress.</p>
<p>To be honest there&#8217;s not really a great deal I was interested in, although the new Twenty-Ten theme is nice.</p>
<p>I took the opportunity to the give the site a bit of a facelift, since it was starting to look a bit cluttered. The new theme actually allows for more content, and doesn&#8217;t feel so cramped.</p>
<p>I did consider for a moment, writing my own blog engine and moving the site on to Google App Engine, but then I thought of the 100 other things I&#8217;d rather be building, and sat down until the thought went away.</p>
<p>WordPress is pretty great for what it is. There are times when I would like to get under the covers and have a bit more control (without learning PHP), but for the most part it does everything I need and is very user friendly.</p>
<p>Maybe when I get that &#8220;spare time&#8221; I hear about, I&#8217;ll reconsider, but for now, I heart WP.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Ffacelift-time-and-on-to-wordpress-3%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Ffacelift-time-and-on-to-wordpress-3%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=off-topic" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/07/thoughts-on-the-wordpress-thesis-gpl-hoo-haa/' rel='bookmark' title='Permanent Link: Thoughts on the WordPress &#038; Thesis GPL hoo-haa'>Thoughts on the WordPress &#038; Thesis GPL hoo-haa</a></li>
<li><a href='http://www.richardnichols.net/2010/05/onmydoorstep-com-au-officially-launched/' rel='bookmark' title='Permanent Link: onmydoorstep.com.au &#8211; officially launched!'>onmydoorstep.com.au &#8211; officially launched!</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=oZuIrqdwjmI:lzpsZz7SJCU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=oZuIrqdwjmI:lzpsZz7SJCU:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=oZuIrqdwjmI:lzpsZz7SJCU:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=oZuIrqdwjmI:lzpsZz7SJCU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=oZuIrqdwjmI:lzpsZz7SJCU:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=oZuIrqdwjmI:lzpsZz7SJCU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=oZuIrqdwjmI:lzpsZz7SJCU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=oZuIrqdwjmI:lzpsZz7SJCU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=oZuIrqdwjmI:lzpsZz7SJCU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=oZuIrqdwjmI:lzpsZz7SJCU:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=oZuIrqdwjmI:lzpsZz7SJCU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=oZuIrqdwjmI:lzpsZz7SJCU:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/07/facelift-time-and-on-to-wordpress-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/07/facelift-time-and-on-to-wordpress-3/</feedburner:origLink></item>
		<item>
		<title>MHTML Browser Compatibility – CSS Inlining</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/Pj88DSrlaC4/</link>
		<comments>http://www.richardnichols.net/2010/07/mhtml-browser-compatibility-css-inlining/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 22:50:06 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=551</guid>
		<description><![CDATA[MHTML is a technology implementing by Microsoft in Internet Explorer for packaging images, stylesheets and other resources inside a single HTML file. Typically this is used for things like help files, ebooks or other &#8220;published&#8221; content, but more recently has &#8230; <a href="http://www.richardnichols.net/2010/07/mhtml-browser-compatibility-css-inlining/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/' rel='bookmark' title='Permanent Link: ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!'>ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!</a></li>
<li><a href='http://www.richardnichols.net/2009/07/automatic-javascript-and-css-compression-for-java-webapps/' rel='bookmark' title='Permanent Link: Automatic Javascript and CSS Compression For Java Webapps'>Automatic Javascript and CSS Compression For Java Webapps</a></li>
<li><a href='http://www.richardnichols.net/2010/03/apache-wicket-force-page-reload-to-fix-ajax-back/' rel='bookmark' title='Permanent Link: Wicket &#8211; forcing page reload on browser back button&#8230;'>Wicket &#8211; forcing page reload on browser back button&#8230;</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>MHTML is a technology implementing by Microsoft in Internet Explorer for packaging images, stylesheets and other resources inside a single HTML file. Typically this is used for things like help files, ebooks or other &#8220;published&#8221; content, but more recently has been proposed as a way of supporting CSS image inline in IE6 and IE7, which don&#8217;t support &#8220;Data URIs&#8221;.</p>
<p>MHTML is as far as I know, only implemented in Internet Explorer. And given that IE8 supports data URI&#8217;s there&#8217;s no reason to use it outside of IE6/IE7.</p>
<p>I&#8217;ve done some testing and, as cited in the comments of <a rel="nofollow" href=" http://www.phpied.com/mhtml-when-you-need-data-uris-in-ie7-and-under/">this thread on MHTML</a>, there are issues with using MHTML to inline images in CSS on <em>Windows Vista</em> running <em>IE7</em>. This specific platform has problems and will not accept a CSS file with inlined MHTML images.</p>
<p>I tried fixing this, as some others have suggested, by separating the MHTML images into a separate file, and keeping the CSS by itself, referencing the MHTML file.</p>
<p>This <em>appears </em>to work &#8212; at least, it works the first time. But a subsequent reload will then display blank images. Essentially the next time it reloads from the cache, it breaks.</p>
<p>That pretty much rules out using MHTML on Windows Vista, since the whole point of MHTML is to load one file rather than making multiple requests. If you can&#8217;t cache the file, then there is no benefit!</p>
<p><strong>What about other platforms?</strong></p>
<p>Well on Windows XP, IE6 and IE7 appear to work just fine.</p>
<p>However &#8211; in some corporate environments there are browser security flags that may cause the inlined MHTML to not load initially. Subsequently you may get strange behaviour when the user does try to load them.</p>
<p><strong>Update:</strong> I&#8217;ve resolved this one &#8211; this can occur when the MHTML content is not matched with appropriate MIME types and formatted as IE expects it. Most of the other articles about using MHTML in this manner do not adhere strictly to the MHTML format and exhibit this issue.</p>
<p><strong>My Verdict</strong></p>
<p>For the open-web, I&#8217;d suggest that MHTML is too much of a liability to use across the board. You really can&#8217;t be sure that people are actually seeing your site as intended.</p>
<p><strong>Update:</strong> Actually, if you have a Java web app, my <a href="http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/">ResourceTransformFilter</a> will apply MHTML in a reliable way across your application &#8211; only to the clients that can use it.</p>
<p>If you have a controlled environment (e.g. intranet or WAN) then MHTML might be a valid choice, since you can be sure that the browser configuration is suitable for your served content.</p>
<p>At least the future for Data URI&#8217;s is bright and as IE6/IE7 market share shrinks this whole issue will disappear.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Fmhtml-browser-compatibility-css-inlining%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Fmhtml-browser-compatibility-css-inlining%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=browsers,css,performance,tips" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/' rel='bookmark' title='Permanent Link: ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!'>ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!</a></li>
<li><a href='http://www.richardnichols.net/2009/07/automatic-javascript-and-css-compression-for-java-webapps/' rel='bookmark' title='Permanent Link: Automatic Javascript and CSS Compression For Java Webapps'>Automatic Javascript and CSS Compression For Java Webapps</a></li>
<li><a href='http://www.richardnichols.net/2010/03/apache-wicket-force-page-reload-to-fix-ajax-back/' rel='bookmark' title='Permanent Link: Wicket &#8211; forcing page reload on browser back button&#8230;'>Wicket &#8211; forcing page reload on browser back button&#8230;</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=Pj88DSrlaC4:6mw4YO8P14M:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=Pj88DSrlaC4:6mw4YO8P14M:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=Pj88DSrlaC4:6mw4YO8P14M:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=Pj88DSrlaC4:6mw4YO8P14M:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=Pj88DSrlaC4:6mw4YO8P14M:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=Pj88DSrlaC4:6mw4YO8P14M:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=Pj88DSrlaC4:6mw4YO8P14M:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=Pj88DSrlaC4:6mw4YO8P14M:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=Pj88DSrlaC4:6mw4YO8P14M:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=Pj88DSrlaC4:6mw4YO8P14M:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=Pj88DSrlaC4:6mw4YO8P14M:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=Pj88DSrlaC4:6mw4YO8P14M:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/07/mhtml-browser-compatibility-css-inlining/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/07/mhtml-browser-compatibility-css-inlining/</feedburner:origLink></item>
		<item>
		<title>What’s In A Name? (or “my right to be an anonymous jerk on the Internets”)</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/B_DeXzr0Ros/</link>
		<comments>http://www.richardnichols.net/2010/07/whats-in-a-name-real-name-blizzard-issue/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 07:28:30 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[soap-box]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=505</guid>
		<description><![CDATA[I found it interesting to watch the reactions around Blizzard&#8217;s recent announcement that from now on, the community forums provided for customers to discuss their games will use the user&#8217;s real names, and not a character name or alias. When &#8230; <a href="http://www.richardnichols.net/2010/07/whats-in-a-name-real-name-blizzard-issue/">Continue reading <span class="meta-nav">&#8594;</span></a>


No related posts.]]></description>
			<content:encoded><![CDATA[<p>I found it interesting to watch the reactions around Blizzard&#8217;s <a href="http://forums.battle.net/thread.html?topicId=25626109041&amp;sid=3000">recent announcement</a> that from now on, the community forums provided for customers to discuss their games will use the user&#8217;s <strong>real names</strong>, and not a character name or alias.</p>
<p>When I designed &#8220;<a href="http://www.onmydoorstep.com.au/">On My Doorstep</a>&#8220;, this was something that I gave quite a lot of thought, and came to the same decision as the one Blizzard just made.</p>
<p>It&#8217;s an interesting thing to consider for any web startup or application &#8211; what sort of community do you want to foster? Is it ok for people to be anonymous?</p>
<p>Generally we&#8217;ve shied away from using real names, I think for practical reasons (having a unique identifier for someone to log in with) and culturally (that&#8217;s the way everyone has always done it). </p>
<p>But, with social networking, users are encouraged to be themselves and be &#8220;celebrities in their own communities&#8221;, so to speak. As social networks merge and inter-operate with each other and web-based apps, it&#8217;s sensible to assume that our real identities will go with us to each service and community that we interact with.</p>
<p>I saw this as a useful thing for the type of community, I had planned for onmydoorstep.com.au.</p>
<p>Social sites revolve around one thing &#8211; the community of users that use them. I haven&#8217;t used a single community focused website that hasn&#8217;t experienced some amount of trolling, griefing or user-to-user abuse. It&#8217;s something of a joke actually &#8211; arguing on the Internet is probably one of the single biggest reasons for it&#8217;s success. Remember this XKCD comic -</p>
<p><center><a href="http://xkcd.com/386/"><img src="http://imgs.xkcd.com/comics/duty_calls.png" alt="someone is wrong in the Internet" /></a></center></p>
<p>Who hasn&#8217;t been the anonymous jerk, madly typing into the Internet to prove to some moron how wrong they are?</p>
<p>Pretty much everyone has done it, <em>and had it done to them</em>.</p>
<p>Certainly stuff like this happens in everyday life&#8230;. it&#8217;s not just an Internet problem?</p>
<p>Well, it seems to happen<em> a lot more</em> on the Internet, and the commonly cited reason (for both doing it and recieving it) is <em>anonymity</em>.</p>
<p>It&#8217;s a lot easier to act like an ass-hat and flame someone when you can&#8217;t be held responsible for your actions. Similarly when you&#8217;re telling &#8220;<em>doomslayer1975</em>&#8221; what&#8217;s what, it&#8217;s easier not to think of them as &#8220;<em>Fred Williams, a 35 year old father of three from New Zealand who likes playing Half-life 2 and taking long walks on the beach</em>&#8220;.</p>
<p>When they don&#8217;t appear as real people, you don&#8217;t have to treat them as real people.</p>
<p>So for &#8220;<a href="http://www.onmydoorstep.com.au/">On My Doorstep</a>&#8220;, it was apparent that for a site focused on the local community, the services, activities and events in your local neighbourhood, it was crucial that the user&#8217;s be real people. It adds to the feeling of locality, and encourages credibility and transparency in the information presented and the discussion of the users.</p>
<p>Was this the right decision? It&#8217;s early days yet, and the site hasn&#8217;t grown enough to know for sure.</p>
<p>I did receive some feedback from early users who were a little surprised to see their real names being used on the site. Other users don&#8217;t seem to be worried one way or another. So I would guess that some users may be discouraged to participate given the lack of anonymity, but others would not be phased. However I think that the potential cost in terms of engagement, is balanced in part by the quality of content and communication.</p>
<p>So to that end, I certainly understand what Blizzard are doing.</p>
<p><center><img src="http://farm4.static.flickr.com/3637/3645211083_43ed00c6e5.jpg" alt="Robert Couse-Baker - http://www.flickr.com/photos/29233640@N07/3645211083/" /></center></p>
<p>One thing about Blizzard though, which is different, is that they have an existing community, that was built upon the understanding of anonymity. They also have a line of products which up until now have presented users not as themselves, but actively as fictional individuals.</p>
<p>It&#8217;s one thing to <strong>build </strong>a community of users who are presenting themselves, as themselves, but to <strong>change </strong>an incumbent (and vocal) community of anonymous users into a publicly-outed one, is a Big Deal&#8230;. and I think this is the source of the backlash.</p>
<p>There are people in that community who value the anonymity they have, and the freedom to interact under the cover it provides. Those users are going to be upset.</p>
<p>Other users are going to simply be adverse to change regardless of what it is. They don&#8217;t like to see anything that&#8217;s going to fragment or disrupt the community that they interact with and value&#8230; I understand where those people are coming from.</p>
<p>There&#8217;s probably going to be a sweeping change to Blizzard&#8217;s hosted gaming community as a result of this change. Some people will leave, they&#8217;ll find other places to go which they feel more at home in. I&#8217;m also sure that other users, both old and new will find the new community to be a better one, and stick around.</p>
<p>Whether Blizzard&#8217;s community grows or shrinks as a result of this decision only time will tell, but I&#8217;m sure it will be interesting to see how it all pans out.</p>
<p>I hope that the use of real identity becomes a trend for web applications &#038; startups which have appropriate communities. It&#8217;s probably not something that is appropriate in every instance, but hopefully we will see some balance, and as a result an improvement in the quality of discussion and interaction provided online.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Fwhats-in-a-name-real-name-blizzard-issue%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F07%2Fwhats-in-a-name-real-name-blizzard-issue%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=community,Design,soap-box" height="61" width="50" /><br />
			</a>
		</div>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=B_DeXzr0Ros:QNnJ7yCuCbw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=B_DeXzr0Ros:QNnJ7yCuCbw:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=B_DeXzr0Ros:QNnJ7yCuCbw:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=B_DeXzr0Ros:QNnJ7yCuCbw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=B_DeXzr0Ros:QNnJ7yCuCbw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=B_DeXzr0Ros:QNnJ7yCuCbw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=B_DeXzr0Ros:QNnJ7yCuCbw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=B_DeXzr0Ros:QNnJ7yCuCbw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=B_DeXzr0Ros:QNnJ7yCuCbw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=B_DeXzr0Ros:QNnJ7yCuCbw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=B_DeXzr0Ros:QNnJ7yCuCbw:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=B_DeXzr0Ros:QNnJ7yCuCbw:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/07/whats-in-a-name-real-name-blizzard-issue/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/07/whats-in-a-name-real-name-blizzard-issue/</feedburner:origLink></item>
		<item>
		<title>Implementing Facebook OAuth 2.0 Authentication in Java</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/JXhVaTE6c9M/</link>
		<comments>http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 08:16:27 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=467</guid>
		<description><![CDATA[I recently switched onmydoorstep.com.au&#8216;s Facebook login feature from the old &#8220;Facebook Connect&#8221; API implemented with facebook-java-api over to the new Facebook Graph API / OAuth 2.0 authentication. This was far easier to implement than the original authentication, particular under Apache &#8230; <a href="http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/' rel='bookmark' title='Permanent Link: Clustering Guice Java Web Applications'>Clustering Guice Java Web Applications</a></li>
<li><a href='http://www.richardnichols.net/2009/08/netbeans-6-7-broke-my-parameterized-tests/' rel='bookmark' title='Permanent Link: NetBeans 6.7 Broke My Parameterized Tests'>NetBeans 6.7 Broke My Parameterized Tests</a></li>
<li><a href='http://www.richardnichols.net/2010/03/wicket-on-google-app-engine-gae-deployment-configuration/' rel='bookmark' title='Permanent Link: Wicket On Google App Engine (GAE) &#8211; Deployment Configuration'>Wicket On Google App Engine (GAE) &#8211; Deployment Configuration</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I recently switched <a href="http://www.onmydoorstep.com.au">onmydoorstep.com.au</a>&#8216;s Facebook login feature from the old &#8220;Facebook Connect&#8221; API implemented with <a rel="nofollow" href="http://code.google.com/p/facebook-java-api/">facebook-java-api</a> over to the new Facebook Graph API / OAuth 2.0 authentication.</p>
<p>This was far easier to implement than the original authentication, particular under Apache Wicket, but it should be easier regardless of your Java framework of choice.</p>
<p>Here&#8217;s how I did it.</p>
<p>First I developed a basic &#8220;magic&#8221; class for the Facebook API -</p>
<pre class="prettyprint">
public class Facebook {
    // get these from your FB Dev App
    private static final String api_key = "MYAPIKEY";
    private static final String secret = "MYSECRETKEY";
    private static final String client_id = "MYCLIENTID";  

    // set this to your servlet URL for the authentication servlet/filter
    private static final String redirect_uri = "http://www.onmydoorstep.com.au/fbauth";
    /// set this to the list of extended permissions you want
    private static final String[] perms = new String[] {"publish_stream", "email"};

    public static String getAPIKey() {
        return api_key;
    }

    public static String getSecret() {
        return secret;
    }

    public static String getLoginRedirectURL() {
        return "https://graph.facebook.com/oauth/authorize?client_id=" +
            client_id + "&#038;display=page&#038;redirect_uri=" +
            redirect_uri+"&#038;scope="+StringUtil.delimitObjectsToString(",", perms);
    }

    public static String getAuthURL(String authCode) {
        return "https://graph.facebook.com/oauth/access_token?client_id=" +
            client_id+"&#038;redirect_uri=" +
            redirect_uri+"&#038;client_secret="+secret+"&#038;code="+authCode;
    }
}
</pre>
<p>You&#8217;ll need the <a href="http://code.google.com/p/visural-common/">visural-common</a> library for some of the code above. </p>
<p>I want the &#8220;email&#8221; and &#8220;publish_stream&#8221; <a href="http://developers.facebook.com/docs/authentication/permissions">extended permissions</a>, so that I can get the user&#8217;s email address and post updates back to their stream in Facebook. You can customise this list with the permissions that you need.</p>
<p>The process of authentication is simple.</p>
<ol>
<li>You create a link on your web UI (generally labelled &#8220;Login With Facebook&#8221; or something like that) to the <em>Facebook.getLoginRedirectURL()</em> URL.</li>
<li>Facebook will authorise the user with the permissions you requested, and redirect the user to your &#8220;redirect_uri&#8221; as specified above.</li>
<li>In a servlet or filter at your &#8220;redirect_uri&#8221; you need to
<ul>
<li>Retrieve the request parameter &#8220;code&#8221;</li>
<li>Make another request to the URL &#8211; <em>Facebook.getAuthURL(request.getParameter(&#8220;code&#8221;))</em></li>
<li>Parse the response for the &#8220;access_token&#8221; and &#8220;expires&#8221;, assuming that it was a valid response that contained them.</li>
</ul>
</li>
<li>You use your access token to retrieve data about the user and/or make other calls to the Facebook Graph API</li>
</ol>
<p>Due to the way Apache Wicket works, I implemented a Servlet Filter for the &#8220;redirect_uri&#8221; (/fbauth) &#8211; </p>
<pre class="prettyprint">
public class FBOAuth implements Filter {

    public void init(FilterConfig fc) throws ServletException {
    }

    public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)sr;
        HttpServletResponse res = (HttpServletResponse)sr1;
        String code = sr.getParameter("code");
        if (StringUtil.isNotBlankStr(code)) {
            String authURL = Facebook.getAuthURL(code);
            URL url = new URL(authURL);
            try {
                String result = readURL(url);
                String accessToken = null;
                Integer expires = null;
                String[] pairs = result.split("&#038;");
                for (String pair : pairs) {
                    String[] kv = pair.split("=");
                    if (kv.length != 2) {
                        throw new RuntimeException("Unexpected auth response");
                    } else {
                        if (kv[0].equals("access_token")) {
                            accessToken = kv[1];
                        }
                        if (kv[0].equals("expires")) {
                            expires = Integer.valueOf(kv[1]);
                        }
                    }
                }
                if (accessToken != null &#038;&#038; expires != null) {
                    UserService us = UserService.get();
                    us.authFacebookLogin(accessToken, expires);
                    res.sendRedirect("http://www.onmydoorstep.com.au/");
                } else {
                    throw new RuntimeException("Access token and expires not found");
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private String readURL(URL url) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        InputStream is = url.openStream();
        int r;
        while ((r = is.read()) != -1) {
            baos.write(r);
        }
        return new String(baos.toByteArray());
    }

    public void destroy() {
    }
}
</pre>
<p>This is a cut-down version of my actual code as I do a bunch of other things on onmydoorstep.com.au which is more related to internal house-keeping and UX.</p>
<p>Your &#8220;UserService&#8221; might look something like -</p>
<pre class="prettyprint">
class UserService {

    // ....

    public void authFacebookLogin(String accessToken, int expires) {
        try {
            JSONObject resp = new JSONObject(
                IOUtil.urlToString(new URL("https://graph.facebook.com/me?access_token=" + accessToken)));
            String id = resp.getString("id");
            String firstName = resp.getString("first_name");
            String lastName = resp.getString("last_name");
            String email = resp.getString("email");

            // ...
            // create and authorise the user in your current system w/ data above
            // ...

        } catch (Throwable ex) {
            throw new RuntimeException("failed login", ex);
        }
    }
}
</pre>
<p>So, just to recap, the sequence of authentication is as follows &#8211; </p>
<ol>
<li>User clicks a link on your site to <em>Facebook.getLoginRedirectURL()</em></li>
<li>Facebook asks them for their username/password to log in to your application</li>
<li>Assuming they authenticate with Facebook, Facebook then redirects the user to your &#8220;redirect_uri&#8221; with a parameter &#8220;code&#8221; passed along.</li>
<li>You use the &#8220;code&#8221; parameter to query the Facebook authentication service &#8211; <em>Facebook.getAuthURL(request.getParameter(&#8220;code&#8221;))</em></li>
<li>Assuming it was a valid authentication code, Facebook will pass you back an &#8220;access_token&#8221; that you can use to access the Facebook Graph API for the given user.</li>
</ol>
<p>This could certainly be formalised into a reusable chunk of code. I may get around to adding it to visural-common, but right now there&#8217;s a lot of onmydoorstep-specific stuff in the real code.</p>
<p>Anyhow, hope it helps someone out!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2Fimplementing-facebook-oauth-2-0-authentication-in-java%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2Fimplementing-facebook-oauth-2-0-authentication-in-java%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=facebook,Java,oauth,tips" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/' rel='bookmark' title='Permanent Link: Clustering Guice Java Web Applications'>Clustering Guice Java Web Applications</a></li>
<li><a href='http://www.richardnichols.net/2009/08/netbeans-6-7-broke-my-parameterized-tests/' rel='bookmark' title='Permanent Link: NetBeans 6.7 Broke My Parameterized Tests'>NetBeans 6.7 Broke My Parameterized Tests</a></li>
<li><a href='http://www.richardnichols.net/2010/03/wicket-on-google-app-engine-gae-deployment-configuration/' rel='bookmark' title='Permanent Link: Wicket On Google App Engine (GAE) &#8211; Deployment Configuration'>Wicket On Google App Engine (GAE) &#8211; Deployment Configuration</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=JXhVaTE6c9M:MxECyiTV2Q4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=JXhVaTE6c9M:MxECyiTV2Q4:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=JXhVaTE6c9M:MxECyiTV2Q4:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=JXhVaTE6c9M:MxECyiTV2Q4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=JXhVaTE6c9M:MxECyiTV2Q4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=JXhVaTE6c9M:MxECyiTV2Q4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=JXhVaTE6c9M:MxECyiTV2Q4:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=JXhVaTE6c9M:MxECyiTV2Q4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=JXhVaTE6c9M:MxECyiTV2Q4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=JXhVaTE6c9M:MxECyiTV2Q4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=JXhVaTE6c9M:MxECyiTV2Q4:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=JXhVaTE6c9M:MxECyiTV2Q4:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/</feedburner:origLink></item>
		<item>
		<title>LessCSS available in Java and Wicket – less.js</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/51pegrfd3Gs/</link>
		<comments>http://www.richardnichols.net/2010/06/less-css-in-wicket-using-mozilla-rhino/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 21:45:04 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Wicket]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[visural-wicket]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[wicket]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=366</guid>
		<description><![CDATA[For the uninitiated, LessCSS is a powerful extension of CSS, that adds variables, mixins, operations and nested rules. What this means is the ability to remove the repetition and redundancy which almost always pops up in CSS for complex web &#8230; <a href="http://www.richardnichols.net/2010/06/less-css-in-wicket-using-mozilla-rhino/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/06/visural-wicket-0-6-released-new-components/' rel='bookmark' title='Permanent Link: visural-wicket 0.6 released &#8211; lots of new components!'>visural-wicket 0.6 released &#8211; lots of new components!</a></li>
<li><a href='http://www.richardnichols.net/2010/02/visural-wicket-0-5-released-ready-for-action/' rel='bookmark' title='Permanent Link: visural-wicket 0.5 released &#8211; ready for action!'>visural-wicket 0.5 released &#8211; ready for action!</a></li>
<li><a href='http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/' rel='bookmark' title='Permanent Link: ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!'>ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>For the uninitiated, <a href="http://www.lesscss.org" target="_blank">LessCSS </a>is a powerful extension of CSS, that adds variables, mixins, operations and nested rules.</p>
<p>What this means is the ability to remove the repetition and redundancy which almost always pops up in CSS for complex web sites. Just the addition of variables is a god-send towards this, but other features like the addition of operations makes support each browser&#8217;s &#8220;-moz-xxx&#8221; or &#8220;-webkit-xxx&#8221; properties, plus the standard ones go from 3+ lines to 1 line of CSS. This improves the signal-to-noise ratio of the CSS dramatically.</p>
<p>After having used LessCSS for a while now, <em>I honestly wouldn&#8217;t go back to using straight CSS again.</em></p>
<p>So&#8230; my problem was, how to use LessCSS in Java, and more specifically Wicket?</p>
<p>The author of LessCSS, cloudhead, wrote the initial version in Ruby, however the new and improved version of <a rel="nofollow" href="http://github.com/cloudhead/less.js">LessCSS is written in Javascript</a>.</p>
<p>This makes integration quite easy, using <a rel="nofollow" href="http://www.mozilla.org/rhino/" target="_blank">Mozilla Rhino</a>, a Java environment for running Javascript.</p>
<p>As part of the 0.3.2 release of <a href="http://code.google.com/p/visural-common/" target="_blank">visural-common</a> I included an integration which Java-enabled less.js by using Mozilla Rhino. <a rel="nofollow" href="http://www.asual.com/lesscss/" target="_blank">Asual also did this</a>, however I had some problems with the way his version was initialised and shutdown when doing redeploys of a web app, so I wrote my own integration using the latest trunk version of less.js.</p>
<p>With the 0.6 release of <a href="http://code.google.com/p/visural-wicket/" target="_blank">visural-wicket</a>, I created a Wicket Resource Provider which will do auto-compilation of &#8220;.less&#8221; files inside of Wicket web applications. This makes working with LessCSS as natural as working with CSS itself.</p>
<p>My only gripe with LessCSS at the moment is that it doesn&#8217;t support the filter:IE&#8230;. garbage that you can use to do certain effects in IE browsers (e.g. gradients, shadows, etc.) which would be nice, however I know these are on the roadmap, and might be best separated out anyhow.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2Fless-css-in-wicket-using-mozilla-rhino%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2Fless-css-in-wicket-using-mozilla-rhino%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=css,Java,ui,visural-wicket,web,wicket" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/06/visural-wicket-0-6-released-new-components/' rel='bookmark' title='Permanent Link: visural-wicket 0.6 released &#8211; lots of new components!'>visural-wicket 0.6 released &#8211; lots of new components!</a></li>
<li><a href='http://www.richardnichols.net/2010/02/visural-wicket-0-5-released-ready-for-action/' rel='bookmark' title='Permanent Link: visural-wicket 0.5 released &#8211; ready for action!'>visural-wicket 0.5 released &#8211; ready for action!</a></li>
<li><a href='http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/' rel='bookmark' title='Permanent Link: ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!'>ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=51pegrfd3Gs:TRfUnHZizvE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=51pegrfd3Gs:TRfUnHZizvE:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=51pegrfd3Gs:TRfUnHZizvE:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=51pegrfd3Gs:TRfUnHZizvE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=51pegrfd3Gs:TRfUnHZizvE:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=51pegrfd3Gs:TRfUnHZizvE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=51pegrfd3Gs:TRfUnHZizvE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=51pegrfd3Gs:TRfUnHZizvE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=51pegrfd3Gs:TRfUnHZizvE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=51pegrfd3Gs:TRfUnHZizvE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=51pegrfd3Gs:TRfUnHZizvE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=51pegrfd3Gs:TRfUnHZizvE:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/06/less-css-in-wicket-using-mozilla-rhino/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/06/less-css-in-wicket-using-mozilla-rhino/</feedburner:origLink></item>
		<item>
		<title>visural-wicket 0.6 released – lots of new components!</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/UARMTvd5HB8/</link>
		<comments>http://www.richardnichols.net/2010/06/visural-wicket-0-6-released-new-components/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 00:29:00 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Wicket]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[releases]]></category>
		<category><![CDATA[visural-wicket]]></category>
		<category><![CDATA[wicket]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=456</guid>
		<description><![CDATA[It&#8217;s been roughly 4 months since the first public release of visural-wicket, a set of open-source components and tools for the Apache Wicket web framework. Since then the project has seen 150+ developer downloads and a generally very positive reaction &#8230; <a href="http://www.richardnichols.net/2010/06/visural-wicket-0-6-released-new-components/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/02/visural-wicket-0-5-released-ready-for-action/' rel='bookmark' title='Permanent Link: visural-wicket 0.5 released &#8211; ready for action!'>visural-wicket 0.5 released &#8211; ready for action!</a></li>
<li><a href='http://www.richardnichols.net/2009/11/announcing-visural-wicket/' rel='bookmark' title='Permanent Link: Announcing &#8211; visural-wicket'>Announcing &#8211; visural-wicket</a></li>
<li><a href='http://www.richardnichols.net/2010/06/less-css-in-wicket-using-mozilla-rhino/' rel='bookmark' title='Permanent Link: LessCSS available in Java and Wicket &#8211; less.js'>LessCSS available in Java and Wicket &#8211; less.js</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been roughly 4 months since the first public release of <a href="http://code.google.com/p/visural-wicket">visural-wicket</a>, a set of open-source components and tools for the Apache Wicket web framework.</p>
<p>Since then the project has seen 150+ developer downloads and a generally very positive reaction from the Wicket community.</p>
<p>I&#8217;m pleased to announce, the release of the next major release of the library &#8211; visural-wicket 0.6</p>
<p>Version <strong>0.6 </strong>brings a bunch of new components and enhancements -</p>
<ul>
<li><strong>DateInput </strong>- a new behavior which provides a pop-up Javascript date picker</li>
<li><strong>InputHint </strong>- a new behavior which provides &#8220;hint text&#8221; inside input fields, which disappears when the user focuses on the field</li>
<li><strong>BeautyTips </strong>- a new behavior which provides rich, attractive,  stylable tooltips for any component</li>
<li>&#8220;<strong>Confirmers</strong>&#8221; &#8211; prompt/confirmation dialogs that can be used for any  Link / Submit type Wicket action</li>
<li><strong>Dialog</strong>-  a flexible modal dialog component which can be open/closed  via Ajax or client-side Javascript</li>
<li><strong><a href="http://www.lesscss.org" target="_blank">LessCSS</a> </strong>- integration of LessCSS and Wicket, so you can use &#8220;.less&#8221; files like they were &#8220;.css&#8221;</li>
<li><strong>JSR303 Validated Form </strong>- a binding behavior and Form which automatically transfers JSR-303 validation annotations on to Wicket Forms</li>
<li><strong>Generic security framework</strong> &#8211; a generic &amp; light-weight way of implementing security integration with Wicket apps</li>
<li>Various bug fixes and API extensions</li>
</ul>
<p>As you can see there was a lot of stuff! Most of this was developed in response to my latest Wicket project &#8211; <a href="http://www.onmydoorstep.com.au/">onmydoorstep.com.au</a></p>
<p>The <a href="http://visural-wicket-examples.appspot.com/" target="_blank">live examples application</a> has also seen an update with example implementations for most of the new features.</p>
<p>You can download the distribution and examples application at the <a href="http://code.google.com/p/visural-wicket/downloads/list" target="_blank">visural-wicket project on Google Code.</a></p>
<p>Some features, such as the generic security framework are not well documented. I intend to do either a blog post or wiki article which steps through these features in the near future.</p>
<p><a href="http://code.google.com/p/visural-wicket/wiki/MavenSupport" target="_blank">Maven support </a>has also been added.</p>
<p>Note that to use LessCSS you also need <a href="http://www.mozilla.org/rhino/" target="_blank">Mozilla Rhino </a>- this is not included as a dependency out of the box. You may add it to your project manually if you are using the LessCSS features of visural-wicket.</p>
<p>Anyhow, hope you enjoy the new release and as always, get in touch if you have any feedback, good or bad!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2Fvisural-wicket-0-6-released-new-components%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2Fvisural-wicket-0-6-released-new-components%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=Java,open-source,releases,visural-wicket,wicket" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/02/visural-wicket-0-5-released-ready-for-action/' rel='bookmark' title='Permanent Link: visural-wicket 0.5 released &#8211; ready for action!'>visural-wicket 0.5 released &#8211; ready for action!</a></li>
<li><a href='http://www.richardnichols.net/2009/11/announcing-visural-wicket/' rel='bookmark' title='Permanent Link: Announcing &#8211; visural-wicket'>Announcing &#8211; visural-wicket</a></li>
<li><a href='http://www.richardnichols.net/2010/06/less-css-in-wicket-using-mozilla-rhino/' rel='bookmark' title='Permanent Link: LessCSS available in Java and Wicket &#8211; less.js'>LessCSS available in Java and Wicket &#8211; less.js</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=UARMTvd5HB8:IXfVTxrIIZA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=UARMTvd5HB8:IXfVTxrIIZA:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=UARMTvd5HB8:IXfVTxrIIZA:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=UARMTvd5HB8:IXfVTxrIIZA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=UARMTvd5HB8:IXfVTxrIIZA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=UARMTvd5HB8:IXfVTxrIIZA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=UARMTvd5HB8:IXfVTxrIIZA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=UARMTvd5HB8:IXfVTxrIIZA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=UARMTvd5HB8:IXfVTxrIIZA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=UARMTvd5HB8:IXfVTxrIIZA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=UARMTvd5HB8:IXfVTxrIIZA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=UARMTvd5HB8:IXfVTxrIIZA:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/06/visural-wicket-0-6-released-new-components/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/06/visural-wicket-0-6-released-new-components/</feedburner:origLink></item>
		<item>
		<title>Blog, and comments launched for On My Doorstep…</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/K31Y8x_qx_0/</link>
		<comments>http://www.richardnichols.net/2010/06/blog-and-comments-launched-for-on-my-doorstep/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 10:49:11 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=446</guid>
		<description><![CDATA[I&#8217;ve been busy the past couple of weeks building out some major new features for onmydoorstep.com.au So, I&#8217;m proud to present the On My Doorstep Blog and the addition of comments / discussion features across the entire site. Building a &#8230; <a href="http://www.richardnichols.net/2010/06/blog-and-comments-launched-for-on-my-doorstep/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/05/onmydoorstep-com-au-officially-launched/' rel='bookmark' title='Permanent Link: onmydoorstep.com.au &#8211; officially launched!'>onmydoorstep.com.au &#8211; officially launched!</a></li>
<li><a href='http://www.richardnichols.net/2010/06/visural-wicket-0-6-released-new-components/' rel='bookmark' title='Permanent Link: visural-wicket 0.6 released &#8211; lots of new components!'>visural-wicket 0.6 released &#8211; lots of new components!</a></li>
<li><a href='http://www.richardnichols.net/2010/02/visural-wicket-0-5-released-ready-for-action/' rel='bookmark' title='Permanent Link: visural-wicket 0.5 released &#8211; ready for action!'>visural-wicket 0.5 released &#8211; ready for action!</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been busy the past couple of weeks building out some major new features for onmydoorstep.com.au</p>
<p>So, I&#8217;m proud to present the <a href="http://www.onmydoorstep.com.au/news">On My Doorstep Blog</a> and the addition of comments / discussion features across the entire site.</p>
<p>Building a blog and commenting system in Wicket was a pleasure, and a smooth development process. I know, I know; creating a blog isn&#8217;t exactly rocket science, but I continue to be impressed with the speed and ease with which it is possible to build out, componentize and refactor major features using Wicket. I have a hard time imagining going back to a Model-2 type web framework. I think it would feel like writing in assembly again.</p>
<p>I&#8217;ve also using the wicketstuff-rome integration for the RSS feed features.</p>
<p>The site also recently introduced Facebook profile picture and Gravatar integration (for people not using Facebook Connect).</p>
<p>Anyhow, subscribe to the RSS feed &#038; stay tuned for more updates coming soon! <img src='http://d3araz99qvcc8b.cloudfront.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Also hard at work on <strong>visural-wicket 0.6</strong>, should be out sometime this week or next.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2Fblog-and-comments-launched-for-on-my-doorstep%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2Fblog-and-comments-launched-for-on-my-doorstep%2F&amp;source=rn_tweets&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/05/onmydoorstep-com-au-officially-launched/' rel='bookmark' title='Permanent Link: onmydoorstep.com.au &#8211; officially launched!'>onmydoorstep.com.au &#8211; officially launched!</a></li>
<li><a href='http://www.richardnichols.net/2010/06/visural-wicket-0-6-released-new-components/' rel='bookmark' title='Permanent Link: visural-wicket 0.6 released &#8211; lots of new components!'>visural-wicket 0.6 released &#8211; lots of new components!</a></li>
<li><a href='http://www.richardnichols.net/2010/02/visural-wicket-0-5-released-ready-for-action/' rel='bookmark' title='Permanent Link: visural-wicket 0.5 released &#8211; ready for action!'>visural-wicket 0.5 released &#8211; ready for action!</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=K31Y8x_qx_0:JGzEAOvW8YM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=K31Y8x_qx_0:JGzEAOvW8YM:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=K31Y8x_qx_0:JGzEAOvW8YM:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=K31Y8x_qx_0:JGzEAOvW8YM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=K31Y8x_qx_0:JGzEAOvW8YM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=K31Y8x_qx_0:JGzEAOvW8YM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=K31Y8x_qx_0:JGzEAOvW8YM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=K31Y8x_qx_0:JGzEAOvW8YM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=K31Y8x_qx_0:JGzEAOvW8YM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=K31Y8x_qx_0:JGzEAOvW8YM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=K31Y8x_qx_0:JGzEAOvW8YM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=K31Y8x_qx_0:JGzEAOvW8YM:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/06/blog-and-comments-launched-for-on-my-doorstep/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/06/blog-and-comments-launched-for-on-my-doorstep/</feedburner:origLink></item>
		<item>
		<title>Bernerd and Mac in a Brand New Bag</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/CuLi1SaEXV8/</link>
		<comments>http://www.richardnichols.net/2010/06/so-i-was-an-animator/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 12:37:00 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[about-me]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[art]]></category>
		<category><![CDATA[off-topic]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=431</guid>
		<description><![CDATA[There was a time around 6-7 years ago, I doubted whether I wanted to spend my life building software and working on technology. I have always had a fond love of animation and art, and so I undertook a 3D &#8230; <a href="http://www.richardnichols.net/2010/06/so-i-was-an-animator/">Continue reading <span class="meta-nav">&#8594;</span></a>


No related posts.]]></description>
			<content:encoded><![CDATA[<p>There was a time around 6-7 years ago, I doubted whether I wanted to spend my life building software and working on technology. I have always had a fond love of animation and art, and so I undertook a 3D animation course part time, and started spending most of my spare time on cgtalk.com and creating digital art.</p>
<p>I had a great time, and even went so far as to take the step of changing careers. I quit IBM in mid 2005 to take a job as a freelance animator on a production being run from Sydney. This only lasted a few weeks though before they let me go, stating that they didn&#8217;t feel the remote working arrangement was working. I then went back to work for a past client part-time and kept working on animation in my spare time. I had a job offer to relocate to work for an advertising agency, but the low pay and move away from family and friends led me to turn it down.</p>
<p><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/sf2aTrVxxEw&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/sf2aTrVxxEw&#038;fs=1" type="application/x-shockwave-flash" width="640" height="505" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>My part time course finished at the end of 2004, and culminated in Bernerd and Mac &#8211; my first animation short which I produced from start to finish. It&#8217;s fairly underwhelming to look at now, but I was proud of it at the time and I still look at back at it with fondness. For those not familiar with the animation process, creating an animated short single-handed is not a trivial (or fast) thing. Most people specialise in only one part of the overall process, and creating a short by yourself requires general skills across the board.</p>
<p>I&#8217;m posting the movie here and on Youtube, more for myself so I can look back on it every now and again when I&#8217;m feeling nostalgic. I&#8217;ll be posting some of the later work I did over the coming months as I dig it up.</p>
<p>I&#8217;m still hoping to get back to animation at a later date when I have more spare time. When I stopped working on animation stuff in late 2006 I was half way through production of a far more ambitious short film. I&#8217;d done all the design, built the 3D sets, characters, recorded the voices and was in the process of building out the animatic when I found my engineering &#8220;mojo&#8221; again. Since then I&#8217;ve been busy coding, but I&#8217;d like to get back and finish that project one day though.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2Fso-i-was-an-animator%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2Fso-i-was-an-animator%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=about-me,animation,art,off-topic" height="61" width="50" /><br />
			</a>
		</div>


<p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=CuLi1SaEXV8:BRqwD4UMg7k:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=CuLi1SaEXV8:BRqwD4UMg7k:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=CuLi1SaEXV8:BRqwD4UMg7k:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=CuLi1SaEXV8:BRqwD4UMg7k:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=CuLi1SaEXV8:BRqwD4UMg7k:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=CuLi1SaEXV8:BRqwD4UMg7k:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=CuLi1SaEXV8:BRqwD4UMg7k:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=CuLi1SaEXV8:BRqwD4UMg7k:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=CuLi1SaEXV8:BRqwD4UMg7k:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=CuLi1SaEXV8:BRqwD4UMg7k:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=CuLi1SaEXV8:BRqwD4UMg7k:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=CuLi1SaEXV8:BRqwD4UMg7k:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/06/so-i-was-an-animator/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/06/so-i-was-an-animator/</feedburner:origLink></item>
		<item>
		<title>301 Redirects Made Easy In Java</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/kVCjpIF02ck/</link>
		<comments>http://www.richardnichols.net/2010/06/301-redirects-made-easy-in-java/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 10:55:31 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[seo]]></category>
		<category><![CDATA[visural-common]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=386</guid>
		<description><![CDATA[I&#8217;ve just released a new version of visural-common &#8211; 0.3.2. This version includes a new Servlet Filter, which makes 301-redirects in Java a breeze. You&#8217;d recall that 301 redirects are useful for SEO (and just general good practice) for when &#8230; <a href="http://www.richardnichols.net/2010/06/301-redirects-made-easy-in-java/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/05/aop-annotation-based-caching-solution-for-guice-projects/' rel='bookmark' title='Permanent Link: AOP, Annotation-based caching solution for Guice projects&#8230;'>AOP, Annotation-based caching solution for Guice projects&#8230;</a></li>
<li><a href='http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/' rel='bookmark' title='Permanent Link: ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!'>ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!</a></li>
<li><a href='http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/' rel='bookmark' title='Permanent Link: Implementing Facebook OAuth 2.0 Authentication in Java'>Implementing Facebook OAuth 2.0 Authentication in Java</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just released a new version of <a href="http://code.google.com/p/visural-common/" target="_blank">visural-common</a> &#8211; 0.3.2.</p>
<p>This version includes a new Servlet Filter, which makes 301-redirects in Java a breeze.</p>
<p>You&#8217;d recall that 301 redirects are useful for SEO (and just general good practice) for when you move content to another place, or to create a &#8220;canonical&#8221; version of a piece of content. <a href="http://twitter.com/mattcutts" target="_blank">Matt Cutt</a>&#8216;s has done a few posts about 301 vs. 302 redirects and when you should use each, <a href="http://www.mattcutts.com/blog/seo-advice-url-canonicalization/" target="_blank">but this post</a> pretty much summarizes the use-case for this filter.</p>
<p>Using the filter is easy, just create a class that extends from <a href="http://code.google.com/p/visural-common/source/browse/trunk/visural-common/src/com/visural/common/web/filter/PermanentRedirectFilter.java" target="_blank"><span class="pln"> </span></a><span class="typ"><a href="http://code.google.com/p/visural-common/source/browse/trunk/visural-common/src/com/visural/common/web/filter/PermanentRedirectFilter.java" target="_blank">PermanentRedirectFilter</a>:</span></p>
<pre class="prettyprint">public class MyRedirect extends PermanentRedirectFilter {
    public void configureRoutes() {
        // ... your config goes in here ...
        // e.g.
        fromHost("mydomain.com").to("www.mydomain.com");

        // urls work too
        fromURL("http://www.mydomain.com/index.jsp")
             .to("http://www.mydomain.com/");

        fromURL("http://www.mydomain.com/blog/post.jsp?p=123")
            .to("http://www.mydomain.com/blog/2010/06/how-to-do-301-redirects-in-java");

        // you could also use this to move your domain to another place altogether.
        // The same page url and parameters will be used after the host.
        fromHost("www.myolddomain.com").to("www.other.com");
    }
}
</pre>
<p>Pretty easy and efficient syntax.</p>
<p>You&#8217;ll then want to add this to your web.xml in the usual way for configuring a filter, e.g.:</p>
<pre>
    &lt;filter&gt;
        &lt;filter-name&gt;MyRedirectFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;com.mycom.MyRedirectFilter&lt;/filter-class&gt;
    &lt;/filter&gt;
    &lt;filter-mapping&gt;
        &lt;filter-name&gt;MyRedirectFilter&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
    &lt;/filter-mapping&gt;
</pre>
<p>Done and done &#8211; that&#8217;s all there is to it.</p>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2F301-redirects-made-easy-in-java%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F06%2F301-redirects-made-easy-in-java%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=Google,Java,open-source,seo,visural-common,web" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/05/aop-annotation-based-caching-solution-for-guice-projects/' rel='bookmark' title='Permanent Link: AOP, Annotation-based caching solution for Guice projects&#8230;'>AOP, Annotation-based caching solution for Guice projects&#8230;</a></li>
<li><a href='http://www.richardnichols.net/2010/07/java-web-datauris-lesscss-javascript-css-compression/' rel='bookmark' title='Permanent Link: ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!'>ResourceTransformFilter &#8211; DataUris, LessCSS, Javascript and CSS Compression Made Easy!</a></li>
<li><a href='http://www.richardnichols.net/2010/06/implementing-facebook-oauth-2-0-authentication-in-java/' rel='bookmark' title='Permanent Link: Implementing Facebook OAuth 2.0 Authentication in Java'>Implementing Facebook OAuth 2.0 Authentication in Java</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=kVCjpIF02ck:lrJ4BZVtnr0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=kVCjpIF02ck:lrJ4BZVtnr0:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=kVCjpIF02ck:lrJ4BZVtnr0:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=kVCjpIF02ck:lrJ4BZVtnr0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=kVCjpIF02ck:lrJ4BZVtnr0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=kVCjpIF02ck:lrJ4BZVtnr0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=kVCjpIF02ck:lrJ4BZVtnr0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=kVCjpIF02ck:lrJ4BZVtnr0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=kVCjpIF02ck:lrJ4BZVtnr0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=kVCjpIF02ck:lrJ4BZVtnr0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=kVCjpIF02ck:lrJ4BZVtnr0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=kVCjpIF02ck:lrJ4BZVtnr0:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/06/301-redirects-made-easy-in-java/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/06/301-redirects-made-easy-in-java/</feedburner:origLink></item>
		<item>
		<title>AOP, Annotation-based caching solution for Guice projects…</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/V2LVxpq44hE/</link>
		<comments>http://www.richardnichols.net/2010/05/aop-annotation-based-caching-solution-for-guice-projects/#comments</comments>
		<pubDate>Tue, 25 May 2010 02:23:58 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[guice]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[visural-common]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=376</guid>
		<description><![CDATA[I just released a new version of the visural-common library (0.3.1) which includes support for a simple, flexible annotation based cache, for non-distributed projects. Why non-distributed projects? Unlike most other caching libraries I don&#8217;t offer integrations with ehcache or other &#8230; <a href="http://www.richardnichols.net/2010/05/aop-annotation-based-caching-solution-for-guice-projects/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/' rel='bookmark' title='Permanent Link: Clustering Guice Java Web Applications'>Clustering Guice Java Web Applications</a></li>
<li><a href='http://www.richardnichols.net/2009/06/the-5-minute-guice-primer/' rel='bookmark' title='Permanent Link: The 5 Minute Guice Primer'>The 5 Minute Guice Primer</a></li>
<li><a href='http://www.richardnichols.net/2010/06/301-redirects-made-easy-in-java/' rel='bookmark' title='Permanent Link: 301 Redirects Made Easy In Java'>301 Redirects Made Easy In Java</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I just released a new version of the visural-common library (0.3.1) which includes support for a simple, flexible annotation based cache, for non-distributed projects.</p>
<p>Why non-distributed projects? </p>
<p>Unlike most other caching libraries I don&#8217;t offer integrations with ehcache or other high-end caching solutions. This is an all-in-one-solution, which offers in-instance caching. </p>
<p>By that I mean caching that is scoped only with an object instance. This is particularly useful in situations where you have code which is scoped in &#8220;request&#8221; or &#8220;session&#8221; scope with Guice. It may not be appropriate to cache across all instances (like with a &#8220;service pattern&#8221;).</p>
<p>Anyhow, here&#8217;s an example of what this solution looks like:</p>
<pre class="prettyprint">
    @Cache(maxEntries=10000, timeToLive=5000)
    public myExpensiveOperation(Object arg1, Object arg2) {
        // do some expensive stuff, e.g. database read
    }
</pre>
<p>To enable it you need to implement the &#8220;Cacheable&#8221; interface. There are 3 basic ways to do this:</p>
<pre class="prettyprint">

class CacheService extends AbstractCacheable {
    // .....
}

class CacheService implements Cacheable {

    private transient CacheData data;

    public CacheData __cacheData() {
        return data;
    }

    @Inject
    public void __cacheData(CacheData data) {
        this.data = data;
    }

    // .....
}

public class CacheService implements Cacheable {

    private final CacheData data;

    @Inject
    protected CacheService(CacheData data) {
        this.data = data;
    }

    public CacheData __cacheData() {
        return data;
    }

    // .....
}
</pre>
<p>If you&#8217;re already using Guice, it&#8217;s a pretty simple, low dependency and easy to configure solution for caching.</p>
<p>For the full details head on over to the <a href="http://code.google.com/p/visural-common/wiki/Guice_AOP_Cache">visural-common wiki&#8230;</a>
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F05%2Faop-annotation-based-caching-solution-for-guice-projects%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F05%2Faop-annotation-based-caching-solution-for-guice-projects%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=caching,Google,guice,Java,open-source,visural-common" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/09/session-replication-with-guice-java-web-applications/' rel='bookmark' title='Permanent Link: Clustering Guice Java Web Applications'>Clustering Guice Java Web Applications</a></li>
<li><a href='http://www.richardnichols.net/2009/06/the-5-minute-guice-primer/' rel='bookmark' title='Permanent Link: The 5 Minute Guice Primer'>The 5 Minute Guice Primer</a></li>
<li><a href='http://www.richardnichols.net/2010/06/301-redirects-made-easy-in-java/' rel='bookmark' title='Permanent Link: 301 Redirects Made Easy In Java'>301 Redirects Made Easy In Java</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=V2LVxpq44hE:vxOiZxnVxlA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=V2LVxpq44hE:vxOiZxnVxlA:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=V2LVxpq44hE:vxOiZxnVxlA:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=V2LVxpq44hE:vxOiZxnVxlA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=V2LVxpq44hE:vxOiZxnVxlA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=V2LVxpq44hE:vxOiZxnVxlA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=V2LVxpq44hE:vxOiZxnVxlA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=V2LVxpq44hE:vxOiZxnVxlA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=V2LVxpq44hE:vxOiZxnVxlA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=V2LVxpq44hE:vxOiZxnVxlA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=V2LVxpq44hE:vxOiZxnVxlA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=V2LVxpq44hE:vxOiZxnVxlA:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/05/aop-annotation-based-caching-solution-for-guice-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/05/aop-annotation-based-caching-solution-for-guice-projects/</feedburner:origLink></item>
		<item>
		<title>onmydoorstep.com.au – officially launched!</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/63KY3ck4OmA/</link>
		<comments>http://www.richardnichols.net/2010/05/onmydoorstep-com-au-officially-launched/#comments</comments>
		<pubDate>Mon, 24 May 2010 10:37:58 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[guice]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[onmydoorstep]]></category>
		<category><![CDATA[warp-persist]]></category>
		<category><![CDATA[wicket]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=373</guid>
		<description><![CDATA[So as of tonight, onmydoorstep.com.au is officially launched! What does that mean? Basically I&#8217;m just telling anyone who&#8217;ll listen, about it. This site represents around 3 months work, in spare time and on weekends. It&#8217;s the reason my blog posts &#8230; <a href="http://www.richardnichols.net/2010/05/onmydoorstep-com-au-officially-launched/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/06/blog-and-comments-launched-for-on-my-doorstep/' rel='bookmark' title='Permanent Link: Blog, and comments launched for On My Doorstep&#8230;'>Blog, and comments launched for On My Doorstep&#8230;</a></li>
<li><a href='http://www.richardnichols.net/2009/08/using-bottom-up-iterative-object-database-layer-with-hbm2java-and-warp-persist/' rel='bookmark' title='Permanent Link: Using Bottom-Up Iterative Object/Database Layer With hbm2java and warp-persist'>Using Bottom-Up Iterative Object/Database Layer With hbm2java and warp-persist</a></li>
<li><a href='http://www.richardnichols.net/2010/02/visural-wicket-0-5-released-ready-for-action/' rel='bookmark' title='Permanent Link: visural-wicket 0.5 released &#8211; ready for action!'>visural-wicket 0.5 released &#8211; ready for action!</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>So as of tonight, <a href="http://www.onmydoorstep.com.au/" target="_blank">onmydoorstep.com.au</a> is officially launched!</p>
<p>What does that mean?</p>
<p>Basically I&#8217;m just telling anyone who&#8217;ll listen, about it.</p>
<p>This site represents around 3 months work, in spare time and on weekends. It&#8217;s the reason my blog posts have been sporadic, I haven&#8217;t been going to the gym and I haven&#8217;t spent enough time relaxing.</p>
<p>The site was designed for the <a href="http://www.premier.vic.gov.au/app-my-state.html" target="_blank">AppMyState</a> competition, run by the Premier of Victoria&#8217;s office. The idea is to encourage innovation in apps for the benefit of Victorians.</p>
<p>You can read more about the ideas behind the site at the <a href="http://onmydoorstep.com.au/about">about page</a>.</p>
<p>The site was built with Apache Wicket, Google Guice, warp-persist/JPA/Hibernate,  <a href="http://code.google.com/p/visural-wicket/" target="_blank">visural-wicket</a> and PostgreSQL.</p>
<p>I dabbled with MongoDB (thought I&#8217;d see what all this NoSQL hype was about) for a week or two, but ended up retiring it in favour of a more familiar and tested stack. I also persevered with Google App Engine + Wicket for the first month or so, but that turned out to not be a great match.</p>
<p>I&#8217;m intending to cover some of the development issues / adventures I had along the way in some future blog posts, but in the mean time &#8211; check out the site! <img src='http://d3araz99qvcc8b.cloudfront.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F05%2Fonmydoorstep-com-au-officially-launched%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F05%2Fonmydoorstep-com-au-officially-launched%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=guice,Java,jpa,onmydoorstep,warp-persist,wicket" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/06/blog-and-comments-launched-for-on-my-doorstep/' rel='bookmark' title='Permanent Link: Blog, and comments launched for On My Doorstep&#8230;'>Blog, and comments launched for On My Doorstep&#8230;</a></li>
<li><a href='http://www.richardnichols.net/2009/08/using-bottom-up-iterative-object-database-layer-with-hbm2java-and-warp-persist/' rel='bookmark' title='Permanent Link: Using Bottom-Up Iterative Object/Database Layer With hbm2java and warp-persist'>Using Bottom-Up Iterative Object/Database Layer With hbm2java and warp-persist</a></li>
<li><a href='http://www.richardnichols.net/2010/02/visural-wicket-0-5-released-ready-for-action/' rel='bookmark' title='Permanent Link: visural-wicket 0.5 released &#8211; ready for action!'>visural-wicket 0.5 released &#8211; ready for action!</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=63KY3ck4OmA:f9vk1GVkMXE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=63KY3ck4OmA:f9vk1GVkMXE:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=63KY3ck4OmA:f9vk1GVkMXE:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=63KY3ck4OmA:f9vk1GVkMXE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=63KY3ck4OmA:f9vk1GVkMXE:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=63KY3ck4OmA:f9vk1GVkMXE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=63KY3ck4OmA:f9vk1GVkMXE:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=63KY3ck4OmA:f9vk1GVkMXE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=63KY3ck4OmA:f9vk1GVkMXE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=63KY3ck4OmA:f9vk1GVkMXE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=63KY3ck4OmA:f9vk1GVkMXE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=63KY3ck4OmA:f9vk1GVkMXE:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/05/onmydoorstep-com-au-officially-launched/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/05/onmydoorstep-com-au-officially-launched/</feedburner:origLink></item>
		<item>
		<title>Roundup – Royalty Free Icons and Images for Web Developers</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/wxab4SEXxd0/</link>
		<comments>http://www.richardnichols.net/2010/04/royalty-free-icons-and-images-for-web-applications/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 04:04:28 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[guides]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=340</guid>
		<description><![CDATA[We all need, &#8216;em &#8211; quality icons and images for websites and applications. One of the biggest problems is finding packs that are - Consistently high quality Have a consistent look and feel There&#8217;s little point in have a hodge-podge &#8230; <a href="http://www.richardnichols.net/2010/04/royalty-free-icons-and-images-for-web-applications/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/08/5-minute-guide-clustering-apache-tomcat/' rel='bookmark' title='Permanent Link: 5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat'>5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>We all need, &#8216;em &#8211; quality icons and images for websites and applications.</p>
<p>One of the biggest problems is finding packs that are -</p>
<ul>
<li>Consistently high quality</li>
<li>Have a consistent look and feel</li>
</ul>
<p>There&#8217;s little point in have a hodge-podge of different image flavours across the site, like some sort of <strong>acid-induced Web 2.0 Geocities flash-back</strong>.</p>
<p>So here&#8217;s the best that I&#8217;ve found &#8211; post any I&#8217;ve missed in the comments!</p>
<h2>Yusuke Kamiyamane&#8217;s &#8220;Fugue&#8221; and &#8220;Diagona&#8221; Packs</h2>
<p><a href="http://p.yusukekamiyamane.com/" target="_blank">http://p.yusukekamiyamane.com/</a><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_fugue.png"><img class="alignright size-thumbnail wp-image-353" title="im_fugue" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_fugue-150x150.png" alt="" width="150" height="150" /></a></p>
<p>Don&#8217;t let the pink background put you off, these packs are fantastic. In fact, they&#8217;re so good you&#8217;ve probably seen them before&#8230; all over the web.</p>
<p>They are CC 3.0 Attribution licenced, and you can buy a full commercial licence for a paltry <strong>$60 USD</strong>. A huge set of quality and consistent icons. Yum!</p>
<h2>Tango Desktop Project Pack</h2>
<p><a href="http://tango.freedesktop.org/Tango_Desktop_Project" target="_blank">http://tango.freedesktop.org/Tango_Desktop_Project</a><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_tango.jpg"><img class="alignright size-thumbnail wp-image-354" title="im_tango" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_tango-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>The Tango project is an open source initiative to provide a set of consistent high-res, quality icons for use in Linux desktop window managers and applications. The project has a style and standards guide which means the icons have a consistent quality and feel.</p>
<p>And they are released into the Public Domain, so you can use them however you wish!</p>
<h2>FamFamFam Silk Icon Pack</h2>
<p><a href="http://www.famfamfam.com/lab/icons/silk/" target="_blank">http://www.famfamfam.com/lab/icons/silk/</a><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_silk.jpg"><img class="alignright size-thumbnail wp-image-355" title="im_silk" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_silk-150x54.jpg" alt="" width="150" height="54" /></a></p>
<p>You definitely seen these before too, all across the Web and in a whole bunch of open-source (and non-open source apps).</p>
<p>They were pretty much the best until the &#8220;Fugue&#8221; pack above came along, but they&#8217;ve still got their place and mix quite well with the Fugue pack anyhow.</p>
<p>Licenced under CC 2.5 and CC 3.0 Attribution.</p>
<h2>Dynamic Drive Favicon Generator</h2>
<p><a href="http://tools.dynamicdrive.com/favicon/" target="_blank">http://tools.dynamicdrive.com/favicon/</a><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_fav.jpg"><img class="alignright size-thumbnail wp-image-356" title="im_fav" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_fav-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>Not a pack of images as such, but generating a <a href="http://en.wikipedia.org/wiki/Favicon" target="_blank">favicon </a>is something that needs to be done by most sites at some stage. Dynamic Drives tool gets you a pretty good favicon 99% of the time, with very little graphic design effort.</p>
<p>Handy!</p>
<h2>Smashing Magazine Freebies</h2>
<p><a href="http://www.smashingmagazine.com/tag/freebies/" target="_blank">http://www.smashingmagazine.com/tag/freebies/</a><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_flavour.jpg"><img class="alignright size-thumbnail wp-image-357" title="im_flavour" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_flavour-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>Smashing Magazine (other than being a pretty good design blog) regularly publishes high quality freebies, in the form of icon packs, images and themes (e.g. for WordPress). They are generally to give exposure to a given designer and made available for any sort of commercial or non-commercial endeavor.</p>
<p>In particular <a href="http://www.smashingmagazine.com/2009/05/20/flavour-extended-the-ultimate-icon-set-for-web-designers/" target="_blank">the &#8220;Flavour&#8221; icon pack</a> is very nice, but I&#8217;d highly recommend mining their archives as they have some very good &#8220;domain specific&#8221; icon and vector packs.</p>
<h2>$99 Designs, $99 Logo Store</h2>
<p><a href="http://99designs.com/logo-design/store" target="_blank">http://99designs.com/logo-design/store</a><a href="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_99.jpg"><img class="alignright size-thumbnail wp-image-358" title="im_99" src="http://d3araz99qvcc8b.cloudfront.net/wp-content/uploads/2010/04/im_99-150x150.jpg" alt="" width="150" height="150" /></a> </p>
<p>Of all the graphic resources in your app, your logo is probably the most important. It&#8217;s your branding, your ID and the way you build association with your users.</p>
<p>If you&#8217;re designing on a budget, or building something as an experiment, then $99 is not much to spend on a high-quality and professional logo for your site. Having bought two logos from the site and having them customized to my request within the day, I&#8217;d say this is a great one-stop shop for getting something in place that will serve you well until you really need to spend more on it.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F04%2Froyalty-free-icons-and-images-for-web-applications%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F04%2Froyalty-free-icons-and-images-for-web-applications%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=Design,guides,images,tips" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/08/5-minute-guide-clustering-apache-tomcat/' rel='bookmark' title='Permanent Link: 5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat'>5 Minute Guide to Clustering &#8211; Java Web Apps in Tomcat</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=wxab4SEXxd0:6CEJw9g2i7M:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=wxab4SEXxd0:6CEJw9g2i7M:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=wxab4SEXxd0:6CEJw9g2i7M:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=wxab4SEXxd0:6CEJw9g2i7M:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=wxab4SEXxd0:6CEJw9g2i7M:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=wxab4SEXxd0:6CEJw9g2i7M:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=wxab4SEXxd0:6CEJw9g2i7M:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=wxab4SEXxd0:6CEJw9g2i7M:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=wxab4SEXxd0:6CEJw9g2i7M:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=wxab4SEXxd0:6CEJw9g2i7M:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=wxab4SEXxd0:6CEJw9g2i7M:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=wxab4SEXxd0:6CEJw9g2i7M:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/04/royalty-free-icons-and-images-for-web-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/04/royalty-free-icons-and-images-for-web-applications/</feedburner:origLink></item>
		<item>
		<title>OraDocletPlus – enhanced Oracle DB documentation generator released</title>
		<link>http://feedproxy.google.com/~r/PragmaticCoder/~3/fdahu720Lxs/</link>
		<comments>http://www.richardnichols.net/2010/04/oradocletplus-enhanced-oracle-db-documentation-generator-released/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 12:04:28 +0000</pubDate>
		<dc:creator>Richard Nichols</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[doclet]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://www.richardnichols.net/?p=350</guid>
		<description><![CDATA[I just finished testing and packaging OraDocletPlus - a modified version of the OraDoclet DB documentation tool for Oracle. The main differences with this version over the original are one or two bugs fixed and a revamp to bring the &#8230; <a href="http://www.richardnichols.net/2010/04/oradocletplus-enhanced-oracle-db-documentation-generator-released/">Continue reading <span class="meta-nav">&#8594;</span></a>


Related posts:<ol><li><a href='http://www.richardnichols.net/2010/06/visural-wicket-0-6-released-new-components/' rel='bookmark' title='Permanent Link: visural-wicket 0.6 released &#8211; lots of new components!'>visural-wicket 0.6 released &#8211; lots of new components!</a></li>
<li><a href='http://www.richardnichols.net/2010/02/visural-wicket-0-5-released-ready-for-action/' rel='bookmark' title='Permanent Link: visural-wicket 0.5 released &#8211; ready for action!'>visural-wicket 0.5 released &#8211; ready for action!</a></li>
<li><a href='http://www.richardnichols.net/2009/06/markdown-doclet-for-javadoc/' rel='bookmark' title='Permanent Link: Markdown Doclet for Javadoc'>Markdown Doclet for Javadoc</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I just finished testing and packaging <a href="http://www.richardnichols.net/open-source/oradocletplus/">OraDocletPlus </a>- a modified version of the <a href="http://oradoclet.sourceforge.net/">OraDoclet </a>DB documentation tool for Oracle.</p>
<p>The main differences with this version over the original are one or two bugs fixed and a revamp to bring the output (almost) up to 2010 standards. The original output was pretty hard to read.</p>
<p>For the full story, head on over to the <a href="http://www.richardnichols.net/open-source/oradocletplus/">OraDocletPlus </a>page.</p>
<p>Feel free to download / modify / restyle this version as you see fit. I threw this together as a quick and dirty solution to an urgent need to generate some DB documentation, but it&#8217;s still a pretty nice solution if you were to implement it into your build process (e.g. in Hudson or similar).
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F04%2Foradocletplus-enhanced-oracle-db-documentation-generator-released%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.richardnichols.net%2F2010%2F04%2Foradocletplus-enhanced-oracle-db-documentation-generator-released%2F&amp;source=rn_tweets&amp;style=normal&amp;hashtags=automation,database,doclet,documentation,open-source,oracle" height="61" width="50" /><br />
			</a>
		</div>


<p>Related posts:<ol><li><a href='http://www.richardnichols.net/2010/06/visural-wicket-0-6-released-new-components/' rel='bookmark' title='Permanent Link: visural-wicket 0.6 released &#8211; lots of new components!'>visural-wicket 0.6 released &#8211; lots of new components!</a></li>
<li><a href='http://www.richardnichols.net/2010/02/visural-wicket-0-5-released-ready-for-action/' rel='bookmark' title='Permanent Link: visural-wicket 0.5 released &#8211; ready for action!'>visural-wicket 0.5 released &#8211; ready for action!</a></li>
<li><a href='http://www.richardnichols.net/2009/06/markdown-doclet-for-javadoc/' rel='bookmark' title='Permanent Link: Markdown Doclet for Javadoc'>Markdown Doclet for Javadoc</a></li>
</ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fdahu720Lxs:D5qkXRrDcdA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fdahu720Lxs:D5qkXRrDcdA:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=fdahu720Lxs:D5qkXRrDcdA:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fdahu720Lxs:D5qkXRrDcdA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=fdahu720Lxs:D5qkXRrDcdA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fdahu720Lxs:D5qkXRrDcdA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=fdahu720Lxs:D5qkXRrDcdA:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fdahu720Lxs:D5qkXRrDcdA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=fdahu720Lxs:D5qkXRrDcdA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fdahu720Lxs:D5qkXRrDcdA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/PragmaticCoder?a=fdahu720Lxs:D5qkXRrDcdA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/PragmaticCoder?i=fdahu720Lxs:D5qkXRrDcdA:gIN9vFwOqvQ" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.richardnichols.net/2010/04/oradocletplus-enhanced-oracle-db-documentation-generator-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.richardnichols.net/2010/04/oradocletplus-enhanced-oracle-db-documentation-generator-released/</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced)
Content Delivery Network via Amazon Web Services: CloudFront: Amazon Web Services: S3: d3araz99qvcc8b.cloudfront.net

Served from: www.richardnichols.net @ 2010-09-01 13:15:43 -->
