<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DUICRXo-eyp7ImA9WhRUFUs.&quot;"><id>tag:blogger.com,1999:blog-32637828</id><updated>2012-01-26T08:46:04.453Z</updated><category term="uname" /><category term="logging" /><category term="fork-bomb" /><category term="bug" /><category term="maven" /><category term="permgen" /><category term="Windows MSN Messenger 7.5 software tips tweaks hack" /><category term="Windows" /><category term="scribd" /><category term="Apple" /><category term="guava" /><category term="sybase" /><category term="bios" /><category term="eid" /><category term="nintendo ds" /><category term="restore" /><category term="stairs" /><category term="awk" /><category term="pmc" /><category term="factorial" /><category term="personality" /><category term="git" /><category term="rss" /><category term="relational algebra" /><category term="xpath" /><category term="email" /><category term="JMS" /><category term="autosys" /><category term="solaris" /><category term="work" /><category term="crontab" /><category term="scripting" /><category term="facebook" /><category term="system" /><category term="restoration" /><category term="SSH" /><category term="waol.exe" /><category term="cobertura" /><category term="property" /><category term="holiday" /><category term="vivisection" /><category term="humour" /><category term="shutdownhook" /><category term="2007" /><category term="memory" /><category term="concurrency" /><category term="record" /><category term="read" /><category term="multiplication" /><category term="interview" /><category term="alert" /><category term="&quot;eid in the square&quot;" /><category term="shutdown" /><category term="highlighting" /><category term="bit-shifting" /><category term="network" /><category term="error" /><category term="google" /><category term="feeds" /><category term="moving" /><category term="Vista" /><category term="technology" /><category term="intern" /><category term="Microsoft" /><category term="trafalgar" /><category term="tmux" /><category term="perl" /><category term="fuser" /><category term="serialization" /><category term="pidgin" /><category term="Oracle" /><category term="recover" /><category term="jcommander" /><category term="isobuster" /><category term="ganymede" /><category term="excel" /><category term="plugin" /><category term="shell" /><category term="uptime" /><category term="computer" /><category term="stanford" /><category term="canvas" /><category term="SSL" /><category term="code" /><category term="infinity" /><category term="spoj" /><category term="e-learning" /><category term="cinema imax films" /><category term="hardware" /><category term="promotion" /><category term="alias" /><category term="charts" /><category term="&quot;google chart api&quot;" /><category term="btrace" /><category term="aol" /><category term="howto" /><category term="associative arrays" /><category term="picitup" /><category term="files" /><category term="version" /><category term="extrovert" /><category term="regex" /><category term="essay" /><category term="epoch" /><category term="sql" /><category term="Linux" /><category term="twitter" /><category term="garbage collection" /><category term="samba" /><category term="Ubuntu" /><category term="questions" /><category term="xstream" /><category term="completion" /><category term="install" /><category term="pictures" /><category term="templates" /><category term="quartz" /><category term="climb" /><category term="space travel" /><category term="funny" /><category term="html5" /><category term="swing" /><category term="searchplugin" /><category term="args4j" /><category term="junit" /><category term="clob" /><category term="rare award" /><category term="sqlplus" /><category term="open source" /><category term="date" /><category term="globbing" /><category term="ocs" /><category term="exceptions" /><category term="firefox" /><category term="stackoverflow" /><category term="dell" /><category term="parallelarray" /><category term="introvert" /><category term="LRO" /><category term="tips" /><category term="favicon" /><category term="performance" /><category term="eclipse" /><category term="review" /><category term="bonus" /><category term="CollabNet" /><category term="cpu" /><category term="laptop" /><category term="java7" /><category term="skip" /><category term="wrapper" /><category term="SMTPAppender" /><category term="security" /><category term="shirt" /><category term="animal testing" /><category term="CVS" /><category term="XML" /><category term="algorithm" /><category term="game" /><category term="bash" /><category term="compile" /><category term="fibonacci" /><category term="RMI" /><category term="xmllint" /><category term="hsqldb" /><category term="organise" /><category term="software" /><category term="html" /><category term="weblogic" /><category term="certificate" /><category term="commons-cli" /><category term="release" /><category term="testing" /><category term="studio" /><category term="UNIX" /><category term="whitespace" /><category term="design patterns" /><category term="jdbc" /><category term="IFS" /><category term="XP" /><category term="connection" /><category term="moon" /><category term="firefox3" /><category term="social" /><category term="graphs" /><category term="photos" /><category term="kill" /><category term="vimrc" /><category term="console" /><category term="download" /><category term="find" /><category term="commands" /><category term="delete" /><category term="python" /><category term="browser" /><category term="PS2" /><category term="internet" /><category term="logback" /><category term="singapore" /><category term="mbeans" /><category term="age" /><category term="syntaxhighlighter" /><category term="csv" /><category term="file" /><category term="addon" /><category term="jmx" /><category term="database" /><category term="brain training" /><category term="debug" /><category term="sharing" /><category term="Islam" /><category term="ant" /><category term="sso" /><category term="process" /><category term="programming" /><category term="document" /><category term="broadband" /><category term="mount" /><category term="&quot;vertical rush&quot; stairs climb" /><category term="webdesign" /><category term="hampton court" /><category term="grc" /><category term="Java" /><category term="trip" /><category term="null" /><category term="keytool" /><category term="life" /><category term="log4j" /><category term="OPML" /><category term="pro/con" /><category term="food" /><category term="search" /><category term="house" /><category term="vtd-xml" /><category term="Kawashima" /><category term="GC" /><category term="slashdot" /><category term="&quot;vertical rush&quot;" /><category term="tweaks" /><category term="jconsole" /><category term="reader" /><category term="profiling" /><category term="NASA" /><category term="deadlock" /><category term="fork-join" /><category term="utilities" /><category term="hermes" /><category term="profile" /><category term="jdk7" /><title>fahd.blog</title><subtitle type="html">Let the code do the talking...</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>234</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Fahdblog" /><feedburner:info uri="fahdblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>Fahdblog</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;C08EQHkzeip7ImA9WhRUEUs.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-2360931873968219119</id><published>2012-01-21T16:00:00.000Z</published><updated>2012-01-21T16:03:21.782Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-21T16:03:21.782Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="pmc" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="game" /><title>Play My Code: Wacky Cannon</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
I have always wanted to make a projectile game and now I have! I've just published &lt;a href="http://www.playmycode.com/play/game/sharfah/wacky-cannon"&gt;Wacky Cannon&lt;/a&gt; on &lt;a href="http://www.playmycode.com"&gt;Play My Code&lt;/a&gt;. The aim of the game is to control the cannon using your mouse and click to shoot the purple targets. See how many levels you can complete!
&lt;p/&gt;
Here's &lt;b&gt;Wacky Cannon&lt;/b&gt;!
&lt;p/&gt;
&lt;iframe width="620" height="438" src="http://www.playmycode.com/play/embed/sharfah/wacky-cannon" marginheight="0" marginwidth="0" scrolling="no" frameborder="0" style="border: none; border-size: 0; overflow: hidden; overflow-x: hidden; overflow-y: hidden;"&gt;&lt;/iframe&gt;
&lt;p/&gt;
&lt;a href="http://www.playmycode.com/about"&gt;Play My Code&lt;/a&gt; is a place where you can create your own online games easily using the site's &lt;a href="http://www.playmycode.com/docs/quby"&gt;Quby&lt;/a&gt; language. The games are compiled into native JavaScript, compatible with all modern HTML5-compliant browsers. Once you've written a game, you can embed it on your website or blog, like I have done above. It's like YouTube, but for games! So, if you think you've got a game in you, head over to Play My Code and write one.
&lt;p/&gt;
Click &lt;a href="http://www.playmycode.com/play/user/sharfah/games"&gt;here&lt;/a&gt; to see all my games, including the popular &lt;a href="http://www.playmycode.com/play/game/sharfah/chain-reaction"&gt;Chain Reaction&lt;/a&gt;!
&lt;p/&gt;
Did you like Wacky Cannon? Share your thoughts in the comments below.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Related posts:&lt;/font&gt;&lt;/b&gt;&lt;/br&gt;
&lt;a href="http://fahdshariff.blogspot.com/2011/08/play-my-code-chain-reaction.html"&gt;Play My Code: Chain Reaction&lt;/a&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-2360931873968219119?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/qpYAYxw9dQY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/2360931873968219119/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2012/01/play-my-code-wacky-cannon.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/2360931873968219119?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/2360931873968219119?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/qpYAYxw9dQY/play-my-code-wacky-cannon.html" title="Play My Code: Wacky Cannon" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2012/01/play-my-code-wacky-cannon.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4HRHg4fSp7ImA9WhRVFUk.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-1193732301758691242</id><published>2012-01-14T13:32:00.000Z</published><updated>2012-01-14T13:32:15.635Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-14T13:32:15.635Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="stackoverflow" /><title>stackoverflow - 30k rep</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
Seven months after crossing the &lt;a href="http://fahdshariff.blogspot.com/2011/05/stackoverflow-20k-rep.html"&gt;20k milestone&lt;/a&gt;, I've now achieved a reputation of 30k on &lt;a href="http://stackoverflow.com"&gt;stackoverflow&lt;/a&gt;! The following table shows some interesting stats about my journey so far:
&lt;table cellpadding="2" style="background-color:#f8f8f8; border-collapse:collapse; border-width:1px; font-size:12px;margin:18px 0pt !important; border:1px solid #BBBBBB; padding:5px;"&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;b&gt;
        &lt;font color="#000099"&gt; &lt;/font&gt;
      &lt;/b&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;b&gt;
        &lt;font color="#000099"&gt;0-10k&lt;/font&gt;
      &lt;/b&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;b&gt;
        &lt;font color="#000099"&gt;10-20k&lt;/font&gt;
      &lt;/b&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;b&gt;
        &lt;font color="#000099"&gt;20-30k&lt;/font&gt;
      &lt;/b&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;b&gt;
        &lt;font color="#000099"&gt;Total&lt;/font&gt;
      &lt;/b&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Date achieved&lt;/td&gt;
    &lt;td&gt;01/2011&lt;/td&gt;
    &lt;td&gt;05/2011&lt;/td&gt;
    &lt;td&gt;01/2012&lt;/td&gt;
    &lt;td&gt; &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Questions answered&lt;/td&gt;
    &lt;td&gt;546&lt;/td&gt;
    &lt;td&gt;376&lt;/td&gt;
    &lt;td&gt;253&lt;/td&gt;
    &lt;td&gt;1175&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Questions asked&lt;/td&gt;
    &lt;td&gt;46&lt;/td&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;6&lt;/td&gt;
    &lt;td&gt;53&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Tags covered&lt;/td&gt;
    &lt;td&gt;609&lt;/td&gt;
    &lt;td&gt;202&lt;/td&gt;
    &lt;td&gt;83&lt;/td&gt;
    &lt;td&gt;894&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Badges &lt;br/&gt;(gold, silver, bronze)&lt;/td&gt;
    &lt;td&gt;35&lt;br/&gt;(2, 10, 23)&lt;/td&gt;
    &lt;td&gt;14&lt;br/&gt;(0, 4, 10)&lt;/td&gt;
    &lt;td&gt;33&lt;br/&gt;(2, 8, 23)&lt;/td&gt;
    &lt;td&gt;82&lt;br/&gt;(4, 22, 56)&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
As I mentioned &lt;a href="http://fahdshariff.blogspot.com/2011/05/stackoverflow-20k-rep.html"&gt;before&lt;/a&gt;, I have really enjoyed being a member of stackoverflow. For me, it has not simply been a quest for a high reputation, but more about learning new technologies and picking up advice from other experts on the site. I like to take on challenging questions, rather than the easy ones, because it pushes me to do research into areas I have never looked at before, and I learn so much during the process.
&lt;p/&gt;
I have to admit, I haven't spent much time on stackoverflow recently. I've been busy at work and also took up &lt;a href="http://fahdshariff.blogspot.com/2011/12/stanfords-online-courses-ml-class-ai.html"&gt;three Stanford online courses&lt;/a&gt; which I completed at the end of last year.
&lt;p/&gt;
Now let's see how fast I can make it to 40k!
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-1193732301758691242?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/eLus9eKxzV0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/1193732301758691242/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2012/01/stackoverflow-30k-rep.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1193732301758691242?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1193732301758691242?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/eLus9eKxzV0/stackoverflow-30k-rep.html" title="stackoverflow - 30k rep" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2012/01/stackoverflow-30k-rep.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQNQ3w_eCp7ImA9WhRWGUk.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-8234257642388199536</id><published>2012-01-07T13:52:00.000Z</published><updated>2012-01-07T13:53:12.240Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-07T13:53:12.240Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="exceptions" /><title>Stackless Exceptions for Improved Performance</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
One of the reasons for standard exceptions being slow is that they have to fill in the execution stack trace for the current thread. Although, this is useful for debugging, in most cases you don't really care about the stack trace. What you care about is that an exception of a certain type was thrown and what the error message was. For example, a &lt;code&gt;java.io.FileNotFoundException&lt;/code&gt; was thrown with message &lt;code&gt;config.xml (The system cannot find the file specified)"&lt;/code&gt;.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Stackless Exceptions&lt;/font&gt;&lt;/b&gt; are exceptions without any associated stack information. They are faster to create than normal exceptions because they don't record information about the current state of the stack frames for the current thread.
&lt;p/&gt;
The class below is an example of a stackless exception. The &lt;code&gt;fillInStackTrace&lt;/code&gt; method has been overridden so that it doesn't do anything and simply returns the current instance.
&lt;pre class="brush:java; gutter:true;"&gt;
/**
 * An exception which does not fill in a stack trace
 * for performance reasons.
 */
@SuppressWarnings("serial")
public class StacklessException extends Exception {

    /**
     * Constructs a new stackless exception
     * with the specified detail message.
     *
     * @param message the detail message.
     * @see java.lang.Exception#Exception(String)
     */
    public StacklessException(String message) {
        super(message);
    }

    /**
     * Does not fill in the stack trace for this exception
     * for performance reasons.
     *
     * @return this instance
     * @see java.lang.Throwable#fillInStackTrace()
     */
    @Override
    public Throwable fillInStackTrace() {
        return this;
    }
}
&lt;/pre&gt;
I measured performance by comparing the time taken to create a million &lt;code&gt;StacklessException&lt;/code&gt; and &lt;code&gt;Exception&lt;/code&gt; objects. I found that the creation of stackless exceptions is nearly &lt;b&gt;40&lt;/b&gt; times faster than normal exceptions.
&lt;p/&gt;
You can then create more specific exception types which subclass &lt;code&gt;StacklessException&lt;/code&gt;. For example:
&lt;pre class="brush:java; gutter:true;"&gt;
public class PersonNotFoundException extends StacklessException {
    public PersonNotFoundException(String message) {
        super(message);
    }
}
&lt;/pre&gt;
As an aside, note that the JVM omits stack traces if an exception is thrown very frequently. This optimisation is enabled by default and can be disabled using the JVM option &lt;code&gt;-XX:-OmitStackTraceInFastThrow&lt;/code&gt;.
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-8234257642388199536?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/KLzi9kCBhCg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/8234257642388199536/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2012/01/stackless-exceptions-for-improved.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/8234257642388199536?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/8234257642388199536?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/KLzi9kCBhCg/stackless-exceptions-for-improved.html" title="Stackless Exceptions for Improved Performance" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2012/01/stackless-exceptions-for-improved.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIMQ3c7cSp7ImA9WhRWFE8.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-5459211645353321420</id><published>2012-01-01T12:56:00.000Z</published><updated>2012-01-01T12:56:22.909Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-01T12:56:22.909Z</app:edited><title>fahd.blog in 2011</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Happy 2012!&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
I'd like to wish everyone a great start to an even greater new year!
&lt;p/&gt;
During 2011, I posted 58 new entries on &lt;a href="http://fahshariff.blogspot.com"&gt;fahd.blog&lt;/a&gt;. I am also thrilled that I have more readers from all over the world too! Thanks for reading and especially for giving feedback.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Top 5 posts of 2011:&lt;/font&gt;&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://fahdshariff.blogspot.com/2011/08/useful-eclipse-templates-for-faster.html"&gt;Useful Eclipse Templates for Faster Coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fahdshariff.blogspot.com/2011/07/java-7-diamond-operator.html"&gt;Java 7: Diamond Operator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fahdshariff.blogspot.com/2011/04/html5-canvas-bouncing-balls.html"&gt;HTML5 Canvas - Bouncing Balls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fahdshariff.blogspot.com/2011/08/java-7-working-with-zip-files.html"&gt;Java 7: Working with Zip Files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fahdshariff.blogspot.com/2011/04/writing-your-own-bash-completion.html"&gt;Writing your own Bash Completion Function&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
I'm going to be writing a lot more this year, so stay tuned for more great techie tips, tricks and hacks! :)
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-5459211645353321420?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/w_qFYv2Fi5I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/5459211645353321420/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2012/01/fahdblog-in-2011.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5459211645353321420?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5459211645353321420?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/w_qFYv2Fi5I/fahdblog-in-2011.html" title="fahd.blog in 2011" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2012/01/fahdblog-in-2011.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQAQ3Y9fSp7ImA9WhRWEkk.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-4285849852092816553</id><published>2011-12-30T10:52:00.000Z</published><updated>2011-12-30T10:52:22.865Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-30T10:52:22.865Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="e-learning" /><category scheme="http://www.blogger.com/atom/ns#" term="stanford" /><title>Stanford's Online Courses: ml-class, ai-class and db-class</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
About three months ago, I signed up to Stanford's first-of-its-kind, free, online courses on Artifical Intelligence, Machine Learning and Databases. I have now successfully completed all three courses!
&lt;ul&gt;
&lt;li&gt;The &lt;a href="http://www.ai-class.com"&gt;Artifical Intelligence (ai-class)&lt;/a&gt; class, led by &lt;a href="http://robots.stanford.edu/"&gt;Sebastian Thrun&lt;/a&gt; and &lt;a href="http://norvig.com/"&gt;Peter Norvig&lt;/a&gt;, covered probability, Bayes networks, machine learning, planning, Markov decision processes (MDPs), particle filters, game theory, computer vision, robotics and natural language processing. There were in-class quizzes, homework exercises and two exams.&lt;/li&gt;
&lt;p/&gt;
&lt;li&gt;The &lt;a href="http://www.ml-class.org"&gt;Machine Learning (ml-class)&lt;/a&gt; class, led by &lt;a href="http://ai.stanford.edu/~ang/"&gt;Professor Andrew Ng&lt;/a&gt;, covered supervised learning (linear regression, logistic regression, neural networks, support vector machines), unsupervised learning (k-Means clustering), anomaly detection and recommender systems. There were in-class quizzes, review questions and programming exercises.&lt;/li&gt;
&lt;p/&gt;
&lt;li&gt;The &lt;a href="http://www.db-class.org"&gt;Introduction to Databases(db-class)&lt;/a&gt; class, led by &lt;a href="http://infolab.stanford.edu/~widom/"&gt;Professor Jennifer Widom&lt;/a&gt;, covered relational databases, relational algebra, XML, XPaths, SQL, UML, constraints, triggers, transactions, authorization, recursion and NoSQL systems. There were in-class quizzes, assignments, including practical exercises (such as creating triggers, writing SQL or XPaths that would run on a set of data) and two exams.&lt;/li&gt;
&lt;/ul&gt;
Even though I had studied these topics a long time ago at university, I found it really useful to refresh my memory. They took up quite a bit of time (about 2 hours a week for each class), but it was definitely worth it.
&lt;p/&gt;
I am now looking forward to starting some &lt;a href="http://www.class-central.com/"&gt;new classes&lt;/a&gt; in 2012!
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-4285849852092816553?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/kaF5YndPfUs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/4285849852092816553/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/12/stanfords-online-courses-ml-class-ai.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/4285849852092816553?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/4285849852092816553?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/kaF5YndPfUs/stanfords-online-courses-ml-class-ai.html" title="Stanford's Online Courses: ml-class, ai-class and db-class" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/12/stanfords-online-courses-ml-class-ai.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcHQHsyfSp7ImA9WhRXGUU.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-396805847552688927</id><published>2011-12-27T11:40:00.000Z</published><updated>2011-12-27T11:40:31.595Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-27T11:40:31.595Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="commons-cli" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="jcommander" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="args4j" /><title>Args4j vs JCommander for Parsing Command Line Parameters</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
In the past, I've always used &lt;a href="http://commons.apache.org/cli"&gt;Apache Commons CLI&lt;/a&gt; for parsing command line options passed to programs and have found it quite tedious because of all the boiler plate code involved. Just take a look at their &lt;a href="http://commons.apache.org/cli/usage.html"&gt;Ant Example&lt;/a&gt; and you will see how much code is required to create each option.
&lt;p/&gt;
As an alternative, there are two annotation-based command line parsing frameworks which I have been evaluating recently:
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kohsuke/args4j"&gt;Args4j&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jcommander.org"&gt;JCommander&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
I'm going to use the Ant example to illustrate how to parse command line options using these two libraries. I'm only going to use a few options in my example because they are all very similar. Here is an extract of the help output for Ant, which I will be aiming to replicate:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
ant [options] [target [target2 [target3] ...]]
Options:
  -help, -h              print this message
  -lib &amp;lt;path&amp;gt;            specifies a path to search for jars and classes
  -buildfile &amp;lt;file&amp;gt;      use given buildfile
    -file    &amp;lt;file&amp;gt;              ''
    -f       &amp;lt;file&amp;gt;              ''
  -D&amp;lt;property&amp;gt;=&amp;lt;value&amp;gt;   use value for given property
  -nice  number          A niceness value for the main thread:
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Args4j (v2.0.12)&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
The class below demonstrates how to parse command line options for Ant using &lt;a href="https://github.com/kohsuke/args4j"&gt;Args4j&lt;/a&gt;. The &lt;code&gt;main&lt;/code&gt; method parses some sample arguments and also prints out the usage of the command.
&lt;pre class="brush:java; gutter:false;"&gt;
import static org.junit.Assert.*;
import java.io.File;
import java.util.*;
import org.kohsuke.args4j.*;

/**
 * Example of using Args4j for parsing
 * Ant command line options
 */
public class AntOptsArgs4j {

  @Argument(metaVar = "[target [target2 [target3] ...]]", usage = "targets")
  private List&amp;lt;String&amp;gt; targets = new ArrayList&amp;lt;String&amp;gt;();

  @Option(name = "-h", aliases = "-help", usage = "print this message")
  private boolean help = false;

  @Option(name = "-lib", metaVar = "&amp;lt;path&amp;gt;",
          usage = "specifies a path to search for jars and classes")
  private String lib;

  @Option(name = "-f", aliases = { "-file", "-buildfile" }, metaVar = "&amp;lt;file&amp;gt;",
          usage = "use given buildfile")
  private File buildFile;

  @Option(name = "-nice", metaVar = "number",
          usage = "A niceness value for the main thread:\n"
          + "1 (lowest) to 10 (highest); 5 is the default")
  private int nice = 5;

  private Map&amp;lt;String, String&amp;gt; properties = new HashMap&amp;lt;String, String&amp;gt;();
  @Option(name = "-D", metaVar = "&amp;lt;property&amp;gt;=&amp;lt;value&amp;gt;",
          usage = "use value for given property")
  private void setProperty(final String property) throws CmdLineException {
    String[] arr = property.split("=");
    if(arr.length != 2) {
        throw new CmdLineException("Properties must be specified in the form:"+
                                   "&amp;lt;property&amp;gt;=&amp;lt;value&amp;gt;");
    }
    properties.put(arr[0], arr[1]);
  }

  public static void main(String[] args) throws CmdLineException {
    final String[] argv = { "-D", "key=value", "-f", "build.xml",
                            "-D", "key2=value2", "clean", "install" };
    final AntOptsArgs4j options = new AntOptsArgs4j();
    final CmdLineParser parser = new CmdLineParser(options);
    parser.parseArgument(argv);

    // print usage
    parser.setUsageWidth(Integer.MAX_VALUE);
    parser.printUsage(System.err);

    // check the options have been set correctly
    assertEquals("build.xml", options.buildFile.getName());
    assertEquals(2, options.targets.size());
    assertEquals(2, options.properties.size());
  }
}
&lt;/pre&gt;
Running this program prints:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
 [target [target2 [target3] ...]] : targets
 -D &amp;lt;property&amp;gt;=&amp;lt;value&amp;gt;            : use value for given property
 -f (-file, -buildfile) &amp;lt;file&amp;gt;    : use given buildfile
 -h (-help)                       : print this message
 -lib &amp;lt;path&amp;gt;                      : specifies a path to search for jars and classes
 -nice number                     : A niceness value for the main thread:
                                    1 (lowest) to 10 (highest); 5 is the default
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;JCommander (v1.13)&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Similarly, here is a class which demonstrates how to parse command line options for Ant using &lt;a href="http://jcommander.org"&gt;JCommander&lt;/a&gt;.
&lt;pre class="brush:java; gutter:false;"&gt;
import static org.junit.Assert.*;
import java.io.File;
import java.util.*;
import com.beust.jcommander.*;

/**
 * Example of using JCommander for parsing
 * Ant command line options
 */
public class AntOptsJCmdr {

  @Parameter(description = "targets")
  private List&amp;lt;String&amp;gt; targets = new ArrayList&amp;lt;String&amp;gt;();

  @Parameter(names = { "-help", "-h" }, description = "print this message")
  private boolean help = false;

  @Parameter(names = { "-lib" },
             description = "specifies a path to search for jars and classes")
  private String lib;

  @Parameter(names = { "-buildfile", "-file", "-f" },
             description = "use given buildfile")
  private File buildFile;

  @Parameter(names = "-nice", description = "A niceness value for the main thread:\n"
        + "1 (lowest) to 10 (highest); 5 is the default")
  private int nice = 5;

  @Parameter(names = { "-D" }, description = "use value for given property")
  private List&amp;lt;String&amp;gt; properties = new ArrayList&amp;lt;String&amp;gt;();

  public static void main(String[] args) {
    final String[] argv = { "-D", "key=value", "-f", "build.xml",
                            "-D", "key2=value2", "clean", "install" };
    final AntOptsJCmdr options = new AntOptsJCmdr();
    final JCommander jcmdr = new JCommander(options, argv);

    // print usage
    jcmdr.setProgramName("ant");
    jcmdr.usage();

    // check the options have been set correctly
    assertEquals("build.xml", options.buildFile.getName());
    assertEquals(2, options.targets.size());
    assertEquals(2, options.properties.size());
  }
}
&lt;/pre&gt;
Running this program prints:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
Usage: ant [options]
 targets
  Options:
    -D                      use value for given property
                            Default: [key=value, key2=value2]
    -buildfile, -file, -f   use given buildfile
    -help, -h               print this message
                            Default: false
    -lib                    specifies a path to search for jars and classes
    -nice                   A niceness value for the main thread:
1 (lowest) to
                            10 (highest); 5 is the default
                            Default: 5
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Args4j vs JCommander&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
As you can see from the implementations above, both frameworks are very similar. There are a few differences though:
&lt;ol&gt;
 &lt;li&gt;JCommander does not have an equivalent to Arg4j's &lt;code&gt;metaVar&lt;/code&gt; which allows you to display the value that an option might take. For example, if you have an option called "-f" which takes a file, you can set &lt;code&gt;metaVar="&amp;lt;file&amp;gt;"&lt;/code&gt; and Args4j will display &lt;code&gt;-f &amp;lt;file&amp;gt;&lt;/code&gt; when it prints the usage. This is not possible in JCommander, so it is difficult to see which options take values and which ones don't.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;JCommander's &lt;code&gt;@Parameter&lt;/code&gt; option can only be applied to fields, not methods. This makes it slightly restrictive. In Args4j, you can add the annotation on a "setter" method, which allows you to tweak the value before it is set. In JCommander, you would have to create a custom converter.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;In the example above, JCommander was unable to place &lt;code&gt;-D property=value&lt;/code&gt; options into a map. It was able to save them into a list and then you would have to do some post-processing to convert the elements in the list to key-value pairs in a map. On the other hand, Args4j was able to put the properties straight into the map by applying the annotation on a setter method.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;JCommander's usage output is not as pretty as Args4j's. In particular, the description of the "nice" option is not aligned correctly.&lt;/li&gt;
&lt;/ol&gt;
&lt;p/&gt;
Based purely on this example, the &lt;b&gt;&lt;em&gt;winner is Args4j&lt;/em&gt;&lt;/b&gt;. However, note that there are other features present in JCommander which are not available in Args4j, such as parameter validation and password type parameters. Please read the documentation to find out which one is better suited to your needs. But one thing is quite clear: annotation based command line parsing is the way forward!
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-396805847552688927?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/f3NTWTTq_wk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/396805847552688927/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/12/args4j-vs-jcommander-for-parsing.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/396805847552688927?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/396805847552688927?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/f3NTWTTq_wk/args4j-vs-jcommander-for-parsing.html" title="Args4j vs JCommander for Parsing Command Line Parameters" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/12/args4j-vs-jcommander-for-parsing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4ASHo-eyp7ImA9WhRXF08.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-7229783489468187207</id><published>2011-12-24T12:14:00.000Z</published><updated>2011-12-24T12:15:49.453Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-24T12:15:49.453Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="guava" /><title>Guava Cache</title><content type="html">&lt;head&gt;&lt;!--Guava Cache --&gt;&lt;/head&gt;
&lt;body&gt;
&lt;span style="font-family: arial,sans-serif;"&gt;
Google's &lt;a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/cache/Cache.html"&gt;Guava Cache&lt;/a&gt; is a lightweight, threadsafe Java cache that provides some nice features such as:
&lt;ul&gt;
  &lt;li&gt;eviction of least recently used entries when a maximum size is breached&lt;/li&gt;
  &lt;li&gt;eviction of entries based on time since last access or last write&lt;/li&gt;
  &lt;li&gt;notification of evicted entries&lt;/li&gt;
  &lt;li&gt;performance statistics e.g. hit and miss counts&lt;/li&gt;
&lt;/ul&gt;
In order to create the &lt;code&gt;Cache&lt;/code&gt;, you need to use a &lt;a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/cache/CacheBuilder.html"&gt;&lt;code&gt;CacheBuilder&lt;/code&gt;&lt;/a&gt;. This allows you to specify the eviction policy and other features such as concurrency level, soft or weak values etc. You also need to specify a &lt;a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/cache/CacheLoader.html"&gt;&lt;code&gt;CacheLoader&lt;/code&gt;&lt;/a&gt; which will be invoked automatically by the cache if a key does not exist and is used to populate it.
&lt;p/&gt;
The following code demonstrates how to create a cache:
&lt;pre class="brush:java; gutter:false;"&gt;
// Create the cache. Only allow a max of 10 entries.
// Old entries will be evicted.
final Cache&amp;lt;String, String&amp;gt; cache = CacheBuilder.newBuilder()
    .maximumSize(10)
    .removalListener(new RemovalListener&amp;lt;String, String&amp;gt;() {
        @Override
        public void onRemoval(RemovalNotification&amp;lt;String, String&amp;gt; n) {
            System.out.println("REMOVED: " + n);
        }
    })
    .build(new CacheLoader&amp;lt;String, String&amp;gt;() {
        @Override
        public String load(String key) throws Exception {
            System.out.println("LOADING: " + key);
            return key + "-VALUE";
        }
    });

// Get values from the cache.
// If a key does not exist, it will be loaded.
for (int i = 0; i &amp;lt; 10; i++) {
  System.out.println(cache.get("Key" + i));
}
for (int i = 9; i &amp;gt;= 0; i--) {
  System.out.println(cache.get("Key" + i));
}

//Print out the hit counts.
System.out.println(cache.stats());
&lt;/pre&gt;
The output of this program is:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;font color="green"&gt;LOADING: Key0
LOADING: Key1
LOADING: Key2
LOADING: Key3
LOADING: Key4
LOADING: Key5
LOADING: Key6&lt;/font&gt;
&lt;font color="red"&gt;REMOVED: Key0=Key0-VALUE&lt;/font&gt;
&lt;font color="green"&gt;LOADING: Key7&lt;/font&gt;
&lt;font color="red"&gt;REMOVED: Key3=Key3-VALUE&lt;/font&gt;
&lt;font color="green"&gt;LOADING: Key8
LOADING: Key9
LOADING: Key3&lt;/font&gt;
&lt;font color="red"&gt;REMOVED: Key7=Key7-VALUE&lt;/font&gt;
&lt;font color="green"&gt;LOADING: Key0&lt;/font&gt;
&lt;font color="red"&gt;REMOVED: Key6=Key6-VALUE&lt;/font&gt;
&lt;font color="blue"&gt;CacheStats{hitCount=8, missCount=12, loadSuccessCount=12, loadExceptionCount=0, 
totalLoadTime=563806, evictionCount=4}&lt;/font&gt;&lt;/pre&gt;
It is important to note that entries were evicted BEFORE the maximum size of 10 was reached. In this case, an entry was removed when the cache had 7 entries in it.
&lt;p/&gt;
The cache stats show that out of 20 calls to the cache, 12 missed and had to be loaded. However, 8 were successfully retrieved from the cache. 4 entries were evicted.
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-7229783489468187207?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/wuZ-pbCRJeU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/7229783489468187207/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/12/guava-cache.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7229783489468187207?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7229783489468187207?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/wuZ-pbCRJeU/guava-cache.html" title="Guava Cache" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/12/guava-cache.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMEQXwyfCp7ImA9WhRRGUw.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-1872752167392169713</id><published>2011-12-03T11:37:00.001Z</published><updated>2011-12-03T11:40:00.294Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-03T11:40:00.294Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="xstream" /><title>Using XStream to Map a Single Element</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
Let's say you have the following XML which has a single element containing an attribute and some text:
&lt;pre class="brush:xml; gutter:false;"&gt;
&amp;lt;error code="99"&amp;gt;This is an error message&amp;lt;/error&amp;gt;
&lt;/pre&gt;
and you would like to convert it, using &lt;a href="http://xstream.codehaus.org/"&gt;XStream&lt;/a&gt;, into an &lt;code&gt;Error&lt;/code&gt; object:
&lt;pre class="brush:java; gutter:false;"&gt;
public class Error {
    String message;
    int code;

    public String getMessage() {
        return message;
    }

    public int getCode() {
        return code;
    }
}
&lt;/pre&gt;
It took me a while to figure this out. It was easy getting the &lt;code&gt;code&lt;/code&gt; attribute set in the &lt;code&gt;Error&lt;/code&gt; object, but it just wasn't picking up the message.
&lt;p/&gt;
Eventually, I found the &lt;a href="http://xstream.codehaus.org/javadoc/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.html"&gt;&lt;code&gt;ToAttributedValueConverter&lt;/code&gt;&lt;/a&gt; class which "supports the definition of one field member that will be written as value and all other field members are written as attributes."
&lt;p/&gt;
The following code shows how the &lt;code&gt;ToAttributedValueConverter&lt;/code&gt; is used. You specify which instance variable maps to the value of the XML element (in this case &lt;code&gt;message&lt;/code&gt;). All other instance variables automatically map to attributes, so you don't need to explicitly annotate them with &lt;code&gt;XStreamAsAttribute&lt;/code&gt;.

&lt;pre class="brush:java; gutter:false;"&gt;
@XStreamAlias("error")
@XStreamConverter(value=ToAttributedValueConverter.class, strings={"message"})
public class Error {

  String message;

  @XStreamAlias("code")
  int code;

  public String getMessage() {
      return message;
  }

  public int getCode() {
      return code;
  }

  public static void main(String[] args) {
      XStream xStream = new XStream();
      xStream.processAnnotations(Error.class);

      String xmlResponse="&amp;lt;error code=\"99\"&amp;gt;This is an error message&amp;lt;/error&amp;gt;";

      Error error = (Error)xStream.fromXML(xmlResponse);
      System.out.println(error.getCode());
      System.out.println(error.getMessage());
  }
}
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-1872752167392169713?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/LNYj52Oce9g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/1872752167392169713/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/12/using-xstream-to-map-single-element.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1872752167392169713?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1872752167392169713?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/LNYj52Oce9g/using-xstream-to-map-single-element.html" title="Using XStream to Map a Single Element" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/12/using-xstream-to-map-single-element.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMGRns8eSp7ImA9WhRTFEQ.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-7690049814321029670</id><published>2011-11-05T12:33:00.000Z</published><updated>2011-11-05T12:33:47.571Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-05T12:33:47.571Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><category scheme="http://www.blogger.com/atom/ns#" term="regex" /><title>Regular Expressions in Bash</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
Traditionally, external tools such as &lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt; and &lt;code&gt;perl&lt;/code&gt; have been used to match a string against a regular expression, but the Bash shell has this functionality built into it as well!
&lt;p/&gt;
In Bash, the &lt;code&gt;=~&lt;/code&gt; operator allows you to match a string on the left against an extended regular expression on the right and returns 0 if the string matches the pattern, and 1 otherwise. Capturing groups are saved in the array variable &lt;code&gt;BASH_REMATCH&lt;/code&gt; with the first element, Group 0, representing the entire expression.
&lt;p/&gt;
The following script matches a string against a regex and prints out the capturing groups:
&lt;pre class="brush:bash; gutter:true;"&gt;
#!/bin/bash

if [ $# -lt 2 ]
then
    echo "Usage: $0 regex string" &gt;&amp;2
    exit 1
fi

regex=$1
input=$2

if [[ $input =~ $regex ]]
then
    echo "$input matches regex: $regex"

    #print out capturing groups
    for (( i=0; i&amp;lt;${#BASH_REMATCH[@]}; i++))
    do
        echo -e "\tGroup[$i]: ${BASH_REMATCH[$i]}"
    done
else
    echo "$input does not match regex: $regex"
fi
&lt;/pre&gt;

Example usage:

&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; matcher.sh '(.*)=(.*)' foo=bar
&lt;font color="green"&gt;foo=bar matches regex (.*)=(.*)
    Group[0]: foo=bar
    Group[1]: foo
    Group[2]: bar
&lt;/font&gt;&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-7690049814321029670?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/FlqDeB4GZoQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/7690049814321029670/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/11/regular-expressions-in-bash.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7690049814321029670?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7690049814321029670?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/FlqDeB4GZoQ/regular-expressions-in-bash.html" title="Regular Expressions in Bash" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/11/regular-expressions-in-bash.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EEQ3Y6fyp7ImA9WhdaE0s.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-8337846830243128970</id><published>2011-10-23T12:32:00.000+01:00</published><updated>2011-10-23T12:33:22.817+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-23T12:33:22.817+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sql" /><category scheme="http://www.blogger.com/atom/ns#" term="relational algebra" /><title>Finding the Maximum using Relational Algebra</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
We know that if you want to get the maximum value of a column in SQL, you can simply use the &lt;code&gt;MAX&lt;/code&gt; function as shown below:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
SELECT MAX(value) FROM T
&lt;/pre&gt;
You can also do it without the MAX function as follows:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
SELECT T.* FROM T
MINUS
SELECT T.* FROM T, T as T2 WHERE T.value&amp;lt;T2.value
&lt;/pre&gt;
or:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
SELECT T.* FROM T
LEFT JOIN T as T2 ON T.value&amp;lt;T2.value
WHERE T2.value IS NULL
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Relational Algebra:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Using &lt;a href="http://infolab.stanford.edu/~widom/cs145/using-ra.html"&gt;Relational Algebra (RA)&lt;/a&gt; syntax, this would be:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
\project_{value}(T)
\diff
\project_{value} (
    \select_{value &amp;lt; value2}(
      \project_{value}(T)
      \cross
      \rename_{value2}(\project_{value}(T))
    )
)
&lt;/pre&gt;
where:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;\cross&lt;/code&gt; is the relational cross-product operator&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\diff&lt;/code&gt; is the relational diff operator&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\project_{attr_list}&lt;/code&gt; is the relational projection operator&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\rename_{new_attr_name_list}&lt;/code&gt; is the relational renaming operator&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\select_{cond}&lt;/code&gt; is the relational selection operator&lt;/li&gt;
&lt;/ul&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-8337846830243128970?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/c65W_944M-k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/8337846830243128970/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/10/finding-maximum-using-relational.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/8337846830243128970?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/8337846830243128970?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/c65W_944M-k/finding-maximum-using-relational.html" title="Finding the Maximum using Relational Algebra" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/10/finding-maximum-using-relational.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8CRHY9eSp7ImA9WhdbF0o.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-7717941017493048279</id><published>2011-10-16T15:21:00.000+01:00</published><updated>2011-10-16T15:21:05.861+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-16T15:21:05.861+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xmllint" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><title>Validating XML with xmllint</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
The following commands show you how to validate an XML file against a DTD or XSD using &lt;a href="http://xmlsoft.org/xmllint.html"&gt;&lt;code&gt;xmllint&lt;/code&gt;&lt;/a&gt;.
&lt;p/&gt;
To validate an XML file against:
&lt;ul&gt;
&lt;li&gt;a DTD stored in the same file:&lt;/li&gt;
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;font color="green"&gt;xmllint --valid --noout fileWithDTD.xml&lt;/font&gt;
&lt;/pre&gt;
&lt;li&gt;a DTD stored in a separate file:&lt;/li&gt;
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;font color="green"&gt;xmllint --dtdvalid DTD.dtd --noout fileWithoutDTD.xml&lt;/font&gt;
&lt;/pre&gt;
&lt;li&gt;an XSD stored in a separate file:&lt;/li&gt;
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;font color="green"&gt;xmllint --schema schema.xsd --noout file.xml&lt;/font&gt;
&lt;/pre&gt;
&lt;/ul&gt;
The &lt;code&gt;--noout&lt;/code&gt; option suppresses the output of the xml file.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Example&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
To validate:
&lt;pre class="brush:xml; gutter:false;" title="countries.xml"&gt;
&amp;lt;countries&amp;gt;
  &amp;lt;country name="Afghanistan" population="22664136" area="647500"&amp;gt;
    &amp;lt;language percentage="11"&amp;gt;Turkic&amp;lt;/language&amp;gt;
    &amp;lt;language percentage="35"&amp;gt;Pashtu&amp;lt;/language&amp;gt;
    &amp;lt;language percentage="50"&amp;gt;Afghan Persian&amp;lt;/language&amp;gt;
  &amp;lt;/country&amp;gt;
  &amp;lt;country name="Albania" population="3249136" area="28750"/&amp;gt;
  &amp;lt;country name="Algeria" population="29183032" area="2381740"&amp;gt;
    &amp;lt;city&amp;gt;
      &amp;lt;name&amp;gt;Algiers&amp;lt;/name&amp;gt;
      &amp;lt;population&amp;gt;1507241&amp;lt;/population&amp;gt;
    &amp;lt;/city&amp;gt;
  &amp;lt;/country&amp;gt;
&amp;lt;/countries&amp;gt;
&lt;/pre&gt;
against:
&lt;pre class="brush:xml; gutter:false;" title="countries.dtd"&gt;
&amp;lt;!ELEMENT countries (country*)&amp;gt;
&amp;lt;!ELEMENT country (language|city)*&amp;gt;
&amp;lt;!ATTLIST country name CDATA #REQUIRED&amp;gt;
&amp;lt;!ATTLIST country population CDATA #REQUIRED&amp;gt;
&amp;lt;!ATTLIST country area CDATA #REQUIRED&amp;gt;
&amp;lt;!ELEMENT language (#PCDATA)&amp;gt;
&amp;lt;!ATTLIST language percentage CDATA #REQUIRED&amp;gt;
&amp;lt;!ELEMENT city (name, population)&amp;gt;
&amp;lt;!ELEMENT name (#PCDATA)&amp;gt;
&amp;lt;!ELEMENT population (#PCDATA)&amp;gt;
&lt;/pre&gt;

use the command:

&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;font color="green"&gt;xmllint --dtdvalid countries.dtd --noout countries.xml&lt;/font&gt;
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-7717941017493048279?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/nIdrU4Eer9k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/7717941017493048279/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/10/validating-xml-with-xmllint.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7717941017493048279?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7717941017493048279?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/nIdrU4Eer9k/validating-xml-with-xmllint.html" title="Validating XML with xmllint" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/10/validating-xml-with-xmllint.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8ERX0_fSp7ImA9WhdbEEU.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-7737740512311015507</id><published>2011-10-08T15:40:00.000+01:00</published><updated>2011-10-08T15:40:04.345+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-08T15:40:04.345+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><category scheme="http://www.blogger.com/atom/ns#" term="commands" /><title>Splitting a large file into smaller pieces</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
If you have a large file and want to break it into smaller pieces, you can use the Unix &lt;a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?split"&gt;split&lt;/a&gt; command. You can tell it what the prefix of each split file should be and it will then append an alphabet (or number) to the end of each name. 
&lt;p/&gt;
In the example below, I split a file containing 100,000 lines. I instruct &lt;code&gt;split&lt;/code&gt; to use numeric suffixes (&lt;code&gt;-d&lt;/code&gt;), put 10,000 lines in each split file (&lt;code&gt;-l 10000&lt;/code&gt;) and use suffixes of length 3 (&lt;code&gt;-a 3&lt;/code&gt;). As a result, ten split files are created, each with 10,000 lines.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;$&lt;/b&gt; ls
&lt;font color="green"&gt;hugefile&lt;/font&gt;

&lt;b&gt;$&lt;/b&gt; wc -l hugefile
&lt;font color="green"&gt;100000 hugefile&lt;/font&gt;

&lt;b&gt;$&lt;/b&gt; split -d -l 10000 -a 3 hugefile hugefile.split.

&lt;b&gt;$&lt;/b&gt; ls
&lt;font color="green"&gt;hugefile                hugefile.split.005
hugefile.split.000      hugefile.split.006
hugefile.split.001      hugefile.split.007  
hugefile.split.002      hugefile.split.008
hugefile.split.003      hugefile.split.009
hugefile.split.004&lt;/font&gt;

&lt;b&gt;$&lt;/b&gt; wc -l *split*&lt;font color="green"&gt;
 10000 hugefile.split.000
 10000 hugefile.split.001
 10000 hugefile.split.002
 10000 hugefile.split.003
 10000 hugefile.split.004
 10000 hugefile.split.005
 10000 hugefile.split.006
 10000 hugefile.split.007
 10000 hugefile.split.008
 10000 hugefile.split.009
100000 total&lt;/font&gt;
&lt;/pre&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-7737740512311015507?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/Ld544zuodLg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/7737740512311015507/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/10/splitting-large-file-into-smaller.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7737740512311015507?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7737740512311015507?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/Ld544zuodLg/splitting-large-file-into-smaller.html" title="Splitting a large file into smaller pieces" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/10/splitting-large-file-into-smaller.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AAQn4_cCp7ImA9WhdUFUs.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-5330042595921537930</id><published>2011-10-02T15:27:00.001+01:00</published><updated>2011-10-02T15:29:03.048+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-02T15:29:03.048+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tmux" /><category scheme="http://www.blogger.com/atom/ns#" term="profile" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><category scheme="http://www.blogger.com/atom/ns#" term="completion" /><title>Better Bash Completion for Tmux</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
In my &lt;a href="http://fahdshariff.blogspot.com/2011/10/managing-multiple-terminals-with-tmux.html"&gt;previous post&lt;/a&gt;, I wrote&lt;/a&gt; about how awesome &lt;a href="http://tmux.sourceforge.net/"&gt;tmux&lt;/a&gt; is for managing multiple terminals. However, even though it is widely used, I haven't been able to find a good Bash completion script for it. The tmux package does come with &lt;code&gt;bash_completion_tmux.sh&lt;/code&gt; but this does not complete command options or command aliases. So I wrote a better version which completes &lt;code&gt;tmux&lt;/code&gt; commands, aliases and their options. However, there is still room for improvement. It would be nice if it could complete session and window names too, but I haven't found the time to implement this yet.
&lt;p/&gt;
Here is a demo:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;$&lt;/b&gt; tmux lis&lt;b&gt;[TAB]&lt;/b&gt;
&lt;font color="green"&gt;list-buffers   list-clients   list-commands
list-keys      list-panes     list-sessions  list-windows&lt;/font&gt;

&lt;b&gt;$&lt;/b&gt; tmux list-windows -&lt;b&gt;[TAB]&lt;/b&gt;
&lt;font color="green"&gt;-a -t&lt;/font&gt;

&lt;b&gt;$&lt;/b&gt; tmux list-windows -a
&lt;font color="green"&gt;sharfah:0: less [180x82] [layout f0de,180x82,0,0]
sharfah:1: tmp [180x82] [layout f0de,180x82,0,0] (active)
sharfah:2: isengard [180x82] [layout f0de,180x82,0,0]
sharfah:3: java [180x82] [layout f0de,180x82,0,0]&lt;/font&gt;
&lt;/pre&gt;
My completion script is shown below. You need to source it in your Bash profile. Alternatively, save it to your Bash completion directory e.g. &lt;code&gt;~/.bash/.bash/.bash_completion.d&lt;/code&gt; and it should automatically get picked up.
&lt;p/&gt;
The script is also available in my &lt;a href="https://github.com/sharfah/dotfiles/blob/master/.bash/.bash_completion.d/tmux"&gt;GitHub dotfiles repository&lt;/a&gt;. If you can improve it, fork it and send me a pull request!
&lt;pre class="brush:bash; gutter:true;"&gt;
#
# tmux completion
# by Fahd Shariff
#
_tmux() {
  # an array of commands and their options
  declare -A tmux_cmd_map
  tmux_cmd_map=( ["attach-session"]="-dr -t target-session" \
                 ["bind-key"]="-cnr -t key-table key command arguments" \
                 ["break-pane"]="-d -t target-pane" \
                 ["capture-pane"]="-b buffer-index -E end-line -S start-line -t target-pane" \
                 ["choose-buffer"]="-t target-window template" \
                 ["choose-client"]="-t target-window template" \
                 ["choose-session"]="-t target-window template" \
                 ["choose-window"]="-t target-window template" \
                 ["clear-history"]="-t target-pane" \
                 ["clock-mode"]="-t target-pane" \
                 ["command-prompt"]="-I inputs -p prompts -t target-client template" \
                 ["confirm-before"]="-p prompt -t target-client command" \
                 ["copy-mode"]="-u -t target-pane" \
                 ["delete-buffer"]="-b buffer-index" \
                 ["detach-client"]="-P -s target-session -t target-client" \
                 ["display-message"]="-p -c target-client -t target-pane message" \
                 ["display-panes"]="-t target-client" \
                 ["find-window"]="-t target-window match-string" \
                 ["has-session"]="-t target-session" \
                 ["if-shell"]="shell-command command" \
                 ["join-pane"]="-dhv -p percentage|-l size -s src-pane -t dst-pane" \
                 ["kill-pane"]="-a -t target-pane" \
                 ["kill-server"]="kill-server" \
                 ["kill-session"]="-t target-session" \
                 ["kill-window"]="-t target-window" \
                 ["last-pane"]="-t target-window" \
                 ["last-window"]="-t target-session" \
                 ["link-window"]="-dk -s src-window -t dst-window" \
                 ["list-buffers"]="list-buffers" \
                 ["list-clients"]="-t target-session" \
                 ["list-commands"]="list-commands" \
                 ["list-keys"]="-t key-table" \
                 ["list-panes"]="-as -t target" \
                 ["list-sessions"]="list-sessions" \
                 ["list-windows"]="-a -t target-session" \
                 ["load-buffer"]="-b buffer-index path" \
                 ["lock-client"]="-t target-client" \
                 ["lock-server"]="lock-server" \
                 ["lock-session"]="-t target-session" \
                 ["move-window"]="-dk -s src-window -t dst-window" \
                 ["new-session"]="-d -n window-name -s session-name -t target-session -x width -y height command" \
                 ["new-window"]="-adk -n window-name -t target-window command" \
                 ["next-layout"]="-t target-window" \
                 ["next-window"]="-a -t target-session" \
                 ["paste-buffer"]="-dr -s separator -b buffer-index -t target-pane" \
                 ["pipe-pane"]="-t target-pane-o command" \
                 ["previous-layout"]="-t target-window" \
                 ["previous-window"]="-a -t target-session" \
                 ["refresh-client"]="-t target-client" \
                 ["rename-session"]="-t target-session new-name" \
                 ["rename-window"]="-t target-window new-name" \
                 ["resize-pane"]="-DLRU -t target-pane adjustment" \
                 ["respawn-pane"]="-k -t target-pane command" \
                 ["respawn-window"]="-k -t target-window command" \
                 ["rotate-window"]="-DU -t target-window" \
                 ["run-shell"]="command" \
                 ["save-buffer"]="-a -b buffer-index" \
                 ["select-layout"]="-np -t target-window layout-name" \
                 ["select-pane"]="-lDLRU -t target-pane" \
                 ["select-window"]="-lnp -t target-window" \
                 ["send-keys"]="-t target-pane key " \
                 ["send-prefix"]="-t target-pane" \
                 ["server-info"]="server-info" \
                 ["set-buffer"]="-b buffer-index data" \
                 ["set-environment"]="-gru -t target-session name value" \
                 ["set-option"]="-agsuw -t target-session|target-window option value" \
                 ["set-window-option"]="-agu -t target-window option value" \
                 ["show-buffer"]="-b buffer-index" \
                 ["show-environment"]="-g -t target-session" \
                 ["show-messages"]="-t target-client" \
                 ["show-options"]="-gsw -t target-session|target-window" \
                 ["show-window-options"]="-g -t target-window" \
                 ["source-file"]="path" \
                 ["split-window"]="-dhvP -p percentage|-l size -t target-pane command" \
                 ["start-server"]="start-server" \
                 ["suspend-client"]="-t target-client" \
                 ["swap-pane"]="-dDU -s src-pane -t dst-pane" \
                 ["swap-window"]="-d -s src-window -t dst-window" \
                 ["switch-client"]="-lnp -c target-client -t target-session" \
                 ["unbind-key"]="-acn -t key-table key" \
                 ["unlink-window"]="-k -t target-window" )

   declare -A tmux_alias_map
   tmux_alias_map=( ["attach"]="attach-session" \
                  ["detach"]="detach-client" \
                  ["has"]="has-session" \
                  ["lsc"]="list-clients" \
                  ["lscm"]="list-commands" \
                  ["ls"]="list-sessions" \
                  ["lockc"]="lock-client" \
                  ["locks"]="lock-session" \
                  ["new"]="new-session" \
                  ["refresh"]="refresh-client" \
                  ["rename"]="rename-session" \
                  ["showmsgs"]="show-messages" \
                  ["source"]="source-file" \
                  ["start"]="start-server" \
                  ["suspendc"]="suspend-client" \
                  ["switchc"]="switch-client" \
                  ["breakp"]="break-pane" \
                  ["capturep"]="target-pane]" \
                  ["displayp"]="display-panes" \
                  ["findw"]="find-window" \
                  ["joinp"]="join-pane" \
                  ["killp"]="kill-pane" \
                  ["killw"]="kill-window" \
                  ["lastp"]="last-pane" \
                  ["last"]="last-window" \
                  ["linkw"]="link-window" \
                  ["lsp"]="list-panes" \
                  ["lsw"]="list-windows" \
                  ["movew"]="move-window" \
                  ["neww"]="new-window" \
                  ["nextl"]="next-layout" \
                  ["next"]="next-window" \
                  ["pipep"]="pipe-pane" \
                  ["prevl"]="previous-layout" \
                  ["prev"]="previous-window" \
                  ["renamew"]="rename-window" \
                  ["resizep"]="resize-pane" \
                  ["respawnp"]="respawn-pane" \
                  ["respawnw"]="respawn-window" \
                  ["rotatew"]="rotate-window" \
                  ["selectl"]="select-layout" \
                  ["selectp"]="select-pane" \
                  ["selectw"]="select-window" \
                  ["splitw"]="[shell-command]" \
                  ["swapp"]="swap-pane" \
                  ["swapw"]="swap-window" \
                  ["unlinkw"]="unlink-window" \
                  ["bind"]="bind-key" \
                  ["lsk"]="list-keys" \
                  ["send"]="send-keys" \
                  ["unbind"]="unbind-key" \
                  ["set"]="set-option" \
                  ["setw"]="set-window-option" \
                  ["show"]="show-options" \
                  ["showw"]="show-window-options" \
                  ["setenv"]="set-environment" \
                  ["showenv"]="show-environment" \
                  ["confirm"]="confirm-before" \
                  ["display"]="display-message" \
                  ["clearhist"]="clear-history" \
                  ["deleteb"]="delete-buffer" \
                  ["lsb"]="list-buffers" \
                  ["loadb"]="load-buffer" \
                  ["pasteb"]="paste-buffer" \
                  ["saveb"]="save-buffer" \
                  ["setb"]="set-buffer" \
                  ["showb"]="show-buffer" \
                  ["if"]="if-shell" \
                  ["lock"]="lock-server" \
                  ["run"]="run-shell" \
                  ["info"]="server-info" )

   local cur="${COMP_WORDS[COMP_CWORD]}"
   local prev="${COMP_WORDS[COMP_CWORD-1]}"
   COMPREPLY=()

   # completing an option
   if [[ "$cur" == -* ]]; then
     #tmux options
     if [[ "$prev" == "tmux" ]]; then
         COMPREPLY=( $( compgen -W "-2 -8 -c -f -L -l -q -S -u -v -V" -- $cur ) )
     else
         #find the tmux command so that we can complete the options
         local cmd="$prev"
         local i=$COMP_CWORD
         while [[ "$cmd" == -* ]]
         do
             cmd="${COMP_WORDS[i]}"
             ((i--))
         done

         #if it is an alias, look up what the alias maps to
         local alias_cmd=${tmux_alias_map[$cmd]}
         if [[ -n ${alias_cmd} ]]
         then
             cmd=${alias_cmd}
         fi

         #now work out the options to this command
         local opts=""
         for opt in ${tmux_cmd_map[$cmd]}
         do
              if [[ "$opt" == -* ]]; then
                  len=${#opt}
                  i=1
                  while [ $i -lt $len ]; do
                      opts="$opts -${opt:$i:1}"
                      ((i++))
                  done
              fi
         done
         COMPREPLY=($(compgen -W "$opts" -- ${cur}))
     fi
   else
     COMPREPLY=($(compgen -W "$(echo ${!tmux_cmd_map[@]} ${!tmux_alias_map[@]})" -- ${cur}))
   fi
   return 0
}
complete -F _tmux tmux
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Related posts:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;a href="http://fahdshariff.blogspot.com/2011/10/managing-multiple-terminals-with-tmux.html"&gt;Managing Multiple Terminals with Tmux&lt;/a&gt;
&lt;a href="http://fahdshariff.blogspot.com/2011/04/writing-your-own-bash-completion.html"&gt;Writing your own Bash Completion Function&lt;/a&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-5330042595921537930?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/U9bmbydZC_4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/5330042595921537930/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/10/better-bash-completion-for-tmux.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5330042595921537930?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5330042595921537930?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/U9bmbydZC_4/better-bash-completion-for-tmux.html" title="Better Bash Completion for Tmux" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/10/better-bash-completion-for-tmux.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcGQXwyeCp7ImA9WhdUFEU.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-7307816922705390727</id><published>2011-10-01T17:36:00.001+01:00</published><updated>2011-10-01T17:37:00.290+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-01T17:37:00.290+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tmux" /><category scheme="http://www.blogger.com/atom/ns#" term="profile" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><title>Managing Multiple Terminals with Tmux</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
I've started using &lt;a href="http://tmux.sourceforge.net/"&gt;tmux&lt;/a&gt;, which is a "terminal multiplexer", similar to &lt;a href="http://www.gnu.org/s/screen/"&gt;screen&lt;/a&gt;. It allows you to manage a number of terminals from a single screen. So, for example, instead of having 5 &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/"&gt;PuTTY&lt;/a&gt; windows cluttering up your desktop, you now have only one window, &lt;i&gt;containing&lt;/i&gt; 5 terminals. If you close this window, you can simply open a new one and "attach" to your running tmux session, to get all your terminals back at the same state you left them in.
&lt;p/&gt;
There are lots of cool things you can do with tmux. For example, you can split a terminal window horizontally or vertically into "panes". This allows you to look at files side by side, or simply watch a process in one pane while you do something else in another.
&lt;p/&gt;
I took the following screenshot of tmux in action:
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-KJCmXWpfH2U/TodAikI07uI/AAAAAAAACtE/XCtMIjXNRic/s1600/tmux.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="215" width="400" src="http://4.bp.blogspot.com/-KJCmXWpfH2U/TodAikI07uI/AAAAAAAACtE/XCtMIjXNRic/s400/tmux.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br/&gt;
The status bar along the bottom shows that I have 5 terminal windows open. I am currently in the one labelled "1-demo" and within this window I have 4 panes, each running a different command.

&lt;p/&gt;
There are quite a few key bindings to learn, but once you have mastered them you will be able to jump back and forth between windows, move them around and kill them without lifting your hands off the keyboard. You can also set your own key bindings for things you do frequently. For example, my &lt;code&gt;Ctrl-b /&lt;/code&gt; binding splits my window vertically and opens up a specified &lt;code&gt;man&lt;/code&gt; page on the right. My &lt;code&gt;Ctrl+b S&lt;/code&gt; binding allows me to SSH to a server in a new window.
&lt;p/&gt;
Here is my tmux configuration taken from &lt;code&gt;~/.tmux.conf&lt;/code&gt; which shows my key bindings and colour setup. You can download this file from my &lt;a href="https://github.com/sharfah/dotfiles"&gt;GitHub dotfiles repository&lt;/a&gt;.

&lt;pre class="brush:bash; gutter:true;" title=".tmux.conf"&gt;
bind | split-window -h
bind - split-window -v
bind _ split-window -v
bind R source-file ~/.tmux.conf \; display-message "tmux.conf reloaded!"

bind / command-prompt -p "man" "split-window -h 'man %%'"
bind S command-prompt -p "ssh" "new-window -n %1 'exec ssh %1'"
bind h split-window -h  "man tmux"

set -g terminal-overrides 'xterm*:smcup@:rmcup@'

set -g history-limit 9999

# Terminal emulator window title
set -g set-titles on
set -g set-titles-string '#S:#I.#P #W'

# notifications
setw -g monitor-activity on
setw -g visual-activity on

# auto rename
setw -g automatic-rename on

# Clock
setw -g clock-mode-colour green
setw -g clock-mode-style 24

# Window status colors
setw -g window-status-bg colour235
setw -g window-status-fg colour248
setw -g window-status-alert-attr underscore
setw -g window-status-alert-bg colour235
setw -g window-status-alert-fg colour248
setw -g window-status-current-attr bright
setw -g window-status-current-bg colour235
setw -g window-status-current-fg colour248

# Message/command input colors
set -g message-bg colour240
set -g message-fg yellow
set -g message-attr bright

# Status Bar
set -g status-bg colour235
set -g status-fg colour248
set -g status-interval 1
set -g status-left '[#H]'
set -g status-right ''

set -g pane-border-fg white
set -g pane-border-bg default
set -g pane-active-border-fg white
set -g pane-active-border-bg default
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-7307816922705390727?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/PFWHTXASpPQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/7307816922705390727/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/10/managing-multiple-terminals-with-tmux.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7307816922705390727?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7307816922705390727?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/PFWHTXASpPQ/managing-multiple-terminals-with-tmux.html" title="Managing Multiple Terminals with Tmux" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-KJCmXWpfH2U/TodAikI07uI/AAAAAAAACtE/XCtMIjXNRic/s72-c/tmux.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/10/managing-multiple-terminals-with-tmux.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8NR38_eSp7ImA9WhdVGUs.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-3699381630635388375</id><published>2011-09-25T16:01:00.000+01:00</published><updated>2011-09-25T16:01:36.141+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-25T16:01:36.141+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="profile" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><category scheme="http://www.blogger.com/atom/ns#" term="completion" /><title>Speeding up Bash Profile Load Time</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
I started noticing a considerable delay whenever opening a new terminal or connecting to another server. After profiling my Bash profile with a few &lt;code&gt;time&lt;/code&gt; commands, I discovered that the slowest part was the loading of the completion file:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
$ time  ~/.bash/.bash_completion

real    0m0.457s
user    0m0.183s
sys     0m0.276s
&lt;/pre&gt;

The Bash completion script I use is from &lt;a href="http://bash-completion.alioth.debian.org"&gt;http://bash-completion.alioth.debian.org&lt;/a&gt;. I found that there is an existing bug for this issue &lt;a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=467231"&gt;#467231: bash_completion is big and loads slowly; load-by-need proposed&lt;/a&gt; and someone has submitted a script to speed up Bash completion load time called &lt;a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=dyncomp.sh;att=1;bug=467231"&gt;dyncomp.sh&lt;/a&gt;.
&lt;p/&gt;
This is a one-time script, which only needs to be run when you install your Bash completions or modify them. It loads your completions and moves the completion functions out of the script and into a separate directory. They are only loaded when needed. This speeds up the load time considerably and new terminal windows open up instantly!
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
$ time  ~/.bash/.bash_dyncompletion

real    0m0.020s
user    0m0.018s
sys     0m0.002s
&lt;/pre&gt;

You can visit my &lt;a href="https://github.com/sharfah/dotfiles"&gt;GitHub dotfiles repository&lt;/a&gt; for the latest version of my Bash profile.
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-3699381630635388375?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/CvcZHJFsEHs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/3699381630635388375/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/09/speeding-up-bash-profile-load-time.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/3699381630635388375?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/3699381630635388375?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/CvcZHJFsEHs/speeding-up-bash-profile-load-time.html" title="Speeding up Bash Profile Load Time" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/09/speeding-up-bash-profile-load-time.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8FRnY-cSp7ImA9WhdVEkQ.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-5934423132234961281</id><published>2011-09-17T21:20:00.000+01:00</published><updated>2011-09-17T21:20:17.859+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-17T21:20:17.859+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="SSH" /><title>Faster SSH with Multiplexing</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
&lt;a href="http://www.openssh.com/"&gt;OpenSSH&lt;/a&gt; allows you to speed up multiple SSH connections to the same server using "multiplexing". The first connection acts as the "master" and any other connections reuse the master instance's network connection rather than initiating new ones.
&lt;p/&gt;
In order to set this up add the following to your ~/.ssh/config file:
&lt;pre class="brush:bash; gutter:false;"&gt;
Host *
ControlMaster auto
ControlPath /tmp/%r@%h:%p
&lt;/pre&gt;
&lt;code&gt;ControlMaster auto&lt;/code&gt; will use a master if one exists, or start a master otherwise. &lt;code&gt;ControlPath&lt;/code&gt; is the path to the control socket used for connection sharing. &lt;code&gt;%r&lt;/code&gt;, &lt;code&gt;%h&lt;/code&gt; and &lt;code&gt;%p&lt;/code&gt; are replaced with your username, host to which you are connecting and the port respectively.
&lt;p/&gt;
In addition, you may want to add &lt;code&gt;Ciphers arcfour&lt;/code&gt; in order to use the arcfour cipher which is faster than the default (aes128-cbc). The transfer rate of arcfour is about 90 MB/s, aes128-cbc is about 75 MB/s and the slowest is 3des-cbc, at 19 MB/s.
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-5934423132234961281?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/-1Qv19LeFvs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/5934423132234961281/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/09/faster-ssh-with-multiplexing.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5934423132234961281?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5934423132234961281?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/-1Qv19LeFvs/faster-ssh-with-multiplexing.html" title="Faster SSH with Multiplexing" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/09/faster-ssh-with-multiplexing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QFR3Y_cSp7ImA9WhdXFUk.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-5917796635916619695</id><published>2011-08-28T16:28:00.000+01:00</published><updated>2011-08-28T16:28:36.849+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-28T16:28:36.849+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cpu" /><category scheme="http://www.blogger.com/atom/ns#" term="profiling" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Profiling Perl Code</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
I've started using &lt;a href="http://search.cpan.org/dist/Devel-NYTProf/lib/Devel/NYTProf.pm"&gt;NYTProf&lt;/a&gt; to profile and optimise my perl code. It produces a very useful report showing how much time is spent in each subroutine and statement.
&lt;p/&gt;
Usage:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
perl -d:NYTProf script.pl&lt;/pre&gt;
or
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
perl -d:NYTProf -I/path/to/Devel-NYTProf/4.06/lib/perl5 script.pl&lt;/pre&gt;

The output of the profiler is written to &lt;code&gt;./nytprof.out&lt;/code&gt;.
&lt;p/&gt;
Use the following command to create HTML reports from the profiler's results:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
/path/Devel-NYTProf/4.06/bin/nytprofhtml --file nytprof.out -out ./htmlReports --delete
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-5917796635916619695?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/UO1dWqVA_dc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/5917796635916619695/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/08/profiling-perl-code.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5917796635916619695?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5917796635916619695?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/UO1dWqVA_dc/profiling-perl-code.html" title="Profiling Perl Code" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/08/profiling-perl-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYGQnw4cSp7ImA9WhdXEUQ.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-5200097967884201809</id><published>2011-08-24T13:48:00.000+01:00</published><updated>2011-08-24T13:48:43.239+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-24T13:48:43.239+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="html5" /><category scheme="http://www.blogger.com/atom/ns#" term="pmc" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="game" /><title>Play My Code: Chain Reaction</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
I've just published a new game called &lt;a href="http://www.playmycode.com/play/game/sharfah/chain-reaction"&gt;Chain Reaction&lt;/a&gt; on &lt;a href="http://www.playmycode.com"&gt;Play My Code&lt;/a&gt;.
&lt;p/&gt;
&lt;a href="http://www.playmycode.com/about"&gt;Play My Code&lt;/a&gt; is a place where you can create your own online games &lt;b&gt;easily&lt;/b&gt; using the site's &lt;a href="http://www.playmycode.com/docs/quby"&gt;Quby&lt;/a&gt; language. The games are compiled into native JavaScript, compatible with all modern HTML5-compliant browsers. Once you've written a game, you can embed it on your website or blog, like I have done below. It's like YouTube, but for games!
&lt;p/&gt;
Here's &lt;b&gt;Chain Reaction&lt;/b&gt;! The aim of the game, is to start a chain reaction (by clicking on the screen) and explode as many atoms as possible. See how many levels you can complete!
&lt;p/&gt;

&lt;iframe width="620" height="438" src="http://www.playmycode.com/play/embed/sharfah/chain-reaction" marginheight="0" marginwidth="0" scrolling="no" frameborder="0" style="border: none; border-size: 0; overflow: hidden; overflow-x: hidden; overflow-y: hidden;"&gt;&lt;/iframe&gt;
&lt;p/&gt;
Click &lt;a href="http://www.playmycode.com/play/user/sharfah/games"&gt;here&lt;/a&gt; to see all my games.

&lt;/span&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-5200097967884201809?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/LUDtvtdEjTE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/5200097967884201809/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/08/play-my-code-chain-reaction.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5200097967884201809?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5200097967884201809?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/LUDtvtdEjTE/play-my-code-chain-reaction.html" title="Play My Code: Chain Reaction" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/08/play-my-code-chain-reaction.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EFQX4yeip7ImA9WhdQGUk.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-5532259834393726982</id><published>2011-08-21T17:53:00.000+01:00</published><updated>2011-08-21T17:53:30.092+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-21T17:53:30.092+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java7" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><title>Java 7: ThreadLocalRandom for Concurrent Random Numbers</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
The &lt;a href="http://download.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadLocalRandom.html"&gt;ThreadLocalRandom&lt;/a&gt; class in JDK 7, allows you to generate random numbers from multiple threads. It is more efficient than using shared &lt;code&gt;Random&lt;/code&gt; objects and will result in better performance as there is less overhead and contention. &lt;p/&gt;
In addition, this class also provides "bounded" generation methods.
&lt;p/&gt;
For example, the statement below generates a random number between 1 (inclusive) and 100 (exclusive).
&lt;pre class="brush:java; gutter:false;"&gt;
int random = ThreadLocalRandom.current().nextInt(1,100);
&lt;/pre&gt;

&lt;b&gt;&lt;font color="red"&gt;Wait, there's a BUG!&lt;/font&gt;&lt;/b&gt;&lt;/br&gt;
While trying out this class, I noticed that the SAME random numbers were being produced across all my threads. I then discovered this &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7051516"&gt;bug&lt;/a&gt; which reported the same issue I was having. It appears that the seed is never initialised so the same random numbers are produced every time. I wouldn't recommend using this class until the bug is fixed. The following code illustrates the issue:
&lt;pre class="brush:java; gutter:true;"&gt;
//3 threads
for(int i = 0; i &amp;lt; 3; i++) {
    final Thread thread = new Thread() {
        @Override
        public void run() {
            System.out.print(Thread.currentThread().getName() + ":");

            //each thread prints 3 random numbers
            for(int j = 0; j &amp;lt; 3; j++) {
                final int random = ThreadLocalRandom.current().nextInt(1, 50);
                System.out.print(random + ",");
            }
            System.out.println();
        }
    };
    thread.start();
    thread.join();
}
&lt;/pre&gt;
prints:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
Thread-0:1,5,24,
Thread-1:1,5,24,
Thread-2:1,5,24,
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-5532259834393726982?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/0fDlHQL6Ow0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/5532259834393726982/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/08/java-7-threadlocalrandom-for-concurrent.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5532259834393726982?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5532259834393726982?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/0fDlHQL6Ow0/java-7-threadlocalrandom-for-concurrent.html" title="Java 7: ThreadLocalRandom for Concurrent Random Numbers" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/08/java-7-threadlocalrandom-for-concurrent.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EAQ3s8cSp7ImA9WhdQGUk.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-4615348860169122972</id><published>2011-08-20T15:14:00.000+01:00</published><updated>2011-08-21T17:54:02.579+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-21T17:54:02.579+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><title>LESSOPEN Powers Up Less</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
A really useful feature of the Unix &lt;code&gt;less&lt;/code&gt; pager is LESSOPEN which is the "input preprocessor" for &lt;code&gt;less&lt;/code&gt;. This is a script, defined in the &lt;code&gt;LESSOPEN&lt;/code&gt; environment variable, which is invoked before the file is opened. It gives you the chance to modify the way the contents of the file are displayed. Why would you want to do this? The most common reason is to uncompress files before you view them, allowing you to &lt;code&gt;less&lt;/code&gt; GZ files. But it also allows you to list the contents of zip files and other archives. I like to use it to format XML files and to view Java class files by invoking &lt;code&gt;jad&lt;/code&gt;.
&lt;p/&gt;
You can download a really useful &lt;code&gt;LESSOPEN&lt;/code&gt; script from &lt;a href="http://sourceforge.net/projects/lesspipe/"&gt;http://sourceforge.net/projects/lesspipe/&lt;/a&gt; and then extend it if necessary.
&lt;p/&gt;
To use it, simply add &lt;code&gt;export LESSOPEN="|/path/to/bin/lesspipe.sh %s"&lt;/code&gt; to your bashrc.
&lt;p/&gt;
You can then &lt;code&gt;less&lt;/code&gt;:
&lt;ul&gt;
	&lt;li&gt;directories&lt;/li&gt;
	&lt;li&gt;compressed files&lt;/li&gt;
	&lt;li&gt;archives, to list the files contained in them&lt;/li&gt;
	&lt;li&gt;files contained in archives e.g. &lt;code&gt;less foo.zip:bar.txt&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;binary files&lt;/code&gt;
&lt;/ul&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-4615348860169122972?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/xbhTEdosu2U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/4615348860169122972/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/08/lessopen-powers-up-less.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/4615348860169122972?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/4615348860169122972?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/xbhTEdosu2U/lessopen-powers-up-less.html" title="LESSOPEN Powers Up Less" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/08/lessopen-powers-up-less.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMHQXYzfCp7ImA9WhdQE0k.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-5155800045143006369</id><published>2011-08-14T17:45:00.000+01:00</published><updated>2011-08-14T17:47:10.884+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-14T17:47:10.884+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="java7" /><category scheme="http://www.blogger.com/atom/ns#" term="templates" /><title>Useful Eclipse Templates for Faster Coding</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
I wrote about my Eclipse code templates &lt;a href="http://fahdshariff.blogspot.com/2008/11/eclipse-code-templates.html"&gt;a few years ago&lt;/a&gt; and since then I've made a quite a few changes to them. I've added a few new templates to help with JUnit tests and xml parsing. I've also updated my existing file IO templates to use &lt;b&gt;Java 7 features&lt;/b&gt;.
&lt;p/&gt;
Templates are simply "magic words" or shortcuts to standard blocks of code or text. They are very handy because once you have them setup you don't have to waste time writing  &lt;a href="http://en.wikipedia.org/wiki/Boilerplate_(text)"&gt;boilerplate&lt;/a&gt; code any more! An example of a pre-defined template in Eclipse is &lt;code&gt;sysout&lt;/code&gt; which expands to  &lt;code&gt;System.out.println();&lt;/code&gt;. All you have to do is type &lt;code&gt;sysout&lt;/code&gt; followed by &lt;code&gt;Ctrl+Space&lt;/code&gt; to insert the statement into your Java source file.
&lt;p/&gt;
To see what templates are defined in Eclipse:
&lt;ul&gt;
&lt;li&gt;Open your Preferences dialog by going to &lt;b&gt;Windows &amp;gt; Preferences&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;On the navigation tree on the left, go to &lt;b&gt;Java &amp;gt; Editor &amp;gt; Templates&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;You will see a list of pre-defined templates&lt;/li&gt;
&lt;li&gt;You can add new ones by pressing the "&lt;b&gt;New...&lt;/b&gt;" button&lt;/li&gt;
&lt;/ul&gt;
My templates are shown below. They can also be downloaded from &lt;a href="https://github.com/sharfah/dotfiles/blob/master/.eclipse/templates.xml"&gt;my GitHub repository&lt;/a&gt; and then imported into Eclipse.
&lt;p/&gt;

&lt;b&gt;&lt;font color="#000099"&gt;General Utility Templates:&lt;/font&gt;&lt;/b&gt;&lt;p/&gt;
&lt;table border="0" cellpadding="2" style="border-collapse:collapse; border: solid 2px #99aabb;  padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;if&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;if null&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
if (${var} == null){
    ${cursor}
}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;if&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;if not null&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
if (${var} != null){
    ${cursor}
}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;for&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;iterate over map&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${:import(java.util.Map.Entry)}
for(Entry&amp;lt;${key:argType(map,0)},${value:argType(map,1)}&amp;gt; entry :
                    ${map:var(java.util.Map)}.entrySet()) {
    ${key} key = entry.getKey();
    ${value} value = entry.getValue();
    ${cursor}
}&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;strf&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;format string&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
String.format("${word_selection}${}",${var}${cursor})
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;sysf&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;print formatted string to standard out&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
System.out.printf("${word_selection}${}",${var}${cursor});
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;static_final&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java type members&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;static final field&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${visibility:link(
              public,
              protected,
              private)} static final ${type} ${NAME} = ${word_selection}${};
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;File IO Templates:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
The following templates are useful for reading or writing files. They use Java 7 features such as &lt;a href="http://fahdshariff.blogspot.com/2011/07/java-7-try-with-resources.html"&gt;try-with-resources&lt;/a&gt; to automatically close files. They also use methods from NIO2.0 to obtain a buffered reader and read the file.&lt;p/&gt;
&lt;table border="0" cellpadding="2" style="border-collapse:collapse; border: solid 2px #99aabb;  padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;
&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;readfile&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;read text from file&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${:import(java.nio.file.Files,
          java.nio.file.Paths,
          java.nio.charset.Charset,
          java.io.IOException,
          java.io.BufferedReader)}
try (BufferedReader in = Files.newBufferedReader(Paths.get(${fileName:var(String)}),
                                                 Charset.forName("UTF-8"))) {
    String line = null;
    while ((line = in.readLine()) != null) {
        ${cursor}
    }
} catch (IOException e) {
    // ${todo}: handle exception
}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;readfile&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;read all lines from file as a list&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${:import(java.nio.file.Files,
          java.nio.file.Paths,
          java.nio.charset.Charset,
          java.util.List,
          java.util.ArrayList)}
Lis&amp;lt;String&amp;gt; lines = new ArrayList&amp;lt;&amp;gt;();
try{
	lines = Files.readAllLines(Paths.get(${fileName:var(String)}),
                                        Charset.forName("UTF-8"));
}catch (IOException e) {
    // ${todo}: handle exception
}
${cursor}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;writefile&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;write text to file&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${:import(java.nio.file.Files,
          java.nio.file.Paths,
          java.nio.Charset,
          java.io.IOException,
          java.io.BufferedWriter)}
try (BufferedWriter out = Files.newBufferedWriter(Paths.get(${fileName:var(String)}),
                                                  Charset.forName("UTF-8"))) {
    out.write(${string:var(String)});
    out.newLine();
    ${cursor}
} catch (IOException e) {
    // ${todo}: handle exception
}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p/&gt;

&lt;b&gt;&lt;font color="#000099"&gt;XML Templates:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
The following templates are used to read xml files or strings and return a DOM.&lt;p/&gt;
&lt;table border="0" cellpadding="2" style="border-collapse:collapse; border: solid 2px #99aabb;  padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;
&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;parsexml&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;parse xml file as Document&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${:import(org.w3c.dom.Document,
          javax.xml.parsers.DocumentBuilderFactory,
          java.io.File,
          java.io.IOException,
          javax.xml.parsers.ParserConfigurationException,
          org.xml.sax.SAXException)}
Document doc = null;
try {
	doc = DocumentBuilderFactory.newInstance()
			.newDocumentBuilder()
			.parse(new File(${filename:var(String)}));
} catch (SAXException | IOException | ParserConfigurationException e) {
	// ${todo}: handle exception
}
${cursor}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;parsexml&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;parse xml string as Document&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${:import(org.w3c.dom.Document,
          javax.xml.parsers.DocumentBuilderFactory,
          org.xml.sax.InputSource,
          java.io.StringReader,
          java.io.IOException,
          javax.xml.parsers.ParserConfigurationException,
          org.xml.sax.SAXException)}
Document doc = null;
try {
	doc = DocumentBuilderFactory.newInstance()
			.newDocumentBuilder()
			.parse(new InputSource(new StringReader(${str:var(String)})));
} catch (SAXException | IOException | ParserConfigurationException e) {
	// ${todo}: handle exception
}
${cursor}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Logging Templates:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
The templates below are useful for creating a logger and logging messages. I use &lt;a href="http://www.slf4j.org/"&gt;SLF4J&lt;/a&gt;, but they could easily be tweaked to use any other logging framework.&lt;p/&gt;
&lt;table border="0" cellpadding="2" style="border-collapse:collapse; border: solid 2px #99aabb;  padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;
&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;logger&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java type members&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;create new logger&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;

${:import(org.slf4j.Logger,
          org.slf4j.LoggerFactory)}
private static final Logger LOGGER =
       LoggerFactory.getLogger(${enclosing_type}.class);
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;logd&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;logger debug&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
if(LOGGER.isDebugEnabled())
     LOGGER.debug(${word_selection}${});
${cursor}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;logi&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;logger info&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
LOGGER.info(${word_selection}${});
${cursor}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;logerr&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;logger error&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
LOGGER.error(${word_selection}${}, ${exception_variable_name});
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;logthrow&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java statements&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;log error and throw exception&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
LOGGER.error(${word_selection}${}, ${exception_variable_name});
throw ${exception_variable_name};
${cursor}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;JUnit Templates:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
The templates below assist in writing &lt;a href="http://junit.org/"&gt;JUnit&lt;/a&gt; tests.&lt;p/&gt;
&lt;table border="0" cellpadding="2" style="border-collapse:collapse; border: solid 2px #99aabb;  padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;
&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;before&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java type members&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;junit before method&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${:import (org.junit.Before)}

@Before
public void setUp() {
    ${cursor}
}&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;after&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java type members&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;junit after method&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${:import (org.junit.After)}

@After
public void tearDown() {
    ${cursor}
}&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;beforeclass&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java type members&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;junit beforeclass method&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${:import (org.junit.BeforeClass)}

@BeforeClass
public static void oneTimeSetUp() {
    // one-time initialization code
    ${cursor}
}&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr style="border: solid 2px #99aabb;  background: #ddddff; padding: 5px; margin: 0; text-align: justify; line-height: 15px;"&gt;&lt;td&gt;&lt;b&gt;Name&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;afterclass&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Context&lt;/b&gt;&lt;/td&gt;&lt;td&gt;Java type members&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;&lt;td&gt;junit afterclass method&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;b&gt;Pattern&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;&lt;pre class="brush:java; gutter:false;"&gt;
${:import (org.junit.AfterClass)}

@AfterClass
public static void oneTimeTearDown() {
    // one-time cleanup code
    ${cursor}
}&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p/&gt;
Do YOU have any useful templates? If so, share them in the comments section!
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-5155800045143006369?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/cPQn8hVnUmU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/5155800045143006369/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/08/useful-eclipse-templates-for-faster.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5155800045143006369?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/5155800045143006369?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/cPQn8hVnUmU/useful-eclipse-templates-for-faster.html" title="Useful Eclipse Templates for Faster Coding" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/08/useful-eclipse-templates-for-faster.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUERXc-fyp7ImA9WhdQE04.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-2130859650430651094</id><published>2011-08-14T16:03:00.000+01:00</published><updated>2011-08-14T16:03:24.957+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-14T16:03:24.957+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Changing Java Library Path at Runtime</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
The &lt;code&gt;java.library.path&lt;/code&gt; system property instructs the JVM where to search for native libraries. You have to specify it as a JVM argument using &lt;code&gt;-Djava.library.path=/path/to/lib&lt;/code&gt; and then when you try to load a library using &lt;code&gt;System.loadLibrary("foo")&lt;/code&gt;, the JVM will search the library path for the specified library. If it cannot be found you will get an exception which looks like:
&lt;pre class="brush:java; gutter:false;"&gt;
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1734)
	at java.lang.Runtime.loadLibrary0(Runtime.java:823)
	at java.lang.System.loadLibrary(System.java:1028)
&lt;/pre&gt;
The &lt;code&gt;java.library.path&lt;/code&gt; is read only once when the JVM starts up. If you change this property using &lt;code&gt;System.setProperty&lt;/code&gt;, it won't make any difference.
&lt;p/&gt;
Here is the code from &lt;code&gt;ClassLoader.loadLibrary&lt;/code&gt; which shows how the path is initialised:
&lt;pre class="brush:java; gutter:false;"&gt;
if (sys_paths == null) {
    usr_paths = initializePath("java.library.path");
    sys_paths = initializePath("sun.boot.library.path");
}
&lt;/pre&gt;
As you can see from the code above, the &lt;code&gt;usr_paths&lt;/code&gt; variable is only initialised if &lt;code&gt;sys_paths&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;, which will only be once.
&lt;p/&gt;
So, how can you modify the library path at runtime? There are a couple of ways to do this, both involving reflection. You should only do this if you really have to.

&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Option 1: Unset &lt;code&gt;sys_paths&lt;/code&gt;&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
If you set &lt;code&gt;sys_paths&lt;/code&gt; to &lt;code&gt;null&lt;/code&gt;, the library path will be re-initialised when you try to load a library. The following code does this:
&lt;pre class="brush:java; gutter:false;"&gt;
/**
 * Sets the java library path to the specified path
 *
 * @param path the new library path
 * @throws Exception
 */
public static void setLibraryPath(String path) throws Exception {
    System.setProperty("java.library.path", path);

    //set sys_paths to null
    final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
    sysPathsField.setAccessible(true);
    sysPathsField.set(null, null);
}
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Option 2: Add path to &lt;code&gt;usr_paths&lt;/code&gt;&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Instead of having to re-evaluate the entire &lt;code&gt;java.library.path&lt;/code&gt; and &lt;code&gt;sun.boot.library.path&lt;/code&gt; as in Option 1, you can instead append your path to the &lt;code&gt;usr_paths&lt;/code&gt; array. This is shown in the following code:
&lt;pre class="brush:java; gutter:false;"&gt;
/**
* Adds the specified path to the java library path
*
* @param pathToAdd the path to add
* @throws Exception
*/
public static void addLibraryPath(String pathToAdd) throws Exception{
    final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
    usrPathsField.setAccessible(true);

    //get array of paths
    final String[] paths = (String[])usrPathsField.get(null);

    //check if the path to add is already present
    for(String path : paths) {
        if(path.equals(pathToAdd)) {
            return;
        }
    }

    //add the new path
    final String[] newPaths = Arrays.copyOf(paths, paths.length + 1);
    newPaths[newPaths.length-1] = pathToAdd;
    usrPathsField.set(null, newPaths);
}
&lt;/pre&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-2130859650430651094?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/zKQ7nKTT-F8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/2130859650430651094/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/08/changing-java-library-path-at-runtime.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/2130859650430651094?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/2130859650430651094?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/zKQ7nKTT-F8/changing-java-library-path-at-runtime.html" title="Changing Java Library Path at Runtime" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/08/changing-java-library-path-at-runtime.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQHRnY8fSp7ImA9WhdQEkg.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-8865640975984542977</id><published>2011-08-13T17:18:00.000+01:00</published><updated>2011-08-13T17:18:57.875+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-13T17:18:57.875+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="profile" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="vimrc" /><title>Dotfiles in Git</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
I've added all my dotfiles (including my entire bash profile and vimrc) to my &lt;a href="https://github.com/sharfah/dotfiles"&gt;GitHub dotfiles repository&lt;/a&gt;. Whenever I make any changes, I will commit them to the repository.
&lt;p/&gt;
In order to download the latest version, go to my &lt;a href="https://github.com/sharfah/dotfiles/archives/master"&gt;Downloads&lt;/a&gt; page. Alternatively, if you have &lt;code&gt;git&lt;/code&gt; installed, use the following command, to clone my repository:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
git clone git://github.com/sharfah/dotfiles.git
&lt;/pre&gt;
This will download them to a directory called &lt;code&gt;dotfiles&lt;/code&gt;. You can then copy the files recursively (&lt;code&gt;cp -r&lt;/code&gt;) to your home directory (don't forget to backup your original files first!). Alternatively, use symlinks.
&lt;/span&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-8865640975984542977?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/B8h4G_vagSE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/8865640975984542977/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/08/dotfiles-in-git.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/8865640975984542977?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/8865640975984542977?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/B8h4G_vagSE/dotfiles-in-git.html" title="Dotfiles in Git" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/08/dotfiles-in-git.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4BQns9eyp7ImA9WhdRF04.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-3119365211350268900</id><published>2011-08-07T18:09:00.000+01:00</published><updated>2011-08-07T18:09:13.563+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-07T18:09:13.563+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java7" /><title>Java 7: WatchService for File Change Notification</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
The &lt;a href="http://download.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html"&gt;Watch Service API&lt;/a&gt; in JDK7 allows you to watch a directory for changes to files and receive notification events when a file is added, deleted or modified. You no longer need to poll the file system for changes which is inefficient and doesn't scale well.
&lt;p/&gt;
The code below shows how you would use the Watch Service API. First, you have to create a &lt;code&gt;WatchService&lt;/code&gt; for the file system and then register the directory you want to monitor with it. You have to specify which events (create, modify or delete) you are interested in receiving. Then start an infinite loop to wait for events. When an event occurs, a &lt;code&gt;WatchKey&lt;/code&gt; is placed into the watch service's queue and you have to call &lt;code&gt;take&lt;/code&gt; to retrieve it. You can then query the key for events and print them out.
&lt;pre class="brush:java; gutter:true;"&gt;
/**
 * Watch the specified directory
 * @param dirname the directory to watch
 * @throws IOException
 * @throws InterruptedException
 */
public static void watchDir(String dir)
    throws IOException, InterruptedException{

  //create the watchService
  final WatchService watchService = FileSystems.getDefault().newWatchService();

  //register the directory with the watchService
  //for create, modify and delete events
  final Path path = Paths.get(dir);
  path.register(watchService,
            StandardWatchEventKinds.ENTRY_CREATE,
            StandardWatchEventKinds.ENTRY_MODIFY,
            StandardWatchEventKinds.ENTRY_DELETE);

  //start an infinite loop
  while(true){

    //remove the next watch key
    final WatchKey key = watchService.take();

    //get list of events for the watch key
    for (WatchEvent&amp;lt;?&amp;gt; watchEvent : key.pollEvents()) {

      //get the filename for the event
      final WatchEvent&amp;lt;Path&amp;gt; ev = (WatchEvent&amp;lt;Path&amp;gt;)watchEvent;
      final Path filename = ev.context();

      //get the kind of event (create, modify, delete)
      final Kind&amp;lt;?&amp;gt; kind = watchEvent.kind();

      //print it out
      System.out.println(kind + ": " + filename);
    }

    //reset the key
    boolean valid = key.reset();

    //exit loop if the key is not valid
    //e.g. if the directory was deleted
      if (!valid) {
          break;
      }
  }
}
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Demo:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
$ java Watcher &amp;
$ touch foo
&lt;font color="green"&gt;ENTRY_CREATE: foo&lt;/font&gt;
$ echo hello &gt;&gt; foo
&lt;font color="green"&gt;ENTRY_MODIFY: foo&lt;/font&gt;
$ rm foo
&lt;font color="green"&gt;ENTRY_DELETE: foo&lt;/font&gt;
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-3119365211350268900?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/wBsjGzIpq-k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/3119365211350268900/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/08/java-7-watchservice-for-file-change.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/3119365211350268900?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/3119365211350268900?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/wBsjGzIpq-k/java-7-watchservice-for-file-change.html" title="Java 7: WatchService for File Change Notification" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/08/java-7-watchservice-for-file-change.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMNQ3kzeCp7ImA9WhdRF04.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-4772507612796867204</id><published>2011-08-07T16:21:00.000+01:00</published><updated>2011-08-07T16:21:32.780+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-07T16:21:32.780+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java7" /><title>Java 7: Working with Zip Files</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
The &lt;a href="http://download.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html"&gt;Zip File System Provider&lt;/a&gt; in JDK7 allows you to treat a zip or jar file as a file system, which means that you can perform operations, such as moving, copying, deleting, renaming etc, just as you would with ordinary files. In previous versions of Java, you would have to use &lt;code&gt;ZipEntry&lt;/code&gt; objects and read/write using &lt;code&gt;ZipInputStream&lt;/code&gt;s and &lt;code&gt;ZipOutputStream&lt;/code&gt;s which was quite messy and verbose. The zip file system makes working with zip files much easier!
&lt;p/&gt;
This post shows you how to create a zip file and extract/list its contents, all using a zip file system.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Constructing a zip file system:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
In order to work with a zip file, you have to construct a "zip file system" first. The method below shows how this is done. You need to pass in a &lt;a href="http://download.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemproviderprops.html"&gt;properties map&lt;/a&gt; with &lt;code&gt;create=true&lt;/code&gt; if you want the file system to create the zip file if it doesn't exist.
&lt;pre class="brush:java; gutter:true;"&gt;
/**
 * Returns a zip file system
 * @param zipFilename to construct the file system from
 * @param create true if the zip file should be created
 * @return a zip file system
 * @throws IOException
 */
private static FileSystem createZipFileSystem(String zipFilename,
                                              boolean create)
                                              throws IOException {
  // convert the filename to a URI
  final Path path = Paths.get(zipFilename);
  final URI uri = URI.create("jar:file:" + path.toUri().getPath());

  final Map&amp;lt;String, String&amp;gt; env = new HashMap&amp;lt;&amp;gt;();
  if (create) {
    env.put("create", "true");
  }
  return FileSystems.newFileSystem(uri, env);
}
&lt;/pre&gt;
Once you have a zip file system, you can invoke methods of the &lt;code&gt;java.nio.file.FileSystem&lt;/code&gt;, &lt;code&gt;java.nio.file.Path&lt;/code&gt; and &lt;code&gt;java.nio.file.Files&lt;/code&gt; classes to manipulate the zip file.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Unzipping a Zip File:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
In order to extract a zip file, you can walk the zip file tree from the root and copy files to the destination directory. Since you are dealing with a zip file system, extracting a directory is exactly the same as copying a directory recursively to another directory. The code below demonstrates this. (Note the use of the &lt;a href="http://fahdshariff.blogspot.com/2011/07/java-7-try-with-resources.html"&gt;try-with-resources statement&lt;/a&gt; to close the zip file system automatically when done.)
&lt;pre class="brush:java; gutter:true;"&gt;
/**
 * Unzips the specified zip file to the specified destination directory.
 * Replaces any files in the destination, if they already exist.
 * @param zipFilename the name of the zip file to extract
 * @param destFilename the directory to unzip to
 * @throws IOException
 */
public static void unzip(String zipFilename, String destDirname)
    throws IOException{

  final Path destDir = Paths.get(destDirname);
  //if the destination doesn't exist, create it
  if(Files.notExists(destDir)){
    System.out.println(destDir + " does not exist. Creating...");
    Files.createDirectories(destDir);
  }

  try (FileSystem zipFileSystem = createZipFileSystem(zipFilename, false)){
    final Path root = zipFileSystem.getPath("/");

    //walk the zip file tree and copy files to the destination
    Files.walkFileTree(root, new SimpleFileVisitor&amp;lt;Path&amp;gt;(){
      @Override
      public FileVisitResult visitFile(Path file,
          BasicFileAttributes attrs) throws IOException {
        final Path destFile = Paths.get(destDir.toString(),
                                        file.toString());
        System.out.printf("Extracting file %s to %s\n", file, destFile);
        Files.copy(file, destFile, StandardCopyOption.REPLACE_EXISTING);
        return FileVisitResult.CONTINUE;
      }

      @Override
      public FileVisitResult preVisitDirectory(Path dir,
          BasicFileAttributes attrs) throws IOException {
        final Path dirToCreate = Paths.get(destDir.toString(),
                                           dir.toString());
        if(Files.notExists(dirToCreate)){
          System.out.printf("Creating directory %s\n", dirToCreate);
          Files.createDirectory(dirToCreate);
        }
        return FileVisitResult.CONTINUE;
      }
    });
  }
}
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Creating a Zip File:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
The following method shows how to create a zip file from a list of files. If a directory is passed in, it walks the directory tree and copies files into the zip file system:
&lt;pre class="brush:java; gutter:true;"&gt;
/**
 * Creates/updates a zip file.
 * @param zipFilename the name of the zip to create
 * @param filenames list of filename to add to the zip
 * @throws IOException
 */
public static void create(String zipFilename, String... filenames)
    throws IOException {

  try (FileSystem zipFileSystem = createZipFileSystem(zipFilename, true)) {
    final Path root = zipFileSystem.getPath("/");

    //iterate over the files we need to add
    for (String filename : filenames) {
      final Path src = Paths.get(filename);

      //add a file to the zip file system
      if(!Files.isDirectory(src)){
        final Path dest = zipFileSystem.getPath(root.toString(),
                                                src.toString());
        final Path parent = dest.getParent();
        if(Files.notExists(parent)){
          System.out.printf("Creating directory %s\n", parent);
          Files.createDirectories(parent);
        }
        Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);
      }
      else{
        //for directories, walk the file tree
        Files.walkFileTree(src, new SimpleFileVisitor&amp;lt;Path&amp;gt;(){
          @Override
          public FileVisitResult visitFile(Path file,
              BasicFileAttributes attrs) throws IOException {
            final Path dest = zipFileSystem.getPath(root.toString(),
                                                    file.toString());
            Files.copy(file, dest, StandardCopyOption.REPLACE_EXISTING);
            return FileVisitResult.CONTINUE;
          }

          @Override
          public FileVisitResult preVisitDirectory(Path dir,
              BasicFileAttributes attrs) throws IOException {
            final Path dirToCreate = zipFileSystem.getPath(root.toString(),
                                                           dir.toString());
            if(Files.notExists(dirToCreate)){
              System.out.printf("Creating directory %s\n", dirToCreate);
              Files.createDirectories(dirToCreate);
            }
            return FileVisitResult.CONTINUE;
          }
        });
      }
    }
  }
}
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Listing the contents of a zip file:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
This is the same as extracting a zip file except that instead of copying the files visited, we simply print them out:
&lt;pre class="brush:java; gutter:true;"&gt;
/**
 * List the contents of the specified zip file
 * @param filename
 * @throws IOException
 * @throws URISyntaxException
 */
public static void list(String zipFilename) throws IOException{

  System.out.printf("Listing Archive:  %s\n",zipFilename);

  //create the file system
  try (FileSystem zipFileSystem = createZipFileSystem(zipFilename, false)) {

    final Path root = zipFileSystem.getPath("/");

    //walk the file tree and print out the directory and filenames
    Files.walkFileTree(root, new SimpleFileVisitor&amp;lt;Path&amp;gt;(){
      @Override
      public FileVisitResult visitFile(Path file,
          BasicFileAttributes attrs) throws IOException {
        print(file);
        return FileVisitResult.CONTINUE;
      }

      @Override
      public FileVisitResult preVisitDirectory(Path dir,
          BasicFileAttributes attrs) throws IOException {
        print(dir);
        return FileVisitResult.CONTINUE;
      }

      /**
       * prints out details about the specified path
       * such as size and modification time
       * @param file
       * @throws IOException
       */
      private void print(Path file) throws IOException{
        final DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
        final String modTime= df.format(new Date(
                             Files.getLastModifiedTime(file).toMillis()));
        System.out.printf("%d  %s  %s\n",
                          Files.size(file),
                          modTime,
                          file);
      }
    });
  }
}
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Further Reading:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;a href="http://download.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html"&gt;Zip File System Provider&lt;/a&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-4772507612796867204?l=fahdshariff.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Fahdblog/~4/t0L652U_nlA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/4772507612796867204/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2011/08/java-7-working-with-zip-files.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/4772507612796867204?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/4772507612796867204?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Fahdblog/~3/t0L652U_nlA/java-7-working-with-zip-files.html" title="Java 7: Working with Zip Files" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="20" height="32" src="http://photos1.blogger.com/blogger/4160/916/320/me_2006.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://fahdshariff.blogspot.com/2011/08/java-7-working-with-zip-files.html</feedburner:origLink></entry></feed>

