<?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/" version="2.0">

<channel>
	<title>ioannis cherouvim</title>
	
	<link>http://blog.cherouvim.com</link>
	<description>software engineering for beginners</description>
	<lastBuildDate>Fri, 03 Sep 2010 06:44:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/cherouvim" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="cherouvim" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>modulating the throughput in JMeter for better longevity stress tests</title>
		<link>http://blog.cherouvim.com/modulating-the-throughput-in-jmeter-for-better-longevity-stress-tests/</link>
		<comments>http://blog.cherouvim.com/modulating-the-throughput-in-jmeter-for-better-longevity-stress-tests/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 19:08:50 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[jmeter]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=208</guid>
		<description><![CDATA[When running a longevity stress test with JMeter (a test which runs for many days) you may need to emulate a load which approximates the real traffic that the site is receiving in production. And that is definitelly not a steady and constant load during the duration of the full 24 hour cycle. Most normal [...]]]></description>
			<content:encoded><![CDATA[<p>When running a longevity stress test with JMeter (a test which runs for many days) you may need to emulate a load which approximates the real traffic that the site is receiving in production. And that is definitelly not a steady and constant load during the duration of the full 24 hour cycle.</p>
<p>Most normal sites (not twitter or facebook) tend to receive different amounts of traffic during a day. Although it depends on the nature of the site, usually the traffic will look like a <a href="http://en.wikipedia.org/wiki/Sine_wave">sine wave</a> with a wave length of 1 day. Even if it doesn&#8217;t look as smooth as a sine wave, a sine modulating throughput will be much better than testing with constant one. Having a constant throuput can mess up with the data you receive from the test since the application, db and o/s level caches and other systems of the stack (e.g the GC) may tune to the specific constant throughput.</p>
<p>So, first of all we need to setup some variables in the JMeter test.<br />
<img src="http://blog.cherouvim.com/wp-content/uploads/2010/09/1.png" alt="JMeter variables setup" title="JMeter variables setup" width="601" height="378" class="alignnone size-full wp-image-211" /><br />
Setting <code>oscillationsPerDay</code> to 1 is what we want.</p>
<p>Next we setup a Constant Throughput Timer to reference the hitsPerMinute variable. Note that the initial value of this variable doesn&#8217;t play any role since we&#8217;ll be constantly changing this via a bean shell script.<br />
<img src="http://blog.cherouvim.com/wp-content/uploads/2010/09/2.png" alt="JMeter Constant Throughput Timer" title="JMeter Constant Throughput Timer" width="601" height="381" class="alignnone size-full wp-image-210" /></p>
<p>Lastly we need a BeanShell PreProcessor with the following script:</p>
<pre>
// variables
double minHitsPerSec = Double.parseDouble(vars.get("minHitsPerSec"));
double maxHitsPerSec = Double.parseDouble(vars.get("maxHitsPerSec"));
double oscillationsPerDay  = Double.parseDouble(vars.get("oscillationsPerDay"));

// calculation
double oscillationFrequency = 1000L * 60 * 60 * 24 / oscillationsPerDay;
double range = maxHitsPerSec - minHitsPerSec;
double hitsPerSecond = Math.sin(System.currentTimeMillis()/oscillationFrequency*(Math.PI*2))*range/2+range/2+minHitsPerSec;

// set
vars.put("hitsPerMinute", String.valueOf(hitsPerSecond*60));

// log
log.info("throughput: " + hitsPerSecond + " hits per second, or " + vars.get("hitsPerMinute") + " hits per minute");
</pre>
<p>So this will generate a load which will modulate from <code>minHitsPerSec</code> to <code>maxHitsPerSec</code> for as many times per day you need. Of course, you can make the load and requests behavior more realistic by adding a <a href="http://jakarta.apache.org/jmeter/usermanual/component_reference.html#Gaussian_Random_Timer">Random Timer</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/modulating-the-throughput-in-jmeter-for-better-longevity-stress-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Disabling quartz and ehcache UpdateChecker</title>
		<link>http://blog.cherouvim.com/disabling-quartz-and-ehcache-update-checker/</link>
		<comments>http://blog.cherouvim.com/disabling-quartz-and-ehcache-update-checker/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 14:59:48 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[ehcache]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[quartz]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=193</guid>
		<description><![CDATA[Last year Terracotta acquired ehcache and quartz and it was all good an exciting news. The problem is that since then they&#8217;ve included an automatic update checker on these two libraries which is turned on by default! What this does is to connect to www.terracotta.org as soon as you bootstrap your application, send some info [...]]]></description>
			<content:encoded><![CDATA[<p>Last year Terracotta <a rel="nofollow" title="Terracotta acquires ehcache" href="http://www.terracotta.org/news/terracotta-aquires-ehcache">acquired ehcache</a> <a rel="nofollow" title="Terracotta acquires quartz" href="http://www.terracotta.org/news/terracotta-acquires-quartz">and quartz</a> and it was all good an exciting news. The problem is that since then they&#8217;ve included an automatic update checker on these two libraries which is turned on by default!</p>
<p>What this does is to connect to www.terracotta.org as soon as you bootstrap your application, send some info (!) and get a response back on whether you are currently using the latest version of the library.<br />
<img src="http://blog.cherouvim.com/wp-content/uploads/2010/08/quartz-ehcache-terracotta.png" alt="firewall complaining that a Java process wants to connect to www.terracotta.org" /></p>
<p>You&#8217;ll get something this on your logs for ehcache:</p>
<pre>
2010-08-16 11:18:04,794 DEBUG (UpdateChecker.java:68) - Checking for update...
2010-08-16 11:18:05,934 INFO  (UpdateChecker.java:98) - New update(s) found: 2.2.0 Please check http://ehcache.org for the latest version.
</pre>
<p>and for quartz:</p>
<pre>2010-08-16 11:15:58,218 DEBUG (UpdateChecker.java:56) - Checking for available updated version of Quartz...
2010-08-16 11:16:01,734 INFO  (UpdateChecker.java:86) - New Quartz update(s) found: 1.8.4 [http://www.terracotta.org/kit/reflector?kitID=default&#038;pageID=QuartzChangeLog]
</pre>
<p>Terracotta <a rel="nofollow" href="http://tech.puredanger.com/2010/07/28/open-source-bargain/">gives an explanation on why they did this</a> but no matter how you try it still makes your brain hurt and wonder what would happen if every vendor of Java libraries did this. Complete misery.</p>
<p>Disabling this check is <strong>highly recommended</strong> both on development and production.</p>
<p>For ehcache you need to add:</p>
<pre>
updateCheck="false"
</pre>
<p>in your ehcache.xml root element (&lt;ehcache&gt;) and:</p>
<pre>
org.quartz.scheduler.skipUpdateCheck=true
</pre>
<p>in your quartz.properties file.</p>
<p>More discussions:<br />
ehcache UpdateChecker: <a rel="nofollow" href="http://forums.terracotta.org/forums/posts/list/2701.page">http://forums.terracotta.org/forums/posts/list/2701.page</a><br />
quartz UpdateChecker: <a rel="nofollow" href="http://forums.terracotta.org/forums/posts/list/3395.page">http://forums.terracotta.org/forums/posts/list/3395.page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/disabling-quartz-and-ehcache-update-checker/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improved svn post-commit hook for hudson</title>
		<link>http://blog.cherouvim.com/improved-svn-post-commit-hook-for-hudson/</link>
		<comments>http://blog.cherouvim.com/improved-svn-post-commit-hook-for-hudson/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 08:48:59 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[hudson]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=187</guid>
		<description><![CDATA[Hudson&#8217;s wiki entry about the Subversion plugin explains how to setup a post-commit svn hook so commits trigger the hudson builds without the need of hudson to constantly poll the repository. The proposed post-commit hook implementation is good, but what happens when the svn server does not respond is that the commit takes place but [...]]]></description>
			<content:encoded><![CDATA[<p>Hudson&#8217;s <a href="http://wiki.hudson-ci.org/display/HUDSON/Subversion+Plugin">wiki entry about the Subversion plugin</a> explains how to setup a post-commit svn hook so commits trigger the hudson builds without the need of hudson to constantly poll the repository.</p>
<p>The proposed post-commit hook implementation is good, but what happens when the svn server does not respond is that the commit takes place but the hook blocks for ever. This can be confusing and annoying.</p>
<p>The svn server may not be able to respond because it may be down or can&#8217;t be reached. In any case, and as the <a href="http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing">Fallacies of Distributed Computing</a> explain, <em>the network is unreliable</em>, so a better approach is to add a timeout and retries setting on the command which attempts to notify svn:</p>
<pre>
REPOS="$1"
REV="$2"
UUID=`svnlook uuid $REPOS`
/usr/bin/wget \
  --timeout=2 \
  --tries=2 \
  --header "Content-Type:text/plain;charset=UTF-8" \
  --post-data "`svnlook changed --revision $REV $REPOS`" \
  --output-document "-" \

http://server/hudson/subversion/${UUID}/notifyCommit?rev=$REV
</pre>
<p>Wget will now fail if after 2 seconds the svn server hasn&#8217;t responded, and will try that twice. After that the user will get an error message but the commit will have been done.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/improved-svn-post-commit-hook-for-hudson/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrating from tomcat to weblogic</title>
		<link>http://blog.cherouvim.com/migrating-from-tomcat-to-weblogic/</link>
		<comments>http://blog.cherouvim.com/migrating-from-tomcat-to-weblogic/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 19:58:36 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[tomcat]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=171</guid>
		<description><![CDATA[Moving from tomcat to weblogic may sound crazy. In case you need to do it though (e.g for business reasons) here are a couple of things which may go wrong. First of all the classloader hierarchy in weblogic do not do what you usually expect from other servers such as tomcat, resin, jetty and jboss. [...]]]></description>
			<content:encoded><![CDATA[<p>Moving from <a href="http://tomcat.apache.org/">tomcat</a> to <a href="http://www.google.com/search?hl=en&#038;q=weblogic+server&#038;btnI=I">weblogic</a> may sound crazy. In case you need to do it though (e.g for business reasons) here are a couple of things which may go wrong.</p>
<p>First of all the classloader hierarchy in weblogic do not do what you usually expect from other servers such as tomcat, resin, jetty and jboss. If your application uses hibernate (and implicitly <a href="http://www.antlr.org/">ANTLR</a>) you may get the following exception:</p>
<pre>Caused by: java.lang.Throwable: Substituted for missing class org.hibernate.QueryException - ClassNotFoundException: org.hibernate.hql.ast.HqlToken [from com.example.model.Person order by id]
        at org.hibernate.hql.ast.HqlLexer.panic(HqlLexer.java:80)
        at antlr.CharScanner.setTokenObjectClass(CharScanner.java:340)
        at org.hibernate.hql.ast.HqlLexer.setTokenObjectClass(HqlLexer.java:54)
        at antlr.CharScanner.&lt;init&gt;(CharScanner.java:51)
        at antlr.CharScanner.&lt;init&gt;(CharScanner.java:60)
        at org.hibernate.hql.antlr.HqlBaseLexer.&lt;init&gt;(HqlBaseLexer.java:56)
...
</pre>
<p>As explained in the <a href="https://www.hibernate.org/250.html#A25">Hibernate3 Migration Guide</a> <q>Weblogic doesn&#8217;t seem to support proper class loader isolation, will not see the Hibernate classes in the application&#8217;s context</q> and will try to use it&#8217;s own version of ANTLR.</p>
<p>In the same fashion you may get the following exception for <a href="http://commons.apache.org/lang/">commons lang</a>:</p>
<pre>java.lang.NoSuchMethodError: org.apache.commons.lang.exception.ExceptionUtils.getMessage(Ljava/lang/Throwable;)Ljava/lang/String;</pre>
<p>because weblogic internally uses commons lang 2.1 and the one you use may have more API methods.</p>
<p>For both these problems the solution is to instruct weblogic to prefer the jars from the WEB-INF of your application. You need to create a weblogic specific file called <a href="http://www.google.com/search?hl=en&#038;q=weblogic.xml+Deployment+Descriptor+Elements&#038;btnI=I">weblogic.xml</a> and place it under WEB-INF:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;weblogic-web-app&gt;
    &lt;container-descriptor&gt;
        &lt;prefer-web-inf-classes&gt;true&lt;/prefer-web-inf-classes&gt;
    &lt;/container-descriptor&gt;
&lt;/weblogic-web-app&gt;</pre>
<p>Another problem is that, <a href="http://blog.cherouvim.com/default-servlet-and-resin/">like in resin</a>, the default servlet is not named &#8220;default&#8221; so if you depend on it in web.xml, your application may throw the following at the deployment phase:</p>
<pre>Caused by: weblogic.management.DeploymentException: [HTTP:101170]The servlet default is referenced in servlet-mapping *.avi, but not defined in web.xml.</pre>
<p>This is because the <a href="http://download.oracle.com/docs/cd/E13222_01/wls/docs92/webapp/configureservlet.html">default servlet is called FileServlet in the web.xml</a>, so you&#8217;ll need to change all references in your web.xml from &#8220;default&#8221; to &#8220;FileServlet&#8221;.</p>
<p>Last, but not least, tomcat will automatically issue a <a href="http://en.wikipedia.org/wiki/HTTP_302">302 redirect</a> from http://localhost:8080/context to http://localhost:8080/context/ before allowing your application to do any processing. So all instances of request.getServletPath() will never return an empty string, but will always start with &#8220;/&#8221;. Weblogic doesn&#8217;t do this so http://localhost:8080/context resolves and if your code contains something like:</p>
<pre>request.getServletPath().substring(1)</pre>
<p>you&#8217;ll get:</p>
<pre>
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
</pre>
<p>so a safer way to trim this leading slash is by doing:</p>
<pre>
request.getServletPath().replaceFirst("^/", "")
</pre>
<p>Good luck, and remember. Every time you use a full blown application server for something that a simple web container would be enough, <a href="http://images.google.com/images?q=god%20kills%20a%20kitten">god kills a kitten</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/migrating-from-tomcat-to-weblogic/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Retaining browser scrollTop between page refreshes</title>
		<link>http://blog.cherouvim.com/retaining-browser-scrolltop-between-page-refreshes/</link>
		<comments>http://blog.cherouvim.com/retaining-browser-scrolltop-between-page-refreshes/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 19:39:17 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=163</guid>
		<description><![CDATA[Sometimes when you develop web applications with CRUD pages and other backend functionalities you need retain the vertical scrollbar state between page loads. This gives the user a smoother experience, especially when your application doesn&#8217;t do any AJAX but it&#8217;s based of good old full HTML page request-responses. We&#8217;ll be using jQuery and the cookie [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes when you develop web applications with <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete"><abbr title="Create, Read, Update, Delete">CRUD</abbr></a> pages and other backend functionalities you need retain the vertical scrollbar state between page loads. This gives the user a smoother experience, especially when your application doesn&#8217;t do any <a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29"><abbr title="Asynchronous Javascript &amp; XML">AJAX</abbr></a> but it&#8217;s based of good old full HTML page request-responses.</p>
<p>We&#8217;ll be using <a href="http://jquery.com/">jQuery</a> and the <a href="http://plugins.jquery.com/project/cookie">cookie</a> plugin:</p>
<pre>
$(function(){
  // if current viewport height is at least 70% of the previous
  if ($(document.body).height()&gt;$.cookie('h2')*0.7)
    // retain previous scroll
    $('html,body').scrollTop($.cookie('h1'));
});
$(window).unload(function(){
  // store current scroll
  $.cookie('h1', $(window).scrollTop());
  // store current viewport height
  $.cookie('h2', $(document.body).height());
});
</pre>
<p>We can completely skip the h2 cookie and the if statement but this is an automatic way to prevent scrolling to the very bottom of a short page when coming from a long page. Such use case is common when jumping from the &#8220;long list of items&#8221; to the &#8220;edit an item&#8221; page.</p>
<p>Good luck</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/retaining-browser-scrolltop-between-page-refreshes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>clearing (or marking) MySQL slow query log</title>
		<link>http://blog.cherouvim.com/clearing-or-marking-mysql-slow-query-log/</link>
		<comments>http://blog.cherouvim.com/clearing-or-marking-mysql-slow-query-log/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 20:01:44 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[databases]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=150</guid>
		<description><![CDATA[The MySQL slow query log is a very useful feature which all applications in production should have enabled. It logs all queries which complete in more seconds than what the long_query_time server variable specifies. Sometimes you need to clear this log without restarting mysqld. You could simply erase the file (in Linux) but the file [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://dev.mysql.com/doc/refman/5.0/en/slow-query-log.html">MySQL slow query log</a> is a very useful feature which all applications in production should have enabled. It logs all queries which complete in more seconds than what the <a href="http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_long_query_time">long_query_time</a> server variable specifies.</p>
<p>Sometimes you need to clear this log without restarting mysqld. You could simply erase the file (in Linux) but the file handle would be lost and no further logging would take place.</p>
<p>The best way to purge the log <strong>in Linux</strong> without having to restart the server is:</p>
<pre>cat /dev/null > /path/to/logfile</pre>
<p>Another way is to erase or rename the logfile and then run the following statement in mysql:</p>
<pre>flush logs;</pre>
<p>references:<br />
<a href="http://bugs.mysql.com/bug.php?id=3337">http://bugs.mysql.com/bug.php?id=3337</a><br />
<a href="http://lists-archives.org/mysql/26837-purge-slow-query-log.html">http://lists-archives.org/mysql/26837-purge-slow-query-log.html</a></p>
<p>When you want to do that <strong>in Windows</strong> though things are different.</p>
<p>I haven&#8217;t yet found a way to safely remove the log file while mysqld is running. What I&#8217;m left with is to mark the current position in the slow query log so I can look it up and examine the log from that point onwards. The way this can be done is by executing a slow query (slow enough to be logged) and the safest of all looks like:</p>
<pre>
select "prod-25", sleep(4);
</pre>
<p>I can now quickly navigate to &#8220;prod-25&#8243; in the slow query log; which by the way is a marker of the 25th production release of a system which I&#8217;m tunning.</p>
<p>The deployment process could be automatically executing (probably via ant) such a marker query in order to keep all the historic (slow log) data grouped by releases for future analysis.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/clearing-or-marking-mysql-slow-query-log/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Simple DoS protection with mod_security</title>
		<link>http://blog.cherouvim.com/simple-dos-protection-with-mod_security/</link>
		<comments>http://blog.cherouvim.com/simple-dos-protection-with-mod_security/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 19:37:51 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[apache httpd]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=139</guid>
		<description><![CDATA[ModSecurity™ is an open source, free web application firewall (WAF) Apache module. It provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring and real-time analysis with little or no changes to existing infrastructure. It can do many things for you, such as detecting for XSS, SQL injection or [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.modsecurity.org/">ModSecurity™</a> is an open source, free web application firewall (WAF) Apache module. It provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring and real-time analysis with little or no changes to existing infrastructure.</p>
<p>It can do many things for you, such as detecting for <a href="http://en.wikipedia.org/wiki/Cross-site_scripting" title="Cross site scripting">XSS</a>, <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL injection</a> or <a href="http://www.owasp.org/index.php/Top_10_2007-A3">file inclusion</a> attacks.</p>
<p>A special use of mod_security can be simple protection from <a href="http://en.wikipedia.org/wiki/Denial-of-service_attack" title="Denial of service">DoS</a> attacks. Suppose your apache or application logs reveal that some specific IP is requesting too many pages per second (e.g 30 pages/sec from a single IP when your normal peak is 5 globally). In the best case scenario this could result in a slight decrease of the performance of the site which could be noticeable by the other users. In the worst case scenario it could bring the whole site down (denial of service). This attack could of course be unintentional. A misconfigured crawler or a spam bot could be the source of the problem, but in any case you&#8217;d like to block such requests.</p>
<p>Here is a possible configuration for mod_security to prevent those simple DoS attacks with explanatory comments:</p>
<pre>
SecRuleEngine On

SecAuditEngine RelevantOnly
SecAuditLogType Serial
SecAuditLog logs/mod_security.log

# a folder where mod_security will store data variables
SecDataDir logs/mod_security-data

# ignore requests from localhost or some other IP
SecRule REMOTE_ADDR "^127\.0\.0\.1$" "phase:1,nolog,allow"

# for all non static urls count requests per second per ip
# (increase var requests by one, expires in 1 second)
SecRule REQUEST_BASENAME "!(\.avi$|\.bmp$|\.css$|\.doc$|\.flv$|\.gif$|\
                            \.htm$|\.html$|\.ico$|\.jpg$|\.js$|\.mp3$|\
                            \.mpeg$|\.pdf$|\.png$|\.pps$|\.ppt$|\.swf$|\
                            \.txt$|\.wmv$|\.xls$|\.xml$|\.zip$)"\
                            "phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},setvar:ip.requests=+1,expirevar:ip.requests=1"

# if there where more than 5 requests per second for this IP
# set var block to 1 (expires in 5 seconds) and increase var blocks by one (expires in an hour)
SecRule ip:requests "@eq 5" "phase:1,pass,nolog,setvar:ip.block=1,expirevar:ip.block=5,setvar:ip.blocks=+1,expirevar:ip.blocks=3600"

# if user was blocked more than 5 times (var blocks&gt;5), log and return http 403
SecRule ip:blocks "@ge 5" "phase:1,deny,log,logdata:'req/sec: %{ip.requests}, blocks: %{ip.blocks}',status:403"

# if user is blocked (var block=1), log and return http 403
SecRule ip:block "@eq 1" "phase:1,deny,log,logdata:'req/sec: %{ip.requests}, blocks: %{ip.blocks}',status:403"

# 403 is some static page or message
ErrorDocument 403 "&lt;center&gt;&lt;h2&gt;take it easy yo!"
</pre>
<p>In case you experiment with this configuration on production make sure you keep an eye on mod_security.log to validate that you are really blocking out requests that you intend to.</p>
<p>Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/simple-dos-protection-with-mod_security/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>fixing javax.mail.MessagingException: Could not connect to SMTP host</title>
		<link>http://blog.cherouvim.com/fixing-javax-mail-messagingexception-could-not-connect-to-smtp-hos/</link>
		<comments>http://blog.cherouvim.com/fixing-javax-mail-messagingexception-could-not-connect-to-smtp-hos/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 18:59:21 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=132</guid>
		<description><![CDATA[You&#8217;ve done everything right. You are using of the JavaMail API with the correct settings and still it doesn&#8217;t manage to connect to the SMTP host to dispatch the email. You are on a windows machine and the exception looks like: javax.mail.MessagingException: Could not connect to SMTP host: your.smtp.host, port: 25; nested exception is: java.net.SocketException: [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;ve done everything right. You are using of the <a href="java.sun.com/products/javamail/">JavaMail API</a> with the correct settings and still it doesn&#8217;t manage to connect to the <a href="http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol" title="Simple Mail Transfer Protocol">SMTP</a> host to dispatch the email. You are on a windows machine and the exception looks like:</p>
<pre>
javax.mail.MessagingException: Could not connect to SMTP host: your.smtp.host, port: 25;
  nested exception is:
	java.net.SocketException: Software caused connection abort: connect
	at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1545)
	at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:453)
	at javax.mail.Service.connect(Service.java:291)
	at javax.mail.Service.connect(Service.java:172)
	at javax.mail.Service.connect(Service.java:121)
	at javax.mail.Transport.send0(Transport.java:190)
	at javax.mail.Transport.send(Transport.java:120)
        ...
Caused by: java.net.SocketException: Software caused connection abort: connect
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
	at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
	at java.net.Socket.connect(Socket.java:519)
	at java.net.Socket.connect(Socket.java:469)
	at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:267)
	at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:227)
	at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1511)
	... 40 more
</pre>
<p>One possibility is that something is blocking JavaMail from connecting to the local or a remote SMTP host, and this something can be <strong>an anti-virus</strong>.</p>
<p>via: <a href="http://forums.sun.com/thread.jspa?threadID=590866">http://forums.sun.com/thread.jspa?threadID=590866</a></p>
<p>p.s Why would a sysadmin want a resident shield anti-virus on a production box serving web content via tomcat still remains a mystery to me</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/fixing-javax-mail-messagingexception-could-not-connect-to-smtp-hos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>mod_expires and Cache Killers</title>
		<link>http://blog.cherouvim.com/mod_expires-and-cache-killers/</link>
		<comments>http://blog.cherouvim.com/mod_expires-and-cache-killers/#comments</comments>
		<pubDate>Sun, 03 May 2009 08:39:56 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[apache httpd]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=113</guid>
		<description><![CDATA[Rule 3 of Steve Souders&#8217; YSlow suggests that websites should Add a far future Expires header to the components. Components with a cache header could be static files such as those with extensions .css, .js, .jpg, .png, .gif etc. This gives a huge boost in client side performance of users with a primed cache. In [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://developer.yahoo.com/performance/rules.html#expires">Rule 3</a> of <a href="http://stevesouders.com/">Steve Souders&#8217;</a> <a href="http://developer.yahoo.com/yslow/">YSlow</a> suggests that websites should <cite>Add a far future Expires header to the components</cite>. Components with a cache header could be static files such as those with extensions .css, .js, .jpg, .png, .gif etc. This gives a huge boost in client side performance of users with a primed cache. In apache this is done via <a href="http://httpd.apache.org/docs/2.2/mod/mod_expires.html">mod_expires</a> and an example configuration would be:</p>
<pre>ExpiresActive On
ExpiresByType image/x-icon "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"</pre>
<p>All this works well until you need to update a cached static file. The users with the primed cache will either have to wait 1 month to get the new file, or explicitly invalidate their cache. Some people will even <a href="http://www.248am.com/mark/blog-info/hard-refresh/">ask their</a> <a href="http://www.ruthlessintent.com/board/announcements/everybody-please-make-a-hard-refresh/">users to</a> <a href="http://www.yarntomato.com/2005/02/hard-refresh/">do a</a> <a href="http://en.wikipedia.org/wiki/Bypass_your_cache">hard refresh</a> but this obviously does not scale and it&#8217;s not very robust.</p>
<p>Since you cannot send an automatic signal to the browsers to reload those files all you can do is change the URL of those files (explicit invalidation). You could simply rename all those files, but an easier way to achieve the same effect is by adding a fake (unused &#8211; dummy) parameter at the end of the resource URL:</p>
<pre>&lt;img src="logo.jpg?2" /&gt;</pre>
<p>The next logical step would be to automate this into the build system and have every production release feature new cache killer tokens. It seems that many well known sites do that already:</p>
<h4><a href="http://slashdot.org/">http://slashdot.org/</a></h4>
<pre>
href="//s.fsdn.com/sd/idlecore-tidied.css?T_2_5_0_254a"
src="//s.fsdn.com/sd/all-minified.js?T_2_5_0_254a"
</pre>
<h4><a href="http://stackoverflow.com/">http://stackoverflow.com/</a></h4>
<pre>
href="/content/all.css?v=3184"
src="/content/js/master.js?v=3141"
</pre>
<h4><a href="http://digg.com/">http://digg.com/</a></h4>
<pre>
@import "/css/189/global.css";
src="http://media.digg.com/js/loader/187/dialog|digg|shouts"
</pre>
<h4><a href="http://www.bbc.co.uk/">http://www.bbc.co.uk/</a></h4>
<pre>
@import 'http://wwwimg.bbc.co.uk/home/release-29-7/style/homepage.min.css';
src="http://wwwimg.bbc.co.uk/home/release-29-7/script/glow.homepage.compressed.js"
</pre>
<h4><a href="http://www.guardian.co.uk/">http://www.guardian.co.uk/</a></h4>
<pre>
href="http://static.guim.co.uk/static/73484/common/styles/wide/ie.css"
src="http://static.guim.co.uk/static/73484/common/scripts/gu.js"
</pre>
<p>What happens with images referenced from within css files? You could rewrite the css files automatically as part of your production build process with <a href="http://ant.apache.org/">Ant</a>.</p>
<pre>&lt;tstamp&gt;
    &lt;format property="cacheKill" pattern="yyyyMMddhhmm" locale="en,UK"/&gt;
&lt;/tstamp&gt;

&lt;target name="rewrite-css"&gt;
    &lt;replace dir="${build.web.dir}" value="css?${cacheKill}&amp;quot;)"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;css&amp;quot;)&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="png?${cacheKill}&amp;quot;)"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;png&amp;quot;)&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="gif?${cacheKill}&amp;quot;)"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;gif&amp;quot;)&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="jpg?${cacheKill}&amp;quot;)"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;jpg&amp;quot;)&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="css?${cacheKill}')"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;css')&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="png?${cacheKill}')"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;png')&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="gif?${cacheKill}')"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;gif')&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="jpg?${cacheKill}')"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;jpg')&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="css?${cacheKill})"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;css)&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="png?${cacheKill})"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;png)&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="gif?${cacheKill})"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;gif)&lt;/replacetoken&gt;&lt;/replace&gt;
    &lt;replace dir="${build.web.dir}" value="jpg?${cacheKill})"&gt;&lt;include name="css/**/*.css"/&gt;&lt;include name="scripts/**/*.css"/&gt;&lt;replacetoken&gt;jpg)&lt;/replacetoken&gt;&lt;/replace&gt;
&lt;/target&gt;
</pre>
<p>This will take care of the following background image reference styles for css, png, gif and jpg files:</p>
<pre>... background-image: url("images/ed-bg.gif");
... background-image: url('images/ed-bg.gif');
... background-image: url(images/ed-bg.gif);</pre>
<p>and convert them to:</p>
<pre>... background-image: url("images/ed-bg.gif?200905031126");
... background-image: url('images/ed-bg.gif?200905031126');
... background-image: url(images/ed-bg.gif?200905031126);</pre>
<p>Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/mod_expires-and-cache-killers/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>A better SMTPAppender</title>
		<link>http://blog.cherouvim.com/a-better-smtpappender/</link>
		<comments>http://blog.cherouvim.com/a-better-smtpappender/#comments</comments>
		<pubDate>Sat, 02 May 2009 20:34:08 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[log4j]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=98</guid>
		<description><![CDATA[SMTPAppender for log4j is a type of appender which sends emails via an SMTP server. It&#8217;s very useful for applications released in production where you&#8217;d definitely need to know of all application errors logged. Of course every caring developer should look at the server logs every now and then, but if you&#8217;ve got hundreds of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/net/SMTPAppender.html">SMTPAppender</a> for <a href="http://logging.apache.org/log4j/">log4j</a> is a type of appender which sends emails via an <a href="http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol"><abbr title="Simple Mail Transfer Protocol">SMTP</abbr></a> server. It&#8217;s very useful for applications released in production where you&#8217;d definitely need to know of all application errors logged. Of course every caring developer should look at the server logs every now and then, but if you&#8217;ve got hundreds of them (applications) then it becomes a full time job in itself.</p>
<p>Sometimes a fresh release of a high traffic website may produce hundreds or thousands of <em>ERROR level</em> log events. Many times this may be something minor which is being logged deep inside your code. Until the bug is fixed and a new release is deployed, your inbox and the mail server may <strong>suffer heavily</strong>.</p>
<p>What follows is an extension of SMTPAppender which limits the amount of emails sent in a specified period of time. It features sensible defaults which of course can be configured externally via the log4j configuration file.</p>
<pre>package com.cherouvim;

import org.apache.log4j.Logger;
import org.apache.log4j.net.SMTPAppender;

public class LimitedSMTPAppender extends SMTPAppender {

    private int limit = 10;           // max at 10 mails ...
    private int cycleSeconds = 3600;  // ... per hour

    public void setLimit(int limit) {
        this.limit = limit;
    }

    public void setCycleSeconds(int cycleSeconds) {
        this.cycleSeconds = cycleSeconds;
    }

    private int lastVisited;
    private long lastCycle;

    protected boolean checkEntryConditions() {
        final long now = System.currentTimeMillis();
        final long thisCycle =  now - (now % (1000L*cycleSeconds));
        if (lastCycle!=thisCycle) {
            lastCycle = thisCycle;
            lastVisited = 0;
        }
        lastVisited++;
        return super.checkEntryConditions() &#038;&#038; lastVisited&lt;=limit;
    }

}</pre>
<p>The configuration would look something like this:</p>
<pre><strong>log4j.appender.???=com.cherouvim.LimitedSMTPAppender</strong>
<strong>log4j.appender.???.limit=3</strong>
<strong>log4j.appender.???.cycleSeconds=60</strong>
log4j.appender.???.BufferSize=25
log4j.appender.???.SMTPHost=${mail.smtp.host}
log4j.appender.???.From=${mail-sender}
log4j.appender.???.To=${sysadmin.email}
log4j.appender.???.Subject=An error occured
log4j.appender.???.layout=org.apache.log4j.PatternLayout
log4j.appender.???.layout.ConversionPattern=%d{ISO8601} %-5p (%F:%L) - %m%n
log4j.appender.???.threshold=ERROR</pre>
<p>The above configuration will limit the mail dispatch to only 3 emails per minute. Any further errors in that minute will not be emailed. The <strong>limit</strong> and <strong>cycleSeconds</strong> setting lines can be omitted and the defaults will be applied.</p>
<p>Happy logging!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/a-better-smtpappender/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>robots.txt control for host aliases via mod_rewrite</title>
		<link>http://blog.cherouvim.com/robotstxt-control-for-host-aliases-via-mod_rewrite/</link>
		<comments>http://blog.cherouvim.com/robotstxt-control-for-host-aliases-via-mod_rewrite/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 16:06:19 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[apache httpd]]></category>
		<category><![CDATA[deployment]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=89</guid>
		<description><![CDATA[Suppose you have a website launched at two different hosts. &#60;VirtualHost *:80&#62; ServerName www.example.com ServerAlias beta.example.com .... &#60;/VirtualHost&#62; The content is the same but you want to serve a different robots.txt file, possibly excluding any indexing from the secondary host. It would be handy if we could simply say: User-agent: * Allow: http://www.example.com/ User-agent: * [...]]]></description>
			<content:encoded><![CDATA[<p>Suppose you have a website launched at two different hosts.</p>
<pre>&lt;VirtualHost *:80&gt;
    ServerName www.example.com
    ServerAlias beta.example.com
    ....
&lt;/VirtualHost&gt;</pre>
<p>The content is the same but you want to serve a different <a href="http://www.robotstxt.org/">robots.txt</a> file, possibly excluding any indexing from the secondary host.</p>
<p>It would be handy if we could simply say:</p>
<pre>User-agent: *
<span class="error" title="erroneous syntax">Allow: http://www.example.com/</span>

User-agent: *
Disallow: <span class="error" title="erroneous syntax">http://beta.example.com/</span></pre>
<p>to allow all bots crawl the primary host and dissalow them from the secondary one, but this syntax is imaginary. Firstly there is no <code>Allow</code> keyword in the spec, and secondly URLs must be relative.</p>
<p>The solution is to have 2 different robots.txt files:</p>
<h3>robots-www.txt</h3>
<pre>User-agent: *
Dissalow:</pre>
<h3>robots-beta.txt</h3>
<pre>User-agent: *
Dissalow: /</pre>
<p>and serve them via mod_rewrite like this:</p>
<pre>&lt;VirtualHost *:80&gt;
    ServerName www.example.com
    ServerAlias beta.example.com
    ...
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^www\.example\.com$
    RewriteRule ^/robots.txt$ /robots-www.txt [L]
    RewriteCond %{HTTP_HOST} ^beta\.example\.com$
    RewriteRule ^/robots.txt$ /robots-beta.txt [L]
&lt;/VirtualHost&gt;</pre>
<p>Now http://www.example.com/robots.txt will silently serve robots-www.txt and http://beta.example.com/robots.txt will serve robots-beta.txt</p>
<p>This is also handy in domain name migration periods where you are waiting for dns to flush all around the globe until you feel safe for completely shutting down the secondary host and possibly assigning <a href="http://en.wikipedia.org/wiki/URL_redirection">301 redirects</a> to the primary.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/robotstxt-control-for-host-aliases-via-mod_rewrite/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>fix hibernate+ehcache: miss for sql</title>
		<link>http://blog.cherouvim.com/fix-hibernate-ehcache-miss-for-sql/</link>
		<comments>http://blog.cherouvim.com/fix-hibernate-ehcache-miss-for-sql/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 15:32:25 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[databases]]></category>
		<category><![CDATA[ehcache]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=81</guid>
		<description><![CDATA[If you are using an entity as a named parameter in a hibernate Query or Criteria which is cachable from ehcache then this entity needs to implement hashcode and equals using a business key. Otherwise the hibernate Query or Criteria may always &#8220;look different&#8221; to ehcache so it will be a constant cache miss. DEBUG [...]]]></description>
			<content:encoded><![CDATA[<p>If you are using an entity as a named parameter in a hibernate <a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Query.html">Query</a> or <a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Criteria.html">Criteria</a> which is cachable from ehcache then this entity needs to <a href="http://www.hibernate.org/109.html">implement hashcode and equals using a business key</a>. Otherwise the hibernate Query or Criteria may always &#8220;look different&#8221; to ehcache so it will be a constant cache miss.</p>
<pre>DEBUG (MemoryStore.java:138) - query.FooBarCache: query.FooBarMemoryStore miss for sql: /* criteria query */ select this_.id as y0_ from foobars this_ where this_.state=?; parameters: LIVE; max rows: 1; transformer: org.hibernate.transform.PassThroughResultTransformer@294633f0
DEBUG (Cache.java:808) - query.FooBar cache - Miss</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/fix-hibernate-ehcache-miss-for-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My favourite string for testing web applications</title>
		<link>http://blog.cherouvim.com/my-favourite-string-for-testing-web-applications/</link>
		<comments>http://blog.cherouvim.com/my-favourite-string-for-testing-web-applications/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 19:51:16 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[databases]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=63</guid>
		<description><![CDATA[Weird title, huh? When creating templates, pages and action responses for your web application you really need to take HTML escaping into consideration. Sometimes the use cases of the system are so many that you may omit HTML escaping for some piece of dynamic or user entered text. HTML escaping means converting &#60;foo&#62;bar &#38; &#34; [...]]]></description>
			<content:encoded><![CDATA[<p>Weird title, huh?</p>
<p>When creating templates, pages and action responses for your web application you really need to take <a href="http://en.wikipedia.org/wiki/Html" title="HyperText Markup Language">HTML</a> escaping into consideration. Sometimes the use cases of the system are so many that you may omit HTML escaping for some piece of dynamic or user entered text.</p>
<p>HTML escaping means converting <strong class="bad">&lt;foo&gt;bar &amp; &quot;</strong> to <strong class="good">&amp;lt;foo&amp;gt;bar &amp;amp; &amp;quot;</strong> in the HTML source.</p>
<p>One of the reasons for HTML escaping is to avoid <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">XSS attacks</a> or simply to make your site <a href="http://validator.w3.org/">valid</a>.</p>
<p>Reasons for making your HTML output valid include:</p>
<ol>
<li>It&#8217;s the &#8220;right thing to do&#8221;</li>
<li>Does not tire the browser</li>
<li>Allows you to manually detect (via CTRL+SHIFT+A on <a href="http://chrispederick.com/work/web-developer/">web developer toolbar</a>) for real HTML output errors</li>
<li>Saves you from css rendering issues due to HTML anomalies</li>
<li>Ensures your content is easily parsable from third party agents (crawlers, scrappers, XSLT transformators etc)</li>
</ol>
<p>So my favourite string is <strong class="good">&lt;script&#8217;&#8221;&lt;i&gt;</strong><br />
You can alter your development database content using statements like these:</p>
<pre>
update articles set title=concat("&lt;script'\"&lt;i&gt;", title);
update users set firstname=concat("&lt;script'\"&lt;i&gt;", lastname), lastname=concat("&lt;script'\"&lt;i&gt;", lastname);
update categories set title=concat("&lt;script'\"&lt;i&gt;", title);
...
</pre>
<p>If after this database content change your site is not functional then there is a problem. You can also check for HTML validity with CTRL+SHIFT+A on <a href="http://chrispederick.com/work/web-developer/">web developer toolbar</a> and quickly spot areas where you missed HTML escaping.</p>
<p>You could even automate this whole process by having a tool (<a href="http://jtidy.sourceforge.net/">JTidy</a>?) scan that all your pages and use cases produce valid HTML. So indirectly you would be testing for insecure (in XSS terms) parts of the application.</p>
<p><a href="http://www.java2s.com/Code/Java/JSTL/OutwithTagEscapingExamples.htm">HTML escaping in JSTL</a><br />
<a href="http://freemarker.sourceforge.net/docs/ref_directive_escape.html">HTML escaping in freemarker</a><br />
<a href="http://velocity.apache.org/engine/devel/webapps.html">HTML escaping in velocity</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/my-favourite-string-for-testing-web-applications/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Duplicate content test and URL canonicalization</title>
		<link>http://blog.cherouvim.com/duplicate-content-test-and-url-canonicalization/</link>
		<comments>http://blog.cherouvim.com/duplicate-content-test-and-url-canonicalization/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 09:17:13 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[google]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=54</guid>
		<description><![CDATA[Days ago I uploaded the following script on my server: &#60;?php if ($_SERVER["QUERY_STRING"]=='foo&#38;bar') { echo "index test one"; } if ($_SERVER["QUERY_STRING"]=='bar&#38;foo') { echo "bar and foo"; } if ($_SERVER["QUERY_STRING"]=='bar&#38;foo&#38;test') { echo "bar and foo"; } ?&#62; I then published 3 links to my site&#8217;s index so Google could follow them: http://cherouvim.com/foo.php?foo&#038;bar http://cherouvim.com/foo.php?bar&#038;foo http://cherouvim.com/foo.php?bar&#038;foo&#038;test Days later [...]]]></description>
			<content:encoded><![CDATA[<p>Days ago I uploaded the following script on my server:</p>
<pre>&lt;?php

  if ($_SERVER["QUERY_STRING"]=='foo&amp;bar') {
    echo "index test one";
  }

  if ($_SERVER["QUERY_STRING"]=='bar&amp;foo') {
    echo "bar and foo";
  }

  if ($_SERVER["QUERY_STRING"]=='bar&amp;foo&amp;test') {
    echo "bar and foo";
  }

?&gt;</pre>
<p>I then published 3 links to my site&#8217;s index so Google could follow them:</p>
<p>http://cherouvim.com/foo.php?foo&#038;bar</p>
<p>http://cherouvim.com/foo.php?bar&#038;foo</p>
<p>http://cherouvim.com/foo.php?bar&#038;foo&#038;test</p>
<p>Days later I got this result for the Google query <strong>site:cherouvim.com/foo</strong>:<br />
<img src="/images/duplicate-content-test.png" /></p>
<p>The first and third result are the same (duplicate content). Google has indexed them both though. This is a common <a href="http://en.wikipedia.org/wiki/Search_engine_optimization">SEO</a> problem in dynamic web sites where there can be many different URLs linking to the same page (paginators, out of date URLs, archive pages etc) or where you want to do <a href="http://janeandrobot.com/post/URL-Referrer-Tracking.aspx">URL Referrer Tracking</a>.</p>
<p>Google has <a href="http://googlewebmastercentral.blogspot.com/2009/02/specify-your-canonical.html">recently published a way of overcoming this problem</a>. You can now specify which is the real (or primary) URL for the page. E.g:</p>
<pre>&lt;link rel="canonical" href="/foo.php?foo&#038;bar" /&gt;</pre>
<p>So, as SEOmoz said, this definitely is <a href="http://www.seomoz.org/blog/canonical-url-tag-the-most-important-advancement-in-seo-practices-since-sitemaps">The Most Important Advancement in SEO Practices Since Sitemaps</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/duplicate-content-test-and-url-canonicalization/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Re: The 140 character webapp challenge!</title>
		<link>http://blog.cherouvim.com/re-the-140-character-webapp-challenge/</link>
		<comments>http://blog.cherouvim.com/re-the-140-character-webapp-challenge/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 20:25:54 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=48</guid>
		<description><![CDATA[This is my response to The 140 character webapp challenge! Epilepsy javascript:{r=0;setInterval(function(){document.body.style.background=(r++%2==0?'#'+r%7+r%9+r%8:'0')},50);void(0)} 114 bytes of inline javascript that you can paste to your browser&#8217;s URL. It&#8217;s a very useful webapp* in case you want to cause epilepsy to yourself. Via: http://f055.net/article/the-140-character-webapp-challenge/ Via: http://synodinos.net/2009/02/14/re-the-140-character-webapp-challenge/ * just kidding :)]]></description>
			<content:encoded><![CDATA[<p>This is my response to <a href="http://f055.net/article/the-140-character-webapp-challenge/">The 140 character webapp challenge!</a></p>
<h3>Epilepsy</h3>
<pre>javascript:{r=0;setInterval(function(){document.body.style.background=(r++%2==0?'#'+r%7+r%9+r%8:'0')},50);void(0)}</pre>
<p>114 bytes of inline javascript that you can paste to your browser&#8217;s URL.</p>
<p>It&#8217;s a very useful webapp<sup>*</sup> in case you want to cause <a href="http://en.wikipedia.org/wiki/Epilepsy">epilepsy</a> to yourself.</p>
<p>Via: <a href="http://f055.net/article/the-140-character-webapp-challenge/">http://f055.net/article/the-140-character-webapp-challenge/</a><br />
Via: <a href="http://synodinos.net/2009/02/14/re-the-140-character-webapp-challenge/">http://synodinos.net/2009/02/14/re-the-140-character-webapp-challenge/</a></p>
<p><sup>*</sup> just kidding :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/re-the-140-character-webapp-challenge/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Singleton ehcache CacheManager warning fix</title>
		<link>http://blog.cherouvim.com/singleton-ehcache-cachemanager-warning-fix/</link>
		<comments>http://blog.cherouvim.com/singleton-ehcache-cachemanager-warning-fix/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 22:15:29 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[ehcache]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=44</guid>
		<description><![CDATA[If you experience the following warning in your hibernate+ehcache application: 2008-11-20 13:02:42,937 WARN (CacheManager.java:322) - Creating a new instance of CacheManager using the diskStorePath "D:\apache-tomcat-5.5.26\temp" which is already used by an existing CacheManager. The source of the configuration was classpath. The diskStore path for this CacheManager will be set to D:\apache-tomcat-5.5.26\temp\ehcache_auto_created_1227178962937. To avoid this warning [...]]]></description>
			<content:encoded><![CDATA[<p>If you experience the following warning in your hibernate+ehcache application:</p>
<pre>2008-11-20 13:02:42,937 WARN  (CacheManager.java:322) -
  Creating a new instance of CacheManager using the diskStorePath
  "D:\apache-tomcat-5.5.26\temp" which is already used by an
  existing CacheManager.
The source of the configuration was classpath.
The diskStore path for this CacheManager will be set to
  D:\apache-tomcat-5.5.26\temp\ehcache_auto_created_1227178962937.
To avoid this warning consider using the CacheManager factory
  methods to create a singleton CacheManager or specifying a
  separate ehcache configuration (ehcache.xml) for each
  CacheManager instance.
</pre>
<p>then you need to set the following in your <em>hibernate.cfg.xml</em> file:</p>
<pre>&lt;property name="hibernate.cache.provider_class">
  net.sf.ehcache.hibernate.SingletonEhCacheProvider
&lt;/property&gt;</pre>
<p><a href="http://ehcache.sourceforge.net/documentation/hibernate.html">Ehcache Hibernate documentation</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/singleton-ehcache-cachemanager-warning-fix/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The * stupidest things I’ve done in my programming job</title>
		<link>http://blog.cherouvim.com/the-stupidest-things-ive-done-in-my-programming-job/</link>
		<comments>http://blog.cherouvim.com/the-stupidest-things-ive-done-in-my-programming-job/#comments</comments>
		<pubDate>Sat, 07 Feb 2009 18:18:36 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[databases]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[webapps]]></category>
		<category><![CDATA[workplace]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=30</guid>
		<description><![CDATA[I&#8217;m not ashamed of those sins any more, so here you go :) 1. ORM Stupidity Building my own Object Relational Mapping framework. Consequence Project is a mess after 2 years of maintenance with hardcore hacks to bypass my own ORM and call custom SQL queries. What should I have done Use hibernate, iBATIS, Cayenne [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not ashamed of those sins any more, so here you go :)</p>
<h3>1. <abbr title="Object Relational Mapping">ORM</abbr></h3>
<dl>
<dt><span class="bad">Stupidity</span></dt>
<dd>Building my own <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">Object Relational Mapping</a> framework.</dd>
<dt>Consequence</dt>
<dd>Project is a mess after 2 years of maintenance with hardcore hacks to bypass my own ORM and call custom SQL queries.</dd>
<dt><span class="right">What should I have done</span></dt>
<dd>Use <a href="http://www.hibernate.org/">hibernate</a>, <a href="http://ibatis.apache.org/">iBATIS</a>, <a href="http://cayenne.apache.org/">Cayenne</a> or something similar.</dd>
</dl>
<h3>2. <abbr title="Entity-Attribute-Value model">EAV</abbr></h3>
<dl>
<dt><span class="bad">Stupidity</span></dt>
<dd>Using an <a href="http://en.wikipedia.org/wiki/Entity-Attribute-Value_model">Entity-Attribute-Value model</a> database schema design.</dd>
<dt>Consequence</dt>
<dd>Non scalable solution and total impossibility to run any useful queries on the database level.</dd>
<dt><span class="right">What should I have done</span></dt>
<dd>Use an ordinary <a href="http://en.wikipedia.org/wiki/Database_normalization">normalized database schema</a> design.</dd>
</dl>
<h3>3. Database Access</h3>
<dl>
<dt><span class="bad">Stupidity</span></dt>
<dd>Synchronize (serialize) database access using one shared connection.</dd>
<dt>Consequence</dt>
<dd>Zero scalability. Very slow response times when more than 10 users where using the application.</dd>
<dt><span class="right">What should I have done</span></dt>
<dd>Don&#8217;t do that and use a connection pool such as <a href="http://sourceforge.net/projects/c3p0">c3p0</a> and use a &#8220;new&#8221; (reused) connection returned from the pool for every request/response cycle.</dd>
</dl>
<h3>4. <abbr title="Integrated development environment">IDE</abbr></h3>
<dl>
<dt><span class="bad">Stupidity</span></dt>
<dd>Avoided learning and using an <a href="http://en.wikipedia.org/wiki/Integrated_development_environment">Integrated development environment</a>.</dd>
<dt>Consequence</dt>
<dd>Inability to build test and deploy the application quickly and generally do anything useful.</dd>
<dt><span class="right">What should I have done</span></dt>
<dd>Get familiar with an IDE. <a href="http://www.netbeans.org/">NetBeans</a>, <a href="http://www.eclipse.org/">eclipse</a> etc.</dd>
</dl>
<h3>5. Transactions</h3>
<dl>
<dt><span class="bad">Stupidity</span></dt>
<dd>Not using them.</dd>
<dt>Consequence</dt>
<dd>Corrupt data in an application involving e-shop like functionality.</dd>
<dt><span class="right">What should I have done</span></dt>
<dd>Use <a href="http://en.wikipedia.org/wiki/Database_transaction">database transactions</a>. When in <a href="http://en.wikipedia.org/wiki/MySQL">MySQL</a> use <a href="http://en.wikipedia.org/wiki/InnoDB">InnoDB</a>.</dd>
</dl>
<h3>6. Prepared Statements</h3>
<dl>
<dt><span class="bad">Stupidity</span></dt>
<dd>Using <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Statement.html">Statement</a>s, string concatenation and naive character escaping to assemble my own &#8220;safe&#8221; queries.</dd>
<dt>Consequence</dt>
<dd><a href="http://en.wikipedia.org/wiki/SQL_injection">SQL Injections</a> possible in my application. I managed to login using <strong>&#8216;or 1=1;delete from users;&#8211;</strong> and alter the database state in a very nasty way.</dd>
<dt><span class="right">What should I have done</span></dt>
<dd>Use <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/PreparedStatement.html">Prepared Statements</a> which correctly assemble and escape the query properly depending on the <a href="http://en.wikipedia.org/wiki/Java_Database_Connectivity">JDBC</a> driver used.</dd>
</dl>
<h3>7. Business Logic</h3>
<dl>
<dt><span class="bad">Stupidity</span></dt>
<dd>Doing it in the template (<a href="http://java.sun.com/products/jsp/" title="JavaServer Pages">JSP</a>).</dd>
<dt>Consequence</dt>
<dd>Messy non maintainable application.</dd>
<dt><span class="right">What should I have done</span></dt>
<dd>Do it in an <a href="http://en.wikipedia.org/wiki/Model-view-controller" title="Model View Controller">MVC</a> style with servlets or with a <a href="http://martinfowler.com/eaaCatalog/frontController.html">Front Controller</a>. Even better by using an existing open source MVC framework such as <a href="http://struts.apache.org/">Struts</a>, <a href="http://www.springsource.org/">Spring MVC</a> etc.</dd>
</dl>
<p>Of course, all the bad choices above have probably made me a better programmer.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/the-stupidest-things-ive-done-in-my-programming-job/feed/</wfw:commentRss>
		<slash:comments>63</slash:comments>
		</item>
		<item>
		<title>Best way to integrate Google Analytics</title>
		<link>http://blog.cherouvim.com/best-way-to-integrate-google-analytics/</link>
		<comments>http://blog.cherouvim.com/best-way-to-integrate-google-analytics/#comments</comments>
		<pubDate>Thu, 06 Nov 2008 20:18:24 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=29</guid>
		<description><![CDATA[This is the best solution to integrate Google Analytics into your site. It uses ideas and code from the following 2 sites: http://www.mattiasgeniar.be/webdevelopment/_gat-is-not-defined-google-analytics-error/ http://www.maifith.com/news/_gat-is-undefined-new-analytics-code Here is the improved snippet: &#60;script type="text/javascript" src="http://www.google-analytics.com/ga.js"&#62;&#60;/script&#62; &#60;script type="text/javascript"&#62; if (typeof(_gat)=='object') setTimeout(function(){ _gat._getTracker("UA-1234567-8")._trackPageview()}, 1500); &#60;/script&#62; Improvements: Does not use document.write Fixes the &#8220;_gat is not defined&#8221; issue Delayed GA access [...]]]></description>
			<content:encoded><![CDATA[<p>This is the best solution to integrate Google Analytics into your site. It uses ideas and code from the following 2 sites:<br />
<a href="http://www.mattiasgeniar.be/webdevelopment/_gat-is-not-defined-google-analytics-error/">http://www.mattiasgeniar.be/webdevelopment/_gat-is-not-defined-google-analytics-error/</a><br />
<a href="http://www.maifith.com/news/_gat-is-undefined-new-analytics-code">http://www.maifith.com/news/_gat-is-undefined-new-analytics-code</a></p>
<p>Here is the improved snippet:</p>
<pre class="code">&lt;script type="text/javascript" src="http://www.google-analytics.com/ga.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
    if (typeof(_gat)=='object')
        setTimeout(function(){
            _gat._getTracker("UA-1234567-8")._trackPageview()}, 1500);
&lt;/script&gt;</pre>
<p>Improvements:</p>
<ol>
<li>Does not use document.write</li>
<li>Fixes the &#8220;_gat is not defined&#8221; issue</li>
<li>Delayed GA access (1.5 second) so the page load time is not affected</li>
<li>Very concise</li>
</ol>
<p>Another improvement would be to <a href="http://stackoverflow.com/questions/220112/is-there-a-faster-alternative-to-google-analytics">cache ga.js locally to avoid the DNS lookup</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/best-way-to-integrate-google-analytics/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Logging website subsections with Apache</title>
		<link>http://blog.cherouvim.com/logging-website-subsections-with-apache/</link>
		<comments>http://blog.cherouvim.com/logging-website-subsections-with-apache/#comments</comments>
		<pubDate>Sat, 26 Apr 2008 21:51:29 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[apache httpd]]></category>
		<category><![CDATA[deployment]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/?p=28</guid>
		<description><![CDATA[This is a typical VirtualHost for example.com in Apache HTTP Server: &#60;VirtualHost xx.xxx.xx.xx:80&#62; DocumentRoot /home/example.com/site ServerName example.com ErrorLog /home/example.com/logs/error.log CustomLog /home/example.com/logs/access.log &#34;combined&#34; &#60;/VirtualHost&#62; This CustomLog directive will produce something like this on the logfile: 64.229.111.27 - - [08/Aug/2007:16:12:54 +0300] GET /foo/index.html HTTP/1.1 64.229.111.27 - - [08/Aug/2007:16:12:54 +0300] GET /bar/index.html HTTP/1.1 64.229.111.27 - - [08/Aug/2007:16:12:54 +0300] [...]]]></description>
			<content:encoded><![CDATA[<p>This is a typical <a href="http://httpd.apache.org/docs/2.2/mod/core.html#virtualhost">VirtualHost</a> for example.com in <a href="http://httpd.apache.org/">Apache HTTP Server</a>:</p>
<pre>&lt;VirtualHost xx.xxx.xx.xx:80&gt;
    DocumentRoot /home/example.com/site
    ServerName example.com
    ErrorLog /home/example.com/logs/error.log
    CustomLog /home/example.com/logs/access.log &quot;combined&quot;
&lt;/VirtualHost&gt;</pre>
<p>This <a href="http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#customlog">CustomLog</a> directive will produce something like this on the logfile:</p>
<pre>64.229.111.27 - - [08/Aug/2007:16:12:54 +0300] GET /foo/index.html HTTP/1.1
64.229.111.27 - - [08/Aug/2007:16:12:54 +0300] GET /bar/index.html HTTP/1.1
64.229.111.27 - - [08/Aug/2007:16:12:54 +0300] GET /bar/about.html HTTP/1.1</pre>
<p>Suppose that you wanted to log requests for /foo and /bar subsections in 2 separate files. That way you (or your client) may find it easier later on to analyze web traffic for the subsites individually.</p>
<p>What you can do is log conditionally using environment variables that you&#8217;ve set using <a href="http://httpd.apache.org/docs/2.2/mod/mod_setenvif.html#setenvif">SetEnvIf</a> based on the request.</p>
<pre>SetEnvIf Request_URI &quot;/foo.*&quot; subsite_foo
SetEnvIf Request_URI &quot;/bar.*&quot; subsite_bar
CustomLog /home/example.com/logs/access.foo.log combined env=subsite_foo
CustomLog /home/example.com/logs/access.bar.log combined env=subsite_bar</pre>
<p>This works nice, but not when the urls for your individual subsites look like this:</p>
<pre>http://example.com/?site=foo&amp;page=5

http://example.com/?site=bar&amp;page=8</pre>
<p>That&#8217;s because the Request_URI does not contain the query string (whatever comes after the ? character).</p>
<p>The solution comes with a little bit of <a href="http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritecond">RewriteCond</a> magic, which helps us set an environment variable using ${QUERY_STRING}:</p>
<pre>RewriteEngine on
RewriteCond %{QUERY_STRING} .*site=foo.*
RewriteRule (.*) $1 [E=subsite_foo:1]
RewriteCond %{QUERY_STRING} .*site=bar.*
RewriteRule (.*) $1 [E=subsite_bar:1]
CustomLog /home/example.com/logs/access.foo.log combined env=subsite_foo
CustomLog /home/example.com/logs/access.bar.log combined env=subsite_bar</pre>
<p>Happy logging&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/logging-website-subsections-with-apache/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bad and Good (code snippets)</title>
		<link>http://blog.cherouvim.com/bad-and-good-code-snippets/</link>
		<comments>http://blog.cherouvim.com/bad-and-good-code-snippets/#comments</comments>
		<pubDate>Sat, 18 Aug 2007 18:05:05 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/bad-and-good-code-snippets/</guid>
		<description><![CDATA[What follows is usual modifications I apply to java code, when I code review. Most of the following changes have a stylistic nature, but some of them can impact performance. Bad code is in red and good code is in green. Feel free to comment. Unnecessary if statement if (foo&#62;bar) { return true; } else [...]]]></description>
			<content:encoded><![CDATA[<p>What follows is usual modifications I apply to java code, when I code review. Most of the following changes have a stylistic nature, but some of them can impact performance. Bad code is <strong class="error">in red</strong> and good code is <strong class="good">in green</strong>. Feel free to comment.</p>
<h3>Unnecessary if statement</h3>
<pre class="error">if (foo&gt;bar) {
  return true;
} else {
  return false;
}</pre>
<pre class="good">return foo&gt;bar;</pre>
<h3>Unnecessary nesting</h3>
<pre class="error">if (foo) {
  if (bar) {
    // do something
  }
}</pre>
<pre class="good">if (foo &#038;&#038; bar) {
  // do something
}</pre>
<h3>A bit of redundancy here</h3>
<pre class="error">if (foo!=null &#038;&#038; foo.equals("bar")) {
  // do something
}</pre>
<pre class="good">if ("bar".equals(foo)) {
  // do something
}</pre>
<h3>Looks ugly</h3>
<pre class="error">String comment = request.getParameter("post");
if (comment==null) {
  comment = "n/a";
}</pre>
<pre class="good">String comment = request.getParameter("post")!=null?
        request.getParameter("post"):
        "n/a";</pre>
<p><small>This only holds if <code>request.getParameter("post")</code> is cheap.</small></p>
<h3>Unnecessary variable allocation</h3>
<pre class="error">Something something = new Something(foo);
return something;</pre>
<pre class="good">return new Something(foo);</pre>
<h3>Too much variable scope</h3>
<pre class="error">Something something = new Something();
if (foo) {
  something.prepare();
  request.setAttribute("something", something);
}</pre>
<pre class="good">if (foo) {
  Something something = new Something();
  something.prepare();
  request.setAttribute("something", something);
}</pre>
<h3>Method exposes implementation</h3>
<pre class="error">public ArrayList getSomething() {
  ...
}</pre>
<pre class="good">public List getSomething() {
  ...
}</pre>
<h3>A bit slow</h3>
<pre class="error">String foo = "something";
if (!foo.equals("")) {
  // do something
}</pre>
<pre class="good">String foo = "something";
if (foo.length()&gt;0) {
  // do something
}</pre>
<h3>Too many lines</h3>
<pre class="error">List immutableList = new ArrayList();
immutableList.add(foo);
immutableList.add(bar);
immutableList.add(example);
Something something = new Something(immutableList);</pre>
<pre class="good">Something something = new Something(
        Arrays.asList(new Object[] {foo, bar, example}));</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/bad-and-good-code-snippets/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Disabling foreign key generation in hbm2ddl</title>
		<link>http://blog.cherouvim.com/disabling-foreign-key-generation-in-hbm2ddl/</link>
		<comments>http://blog.cherouvim.com/disabling-foreign-key-generation-in-hbm2ddl/#comments</comments>
		<pubDate>Mon, 13 Aug 2007 10:47:49 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[databases]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/disable-foreign-key-generation-in-hbm2ddl/</guid>
		<description><![CDATA[When generating the database schema using the hbm2ddl tools, foreign keys are being created for every relation. You can enhance the schema by using the foreign-key attribute to specify your own name for a particular foreign key. But, what happens when you don&#8217;t want a foreign key generated? There is an undocumented behavior of the [...]]]></description>
			<content:encoded><![CDATA[<p>When generating the database schema using the <a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/tool/hbm2ddl/package-summary.html">hbm2ddl tools</a>, foreign keys are being created for every relation. You can enhance the schema by using the <strong>foreign-key</strong> attribute to <a href="http://www.hibernate.org/hib_docs/reference/en/html_single/#toolsetguide-s1-2">specify your own name for a particular foreign key</a>. </p>
<p>But, what happens when you don&#8217;t want a foreign key generated?</p>
<p>There is an undocumented behavior of the foreign-key attribute, and that is to specify <strong>foreign-key=&#8221;none&#8221;</strong>. hbm2ddl will not create an FK for a relation which has such an attribute. The <a href="http://www.hibernate.org/hib_docs/reference/en/html_single/">hibernate documentation</a> and the two bibles <a href="http://www.manning.com/bauer/">Hibernate in Action</a> and <a href="http://www.manning.com/bauer2/">Java Persistence with Hibernate</a> state absolutely nothing about this feature. I found it after hardcore googling in the following hibernate changelog:</p>
<pre>Changes in version 2.1.9 (xx.x.xxxx)
------------------------------------
* foreign-key="none" can be used to disable generation of a foreign key.</pre>
<p>Later on, I found another blog mentioning this behavior: <a href="http://blog.xebia.com/2007/02/05/let-hibernate-connect-your-world/">http://blog.xebia.com/2007/02/05/let-hibernate-connect-your-world/</a></p>
<p>The most logical question now is &#8220;why don&#8217;t you want an FK?&#8221;. That depends on the system you are building. Sometimes you might have a table in your application which will be <a href="http://en.wikipedia.org/wiki/Create%2C_read%2C_update_and_delete">CRUD</a>ed from another system, which you do not control. You may want to be able to keep references (ids) to entities which may be deleted. foreign-key=&#8221;none&#8221; together with not-found=&#8221;ignore&#8221; can solve these kind of problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/disabling-foreign-key-generation-in-hbm2ddl/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Test First (#2)</title>
		<link>http://blog.cherouvim.com/test-first-2/</link>
		<comments>http://blog.cherouvim.com/test-first-2/#comments</comments>
		<pubDate>Wed, 01 Aug 2007 20:27:52 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[ide]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[xp]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/test-first-2/</guid>
		<description><![CDATA[You want to create a helper class to analyse an HttpServletRequest and provide you with helper methods which determine the type of request. You basically care about GET and POST request methods. More specifically you want to be able to tell whether a POST is Multipart (usually containing file uploads). Without losing a second, you [...]]]></description>
			<content:encoded><![CDATA[<p>You want to create a helper class to analyse an <a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/http/HttpServletRequest.html">HttpServletRequest</a> and provide you with helper methods which determine the type of request. You basically care about <a href="http://en.wikipedia.org/wiki/Http_request#Request_message">GET and POST request methods</a>. More specifically you want to be able to tell whether a POST is <a href="http://en.wikipedia.org/wiki/Multipart#Multipart_Messages">Multipart</a> (usually containing file uploads).</p>
<p>Without losing a second, you create the class and make it compile. Right now you only care about the <abbr title="Application programming interface">API</abbr> of the class, and how will it be used from the client side of view. The class is <a href="http://en.wikipedia.org/wiki/Immutable_class">immutable</a>.</p>
<pre>import javax.servlet.http.HttpServletRequest;

public class HttpRequestAnalyser {

  private final boolean get;
  private final boolean post;
  private final boolean multipart;

  public HttpRequestAnalyser(HttpServletRequest request) {
    // do nothing of value (yet)
    this.get = false;
    this.post = false;
    this.multipart = false;
  }

  public boolean isGet() {
    return get;
  }

  public boolean isPost() {
    return post;
  }

  public boolean isMultipart() {
    return multipart;
  }

}</pre>
<p>Press F9, it compiles (<a href="http://www.netbeans.org/">NetBeans</a>).<br />
No matter what kind of request we construct this class with, it will never give us a true answer on whether the method was GET, POST or POST-MULTIPART. That&#8217;s because the implementation is the absolute minimum we need in order to define our API and have something that compiles.</p>
<p>Press CTRL+SHIFT+U to create the following empty test.</p>
<pre>import junit.framework.*;

public class HttpRequestAnalyserTest extends TestCase {

  public HttpRequestAnalyserTest(String testName) {
    super(testName);
  }

  public void setUp() {
  }

  public void testIsGet() {
  }

  public void testIsPost() {
  }

  public void testIsMultipart() {
  }

}</pre>
<p>Press SHIFT+F6, the test passes because there are no assertions yet.</p>
<p>The point is to create good tests for our HttpRequestAnalyser class. The tests will fail, and then we&#8217;ll try to make them pass by doing real work in our class, which is the <a href="http://en.wikipedia.org/wiki/System_Under_Test">System Under Test</a>.</p>
<p>In order to test our class we will need instances of HttpServletRequest. It&#8217;s not (easily) possible to create such instances, as this is an interface, and usually the <a href="http://en.wikipedia.org/wiki/Web_container">servlet container</a> generates concrete implementations. We don&#8217;t want to incorporate a servlet container in our tests. What we are going to do is mock an HttpServletRequest, as if it was coming over http from a client.</p>
<p>In order to mock such a request we could provide our own implementation, possibly in an inner static class, inside our test and we&#8217;d have to implement all methods.</p>
<p>Another way is to create a <a href="http://en.wikipedia.org/wiki/Mock_object">mock object</a> which will implement HttpServletRequest and program it with canned answers for our class. There exist <a href="http://www.mockobjects.com/">many frameworks out there for mocking</a> and we&#8217;ll use <a href="https://mocquer.dev.java.net/">mocquer</a>.</p>
<p>We need to add the servlet-api.jar and the mocquer dependencies on our project&#8217;s test libraries.</p>
<p>In order to fake HTTP request data, we need to know how these look like. <a href="http://www.mozilla.com/en-US/firefox/">Firefox</a> and many other http header monitor tools out there help us gather the following interesting parts of the requests:</p>
<h4>GET method</h4>
<pre>GET /example.html HTTP/1.1
Host: www.domain.com</pre>
<h4>POST method</h4>
<pre>POST /example.html HTTP/1.1
Host: www.domain.com
Content-Type: application/x-www-form-urlencoded</pre>
<h4>POST method with file upload</h4>
<pre>POST /example.html HTTP/1.1
Host: www.domain.com
Content-Type: multipart/form-data; boundary=...</pre>
<p>The test now becomes:</p>
<pre><strong>import javax.servlet.http.HttpServletRequest;</strong>
import junit.framework.*;
<strong>import org.jingle.mocquer.MockControl;</strong>

public class HttpRequestAnalyserTest extends TestCase {

  public HttpRequestAnalyserTest(String testName) {
    super(testName);
  }

<strong>  private MockControl requestControl;
  private HttpServletRequest request;</strong>

  public void setUp() {
<strong>    requestControl = MockControl.createControl(HttpServletRequest.class);
    request = (HttpServletRequest)requestControl.getMock();</strong>
  }

  public void testIsGet() {
<strong>    request.getMethod();
    requestControl.setReturnValue("GET");
    requestControl.replay();
    HttpRequestAnalyser analyser = new HttpRequestAnalyser(request);

    assertTrue(analyser.isGet());
    assertFalse(analyser.isPost());
    assertFalse(analyser.isMultipart());</strong>
  }

  public void testIsPost() {
<strong>    request.getMethod();
    requestControl.setReturnValue("POST");
    request.getHeader("Content-Type");
    requestControl.setReturnValue("application/x-www-form-urlencoded");
    requestControl.replay();
    HttpRequestAnalyser analyser = new HttpRequestAnalyser(request);

    assertFalse(analyser.isGet());
    assertTrue(analyser.isPost());
    assertFalse(analyser.isMultipart());</strong>
  }

  public void testIsMultipart() {
<strong>    request.getMethod();
    requestControl.setReturnValue("POST");
    request.getHeader("Content-Type");
    requestControl.setReturnValue("multipart/form-data; boundary=...");
    requestControl.replay();
    HttpRequestAnalyser analyser = new HttpRequestAnalyser(request);

    assertFalse(analyser.isGet());
    assertTrue(analyser.isPost());
    assertTrue(analyser.isMultipart());</strong>
  }

}</pre>
<p>We&#8217;ve provided method call expectations, and canned answers on the mock. The tests fail.<br />
We fill in the HttpRequestAnalyser constructor implementation which now becomes:</p>
<pre>import javax.servlet.http.HttpServletRequest;

public class HttpRequestAnalyser {

  private final boolean get;
  private final boolean post;
  private final boolean multipart;

  public HttpRequestAnalyser(HttpServletRequest request) {
<strong>    this.get = request.getMethod().equals("GET");
    this.post = request.getMethod().equals("POST");
    this.multipart =
        request.getHeader("Content-Type").startsWith("multipart/");</strong>
  }

  public boolean isGet() {
    return get;
  }

  public boolean isPost() {
    return post;
  }

  public boolean isMultipart() {
    return multipart;
  }

}</pre>
<p>Post and multipart tests pass. The get test fails, because we haven&#8217;t set an expectation for getHeader(&#8220;Content-Type&#8221;) to be called. That is because the GET Http method doesn&#8217;t have such a header.<br />
The multipart check should only happen if the request has been recognised to be a post:</p>
<pre>import javax.servlet.http.HttpServletRequest;

public class HttpRequestAnalyser {

  private final boolean get;
  private final boolean post;
  private final boolean multipart;

  public HttpRequestAnalyser(HttpServletRequest request) {
    this.get = request.getMethod().equals("GET");
    this.post = request.getMethod().equals("POST");
    this.multipart = <strong>post ?</strong>
      request.getHeader("Content-Type").startsWith("multipart/") <strong>:
      false;</strong>
  }

  public boolean isGet() {
    return get;
  }

  public boolean isPost() {
    return post;
  }

  public boolean isMultipart() {
    return multipart;
  }

}</pre>
<p>Tests pass, and the class is ready to rock! Happy testing (before coding).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/test-first-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Good Javadoc use</title>
		<link>http://blog.cherouvim.com/good-javadoc-use/</link>
		<comments>http://blog.cherouvim.com/good-javadoc-use/#comments</comments>
		<pubDate>Sun, 29 Jul 2007 07:13:39 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[ide]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/good-javadoc-use/</guid>
		<description><![CDATA[Javadoc is a tool that you have in your %JAVA_HOME%\bin (Windows) or $JAVA_HOME/bin (UNIX) directory. It is being used to extract API documentation from your Java source code, into HTML. Most IDEs fully support Javadoc. They assist the developer in writing, displaying and generating the Javadoc documentation. Javadoc is part of the development lifecycle. Good [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://java.sun.com/j2se/javadoc/">Javadoc</a> is a tool that you have in your <code>%JAVA_HOME%\bin</code> (Windows) or <code>$JAVA_HOME/bin</code> (UNIX) directory. It is being used to extract <abbr title="Application Programming Interface">API</abbr> documentation from your Java source code, into <abbr title="HyperText Markup Language">HTML</abbr>.</p>
<p>Most <abbr title="Integrated Development Environment">IDE</abbr>s fully support Javadoc. They assist the developer in writing, displaying and generating the Javadoc documentation. Javadoc is part of the development lifecycle. Good and up-to-date Javadoc is a sign of a healthy project.</p>
<h3>API Users</h3>
<p>The worst thing an API user can do is to ignore Javadoc. Having an easily accessible, local copy of the Javadoc for the library you are working with (Spring, Hibernate, Lucene etc) is the only way to work efficiently. Vast amounts of time have been put into compiling quality documentation for these libraries. Not using it will only slow you down.</p>
<h3>Development Teams</h3>
<p>One of the worst <a href="http://www.netbeans.org/">Netbeans</a> feature is that it allows you to collapse all comments and even set this as the default behavior when opening a source file. Team members, working in the same piece of code, can no longer see the documentation written by other developers.<br />
I actually had a developer asking me about what one of my methods did. For a moment I was confused and asked him whether I had written poor documentation. He then told me that he didn&#8217;t know that there was any Javadoc for that method. I don&#8217;t (want to) know whether Javadoc hiding is a feature of Netbeans or is a plugin, but that was definitely one of the most ineffective behaviors I&#8217;ve seen in a development team.</p>
<h3>API designers</h3>
<p>Writing good Javadoc involves many things which are <a href="http://java.sun.com/j2se/javadoc/writingdoccomments/">documented by SUN</a>. The general idea is that you don&#8217;t want to expose the implementation of the method through the documentation. API users will not care <strong>how</strong> you do it, but only <strong>what</strong> (and maybe why) you do.<br />
So the following comment is bad:</p>
<pre>/**
 * This method uses StringBuffer to merge the name with surname and return
 * the person's full name
 */
 public String getFullName() {</pre>
<p>A better version is:</p>
<pre>/**
 * Returns the full name of the Person. Will return "Nick Cave" if
 * firstname is "Nick" and lastname is "Cave".
 *
 * @return      the full name of the Person
 */
 public String getFullName() {</pre>
<h3>Conclusion</h3>
<p>We (Java developers) are very lucky that documentation is so tightly integrated with the language. Not using it though, takes all this goodness away.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/good-javadoc-use/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>FreeMarker exception handling</title>
		<link>http://blog.cherouvim.com/freemarker-exception-handling/</link>
		<comments>http://blog.cherouvim.com/freemarker-exception-handling/#comments</comments>
		<pubDate>Wed, 20 Jun 2007 15:25:11 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[freemarker]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/freemarker-exception-handling/</guid>
		<description><![CDATA[FreeMarker is a very flexible templating engine for Java. Exception handling (while rendering the template) is a very important issue for a templating engine. As with JSP the default behaviour of FreeMarker is to completely cancel rendering and display an error page. When developing a webapp this might not be very helpful. Sometimes errors might [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://freemarker.sourceforge.net/" title="FreeMarker templating engine">FreeMarker</a> is a very flexible templating engine for Java. Exception handling (while rendering the template) is a very important issue for a templating engine. As with <a href="http://java.sun.com/products/jsp/" title="JavaServer Pages">JSP</a> the default behaviour of FreeMarker is to completely cancel rendering and display an error page. When developing a webapp this might not be very helpful. Sometimes errors might need to be tolerated; at least for the development phase of the application development.</p>
<p>FreeMarker provides the <a href="http://freemarker.org/docs/api/freemarker/template/TemplateExceptionHandler.html">TemplateExceptionHandler</a> interface with some implementations but we&#8217;ll define our own in order to provide a more failsafe and usable behaviour.</p>
<pre>public class MyTemplateExceptionHandler
          implements TemplateExceptionHandler {

  public void handleTemplateException(TemplateException te,
          Environment env, Writer out) {
    freemarkerlog.error("template error", te);
    try {
      out.write("&lt;span style=\"cursor:help; color: red\" " +
                "title=\"" + ExceptionUtils.getMessage(te) + "\"&gt;" +
                "[e]" +
                "&lt;/span&gt;\n");
    } catch (IOException ignored) { }
  }

}</pre>
<p>Then, in the code where you configure FreeMarker you need:</p>
<pre>config.setTemplateExceptionHandler(new MyTemplateExceptionHandler());</pre>
<p>This is what you&#8217;ll see whenever there is an exception thrown while rendering the template:<br />
<img src="/images/2007-06-19-freemarker-exception-handling.png" alt="FreeMarker exception handling" width="522" height="165" /><br />
A nice little <span style="cursor:help; color:red" title="InvalidReferenceException: Expression foo is undefined on line 29, column 17 in index.ftl.">[e]</span> with a tooltip containing the exception message.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/freemarker-exception-handling/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Unit testing JavaScript with JsUnit</title>
		<link>http://blog.cherouvim.com/unit-testing-javascript-with-jsunit/</link>
		<comments>http://blog.cherouvim.com/unit-testing-javascript-with-jsunit/#comments</comments>
		<pubDate>Sun, 17 Jun 2007 17:31:08 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[xp]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/unit-testing-javascript-with-jsunit/</guid>
		<description><![CDATA[my-script.js function capitalize(str) { return str? str.length&#62;1?str[0].toUpperCase()+str.substring(1): str.toUpperCase():str; } This is my JavaScript function for capitalizing the first letter of a String. I was sure that I got capitalization right, but I wasn&#8217;t too sure about how this function would handle null/empty values. So I wrote a unit test, for JsUnit: my-script.test.html &#60;script language="javascript" src="jsUnitCore.js"&#62;&#60;/script&#62; [...]]]></description>
			<content:encoded><![CDATA[<h3>my-script.js</h3>
<pre>function capitalize(str) {
  return str?
    str.length&gt;1?str[0].toUpperCase()+str.substring(1):
      str.toUpperCase():str;
}</pre>
<p>This is my JavaScript function for capitalizing the first letter of a String. I was sure that I got capitalization right, but I wasn&#8217;t too sure about how this function would handle null/empty values.</p>
<p>So I wrote a unit test, for <a href="http://www.jsunit.net/">JsUnit</a>:</p>
<h3>my-script.test.html</h3>
<pre>&lt;script language="javascript" src="jsUnitCore.js"&gt;&lt;/script&gt;
&lt;script language="javascript" src="my-script.js"&gt;&lt;/script&gt;
&lt;script language="javascript"&gt;

function testCapitalize() {
  assertEquals("Foo bar", capitalize("foo bar"));
  assertEquals("Foobar", capitalize("foobar"));
  assertEquals("F", capitalize("f"));
  assertEquals("", capitalize(""));
  assertEquals(JSUNIT_UNDEFINED_VALUE, capitalize(JSUNIT_UNDEFINED_VALUE));
}

&lt;/script&gt;</pre>
<p>The test requires loading the jsUnitCore.js script. This test loads a local copy but you could use <a href="http://www.jsunit.net/runner/app/jsUnitCore.js" title="jsUnitCore.js from JsUnit">the online version</a> as well. Then I can run the test with my local <a href="http://www.jsunit.net/runner/testRunner.html">TestRunner</a>.</p>
<pre>Status: Done (0.156 seconds)
Runs: 1&nbsp;&nbsp;&nbsp;Errors: 0&nbsp;&nbsp;&nbsp;Failures: 0</pre>
<p>Now I know that my function is correct!</p>
<p>When a test fails the assertion error looks like this:</p>
<pre><strong>1. my-script.test.html:testCapitalize failed</strong>

Expected &lt;Foobar&gt; (String) but was &lt;foobar&gt; (String)

Stack trace follows:
&gt; JsUnitException
&gt; _assert
&gt; assertEquals
&gt; testCapitalize</pre>
<p>Happy testing!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/unit-testing-javascript-with-jsunit/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Overcoming the MySQL BIT datatype problems with hibernate</title>
		<link>http://blog.cherouvim.com/overcoming-the-mysql-bit-datatype-problems-with-hibernate/</link>
		<comments>http://blog.cherouvim.com/overcoming-the-mysql-bit-datatype-problems-with-hibernate/#comments</comments>
		<pubDate>Fri, 15 Jun 2007 18:38:45 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[databases]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/overcoming-the-mysql-bit-datatype-problems-with-hibernate/</guid>
		<description><![CDATA[I&#8217;m fond of optimization. When I code or design my database schema I try to avoid waisting CPU cycles or storage space (at least without a good reason). So when my domain class has the following field: private boolean active; // determines whether this Person is active I will let hibernate and the MySQL5InnoDBDialect choose [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m fond of optimization. When I code or design my database schema I try to avoid waisting CPU cycles or storage space (at least without a good reason). So when my domain class has the following field:</p>
<pre>
private boolean active; // determines whether this Person is active
</pre>
<p>I will let hibernate and the <a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/dialect/MySQL5InnoDBDialect.html">MySQL5InnoDBDialect</a> choose what is most appropriate:</p>
<pre>&lt;property name="active" not-null="true" /&gt;</pre>
<p>In that case it will generate a BIT:</p>
<pre>...
active bit not null,
...</pre>
<h4>The problem</h4>
<p>So far so good&#8230;<br />
&#8230;until you read the blog post called <a href="http://www.xaprb.com/blog/2006/04/11/bit-values-in-mysql/">&#8220;Why you should not use BIT columns in MySQL&#8221;</a> by <a href="http://www.xaprb.com/blog/">Xaprb</a>.<br />
Another serious deficiency is the fact that a database dump will not export bit data as &#8220;0&#8243; or &#8220;1&#8243;. Depending on the tool used to dump and the MySQL server version you may find one of the following:</p>
<pre>INSERT INTO `person` VALUES (1,&quot;foo&quot;,&quot;\\0&quot;);
INSERT INTO `person` VALUES (2,&quot;bar&quot;,&quot;<span style="font-size:1.3em">&#9786;</span>&quot;);</pre>
<p>or</p>
<pre>INSERT INTO `person` VALUES (1,&quot;foo&quot;,&quot;<span style="border: 1px solid black">&nbsp;</span>&quot;);
INSERT INTO `person` VALUES (2,&quot;bar&quot;,&quot;<span style="border: 1px solid black">&nbsp;</span>&quot;);</pre>
<p>The third field is of datatype BIT. Row number 1 is false and row number 2 is true. The problem with that is that some MySQL client tools cannot import such things. It gives you an <em>ERROR 1064 (42000) at line 23: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near &#8221; at line 1</em></p>
<h4>Solution #1</h4>
<p>Hand edit the sql script and change all false bits to 0 and all true bits to 1, the script can be imported like a charm.</p>
<h4>Solution #2</h4>
<p>Extend MySQL5InnoDBDialect and make all BITs rendered as TinyInt(1). The code is very simple:</p>
<pre>package com.foo.hibernate;

import java.sql.Types;
import org.hibernate.dialect.MySQL5InnoDBDialect;

public class MySQL5InnoDBDialectBitFixed extends MySQL5InnoDBDialect {

  public MySQL5InnoDBDialectBitFixed() {
    super();
    registerColumnType(Types.BIT, "tinyint(1)");
  }

}</pre>
<p>Now when using the <code>MySQL5InnoDBDialectBitFixed</code> dialect, hbm2ddl will generate:</p>
<pre>...
active tinyint(1) not null,
...</pre>
<p>Until we get better 5.x MySQL versions, with better BIT support, this plan should do the job nicely.</p>
<p>Good luck</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/overcoming-the-mysql-bit-datatype-problems-with-hibernate/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Runtime dispatching freemarker macros for pojo views</title>
		<link>http://blog.cherouvim.com/runtime-dispatching-freemarker-macros-for-pojo-views/</link>
		<comments>http://blog.cherouvim.com/runtime-dispatching-freemarker-macros-for-pojo-views/#comments</comments>
		<pubDate>Sun, 10 Jun 2007 06:14:21 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[freemarker]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/runtime-dispatching-freemarker-macros-for-pojo-views/</guid>
		<description><![CDATA[One of the (many) reasons I switched from JSP to FreeMarker is that I couldn&#8217;t achieve what I describe in this post. Tutorials or blog posts regarding this situation were never to be found, and in addition it was really hard to find anyone considering this issue a real problem. The problem Suppose we are [...]]]></description>
			<content:encoded><![CDATA[<p>One of the (many) reasons I switched from <a href="http://java.sun.com/products/jsp/" title="JavaServer Pages">JSP</a> to <a href="http://freemarker.sourceforge.net/">FreeMarker</a> is that I couldn&#8217;t achieve what I describe in this post. Tutorials or blog posts regarding this situation were never to be found, and in addition it was really hard to find anyone considering this issue a real problem.</p>
<h4>The problem</h4>
<p>Suppose we are building an <a href="http://en.wikipedia.org/wiki/Issue_tracking_system">issue tracking system</a>. We have a rich <a href="http://www.martinfowler.com/eaaCatalog/domainModel.html">Domain Model</a> which includes entities such as <code>User</code>, <code>Project</code>, <code>Account</code>, <code>Role</code> etc. We&#8217;ve also got an abstract <code>Issue</code> object which is the root of the issue&#8217;s hierarchy. Concrete classes extending <code>Issue</code> include <code>Bug</code>, <code>Feature</code>, <code>Request</code> and <code>Change</code>. These 4 <a href="http://www.martinfowler.com/bliki/POJO.html" title="Plain Old Java Object">POJO</a>s inherit common fields from <code>Issue</code> but add fields, methods and logic of their own.</p>
<p>Each of the issue&#8217;s subclass will need to have a slightly different <a href="http://en.wikipedia.org/wiki/HTML" title="Hypertext Markup Language">HTML</a> view. I tend to use the <a href="http://www.javaworld.com/javaworld/jw-09-2002/jw-0913-designpatterns.html">composite design pattern</a> for my views, so I can break the HTML down to small reusable components. So it is obvious that we&#8217;re going to need 4 different views, one for each of them. Here are those issue rendering methods <small>(presented in an imaginary pseudolanguage which combines <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSPIntro7.html" title="Expression Language">EL</a>, HTML and functions)</small>:</p>
<pre>renderBug(bug) {
  &lt;fieldset&gt;
    &lt;legend&gt;Bug #${bug.id}&lt;/legend&gt;
    &lt;p&gt;Author: ${bug.author}&lt;/p&gt;
    &lt;p&gt;Date: ${bug.date}&lt;/p&gt;
    &lt;p&gt;Description: ${bug.description}&lt;/p&gt;
    &lt;p&gt;Steps to recreate bug: ${bug.stepsToRecreate}&lt;/p&gt;
  &lt;/fieldset&gt;
}

renderFeature(feature) {
  &lt;fieldset&gt;
    &lt;legend&gt;feature #${feature.id}&lt;/legend&gt;
    &lt;p&gt;Author: ${feature.author}&lt;/p&gt;
    &lt;p&gt;Date: ${feature.date}&lt;/p&gt;
    &lt;p&gt;Description: ${feature.description}&lt;/p&gt;
    &lt;p&gt;Related URL: ${feature.url}&lt;/p&gt;
    &lt;p&gt;Screenshot upload: &lt;img src="${feature.screenshot}" /&gt;&lt;/p&gt;
  &lt;/fieldset&gt;
}

...</pre>
<p>Our <a href="http://java.sun.com/blueprints/patterns/DAO.html" title="Data Access Object">DAO</a> (probably called IssueDao) is going to fetch a <code>Collection&lt;Issue&gt;</code> (a bunch of issues) from the database for a particular use case. The runtime type of each of those entities cannot be <code>Issue</code> but it will be <code>Bug</code>, <code>Feature</code>, <code>Request</code> or <code>Change</code>. The problem is that we are presenting them altogether in the same screen, so in order to render them we have to write code such as this:</p>
<pre>foreach(issues as issue) {
  if (issue instanceof Bug) renderBug(issue); continue;
  if (issue instanceof Feature) renderFeature(issue); continue;
  if (issue instanceof Request) renderRequest(issue); continue;
  if (issue instanceof Change) renderChange(issue);
}</pre>
<p>If this doesn&#8217;t seem very bad to you, here is an actual view implementation of a slightly bigger hierarchy using <a href="http://www.oracle.com/technology/pub/articles/cioroianu_tagfiles.html">JSP 2.0 Tag Files</a>:</p>
<pre>if (t instanceof ActivityInternal) {%&gt;&lt;p:activityInternalView pojo="${t}" /&gt;&lt;%;}
if (t instanceof ActivityExternal) {%&gt;&lt;p:activityExternalView pojo="${t}" /&gt;&lt;%;}
if (t instanceof ActivityMilestone) {%&gt;&lt;p:activityMilestoneView pojo="${t}" /&gt;&lt;%;}
if (t instanceof Review) {%&gt;&lt;p:reviewView pojo="${t}" /&gt;&lt;%;}
if (t instanceof PublicationReport) {%&gt;&lt;p:publicationReportView pojo="${t}" /&gt;&lt;%;}
if (t instanceof PublicationWebsite) {%&gt;&lt;p:publicationWebsiteView pojo="${t}" /&gt;&lt;%;}
if (t instanceof InfoConference) {%&gt;&lt;p:infoConferenceView pojo="${t}" /&gt;&lt;%;}
if (t instanceof InfoBase) {%&gt;&lt;p:infoBaseView pojo="${t}" /&gt;&lt;%;}
if (t instanceof InfoChannel) {%&gt;&lt;p:infoChannelView pojo="${t}" /&gt;&lt;%;}
if (t instanceof Meeting) {%&gt;&lt;p:meetingView pojo="${t}" /&gt;&lt;%;}
if (t instanceof Interpretation) {%&gt;&lt;p:interpretationView pojo="${t}" /&gt;&lt;%;}
if (t instanceof BudgetItem) {%&gt;&lt;p:budgetItemView pojo="${t}" /&gt;&lt;%;}
if (t instanceof FocusGeneral) {%&gt;&lt;p:focusGeneralView pojo="${t}" /&gt;&lt;%;}
if (t instanceof FocusResearch) {%&gt;&lt;p:focusResearchView pojo="${t}" /&gt;&lt;%;}
if (t instanceof Risk) {%&gt;&lt;p:riskView pojo="${t}" /&gt;&lt;%;}
if (t instanceof QAChecklist) {%&gt;&lt;p:QAChecklistView pojo="${t}" /&gt;&lt;%;}
if (t instanceof TargetAudience) {%&gt;&lt;p:targetAudienceView pojo="${t}" /&gt;&lt;%;}
if (t instanceof LessonsLearned) {%&gt;&lt;p:lessonsLearnedView pojo="${t}" /&gt;&lt;%;}</pre>
<p>If you still don&#8217;t think this is bad, you can stop reading ;)</p>
<h4>What not to do</h4>
<p>In a project I did in my early JSP days, what I did was to put all the view logic in the Java class! So it looked like this (this is actual Java):</p>
<pre>public class Bug extends Issue {

  ...

  public String renderMe() {
    return "&lt;fieldset&gt;&lt;legend&gt;" + this.getName() + "&lt;/legend&gt;" +
           "&lt;p&gt;Author: " + this.getAuthor() + "&lt;/p&gt;" +
           "&lt;p&gt;Date: " + this.getDate() + "&lt;/p&gt;" +
           "&lt;p&gt;Description: " + this.getDescription() + "&lt;/p&gt;" +
           "&lt;/fieldset&gt;";
  }
}</pre>
<p>Although this type of code is a perfect candidate for <a href="http://worsethanfailure.com/" title="Worse Than Failure">The Daily WTF</a>, the (only) advantage was that I could now render my pojos using (pseudocode):</p>
<pre>foreach(issues as issue) {
  issue.renderMe();
}</pre>
<h4>The solution</h4>
<p>It seems that all we want is the ability to construct and dynamically (reflectively in Java terms) call the appropriate render tag each time. In freemarker we define macros which look like this:</p>
<pre>&lt;#macro renderBug bug&gt;
  &lt;fieldset&gt;
    &lt;legend&gt;Bug #${bug.id}&lt;/legend&gt;
    &lt;p&gt;Author: ${bug.author}&lt;/p&gt;
    &lt;p&gt;Date: ${bug.date}&lt;/p&gt;
    &lt;p&gt;Description: ${bug.description}&lt;/p&gt;
    &lt;p&gt;Steps to recreate bug: ${bug.stepsToRecreate}&lt;/p&gt;
  &lt;/fieldset&gt;
&lt;/#macro&gt;</pre>
<p>We need a way to call renderXXX where XXX is the <a href="http://jakarta.apache.org/commons/lang/api-2.0/org/apache/commons/lang/ClassUtils.html#getShortClassName(java.lang.Class)">short class name</a> of the issue in question. And here is how you can do this in freemarker:</p>
<pre>&lt;#local macroname='render' + issue.class.name?split(".")?last /&gt;
&lt;@.vars[macroname] issue /&gt;</pre>
<p>For an issue of runtime type com.example.Foo, it concatenates the word &#8220;render&#8221; with &#8220;Foo&#8221; and calls the macro with that name. The magic happens with the help of the <a href="http://freemarker.sourceforge.net/docs/ref_specvar.html"><strong>.vars</strong> special variable</a>. It allows us to access variables by name. The full code now becomes:</p>
<pre>&lt;#macro renderIssue issue&gt;
  &lt;#local macroname='render' + issue.class.name?split(".")?last /&gt;
  &lt;@.vars[macroname] issue /&gt;
&lt;/#macro&gt;

&lt;#list issues as issue&gt;
  &lt;@renderIssue issue /&gt;
&lt;/#list&gt;</pre>
<p>By the way, this capability is usually present in dynamic scripting languages. So for example there are many ways to do that in <a href="http://php.net">PHP</a>.</p>
<h5>using dynamic evaluation</h5>
<pre>$functionName = "renderBug";
$functionName($issue);</pre>
<h5>using <a href="http://php.net/eval">eval</a></h5>
<pre>eval("renderBug($issue);");</pre>
<h5>using <a href="http://php.net/call_user_func">call_user_func</a> (probably safest of all)</h5>
<pre>call_user_func("renderBug", $issue);</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/runtime-dispatching-freemarker-macros-for-pojo-views/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Caching pages using ehcache</title>
		<link>http://blog.cherouvim.com/caching-pages-using-ehcache/</link>
		<comments>http://blog.cherouvim.com/caching-pages-using-ehcache/#comments</comments>
		<pubDate>Mon, 04 Jun 2007 18:44:09 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[ehcache]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/caching-pages-using-ehcache/</guid>
		<description><![CDATA[When an http request to your /rss page needs 400 milliseconds to complete, it seems obvious that your website could benefit from some caching. Ehcache is a well known cache provider, which most of us know from hibernate. Since we are already &#8220;bound&#8221; to ehcache, lets see how we can benefit from caching some dynamically [...]]]></description>
			<content:encoded><![CDATA[<p>When an http request to your /rss page needs 400 milliseconds to complete, it seems obvious that your website could benefit from some caching. <a href="http://ehcache.sourceforge.net/">Ehcache</a> is a well known cache provider, which most of us know from <a href="http://hibernate.org/">hibernate</a>. Since we are already &#8220;bound&#8221; to ehcache, lets see how we can benefit from caching some dynamically generated pages:</p>
<h3>web.xml</h3>
<pre>&lt;filter&gt;
  &lt;filter-name&gt;SimplePageCachingFilter&lt;/filter-name&gt;
  &lt;filter-class&gt;net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
  &lt;filter-name&gt;SimplePageCachingFilter&lt;/filter-name&gt;
  &lt;url-pattern&gt;/rss&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</pre>
<p>We set up the <a href="http://ehcache.sourceforge.net/javadoc/net/sf/ehcache/constructs/web/filter/SimplePageCachingFilter.html">SimplePageCachingFilter</a> in the web.xml of the web application and map it to one or more url patterns or servlets. All requests to /rss will be intercepted by the SimplePageCachingFilter.</p>
<h3>ehcache.xml</h3>
<pre>&lt;ehcache&gt;
  &lt;diskStore path="java.io.tmpdir" /&gt;
  &lt;cache name="SimplePageCachingFilter"
         maxElementsInMemory="0"
         eternal="false"
         timeToIdleSeconds="600"
         timeToLiveSeconds="600"
         overflowToDisk="true"/&gt;
&lt;/ehcache&gt;</pre>
<p>We then configure the cache region for pages. We don&#8217;t want any elements kept in memory. Everything should be written to disk at the java.io.tmpdir location. The cache expires every 10 minutes.</p>
<p>Now hitting http://example.com/rss (our default rss page) results in a cache miss. The content is being generated from scratch but before returning to the client, the filter stores it locally. The second time we&#8217;ll get a cache hit. The content now is being fetched from the cache and its very fast. 10 minutes later this cache element will be invalidated. Note that the default implementation uses the <a href="http://en.wikipedia.org/wiki/URI" title="Uniform Resource Identifier">URI</a> together with the <a href="http://en.wikipedia.org/wiki/Query_string">query string</a> to calculate the cache key, so /rss?type=news and /rss?type=forum will result in two different cache elements.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/caching-pages-using-ehcache/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>5 sins of subversion usage</title>
		<link>http://blog.cherouvim.com/5-sins-of-subversion-usage/</link>
		<comments>http://blog.cherouvim.com/5-sins-of-subversion-usage/#comments</comments>
		<pubDate>Sat, 05 May 2007 06:36:15 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[subversion]]></category>
		<category><![CDATA[workplace]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/the-5-sins-of-subversion-usage/</guid>
		<description><![CDATA[Whether you develop alone, or with others, there are some things that you should avoid doing when using subversion (or any other version control system). 1. Break the build and/or tests The problem It&#8217;s very common to break the build because you removed a class or changed a method contract. This can sometimes get frustrating. [...]]]></description>
			<content:encoded><![CDATA[<p>Whether you develop alone, or with others, there are some things that you should avoid doing when using <a href="http://subversion.tigris.org/">subversion</a> (or any other version control system).</p>
<h3>1. Break the build and/or tests</h3>
<h4>The problem</h4>
<p>It&#8217;s very common to break the build because you removed a class or changed a method contract. This can sometimes get frustrating. Others, who continue working on the project, will either have to tell you that you broke the build (thus asking you to fix it), or fix it themselves. This is something that requires communication and time. If more than one person fixes the problems, the possibility of conflicts is high.</p>
<h4>Solution</h4>
<p>a) Do a clean build and run all tests before committing. That is Shift+F11 and ALT+F6 in NetBeans.<br />
b) Use a <a href="http://www.martinfowler.com/articles/continuousIntegration.html" title="Continuous Integration article by Martin Fowler">Continuous Integration</a> system which does this for you.</p>
<h3>2. No comments or bad comments</h3>
<h4>The problem</h4>
<p>Examples of bad comments (yes, the first one is an empty string):</p>
<ul>
<li>&nbsp;</li>
<li>uploaded Member.java</li>
<li>Deleted some files</li>
<li>Improvements</li>
</ul>
<p>These comments are useless. Everybody can see from the log that Member.java was &#8220;uploaded&#8221;, or that some files where deleted. It is also not useful to say &#8220;improvements&#8221;, because it is very general, and also because it&#8217;s common sense that you are working on a project only to improve it (and not to make it worse).</p>
<h4>Solution</h4>
<p>Always write comments about changes in the software, and not about which files have been changed. Try to comment in terms of software modules, requests and bug fixes. You could even use issue numbers from your bug tracking software. Examples of good comments would include:</p>
<ul>
<li>Changed authentication to use cookies instead of the http session</li>
<li>Changed from dbcp to c3p0</li>
<li>First stages of html/css layout integration</li>
<li>mock dao tests</li>
<li>fixed mail scheduler (Issue 5532)</li>
<li>Reporting engine now supports PDF export</li>
</ul>
<p>One of the advantages of having comments such as the above is that you can easily select a range of dates and produce a change log.</p>
<h3>3. Committing useless files</h3>
<h4>The problem</h4>
<p>Some people commit stuff such as:</p>
<ul>
<li><a href="http://www.ofzenandcomputing.com/zanswers/98" title="Thumbs.db - a Windows specific database file">Thumbs.db</a></li>
<li><a href="http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=tn_15237" title="_notes - a Dreamweaver specific folder">_notes</a></li>
<li>/build</li>
<li>/dist</li>
<li>nbproject</li>
</ul>
<p>Sometimes Thumbs.db and _notes end up deployed on the production server. This is useless, bad and inappropriate.</p>
<h4>Solution</h4>
<p>Never commit stuff that should not be committed. Learn how to use the ignore/exclude patterns of your favourite svn client. In <a href="http://tortoisesvn.tigris.org/" title="TortoiseSVN is an SVN client for Windows">TortoiseSVN</a> a the exclude/ignore pattern &#8220;<em>thumbs.db _notes dist build nbproject</em>&#8221; will do the job.</p>
<h3>4. Not committing for days (or weeks)</h3>
<h4>The problem</h4>
<p>A developer does not commit for days (or weeks) because he is lazy, always leaves from work in a rush, or hasn&#8217;t got a compiling application (for days&#8230; or weeks). Some reasons why this is very bad are:</p>
<ol>
<li>Code reviewer can&#8217;t review the code.</li>
<li>Developer might be working on something that has already been done before, but nobody can tell him so.</li>
<li>Developer might be trying to solve problem in a wrong way, but nobody can see that.</li>
<li>Anxiety levels of Project Lead increases because he doesn&#8217;t know about work being done.</li>
<li>Merging becomes really hard due to many (and difficult to resolve) conflicts.</li>
<li>The possibility of completely loosing work increases as hard drives tend to fail when you least expect it.</li>
</ol>
<h4>Solution</h4>
<p>Commit at least once a day. If you are working on a feature or fix that is completely unrelated with work that others do, consider <a href="http://nedbatchelder.com/text/quicksvnbranch.html" title="Subversion branching quick start">branching</a>.</p>
<h3>5. Not following naming/structure conventions</h3>
<h4>The problem</h4>
<p>When a repository is shared between many different people with many different projects, things can get messy:</p>
<pre>svn://192.168.1.44/2006-playboy_website
svn://192.168.1.44/COCA_COLA
svn://192.168.1.44/JAVA-DEVELOPMENT/coca-cola-project
svn://192.168.1.44/JAVA-DEVELOPMENT/coca-cola-project-DELETE_THIS
svn://192.168.1.44/JAVA-DEVELOPMENT/coca-cola-project-static-layout
svn://192.168.1.44/Project_1
svn://192.168.1.44/backup/Project_1
svn://192.168.1.44/backup/coca-cola-project-DELETE_THIS
svn://192.168.1.44/dynamic site coca cola
svn://192.168.1.44/important_docs
svn://192.168.1.44/java-projects
svn://192.168.1.44/java-projects/bar
svn://192.168.1.44/java-projects/foo
svn://192.168.1.44/java-projects/foo_1
svn://192.168.1.44/java-projects/foo_old
svn://192.168.1.44/playboy_PROPOSAL_2002
svn://192.168.1.44/project1
svn://192.168.1.44/project1_
svn://192.168.1.44/οι εικόνες</pre>
<h4>Solution</h4>
<p>Use naming and structure conventions. Make up your own, propose them in your team and adopt them. A possible convention could be:</p>
<ol>
<li>Only lower case in folders</li>
<li>No native characters in folders</li>
<li>Only dashes in folders (no spaces or underscores)</li>
<li>Folder structure always uses <em>root/account name/project name/project artifact</em></li>
</ol>
<p>These simple rules greatly improve company&#8217;s xyz repository structure:</p>
<pre>svn://192.168.1.44/coca-cola/dynamic-site/documents
svn://192.168.1.44/coca-cola/dynamic-site/project
svn://192.168.1.44/coca-cola/old-stuff
svn://192.168.1.44/coca-cola/static-site/old-site
svn://192.168.1.44/coca-cola/static-site/site1
svn://192.168.1.44/playboy/dynamic-site/community
svn://192.168.1.44/playboy/dynamic-site/forum
svn://192.168.1.44/playboy/dynamic-site/project
svn://192.168.1.44/playboy/proposals
svn://192.168.1.44/playboy/static-site/old-site
svn://192.168.1.44/playboy/static-site/site1
svn://192.168.1.44/xyz/cms/project
svn://192.168.1.44/xyz/cms/static-layout
svn://192.168.1.44/xyz/interns/documents
svn://192.168.1.44/xyz/interns/nick
svn://192.168.1.44/xyz/interns/project-1
svn://192.168.1.44/xyz/interns/test-project
svn://192.168.1.44/xyz/website/layout-1
svn://192.168.1.44/xyz/website/layout-2
svn://192.168.1.44/xyz/website/layout-3</pre>
<p>Good luck.</p>
<p><small>Interesting reads:<br />
- <a href="http://developer.kde.org/policies/commitpolicy.html" title="KDE SVN Commit Policy">KDE SVN Commit Policy</a><br />
- <a href="http://svnbook.red-bean.com/nightly/en/index.html" title="Version Control with Subversion">Version Control with Subversion</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/5-sins-of-subversion-usage/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>SQL Server + hbm2ddl + unicode columns</title>
		<link>http://blog.cherouvim.com/sql-server-hbm2ddl-unicode-columns/</link>
		<comments>http://blog.cherouvim.com/sql-server-hbm2ddl-unicode-columns/#comments</comments>
		<pubDate>Tue, 01 May 2007 08:21:25 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[databases]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/sql-server-hbm2ddl-unicode-columns/</guid>
		<description><![CDATA[Hibernate offers org.hibernate.dialect.SQLServerDialect as the dialect for SQL Server. When generating the database schema, using hbm2ddl, the string type columns do not support native characters. So the following mapping: &#60;property name="title" length="128" /&#62; will produce the following SQL: ... title varchar(128) null, ... By extending the org.hibernate.dialect.SQLServerDialect we can achieve the generation of NCHAR, NVARCHAR, [...]]]></description>
			<content:encoded><![CDATA[<p>Hibernate offers <code><a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/dialect/SQLServerDialect.html">org.hibernate.dialect.SQLServerDialect</a></code> as the dialect for <a href="http://en.wikipedia.org/wiki/Microsoft_SQL_Server" title="Microsoft SQL Server">SQL Server</a>. When generating the database schema, using <a href="http://www.hibernate.org/hib_docs/v3/reference/en/html/toolsetguide.html">hbm2ddl</a>, the string type columns do not support native characters. So the following mapping:</p>
<pre>&lt;property name="title" length="128" /&gt;</pre>
<p>will produce the following SQL:</p>
<pre>...
title varchar(128) null,
...</pre>
<p>By extending the <code>org.hibernate.dialect.SQLServerDialect</code> we can achieve the generation of NCHAR, NVARCHAR, and NTEXT columns instead of CHAR, VARCHAR and TEXT.</p>
<pre>package com.foo.hibernate;

import java.sql.Types;
import org.hibernate.dialect.SQLServerDialect;

public class SQLServerNativeDialect extends SQLServerDialect{

  public SQLServerNativeDialect() {
    super();
    registerColumnType(Types.CHAR, "nchar(1)");
    registerColumnType(Types.VARCHAR, "nvarchar($l)");
    registerColumnType(Types.LONGVARCHAR, "nvarchar($l)");
    registerColumnType(Types.CLOB, "ntext");
  }

}</pre>
<p>All we need to do now is plug this dialect in our hibernate configuration:</p>
<pre>&lt;property name="hibernate.dialect"&gt;
  com.foo.hibernate.SQLServerNativeDialect
&lt;/property&gt;</pre>
<p><small>Related hibernate forums thread: <a href="http://forum.hibernate.org/viewtopic.php?t=972518">http://forum.hibernate.org/viewtopic.php?t=972518</a><br />
Related API method: <a href="http://www.hibernate.org/hib_docs/v3/api/org/hibernate/dialect/Dialect.html#registerColumnType(int,%20int,%20java.lang.String)">http://www.hibernate.org/hib_docs/v3/api/org/hibernate/dialect/Dialect.html</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/sql-server-hbm2ddl-unicode-columns/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Learn to use the debugger</title>
		<link>http://blog.cherouvim.com/learn-to-use-the-debugger/</link>
		<comments>http://blog.cherouvim.com/learn-to-use-the-debugger/#comments</comments>
		<pubDate>Mon, 30 Apr 2007 19:51:27 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[ide]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/learn-to-use-the-debugger/</guid>
		<description><![CDATA[Your favourite IDE has a powerful debugger which you can use to debug your programs. If you are new to programming, chances are that you are aware of it&#8217;s existence, but never use it. The problem Here is an example method, which has a problem. (It actually does nothing of value, but demonstrates the problem [...]]]></description>
			<content:encoded><![CDATA[<p>Your favourite <a href="http://en.wikipedia.org/wiki/Integrated_Development_Environment" title="Integrated Development Environment">IDE</a> has a powerful debugger which you can use to debug your programs. If you are new to programming, chances are that you are aware of it&#8217;s existence, but never use it.</p>
<h3>The problem</h3>
<p>Here is an example method, which has a problem. (It actually does nothing of value, but demonstrates the problem case). The method <em>doSomething</em> is called with a parameter, but the expected result is not returned.</p>
<pre>public Box doSomething(Box foo, Box bar) {
  Box temp = foo.cloneMe();
  if (bar!=null) {
    Box newBox = new Box(bar);
    if (newBox!=null) {
      temp = doSomethingElse(foo);
      if (foo==null) {
        temp = bar;
      }
    }
  }
  return temp;
}</pre>
<p>Here you can see the most frequent (ab)use of <em>System.out.println</em> statements. </p>
<pre>public Box doSomething(Box foo, Box bar) {
<strong>  System.out.println("1");</strong>
  Box temp = foo.cloneMe();
  if (bar!=null) {
<strong>    System.out.println("2");</strong>
    Box newBox = new Box(bar);
    if (newBox!=null) {
<strong>      System.out.println("3");</strong>
      temp = doSomethingElse(foo);
      if (foo==null) {
<strong>        System.out.println("4");</strong>
        temp = bar;
      }
    }
  }
  return temp;
}</pre>
<p>The developer&#8217;s intent is to trace which if-statements execute, so as to find the bug. If <em>1 2 3</em> is displayed in the console, the developer knows that <em>foo==null</em> evaluated to false.</p>
<p>An &#8220;enhancement&#8221; of this method is to add variables of interest in those System.out.println statements.</p>
<pre>public Box doSomething(Box foo, Box bar) {
  System.out.println(<strong>"1: " + foo + " " + bar</strong>);
  Box temp = foo.cloneMe();
  if (bar!=null) {
    System.out.println(<strong>"2: " + temp</strong>);
    Box newBox = new Box(bar);
    if (newBox!=null) {
      System.out.println(<strong>"3: " + newBox</strong>);
      temp = doSomethingElse(foo);
      if (foo==null) {
        System.out.println(<strong>"4: " + temp</strong>);
        temp = bar;
      }
    }
  }
  return temp;
}
</pre>
<p>This is one of the most crude ways to debug a program. Unfortunately it&#8217;s quite common between junior developers. Note that if logging needs to be performed (for monitoring or historical purposes) a <a href="http://logging.apache.org/log4j/docs/">proper logging framework</a> has to be used.</p>
<p>Things get interesting when the developer forgets to delete those System.out.println statements. The application is deployed, in a servlet container which hosts more applications, featuring code &#8220;debugged&#8221; in this way.<br />
It&#8217;s not rare to see catalina.out logs which look like this:</p>
<pre>INFO: Find registry server-registry.xml at classpath resource
20 Απρ 2007 10:23:24 μμ org.apache.catalina.startup.Catalina start
INFO: Server startup in 14063 ms
20 Απρ 2007 10:23:24 μμ org.apache.catalina.core.StandardContext reload
INFO: Reloading this Context has started
1
2
is null
3
copying file pic_01.jpg->temp/pic_01.jpg
copying file pic_02.jpg->temp/pic_02.jpg
copying file pic_03.jpg->temp/pic_03.jpg
copying file pic_06.jpg->temp/pic_06.jpg
1
2
is null
3
true
4
5
6

** BEGIN NESTED EXCEPTION ** 

java.net.ConnectException
MESSAGE: Connection refused: connect

STACKTRACE:

java.net.ConnectException: Connection refused: connect
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
...
is null
false
java.lang.NullPointerException
BoxExample$Box@126b249
1
2
is null
3
resultset was null
1
resultset was null
...</pre>
<h3>The solution</h3>
<p>Learn to use your debugger. All you have to do is go to the line you want debugging to start, set a breakpoint (CTRL+F8 in <a href="http://www.netbeans.org/">Netbeans</a>) and start the debug process. You will either debug the whole application (F5) or that single file/unit test (CTRL+SHIFT+F5).<br />
You can set watches, see the stacktrace and examine the contents of all the local variables at any time in the program execution. You get orders of magnitude more power, in less time; for free!</p>
<p>Try it out. When you get used to it, you&#8217;ll never look back.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/learn-to-use-the-debugger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test First (#1)</title>
		<link>http://blog.cherouvim.com/test-first-1/</link>
		<comments>http://blog.cherouvim.com/test-first-1/#comments</comments>
		<pubDate>Sat, 28 Apr 2007 07:44:00 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[ide]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[xp]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/test-first-1/</guid>
		<description><![CDATA[Unit testing not only ensures that the code you write is correct, but also helps you develop your code. This can be achieved by testing unimplemented methods and functionalities first, and then &#8220;filling in&#8221; the code to satisfy the tests. This is the &#8220;test first&#8221; rule that your XP coworker will always remind you, at [...]]]></description>
			<content:encoded><![CDATA[<p>Unit testing not only ensures that the code you write is correct, but also helps you develop your code. This can be achieved by testing unimplemented methods and functionalities first, and then &#8220;filling in&#8221; the code to satisfy the tests. This is the <a href="http://www.extremeprogramming.org/rules.html">&#8220;test first&#8221; rule</a> that your <a href="http://en.wikipedia.org/wiki/Extreme_programming" title="Extreme Programming">XP</a> coworker will always remind you, at any occasion. <small>(You do have an XP coworker, don&#8217;t you? :)</small></p>
<h3>The Requirement</h3>
<p>Suppose you have a webapp which displays some data from a database. Some of those texts are long, and you are asked to be able to truncate them at predefined lengths on some particular views. So instead of printing &#8220;Lorem ipsum dolor sit&#8221; you should be able to fit that in 12 chars and print &#8220;Lorem ips&#8230;&#8221;.</p>
<h3>Wait</h3>
<p>The first worst thing you could do there would be to stick that logic straight into the view (JSP, velocity or whatever templating engine you use). You will not be able to test that piece of logic, nor easily reuse it in some other project. You will need to do this in a Java class and then find a way to call it from the template. </p>
<p>The second worst thing you could do would be to implement this functionality yourself, as it already exists in <a href="http://jakarta.apache.org/commons/lang/api-release/org/apache/commons/lang/StringUtils.html#abbreviate(java.lang.String,%20int)">commons lang</a>. You should know what APIs exist out there and try to reuse as often as possible. But anyhow, we&#8217;ll assume that you want to do it yourself.</p>
<h3>Think</h3>
<p>You start by thinking of where to place this method and whether it will be a helper (static?) method or part of a full fledged class with state etc. Then you choose a good method name and what parameters it will accept. Think of how you would like to use this method.</p>
<h3>Code</h3>
<p>You write the method signature:</p>
<pre>public static String truncate(String text, int length) {
}</pre>
<p>Then fill it&#8217;s body to the absolute minimum to make it &#8220;compilable&#8221;:</p>
<pre>public static String truncate(String text, int length) {
<strong>  throw new RuntimeException("not implemented");</strong>
}</pre>
<p>&#8230;or&#8230;</p>
<pre>public static String truncate(String text, int length) {
<strong>  return "";</strong>
}</pre>
<p>And then <strong>stop</strong>, because that&#8217;s all you need to implement for now.</p>
<h3>Test</h3>
<p>You create a test (hit CTRL+SHIFT+U if you use <a href="http://www.netbeans.org/" title="NetBeans">http://www.netbeans.org/</a>) and create a test for the method <code>truncate</code></p>
<pre>public void testTruncate() {
}</pre>
<p>This test passes, because it doesn&#8217;t test anything. You make things more interesting by adding some basic assertions of what you expect from this method.</p>
<pre>public void testTruncate() {
<strong>  assertEquals("Lorem ip...", Demo.truncate("Lorem ipsum dolor sit", 11));
  assertEquals("Lorem ips...", Demo.truncate("Lorem ipsum dolor sit", 12));
  assertEquals("Lorem ipsu...", Demo.truncate("Lorem ipsum dolor sit", 13));</strong>
}</pre>
<p>You run the test and it fails.<br />
You go back to the source code and implement some logic to satisfy this test.</p>
<h3>Code</h3>
<pre>public static final String truncate(String text, int length) {
<strong>  return text.substring(0, length-3) + "...";</strong>
}</pre>
<p>You run the test and it now passes.</p>
<h3>Test</h3>
<p>It&#8217;s time to test for some corner cases.</p>
<pre>public void testTruncate() {
  <strong>assertEquals("", Demo.truncate("Lorem", 0));
  assertEquals(".", Demo.truncate("Lorem", 1));
  assertEquals("..", Demo.truncate("Lorem", 2));
  assertEquals("...", Demo.truncate("Lorem", 3));</strong>
  assertEquals("Lorem ip...", Demo.truncate("Lorem ipsum dolor sit", 11));
  assertEquals("Lorem ips...", Demo.truncate("Lorem ipsum dolor sit", 12));
  assertEquals("Lorem ipsu...", Demo.truncate("Lorem ipsum dolor sit", 13));
<strong>  assertEquals("Lorem ipsum dolor sit", Demo.truncate("Lorem ipsum dolor sit", 21));</strong>
}</pre>
<p>All new assertions fail with a <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/StringIndexOutOfBoundsException.html">StringIndexOutOfBoundsException</a>. You write code to satisfy these corner cases.</p>
<h3>Code</h3>
<pre>public static final String truncate(String text, int length) {
<strong>  switch(length) {
    case 0: return "";
    case 1: return ".";
    case 2: return "..";
    case 3: return "...";
    default:
      return length&lt;text.length() ?
        text.substring(0, length-3) + "..." :
        text;
  }</strong>
}</pre>
<p>You run the test and it now passes.</p>
<h3>Test</h3>
<p>Then you test even more.</p>
<pre>public void testTruncate() {
  assertEquals("", Demo.truncate("Lorem", 0));
  assertEquals(".", Demo.truncate("Lorem", 1));
  assertEquals("..", Demo.truncate("Lorem", 2));
  assertEquals("...", Demo.truncate("Lorem", 3));
  assertEquals("Lorem ip...", Demo.truncate("Lorem ipsum dolor sit", 11));
  assertEquals("Lorem ips...", Demo.truncate("Lorem ipsum dolor sit", 12));
  assertEquals("Lorem ipsu...", Demo.truncate("Lorem ipsum dolor sit", 13));
  assertEquals("Lorem ipsum dolor sit", Demo.truncate("Lorem ipsum dolor sit", 21));
<strong>  try {
    Demo.truncate("Lorem ipsum dolor sit", -1);
    fail("Should have thrown illegal argument exception");
  } catch (IllegalArgumentException expected) { }</strong>
}</pre>
<p>This is a standard idiom for testing that an exception should be thrown. If this method is called with a negative length parameter, we&#8217;d like an <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/IllegalArgumentException.html">IllegalArgumentException</a> to be thrown. It is not mandatory to test for things like these, but some people like to seal their methods from really bad usage.</p>
<h3>Code</h3>
<pre>public static final String truncate(String text, int length) {
<strong>  if (length&lt;0) {
    throw new IllegalArgumentException("Length cannot be negative");
  }</strong>
  switch(length) {
    case 0: return "";
    case 1: return ".";
    case 2: return "..";
    case 3: return "...";
    default:
      return length&lt;text.length() ?
        text.substring(0, length-3) + "..." :
        text;
  }
}</pre>
<p>You run the test and it now passes. You are done.</p>
<h3>Conclusion</h3>
<p>This implementation might not be the best in the world, but right now this doesn&#8217;t matter. The code runs, and it&#8217;s robust. Whenever you feel like, you can <a href="http://en.wikipedia.org/wiki/Code_refactoring">refactor</a> it and make it perform better. The test will be there to guide you.</p>
<p>p.s What we&#8217;ve omitted when we wrote the signature of this method, was to write <a href="http://java.sun.com/j2se/javadoc/">Javadoc</a>. It is very important to document your API, and we&#8217;ll discuss that in another post.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/test-first-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learn to use Google</title>
		<link>http://blog.cherouvim.com/learn-to-use-google/</link>
		<comments>http://blog.cherouvim.com/learn-to-use-google/#comments</comments>
		<pubDate>Tue, 03 Apr 2007 19:01:20 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[google]]></category>
		<category><![CDATA[workplace]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/learn-to-use-google/</guid>
		<description><![CDATA[What is Google Google is the best search engine around. It is very user friendly, easy to use and has tons of features. By using Google you can have all the knowledge in the world, available to you; in a snap. The Problem Although the facts above sound very nice, and everybody seems to be [...]]]></description>
			<content:encoded><![CDATA[<h3>What is Google</h3>
<p><a href="http://google.com/">Google</a> is the best search engine around. It is very user friendly, easy to use and has tons of <a href="http://www.google.com/help/features.html">features</a>. By using Google you can have all the knowledge in the world, available to you; in a snap.</p>
<h3>The Problem</h3>
<p>Although the facts above sound very nice, and everybody seems to be using Google, it is still (on 2007) considered natural for non technical people (my mom, your mom etc) to <b>be hands tied</b> and <b>feel &#8220;blind&#8221;</b> when using the <a href="http://en.wikipedia.org/wiki/Internet">Internet</a>. It is not expected from them to be able to find the information they want, easily and accurately, although this is not hard at all.</p>
<p>When talking for technical people though (developers, designers, analysts, managers etc) it is <b>completely unacceptable</b> when one (or more) of the following behaviors are observed:</p>
<ol>
<li>Complete ignorance of the search engine (rare).</li>
<li>Boredom to such degree where searching is not an option (common).</li>
<li>Inability to find correct search keywords for the topic in question (common).</li>
<li>Incompetence to use <a href="http://www.mozilla.com/en-US/firefox/">Firefox</a> properly (Tabs, Search Bar, maximal use of keyboard) in a degree that makes searching slower than it should be, thus turning away the individual from searching as often as possible (common).</li>
<li>&#8220;Can&#8217;t be bothered-I&#8217;ll ask my co-worker&#8221; syndrome (very common).</li>
<li>&#8220;I give up, this is not possible &#8211; has not been done before&#8221; syndrome (rare).</li>
</ol>
<h3>The Facts</h3>
<p>These behaviors are definite showstoppers. They make you a less productive and irritated person. No need to analyze that further.</p>
<h3>The Solutions</h3>
<ul>
<li>Do you observe such behaviors on your employees? Time for a chat with them. Have someone show them how <a href="http://thinkprogress.org/2006/10/23/bush-says-he-uses-the-google/">&#8220;the Google&#8221; works</a>.</li>
<li>Do you observe such behaviors on you; on your daily work routine? You can do better &#8211; and please start <b>today</b>!</li>
</ul>
<h3>And why do you care?</h3>
<p>I&#8217;ve been watching people, engaging into long discussions with other people about that tool&#8230; that <a href="http://www.w3.org/Style/CSS/">css</a> compressor tool that has been mentioned once in a meeting&#8230; which meeting? Yes, that meeting, oh yes&#8230; and what does it do? It strips whitespace and makes the css file less readable and blah blah blah&#8230;<br />
- google: <a href="http://www.google.com/search?q=css+compressor">css compressor</a><br />
1st result</p>
<p>I&#8217;ve been watching people, trying to explain what they want to achieve, and whether it is possible. They want an <a href="http://en.wikipedia.org/wiki/AJAX">ajax</a> thingy which will update part of the screen without refreshing the whole screen (irony?), which will be displaying chat messages from many people, possibly by polling the server every so ofter&#8230; blah blah blah<br />
- google: <a href="http://www.google.com/search?q=ajax+chat+example+poll+server">ajax chat example poll server</a><br />
1st result</p>
<p>I&#8217;ve seen people lifting themselves (literally) from their seat, walking down the aisle, to ask a colleague to give them (yes <i>give them</i>) the <a href="http://en.wikipedia.org/wiki/URL">URL</a> where from they can download <a href="http://www.netbeans.org/">NetBeans</a>!<br />
- google: <a href="http://www.google.com/search?q=download netbeans">download netbeans</a><br />
1st result</p>
<h3>Conclusion</h3>
<p>Man&#8230; it&#8217;s not that hard. Make your lives easier, and let the people around you work! If you don&#8217;t know how to use Google, then google for a google tutorial :)</p>
<p>Happy googling&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/learn-to-use-google/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Unit testing needs time?</title>
		<link>http://blog.cherouvim.com/unit-testing-needs-time/</link>
		<comments>http://blog.cherouvim.com/unit-testing-needs-time/#comments</comments>
		<pubDate>Tue, 20 Mar 2007 15:59:23 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[workplace]]></category>
		<category><![CDATA[xp]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/unit-testing-needs-time/</guid>
		<description><![CDATA[New developers will sometimes complain about how Unit Testing requires a lot of time. How much it slows them down, and how they cannot see any good in writing tests for their code. There are many scenarios which prove that unit testing is necessary. These include speed of development, ability to refactor easily, test-driven development, [...]]]></description>
			<content:encoded><![CDATA[<p>New developers will sometimes complain about how <a href="http://en.wikipedia.org/wiki/Unit_testing">Unit Testing</a>  requires a lot of time. How much it slows them down, and how they cannot  see any good in writing tests for their code.<br />
There are many scenarios which prove that unit testing is necessary. These include speed of development, ability to refactor easily, <a href="http://en.wikipedia.org/wiki/Test_driven_development">test-driven  development</a>, testing without the need of web container, <a href="http://www.mockobjects.com/">testing with mock objects</a> etc.</p>
<p>My favorite though is the &#8220;client calls to report something weird&#8221; scenario. I&#8217;ve seen it many times and it goes something like this:</p>
<h3>Scenario:</h3>
<ol>
<li>Your webapp is deployed, weeks ago, and you&#8217;ve moved on with a new, exciting project. Everything is feels good, as you&#8217;ve completely forgotten about sins of the past (not writing tests)</li>
<li>Client calls you to report &#8220;something weird&#8221;.</li>
<li>You stop whatever you are doing at that moment to switch to that project.</li>
<li>You connect (VPN or whatever) to the remote server to see possibly logged exceptions.</li>
<li>You collect your data.</li>
<li>You try to reproduce the error locally, on the development server.</li>
<li>You find the bug.</li>
<li>You issue the bug in the bug tracking system.</li>
<li>You fix the bug.</li>
<li>You build for deployment.</li>
<li>You deploy (while solving any possible application version issues).</li>
<li>You contact the client.</li>
<li>Wait for his confirmation that the bug has been corrected.</li>
<li>You deliver the bug in the issue tracking system.</li>
<li>Finally you commit the code back to <a href="http://en.wikipedia.org/wiki/Subversion_%28software%29" title="Subversion">SVN</a>.</li>
</ol>
<p><small><em>&#8230;or in whatever order feels more natural to you.</em></small></p>
<p>If the above scenario feels OK, and you need some hints on why you should try to minimize such cases, have a look at the costs involved:</p>
<h3>Costs:</h3>
<ul>
<li>All of these actions need time. Your time.</li>
<li>Most of them require a context switch. Not only you lose X minutes from your previous work, but also need Y minutes to get back into the flow (mind state) you had previously.</li>
<li>Some of these steps might not be what you really want to be doing (talking directly to the client).</li>
<li>You become a slow worker producing bad code.</li>
<li>People will never trust you with that mission critical application, because your code has a tendency to develop &#8220;random features&#8221; on runtime (usually involving exciting names such as <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/NullPointerException.html" title="java.lang.NullPointerException">NullPointerException</a>).</li>
</ul>
<h3>Facts:</h3>
<p>This scenario can definitely happen for tested code. Bugs will always creep into your code no matter what. The point is try to at least minimize the stupid ones. Cases which can easily be covered by unit tests.<br />
Unit testing <strong>is important</strong> (if not mandatory). If you feel that it needs time, you have to press yourself and do it. It&#8217;s a matter of weeks until you become <a href="http://junit.sourceforge.net/doc/testinfected/testing.htm">test infected</a> and experience how your software becomes better in less time.</p>
<h3>Hints for NetBeans users:</h3>
<ul>
<li>Got a class that you want to create a <a href="http://junit.sourceforge.net/">JUnit</a> test for? <strong>CTRL+SHIFT+U</strong></li>
<li>Got a class and want to jump to the unit test (and vice versa)? <strong>ALT+SHIFT+E</strong></li>
<li>Want to test the project? <strong>ALT+F6</strong></li>
</ul>
<p>Happy testing.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/unit-testing-needs-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unobtrusive JavaScript</title>
		<link>http://blog.cherouvim.com/unobtrusive-javascript/</link>
		<comments>http://blog.cherouvim.com/unobtrusive-javascript/#comments</comments>
		<pubDate>Mon, 19 Mar 2007 19:42:01 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/unobtrusive-javascript/</guid>
		<description><![CDATA[JavaScript. Yes, it does happen sometimes. Someone asks you to add some client side functionality in your webapp, and you start vomiting js code straight into your (x)html templates. That is very very bad, and you should stop immediately. Since it&#8217;s 2007, and given that you want to evolve and keep enjoying what you are [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Javascript">JavaScript</a>. Yes, it does happen sometimes. Someone asks you to add some client side functionality in your webapp, and you start vomiting js code straight into your (x)html templates. That is very very bad, and you should stop immediately. Since it&#8217;s 2007, and given that you want to evolve and keep enjoying what you are doing, here is how you should start thinking about client side code.</p>
<p><a href="http://en.wikipedia.org/wiki/Separation_of_concerns">Separation of concerns</a>. Years ago, we used to do our presentation inside our (x)html templates. Then we figured our <a href="http://csszengarden.com/" title="CSS Zen Garden">how to do it using CSS</a>. Years ago, we used to do all our persisted data (from database) to Objects translation, inside our <acronym title="Plain Old Java Objects">POJOs</acronym>. Then we started using <a href="http://en.wikipedia.org/wiki/Data_Access_Object" title="Data Access Objects">DAOs</a>. Separation is what makes software scale. Unless you are only &#8220;engineering&#8221; basic contact forms and guestbooks, you should try to embrace separation of concerns and layering, which will make your life easier.</p>
<p>So, back to JavaScript. The idea is to <a href="http://onlinetools.org/articles/unobtrusivejavascript/">apply your behaviors in an unobtrusive way</a>. Add a class, if necessary, to the elements you want to enhance, and apply the new functionality when the document loads.</p>
<h3>Example:</h3>
<p>You want to apply duplication functionality in some paragraphs. Clicking on those paragraphs, which have a class &#8220;duplicate&#8221;, will make them duplicate themselves.</p>
<h3>HTML:</h3>
<pre>&lt;p class="duplicate"&gt;Click me!&lt;/p&gt;</pre>
<p>You&#8217;ve got a little piece of nice (x)html. Google does not care what you are going to do on the client side. Screen readers and most mobiles won&#8217;t care as well. Why feed them anything more than pure accessible semantic markup? All client side code goes on a separate file, which on load will apply the behavior.</p>
<h3>JavaScript:</h3>
<pre>// when window has loaded
window.onload=init;

  function init() {

  // if browser is capable
  if(document.getElementById) {

    // get all &lt;p&gt;
    var ps = document.getElementsByTagName('p');
    for(var i=0,length=ps.length; i&lt;length; i++) {

      // if paragraph element has class 'duplicate'
      if (p[i].className.indexOf('duplicate')&gt;=0) {

        // apply behavior
        ps[i].onclick=function() {
          this.parentNode.appendChild(this.cloneNode(true));
        };
      }
    }
  }
}</pre>
<p><a href="/demos/duplicate/" title="A demo for unobtrusive JavaScript">Live Demo</a><br />
The first disadvantage here is that we have to write tedious <acronym title="Document Object Model">DOM</acronym> manipulation code. The second is that we have to do browser detection. In this simple example this is not so painful, but when you want to do complex stuff (possibly with asynchronous calls) there will be lots of code for browser compatibility. The third (and most important) problem is that this code will start executing only when the window has finished rendering. In complex documents and slow connections this will be seen.<br />
The answer to all those problems comes with lightweight JavaScript libraries. Have a look at the same code, written in <a href="http://jquery.com/">jQuery</a>:</p>
<pre>
// when window has loaded
$(function(){

  // for all p with class duplicate which will be clicked
  $('p.duplicate').click(function() {

    // apply behavior
    $(this).parent().append($(this).clone());
  })
})</pre>
<p>The best advice of course is to avoid use of JavaScript at any cost. <a href="http://en.wikipedia.org/wiki/IE6" title="Internet Exploder 6">IE6</a>, a very popular browser, <a href="http://www.bazon.net/mishoo/articles.epl?art_id=824">memory leaks</a> very badly, which is another reason to try and keep JavaScript code to the absolute minimum.<br />
Good luck.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/unobtrusive-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tomcat vs JBoss Web</title>
		<link>http://blog.cherouvim.com/tomcat-vs-jboss-web/</link>
		<comments>http://blog.cherouvim.com/tomcat-vs-jboss-web/#comments</comments>
		<pubDate>Wed, 14 Mar 2007 14:58:14 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[jboss]]></category>
		<category><![CDATA[jmeter]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/tomcat-vs-jboss-web/</guid>
		<description><![CDATA[JBoss Web is a web server and servlet container at the same time. It&#8217;s promise is that it can serve static and dynamic content, very fast, without the need of an Apache HTTPD fronting it. If that&#8217;s true, its party time, and I personally live for the day where it will be easy to get [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jboss.com/products/jbossweb">JBoss Web</a> is a web server and servlet container at the same time. It&#8217;s promise is that it can serve static and dynamic content, very fast, without the need of an <a href="http://httpd.apache.org/">Apache HTTPD</a> fronting it. If that&#8217;s true, its <strong>party time</strong>, and I personally live for the day where it will be easy to get Java 5 enabled hosting for ~5USD/month (as it is the case today with <a href="http://en.wikipedia.org/wiki/LAMP_%28software_bundle%29" title="Linux Apache MySQL PHP">LAMP</a> stacks).</p>
<p>JBoss Web uses <a href="http://apr.apache.org/" title="Apache Native Runtime">APR</a> and native extensions in order to achieve better utilization of the resources of the O/S. Note that APR is also <a href="http://tomcat.apache.org/tomcat-5.5-doc/apr.html" title="APR and Tomcat">available for Tomcat</a> now.</p>
<p>I&#8217;ve decided to give JBoss Web a try, locally, and stress test it against a regular Tomcat. Note that what I did was done for pure fun (and out of curiosity). I do not own a lab, I am definitely not a stress test expert and I do not understand many things at the low level (I/O, threads etc).</p>
<h3>Test info</h3>
<ol>
<li><a href="http://jakarta.apache.org/jmeter/">JMeter</a> was used and it was running on the same machine with the servers tested.</li>
<li>During tests JMeter would use ~30% of cpu, and the server would consume the rest ~70%.</li>
<li>O/S was Windows XP SP2 on an AMD64 3000+ with 1.5GB ram.</li>
<li>Java 1.5.0_06 on -server mode for both servers.</li>
<li>Default installations of JBoss Web 1.0.1 GA and Tomcat 5.5.23 were used.</li>
<li>-Xms and -Xmx settings were not altered. Don&#8217;t think it mattered.</li>
<li>I stress tested 10 URLs of a very small webapp with a front controller delegating to cached <a href="http://freemarker.sourceforge.net/">freemarker</a> views. No logging, no persistence or database calls. JBoss&#8217; CONSOLE appender&#8217;s threshold was changed to FATAL, to avoid any logging output which would slow down things. The most interesting operations in the webapp would be the GZIP filter, and multipart request using <a href="http://jakarta.apache.org/commons/fileupload/">commons fileupload</a>.</li>
<li>Warm up of the servers was performed. I found out that even for small amount of concurrent threads hitting the server, if these all start immediately, it&#8217;s most likely you&#8217;ll get some <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes" title="500 Internal Server Error">500s</a> at the beginning. The warm up would be anything between 2500-5000 requests until the server throughput was stabilized.</li>
<li>When the server was warmed up, I would get my sample from the next 5000-10000 requests.</li>
<li>The &#8220;threads&#8221; column in the results table, is the amount of concurrent threads which where hitting the server.</li>
<li>An http cookie manager was used on JMeter, so 10000 sessions were <em>not</em> being created.</li>
</ol>
<h3>Results</h3>
<table class="table">
<tr>
<th>threads</th>
<th>Tomcat 5.5.23</th>
<th>JBoss Web 1.0.1</th>
</tr>
<tr>
<td>50</td>
<td class="good">95 requests/sec</td>
<td class="good">88 requests/sec</td>
</tr>
<tr>
<td>75</td>
<td class="good">105 requests/sec</td>
<td class="good">95 requests/sec</td>
</tr>
<tr>
<td>100</td>
<td class="good">123 requests/sec</td>
<td class="good">100 requests/sec</td>
</tr>
<tr>
<td>125</td>
<td class="good">75 requests/sec</td>
<td class="good">104 requests/sec</td>
</tr>
<tr>
<td>150</td>
<td class="good">110 requests/sec<br />
<em><small>at this point I had to increase the maxThreads</small></em></td>
<td class="good">110 requests/sec</td>
</tr>
<tr>
<td>200</td>
<td class="good">62 requests/sec</td>
<td class="good">97 requests/sec</td>
</tr>
<tr>
<td>300</td>
<td class="good">115 requests/sec</td>
<td class="good">108 requests/sec</td>
</tr>
<tr>
<td>400</td>
<td class="error">n/a<br />
<em><small>at this point JMeter would block.</small></em><br />
<em><small>[25 seconds per page]</small></em></td>
<td class="good">80 requests/sec</td>
</tr>
<tr>
<td>500</td>
<td class="error">n/a</td>
<td class="good">75 requests/sec</td>
</tr>
<tr>
<td>600</td>
<td class="error">n/a</td>
<td class="good">84 requests/sec</td>
</tr>
<tr>
<td>700</td>
<td class="error">n/a</td>
<td class="good">55 requests/sec<br />
<em><small>[10 seconds per page]</small></em></td>
</tr>
<tr>
<td>800</td>
<td class="error">n/a</td>
<td class="good">48 requests/sec<br />
<em><small>[13 seconds per page]</small></em></td>
</tr>
<tr>
<td>1000</td>
<td class="error">n/a</td>
<td class="error">n/a<br />
<em><small>at this point JMeter would block</small></em></td>
</tr>
</table>
<h3>Findings</h3>
<p>Even this test can be considered rudimentary, JBoss Web looks very good. The biggest problem with the whole procedure is that JMeter was on the same machine as the servers. JMeter supports <a href="http://jakarta.apache.org/jmeter/usermanual/remote-test.html">Remote Testing</a> and <a href="http://jakarta.apache.org/jmeter/usermanual/jmeter_distributed_testing_step_by_step.pdf">Distributed Testing</a> which would have produced more accurate results.</p>
<p>In any case, it was fun.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/tomcat-vs-jboss-web/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Default Servlet and Resin</title>
		<link>http://blog.cherouvim.com/default-servlet-and-resin/</link>
		<comments>http://blog.cherouvim.com/default-servlet-and-resin/#comments</comments>
		<pubDate>Thu, 08 Mar 2007 16:15:28 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[resin]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/default-servlet-and-resin/</guid>
		<description><![CDATA[Suppose you use a servlet as a front controller to catch and process all urls in a web app. If you want clean URLs you may have mapped it using: &#60;servlet-mapping&#62; &#60;servlet-name&#62;FrontController&#60;/servlet-name&#62; &#60;url-pattern&#62;/&#60;/url-pattern&#62; &#60;/servlet-mapping&#62; Your front controller will now attempt to serve all URLs, and this is something you don&#8217;t want. Static content (png, html, [...]]]></description>
			<content:encoded><![CDATA[<p>Suppose you use a servlet as a <a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html">front controller</a> to catch and process all urls in a web app. If you want clean URLs you may have mapped it using:</p>
<pre>&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;FrontController&lt;/servlet-name&gt;
  &lt;url-pattern&gt;/&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre>
<p>Your front controller will now attempt to serve <strong>all URLs</strong>, and this is something you don&#8217;t want. Static content (png, html, ico, css&#8230;) are being served by a default servlet. In tomcat that is <a href="http://tomcat.apache.org/tomcat-5.5-doc/default-servlet.html">org.apache.catalina.servlets.DefaultServlet</a>, and has been configured for you in <em>conf/web.xml</em> with the name &#8220;default&#8221;.</p>
<p>So, in order to exclude all static content from the catch-all of your front controller, you have to map static content to the default servlet, before the mapping of the front controller:</p>
<pre>&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;default&lt;/servlet-name&gt;&lt;url-pattern&gt;*.css&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;default&lt;/servlet-name&gt;&lt;url-pattern&gt;*.js&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;default&lt;/servlet-name&gt;&lt;url-pattern&gt;*.png&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;default&lt;/servlet-name&gt;&lt;url-pattern&gt;*.jpg&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
...</pre>
<p>That works nicely, when deploying in <a href="http://tomcat.apache.org/">Tomcat</a>, <a href="http://www.mortbay.org/">Jetty</a> and <a href="http://www.jboss.org/products/jbossas">JBoss Application Server</a>.<br />
On <a href="http://www.caucho.com/">Resin</a>, deployment fails with the following message:<br />
<strong>WEB-INF/web.xml:89: `default&#8217; is an unknown servlet-name. servlet-mapping requires that the named servlet be defined in a &lt;servlet&gt; configuration before the &lt;servlet-mapping&gt;.&lt;/servlet-mapping&gt;&lt;/servlet&gt;</strong><br />
Resin&#8217;s static content servlet is <a href="http://www.caucho.com/resin-javadoc/com/caucho/servlets/FileServlet.html">com.caucho.servlets.FileServlet</a> and until 3.0 was mapped using the name &#8220;file&#8221;. Then, on 3.1, and after some people complained that they couldn&#8217;t have a servlet called &#8220;file&#8221;, the name was changed to &#8220;resin-file&#8221;.<br />
So, there are 2 solutions to make your application function properly. You can either change all references from &#8220;default&#8221; to &#8220;resin-file&#8221; in your web.xml, or change the FileServlet&#8217;s name from &#8220;resin-file&#8221; to &#8220;default&#8221; in Resin&#8217;s <a href="http://www.caucho.com/resin-3.0/config/webapp.xtp">conf\app-default.xml</a>.</p>
<p>Happy deployments.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/default-servlet-and-resin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Time to get Groovy</title>
		<link>http://blog.cherouvim.com/time-to-get-groovy/</link>
		<comments>http://blog.cherouvim.com/time-to-get-groovy/#comments</comments>
		<pubDate>Fri, 02 Mar 2007 21:23:34 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/time-to-get-groovy/</guid>
		<description><![CDATA[Groovy is a dynamic language for Java. It allows you to do all funky stuff that you can do in dynamic languages, but still be able to write Java and execute inside the JVM. Let&#8217;s get busy and write a simple Person Java class, in Java: Person.java package com.cherouvim.blog; public abstract class Person { private [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://groovy.codehaus.org/">Groovy</a> is a dynamic language for Java. It allows you to do all funky stuff that you can do in <a href="http://en.wikipedia.org/wiki/Dynamic_language">dynamic languages</a>, but still be able to write Java and execute inside the JVM.</p>
<p>Let&#8217;s get busy and write a simple Person Java class, in Java:<br />
<code><strong>Person.java</strong></code></p>
<pre>package com.cherouvim.blog;
public abstract class Person {
  private int age;

  public Person() {
  }

  public void setAge(int age) {
    this.age = age;
  }

  public int getAge() {
    return this.age;
  }

  /**
   * Determines whether this person should
   * start smoking.
   * Always returns false!
   */
  public boolean shouldStartSmoking() {
    return false;
  }

  /**
   * Determines whether this person is allowed
   * to drive a car.
   * To be implemented on subclass.
   */
  public abstract boolean isAllowedToDriveCar();

}</pre>
<p>This is an abstract class; it could have also been an interface. We want to add more behaviour now with Groovy code, so we are going to extend it and define the <code>isAllowedToDriveCar</code> method:<br />
<code><strong>Person.groovy</strong></code></p>
<pre>package com.cherouvim.blog
public class PersonGroovy extends Person {
  public boolean isAllowedToDriveCar() {
    return this.getAge()&gt;18
  }
}</pre>
<p>In order to make this groovy script available to our Java program, we need to load it via the <a href="http://groovy.codehaus.org/api/groovy/lang/GroovyClassLoader.html">GroovyClassLoader</a>. I define a helper method so I can easily get instances of Groovy classes:<br />
<code><strong>GroovyLoader</strong></code></p>
<pre>public static final Object loadGroovyObject(String groovyScriptLocation) {
  GroovyClassLoader gc = new GroovyClassLoader();
  Class groovyClass = gc.parseClass(
      ClassLoader.getSystemResourceAsStream(groovyScriptLocation));
  Object groovyObject = null;
  try {
    groovyObject = groovyClass.newInstance();
  } catch (Exception ex) {
    // log exception
    ex.printStackTrace();
  }
  return groovyObject;
}</pre>
<p>Now let&#8217;s test our concrete PersonGroovy class:<br />
<code><strong>PersonTest.java</strong></code></p>
<pre>  Person p;
  public void setUp() {
    p = (Person)GroovyLoader.loadGroovyObject(
        "com/cherouvim/blog/Person.groovy");
  }

  /**
   * Test java method
   */
  public void testShouldStartSmoking() {
    assertFalse(p.shouldStartSmoking());
  }

  /**
   * Test groovy method
   */
  public void testIsAllowedToDriveCar() {
    p.setAge(14);
    assertFalse(p.isAllowedToDriveCar());
    p.setAge(27);
    assertTrue(p.isAllowedToDriveCar());
  }</pre>
<p>This test gets an instance of the PersonGroovy class, casts it to the known type of Person and we are ready to go. The <code>isAllowedToDriveCar</code> method is available because we defined it in the abstract superclass. The tests pass.</p>
<p><em>Note that the way I&#8217;ve presented parses the groovy file every time we call <code>loadGroovyObject</code> which is slow. You can cache the class.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/time-to-get-groovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An http session impersonation protection filter</title>
		<link>http://blog.cherouvim.com/an-http-session-impersonation-protection-filter/</link>
		<comments>http://blog.cherouvim.com/an-http-session-impersonation-protection-filter/#comments</comments>
		<pubDate>Thu, 01 Mar 2007 08:00:32 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[webapps]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/an-http-session-impersonation-protection-filter/</guid>
		<description><![CDATA[Session Impersonation is an attack which works for webapps and dynamic websites. Someone steals your session cookie (possibly by using XSS &#8211; Cross Site Scripting), injects it into his browser visits the site and suddenly appears to be you. If you happened to be logged in as the single superadmin of the system, then he [...]]]></description>
			<content:encoded><![CDATA[<p>Session Impersonation is an attack which works for webapps and dynamic websites. Someone steals your session cookie (possibly by using <a href="http://en.wikipedia.org/wiki/XSS">XSS &#8211; Cross Site Scripting</a>), injects it into his browser visits the site and suddenly appears to be you. If you happened to be logged in as the single superadmin of the system, then he is a superadmin as well.</p>
<p>One of the ways to avoid this problem is by storing a hash (or token) the first time the http session is created. That hash will contain the user&#8217;s IP address and his user agent (the browser he uses). On each following request, the hash is being recalculated, and must match the hash previously stored in the http session. If it does not match, any of the 3 things might have happened:</p>
<ol>
<li>Client has changed his IP.</li>
<li>Client has changed his user agent String.</li>
<li>Client is using another clients session (session impersonation attack).</li>
</ol>
<p>Changing you IP is hard (unless your ISP is <a href="http://en.wikipedia.org/wiki/AOL">AOL</a> or you use an anonymity service such as <a href="http://tor.eff.org/">TOR</a>). Changing browsers will initiate a new http session anyway, and changing your user-agent String is rare. It can be done in Firefox using the <a href="http://www.mozillazine.org/misc/about:config/">about:config page</a> but that&#8217;s not a thing that users do everyday.</p>
<p>Note that session impersonation protection is hard (impossible?) to do when people use the same IP. That can be the case in universities, companies and netcafes.</p>
<p>Here is the doFilter method of an http filter which you can use to protect your application from session impersonation attacks. It will invalidate the session when this happens.</p>
<pre>if (request instanceof HttpServletRequest) {
  HttpServletRequest httpRequest = (HttpServletRequest)request;
  // get the session, without creating one if there isn't any
  HttpSession session = httpRequest.getSession(false);
  // if there is a session
  if (session!=null) {
    //calculate a hash using ip and user agent
    String hash = getHash(httpRequest.getRemoteAddr(),
        httpRequest.getHeader(USER_AGENT_KEY));
    if (session.getAttribute(HASH_KEY)==null) {
      // put hash in session
      session.setAttribute(HASH_KEY, hash);
    } else {
      // session does not contain hash
      if(!hash.equals(session.getAttribute(HASH_KEY))) {
        // TODO log session impersonation attempt?
        session.invalidate();
      }
    }
  }
}
chain.doFilter(request, response);</pre>
<p>The getHash method could just return the two Strings concatenated, but ideally you should hash them.</p>
<pre>public static final String getHash(String ip, String agent) {
  return Integer.toString(ip.hashCode()) + agent.hashCode();
}</pre>
<p>MD5 would be good but usually it&#8217;s costly. Here I just used String#hashCode.<br />
You&#8217;ll also need two constants for the filter:</p>
<pre>public static final String HASH_KEY = "HASH";
public static final String USER_AGENT_KEY = "user-agent";</pre>
<p>Thats it. Set the filter on the top of your filters chain and you are ready.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/an-http-session-impersonation-protection-filter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java Code Conventions</title>
		<link>http://blog.cherouvim.com/java-code-conventions/</link>
		<comments>http://blog.cherouvim.com/java-code-conventions/#comments</comments>
		<pubDate>Sat, 24 Feb 2007 12:49:05 +0000</pubDate>
		<dc:creator>cherouvim</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[workplace]]></category>

		<guid isPermaLink="false">http://blog.cherouvim.com/java-code-conventions/</guid>
		<description><![CDATA[When writing Java code you must follow the Code Conventions for the Java Programming Language. It&#8217;s a document written by Sun back in 1997. Why should you read such an ancient (in computer science terms) document? Code conventions are important to programmers for a number of reasons: * 80% of the lifetime cost of a [...]]]></description>
			<content:encoded><![CDATA[<p>When writing Java code you <strong>must</strong> follow the <a href="http://java.sun.com/docs/codeconv/">Code Conventions for the Java Programming Language</a>. It&#8217;s a document written by <a href="http://www.sun.com/" title="Sun Microsystems, Inc.">Sun</a> back in 1997. Why should you read such an ancient (in computer science terms) document?</p>
<blockquote><p>Code conventions are important to programmers for a number of reasons:</p>
<p>* 80% of the lifetime cost of a piece of software goes to maintenance.<br />
* Hardly any software is maintained for its whole life by the original author.<br />
* Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly.</p></blockquote>
<p>Some people tell me that they cannot change their style, because that&#8217;s how they are used to coding. Fair enough. Do whatever you want when coding alone, in your home. But not in a professional environment. If you can&#8217;t be bothered, do us a favour and leave. Resign. Start selling popcorn. Whatever.</p>
<p>I have a serious problem working with people who commit Java code which looks like this:</p>
<pre>public class persons {</pre>
<pre>public void PersonSave(persons p) {</pre>
<pre>package foo.bar.personUtils;</pre>
<pre>public static final String foo = "whatever";</pre>
<pre>whatever()
{
  // do stuff
}</pre>
<p>Seriously, please try to read the following piece of code found in a real life project. Does this look like Java?</p>
<pre>if(e&lt;0.0)d= -d;
if(d!=0.0)for(int i=0;i&lt;dim;i++)this.n[i] = this.n[i]/d;
else this.tW.writeString("normalise: non simplex");
Object leftList = null, rightList = null;
try{ leftList = c.newInstance();}
catch(Exception e){tW.writeString("sort:error1 ");return null;};</pre>
<p>OK, this style might have been good in an <a href="http://en.wikipedia.org/wiki/Obfuscated_code">Obfuscated Code</a> Contest, but it definitely does not get you going in the workplace.</p>
<p>Good luck</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cherouvim.com/java-code-conventions/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
