<?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:blogger="http://schemas.google.com/blogger/2008" 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;CkUMQ3w8eCp7ImA9WhFSFE8.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447</id><updated>2013-06-16T15:04:42.270-07:00</updated><category term="JBoss" /><category term="scala" /><category term="jQuery" /><category term="git" /><category term="Javascript" /><category term="Web Services" /><category term="nodejs" /><category term="Play Framework" /><category term="Hibernate" /><category term="maven" /><category term="eclipse" /><category term="Java" /><category term="mongodb" /><category term="lift" /><title>Development in progress...</title><subtitle type="html">Some hopefully useful articles about software development</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.devinprogress.info/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.devinprogress.info/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>27</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/DevelopmentInProgress" /><feedburner:info uri="developmentinprogress" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CkUMQ3w8fip7ImA9WhFSFE8.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-3322841828717198149</id><published>2013-06-16T15:04:00.001-07:00</published><updated>2013-06-16T15:04:42.276-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-06-16T15:04:42.276-07:00</app:edited><title>git configuration options you can't miss</title><content type="html">&lt;p&gt;Whenever I start using a new machine for development these are the first options I setup.&lt;/p&gt;

&lt;h2&gt;First things first - Your name&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;git config --global user.name "Andrea Salvadore"
git config --global user.email "me@here.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Better log messages&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;git config --global alias.lg "log --color --graph 
  --pretty=format:'%Cred%h%Creset 
  -%C(yellow)%d%Creset %s %Cgreen(%cr) 
  %C(bold blue)&amp;lt;%an&amp;gt;%Creset' 
  --abbrev-commit"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt; This command will generate nicely coloured and formatted git logs. See more details in &lt;a href="https://coderwall.com/p/euwpig?i=3&amp;amp;p=1&amp;amp;t=git"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Some common aliases&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;git config --global alias.st status
git config --global alias.ck=checkout
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;merge tool&lt;/h2&gt;

&lt;p&gt;I use diffmerge or meld. The following configuration is for diffmerge&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config --global merge.tool diffmerge
git config --global mergetool.diffmerge.trustexitcode true
git config --global mergetool.keepbackup false
git config --global mergetool.diffmerge.cmd "/usr/bin/diffmerge --merge --result=\"$MERGED\" \"$LOCAL\" \"$BASE\" \"$REMOTE\""
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;diff tool&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;git config --global diff.tool diffmerge
git config --global difftool.diffmerge.cmd diffmerge '$LOCAL' '$REMOTE'
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;push current folder&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;git config --global push.default current
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will allow you to type&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git push origin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;instead of&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git push origin &amp;lt;current_branch_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Tell git to ignore file permission changes&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;git config --global core.filemode false
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/_AXIUmcaN1o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/3322841828717198149/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=3322841828717198149&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/3322841828717198149?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/3322841828717198149?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/_AXIUmcaN1o/git-configuration-options-you-cant-miss.html" title="git configuration options you can't miss" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2013/06/git-configuration-options-you-cant-miss.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcGQ3syfCp7ImA9WhBQFUQ.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-8755696906163701335</id><published>2013-03-18T02:13:00.002-07:00</published><updated>2013-03-18T02:13:42.594-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-18T02:13:42.594-07:00</app:edited><title>stop writing unit tests in java - Groovy part 1</title><content type="html">Many people are concerned with the libraries they use in production code, and you know maybe I can understand that. You can say that introducing them might have some unexpected consequences.&lt;br /&gt;
What I can't understand is why we keep using java to write unit tests when we have some awesome languages like groovy and scala.&lt;br /&gt;
To that goal, I am going to write a couple of articles to help you start using them today. That's right, don't wait till tomorrow. Just do it for your finger tips' sake.&lt;br /&gt;
Will start with groovy. Our build tool will be maven, not my favourite, simply the most popular. &lt;br /&gt;
Also, I will be using eclipse. I did not bother using m2eclipse.&lt;br /&gt;
&lt;h2&gt;
The base project&lt;/h2&gt;
Will start creating a new service project using maven archetypes:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;mvn archetype:generate -DgroupId=info.devinprogress -DartifactId=PostService -DarchetypeArtifactId=spring-data-basic -DarchetypeGroupId=com.cloudfoundry.tothought -DinteractiveMode=false
//Generate the eclipse project files
mvn eclipse:eclipse
&lt;/code&gt;&lt;/pre&gt;
Unfortunately I could not get maven to generate a proper eclipse .classpath file for groovy files. &lt;br /&gt;
After trying to tweak the &lt;em&gt;maven-compiler&lt;/em&gt; plugin and then using the &lt;em&gt;build-helper-maven-plugin&lt;/em&gt; eventually I gave up and had to manually change the eclipse &lt;br /&gt;
If you get it working well, let me know. Otherwise add this line to the .classpath file.&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;classpathentry including="**/*.groovy" kind="src" output="target/test-classes" path="src/test/groovy"/&amp;gt;
&lt;/pre&gt;
&lt;h2&gt;
Add the groovy source code to your maven build&lt;/h2&gt;
We need to tell maven we also have some groovy files to be compiled. To do that we'll change the build step and add the groovy compiler.&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;build&amp;gt;
    &amp;lt;plugins&amp;gt;
        &amp;lt;plugin&amp;gt;
            &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;2.3.2&amp;lt;/version&amp;gt;
            &amp;lt;configuration&amp;gt;
                &amp;lt;compilerId&amp;gt;groovy-eclipse-compiler&amp;lt;/compilerId&amp;gt;
                &amp;lt;source&amp;gt;1.7&amp;lt;/source&amp;gt;
                &amp;lt;target&amp;gt;1.7&amp;lt;/target&amp;gt;
            &amp;lt;/configuration&amp;gt;
            &amp;lt;dependencies&amp;gt;
                &amp;lt;dependency&amp;gt;
                    &amp;lt;groupId&amp;gt;org.codehaus.groovy&amp;lt;/groupId&amp;gt;
                    &amp;lt;artifactId&amp;gt;groovy-eclipse-compiler&amp;lt;/artifactId&amp;gt;
                    &amp;lt;version&amp;gt;2.7.0-01&amp;lt;/version&amp;gt;
                &amp;lt;/dependency&amp;gt;
            &amp;lt;/dependencies&amp;gt;
        &amp;lt;/plugin&amp;gt;
    &amp;lt;/plugins&amp;gt;
&amp;lt;/build&amp;gt;
&lt;/pre&gt;
Also you'll need the groovy dependency added for your test scope.&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.codehaus.groovy&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;groovy&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.1.0&amp;lt;/version&amp;gt;
    &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;h2&gt;
Install groovy plugin&lt;/h2&gt;
The groovy plugin will help when creating a new groovy class. It comes with code completion, syntax highlight and all those nice things. But probably most importantly it will compile your groovy files to bytecode. That will be handy when running test units from your IDE.&lt;br /&gt;
You can get the update site for your eclipse version &lt;a href="http://groovy.codehaus.org/Eclipse+Plugin"&gt;here&lt;/a&gt;&lt;br /&gt;
Make sure you pick the features as shown in the screenshot below:

&lt;a href="http://1.bp.blogspot.com/-_wDeJDjRt4U/UUUb2HRpilI/AAAAAAAACO0/pVjAsA6d_K8/s1600/addGroovyPlugin.png" imageanchor="1"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-_wDeJDjRt4U/UUUb2HRpilI/AAAAAAAACO0/pVjAsA6d_K8/s320/addGroovyPlugin.png" /&gt;&lt;/a&gt;

&lt;br /&gt;
Once you install it, restart eclipse. Right click on the project and add the groovy nature.&lt;br /&gt;
&lt;h2&gt;
You are ready to test&lt;/h2&gt;
Create a new folder src/test/groovy and add all your groovy tests in there. To run the in eclipse make sure you select the class in the explorer and not the file, like shown in the screenshot below.&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/-9yzrMwYDwe8/UUUeL2d6ymI/AAAAAAAACO8/8s4VrWNbiLI/s1600/rightClickOnGroovyClass.png" imageanchor="1"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-9yzrMwYDwe8/UUUeL2d6ymI/AAAAAAAACO8/8s4VrWNbiLI/s320/rightClickOnGroovyClass.png" /&gt;&lt;/a&gt;

&lt;br /&gt;
&lt;a href="http://4.bp.blogspot.com/-j5a3BHKFM-4/UUUfKoq88RI/AAAAAAAACPE/Wa6WfrUZArA/s1600/groovyTestRan.png" imageanchor="1"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-j5a3BHKFM-4/UUUfKoq88RI/AAAAAAAACPE/Wa6WfrUZArA/s320/groovyTestRan.png" /&gt;&lt;/a&gt;

&lt;br /&gt;
You are ready to test and roll.&lt;br /&gt;
Check the project on github. &lt;br /&gt;
Next post we'll right some more unit test for the PostRepository taking advantage of the groovy features.&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/wVQID2GsYI0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/8755696906163701335/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=8755696906163701335&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/8755696906163701335?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/8755696906163701335?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/wVQID2GsYI0/stop-writing-unit-tests-in-java-groovy.html" title="stop writing unit tests in java - Groovy part 1" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-_wDeJDjRt4U/UUUb2HRpilI/AAAAAAAACO0/pVjAsA6d_K8/s72-c/addGroovyPlugin.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2013/03/stop-writing-unit-tests-in-java-groovy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IARX85fSp7ImA9WhBRFks.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-263787140650467796</id><published>2013-03-07T05:05:00.001-08:00</published><updated>2013-03-07T05:05:44.125-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-03-07T05:05:44.125-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="maven" /><title>maven - only build what you need</title><content type="html">&lt;h2&gt;
Building a specific project&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;// syntax: mvn clean package -pl &amp;lt;groupId&amp;gt;:&amp;lt;artifactId&amp;gt;
mvn clean package -pl com.mycompany:myproduct

// build to succeed **You need to have dependencies installed (you must have run mvn install first)**
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;
Building a specific project and its dependencies&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;mvn clean package -pl com.mycompany:myproduct -am

// The -am option means also-make and will build dependent projects
&lt;/code&gt;&lt;/pre&gt;
&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/cvgL3rsIP7M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/263787140650467796/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=263787140650467796&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/263787140650467796?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/263787140650467796?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/cvgL3rsIP7M/maven-only-build-what-you-need.html" title="maven - only build what you need" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2013/03/maven-only-build-what-you-need.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUHSX0zfSp7ImA9WhBTFk8.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-4793831678519844360</id><published>2013-02-11T14:56:00.001-08:00</published><updated>2013-02-11T15:10:38.385-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-11T15:10:38.385-08:00</app:edited><title>My favourite programming quotes</title><content type="html">I find myself thinking about some of these quotes every now and then and I just wanted to share them here.&lt;br /&gt;
&lt;br /&gt;
Some of them are kind of funny but mostly I believe they all should make us think for a second about our job and how many times you've been in that situation...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you have some pearl of wisdom please share it at the bottom leaving a comment. I will keep this page updated!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Premature optimization is the source of all evil&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Donald Knuth&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;There are two ways of constructing a software design:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-C.A.R. Hoare, The 1980 ACM Turing Award Lecture&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Any fool can write code that a computer can understand.  Good programmers write code that humans can understand.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Martin Fowler&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Brian W. Kernighan and P. J. Plauger in The Elements of Programming Style.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;[Most managers] may defend the schedule and requirements with passion; but that's their job. It's your job to defend the code with equal passion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Robert Martin (Uncle Bob), Clean  code&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Tom Cargil Bell labs&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Before software can be reusable it first has to be usable.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Ralph Johnson&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Rick Osborne&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The best way to predict the future is to implement it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Alan Key&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Talk is cheap. Show me the code.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Linus Torvalds&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Perl – The only language that looks the same before and after RSA encryption.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Keith Bostic&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I invented the term 'Object-Oriented', and I can tell you I did not have C++ in mind.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Alan Kay&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Linus Torvalds&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Controlling complexity is the essence of computer programming.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;-Brian Kernighan&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;Finally I'd like to throw one in there myself...&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I lost count of how many times I've seen that quick, little, insignificant proof of concept going to production&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/JT3q-gxqlxQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/4793831678519844360/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=4793831678519844360&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/4793831678519844360?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/4793831678519844360?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/JT3q-gxqlxQ/my-favourite-programming-quotes.html" title="My favourite programming quotes" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2013/02/my-favourite-programming-quotes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMCRHc8fyp7ImA9WhNaFUQ.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-7131786028328847437</id><published>2013-01-30T16:33:00.002-08:00</published><updated>2013-01-30T16:34:25.977-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-30T16:34:25.977-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="nodejs" /><category scheme="http://www.blogger.com/atom/ns#" term="mongodb" /><title>A Meteor nodejs app to heroku in 5 minutes</title><content type="html">&lt;p&gt;&lt;a href="http://www.meteor.com"&gt;Meteor&lt;/a&gt; is an amazing framework to rapidly build fully interactive web applications based on node.js and MongoDB.&lt;/p&gt;
&lt;p&gt;I had a look at the video on the home page and I was quite impressed. I wanted to check it out myself on the web so I installed the framework&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl https://install.meteor.com | /bin/sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and then went ahead with creating a new app.&lt;/p&gt;
&lt;p&gt;If you create a new app you probably won't have a feeling of where to start. So instead of starting from scratch, try starting from one of the examples&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;meteor create --example parties
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that you have the code just browse through the client and the server folders, you can get a feeling of how to structure a web app.&lt;/p&gt;
&lt;p&gt;Ok now, let's chuck it on heroku&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd parties
heroku create devparties --stack cedar --buildpack https://github.com/jordansissel/heroku-buildpack-meteor.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The command above will create a new heroku app called devparties using this &lt;a href="https://github.com/jordansissel/heroku-buildpack-meteor"&gt;buildpack&lt;/a&gt; that has all the configuration to use a MongoHQ free db.&lt;/p&gt;
&lt;p&gt;Now let's use git to add to heroku&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git init
git commit -a -m "Initial commit"
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before pushing you will have to add the remote (heroku) git url&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git remote add heroku git@heroku.com:devparties.git
git push heroku master
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OK, that's it. You have your app running.&lt;/p&gt;
&lt;p&gt;There is one last thing you command you'll have to run to set the ROOT_URL ( not sure, must be in the buildpack somewhere.. )
Anyway, if you get an error like &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Starting process with command `PATH=.meteor/local/usr/bin:.meteor/local/usr/lib/meteor/bin:bin:/usr/local/bin:/usr/bin:/bin NODE_PATH=.meteor/local/usr/lib/meteor/lib/node_modules MONGO_URL=mongodb://heroku:1e2cc27d5f5415f5cd31783b6fa29afa@linus.mongohq.com:10011/app11455582 node .meteor/local/build/main.js`
2013-01-31T00:03:57+00:00 app[web.1]:             ^
2013-01-31T00:03:57+00:00 app[web.1]: app/packages/meteor/url_common.js:14
2013-01-31T00:03:57+00:00 app[web.1]: 
2013-01-31T00:03:57+00:00 app[web.1]:     at Object.Meteor.absoluteUrl (app/packages/meteor/url_common.js:14:13)
2013-01-31T00:03:57+00:00 app[web.1]:     at app/packages/accounts-password/email_templates.js:3:20
2013-01-31T00:03:57+00:00 app[web.1]:       throw new Error("Must pass options.rootUrl or set ROOT_URL in the server
2013-01-31T00:03:57+00:00 app[web.1]: Error: Must pass options.rootUrl or set ROOT_URL in the server environment
2013-01-31T00:03:57+00:00 app[web.1]:     at Array.forEach (native)
2013-01-31T00:03:57+00:00 app[web.1]:     at Function._.each._.forEach (/app/.meteor/local/build/server/node_modules/underscore/underscore.js:79:11)
2013-01-31T00:03:57+00:00 app[web.1]:     at run (/app/.meteor/local/build/server/server.js:99:7)
2013-01-31T00:03:57+00:00 app[web.1]:     at /app/.meteor/local/build/server/server.js:113:21
2013-01-31T00:03:58+00:00 heroku[web.1]: Process exited with status 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;then run the command&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;heroku config:add ROOT_URL=http://devparties.herokuapp.com
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/VFogS7ytlfg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/7131786028328847437/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=7131786028328847437&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7131786028328847437?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7131786028328847437?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/VFogS7ytlfg/a-meteor-nodejs-app-to-heroku-in-5.html" title="A Meteor nodejs app to heroku in 5 minutes" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2013/01/a-meteor-nodejs-app-to-heroku-in-5.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIBRXc4cSp7ImA9WhNaE0Q.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-4568853062990420515</id><published>2013-01-28T10:08:00.003-08:00</published><updated>2013-01-28T10:09:14.939-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-28T10:09:14.939-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mongodb" /><title>MongoDB online course videos and how to download them</title><content type="html">hey guys, The MongoDB guys are doing some free online course on MongoDB.
The MongoDB for DBAs is already online with the first two weeks&lt;br /&gt;
if you want to download the videos and watch them online (like me on the tube) you can check you &lt;a href="https://github.com/nonsleepr/edu_10gen_dl"&gt;this project&lt;/a&gt;  on github.&lt;br /&gt;
To get it running on Ubuntu make sure you have python 2.7 and a few other dependencies.&lt;br /&gt;
&lt;h3&gt;
Run&lt;/h3&gt;
Run the following commands and you'll be downloading in secs. &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;git clone git://github.com/nonsleepr/edu_10gen_dl.git
vi config.py // change email and password in the config file. 
// Also set domain to 'education.10gen.com'
sudo apt-get install python-bs4
sudo apt-get install python-mechanize
python edu_10gen.py
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The config.py needs to have your 10gen username (email) and password.
&lt;br /&gt;
&lt;br /&gt;
Hope it helps!&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/EVutZRqzZ2Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/4568853062990420515/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=4568853062990420515&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/4568853062990420515?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/4568853062990420515?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/EVutZRqzZ2Q/mongodb-online-course-videos-and-how-to.html" title="MongoDB online course videos and how to download them" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2013/01/mongodb-online-course-videos-and-how-to.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cER388eSp7ImA9WhNVF0U.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-3070013136324650644</id><published>2012-12-28T16:39:00.001-08:00</published><updated>2012-12-29T04:43:26.171-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-29T04:43:26.171-08:00</app:edited><title>play2 deploy and config on cloudbees</title><content type="html">I did some work recently to update a few web apps from play 1.2.3 to play 2. Some of them are running on heroku and others are on cloudbees.&lt;br /&gt;
One of the things I like about heroku is the &lt;a href="https://github.com/playframework/Play20/wiki/ProductionHeroku"&gt;Procfile&lt;/a&gt; that allows you to overwrite the play application.conf properties. But hold on, you can do the same on cloudbees!&lt;br /&gt;
&lt;br /&gt;
Install the &lt;a href="http://developer.cloudbees.com/bin/view/RUN/BeesSDK"&gt;bees sdk&lt;/a&gt; and try running the following command:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;bees config:list [accountname]/[appname]
&lt;/pre&gt;
&lt;br /&gt;
you should see a list of all the configuration options for your application. Now, lets tweak them a little.&lt;br /&gt;
Let's set the runtime db info :&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;bees config:set -a myaccount/myapp db.default.driver=com.mysql.jdbc.Driver \&lt;/pre&gt;
&lt;pre&gt;db.default.user=mydbuser \
db.default.password=mydbuserpass \
db.default.url=jdbc:mysql://mydbhost:3306/mydbname
&lt;/pre&gt;
&lt;br /&gt;
Now you can leave your local machine settings in the application.conf file and still pick up the right db at runtime when deployed on cloudbees, isn't that great?&lt;br /&gt;
&lt;br /&gt;
Another thing you might want to change is the smtp settings for your production environment... not problem&lt;br/&gt;
&lt;pre&gt;
bees config:set -a myaccount/myapp smtp.mock=false
&lt;/pre&gt;
&lt;br/&gt;
This will tell your play2 app to use the other smtp configuration (host, user/pass)&lt;br/&gt;
Also if you want to change some of the runtime options (like the java version) use the -R prefix

&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;bees config:set -a myaccount/myapp -Rjava_version=1.7&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Now combine that with the &lt;a href="http://wiki.cloudbees.com/bin/view/RUN/Playframework#HDeployingaPlay2application"&gt;play2 sbt plugin&lt;/a&gt; for deploying your app and you have a complete suite of tools to get you going!
&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/3IJfptmwq64" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/3070013136324650644/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=3070013136324650644&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/3070013136324650644?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/3070013136324650644?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/3IJfptmwq64/play2-deploy-and-config-on-cloudbees.html" title="play2 deploy and config on cloudbees" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2012/12/play2-deploy-and-config-on-cloudbees.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcBRng-cSp7ImA9WhNUFU0.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-1177048624555386641</id><published>2012-12-07T08:06:00.000-08:00</published><updated>2013-01-06T12:27:37.659-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-06T12:27:37.659-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="eclipse" /><title>Escape String literals in eclipse</title><content type="html">If you've been using xml literals in your (hopefully only testing) code then you've gone through the pain of escaping the double quotes of all the attributes.&lt;br /&gt;
&lt;br /&gt;
Scala has a great way to handle it using triple - double quotes. In scala this would work fine&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
val xml = """&amp;nbsp;&amp;lt;user type="simple"/&amp;gt;&amp;nbsp;"""
&lt;/pre&gt;
&lt;br /&gt;
but if you are stuck with java, then eclipse can escape the string for you..&lt;br /&gt;
&lt;br /&gt;
Go to&amp;nbsp;&lt;b&gt;Window&amp;gt;Preference&amp;gt;Java&amp;gt;Editor&amp;gt;Typing&lt;/b&gt; and check the “&lt;b&gt;Escape text when pasting into a string literal&lt;/b&gt;“&lt;br /&gt;
&lt;br /&gt;
Check this article for some nice screenshots&lt;br /&gt;
&lt;a href="http://www.vasanth.in/2009/03/10/eclipse-tip-escape-text-when-pasting/"&gt;http://www.vasanth.in/2009/03/10/eclipse-tip-escape-text-when-pasting/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/s_aREUix6So" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/1177048624555386641/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=1177048624555386641&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/1177048624555386641?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/1177048624555386641?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/s_aREUix6So/escape-string-literals-in-eclipse.html" title="Escape String literals in eclipse" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2012/12/escape-string-literals-in-eclipse.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEBSX4-cCp7ImA9WhNXF0k.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-1998800906566596409</id><published>2012-12-05T13:57:00.002-08:00</published><updated>2012-12-05T13:57:38.058-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-05T13:57:38.058-08:00</app:edited><title>back in town</title><content type="html">It's been a long time since my last post, but I have a good excuse! I got married to a beautiful woman and I've been off for some time. I managed to see some foreign countries and enjoy a bit of time off.&lt;br /&gt;
&lt;br /&gt;
Also I moved to London!&lt;br /&gt;
&lt;br /&gt;
I enjoy living here, so far so good. There is so much going on. I'm attending as many tech meetups as I possibly can, making the most out of it. The scala group here is great, I went to a few meetups and coding dojos. I also seem to end up in skillsmatter quite often, they have great talks.&lt;br /&gt;
&lt;br /&gt;
So, that being said I am recharged and ready to get back to work!&lt;br /&gt;
I'm planning to write some posts about software quality, concurrency and performance on the JVM.&lt;br /&gt;
&lt;br /&gt;
So, don't miss out, stay tuned and &lt;a href="https://twitter.com/mericano1"&gt;follow me&lt;/a&gt; on twitter to get the latest updates!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/FKN28qglWd4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/1998800906566596409/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=1998800906566596409&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/1998800906566596409?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/1998800906566596409?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/FKN28qglWd4/back-in-town.html" title="back in town" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2012/12/back-in-town.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQMQHo7fSp7ImA9WhNXGU0.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-4343303366082633973</id><published>2012-02-14T02:59:00.003-08:00</published><updated>2012-12-07T09:13:01.405-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-07T09:13:01.405-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="eclipse" /><title>eclipse regular expressions find replace</title><content type="html">Using regular expressions in eclipse to search and replace text in a file, is straight forward and very handy!&lt;br /&gt;
All you need to know is that the matched text is going to be available in the replace textbox using the '$' dollar sign.&lt;br /&gt;
So to access the first matched element use $1, for the second $2 and so on.&lt;br /&gt;
&lt;br /&gt;
I had an old method with hundreds of lines doing calling a getAttribute("X") and casting the result to a string.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:java"&gt;(String)object1.getAttribute("X")
(String)object2.getAttribute("Y")
(String)objectN.getAttribute("Z")
&lt;/pre&gt;
&lt;br /&gt;
I had to change them all to use a new method that checks if the attribute is null. So the new line would be&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:java"&gt;getSafeStringAttribute(object1,"X")
getSafeStringAttribute(object2,"Y")
getSafeStringAttribute(objectN,"Z")
&lt;/pre&gt;
&lt;br /&gt;
With this simple regEx you can do a replace all!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;find &lt;/b&gt;: \(String\)(.+)\.getAttribute\("(.+)"\)&lt;br /&gt;
&lt;div&gt;
&lt;b&gt;replace&lt;/b&gt;:&amp;nbsp;getSafeStringAttribute($1,"$2")&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
The first&amp;nbsp;(.+) will match the objectX part while the second will match the attribute name.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
The best thing is that when you select some text and type CTRL + F (if the Regular Expressions checkbox is ticked) you string in the find will be already escaped from characters like '(', ')' etc!

&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-jrdAUemoaTw/Tx1Wup0_LJI/AAAAAAAAAJY/bcrqz-tyw4o/s1600/findReplace.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="284" src="http://2.bp.blogspot.com/-jrdAUemoaTw/Tx1Wup0_LJI/AAAAAAAAAJY/bcrqz-tyw4o/s320/findReplace.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/at3AQjWv3cY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/4343303366082633973/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=4343303366082633973&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/4343303366082633973?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/4343303366082633973?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/at3AQjWv3cY/eclipse-regular-expressions-find.html" title="eclipse regular expressions find replace" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-jrdAUemoaTw/Tx1Wup0_LJI/AAAAAAAAAJY/bcrqz-tyw4o/s72-c/findReplace.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2012/02/eclipse-regular-expressions-find.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMEQ34-eCp7ImA9WhNXGU0.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-682039902943520957</id><published>2012-01-26T08:03:00.000-08:00</published><updated>2012-12-07T09:13:22.050-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-07T09:13:22.050-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Play Framework" /><title>using play dependencies behind a proxy</title><content type="html">It took me some googling and some time to find this&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 10px; max-height: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;code&gt;
play dependencies --sync --verbose -Dhttp.proxyHost=&amp;lt;your proxy host&amp;gt;&lt;your host="" proxy=""&gt; -Dhttp.proxyPort=&amp;lt;your proxy port&amp;gt;&lt;your port="" proxy=""&gt;
&lt;/your&gt;&lt;/your&gt;&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;
and if you get an error like this


&lt;br /&gt;
&lt;pre style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 10px; max-height: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;
Traceback (most recent call last):
  File "C:\programs\play\play-1.2.3\play", line 153, in &lt;module&gt;
    status = cmdloader.commands[play_command].execute(command=play_command, app=play_app, args=remaining_args, env=play_env, cmdloader=cmdloader)
  File "C:\programs\play\play-1.2.3\framework\pym\play\commands\modulesrepo.py", line 58, in execute
    install(app, args, env)
  File "C:\programs\play\play-1.2.3\framework\pym\play\commands\modulesrepo.py", line 378, in install
    Downloader().retrieve(fetch, archive)
  File "C:\programs\play\play-1.2.3\framework\pym\play\commands\modulesrepo.py", line 88, in retrieve
    try: urllib.urlretrieve(url, destination, self.progress)
  File "C:\programs\play\play-1.2.3\python\lib\urllib.py", line 94, in urlretrieve
    return _urlopener.retrieve(url, filename, reporthook, data)
  File "C:\programs\play\play-1.2.3\python\lib\urllib.py", line 235, in retrieve
    fp = self.open(url, data)
  File "C:\programs\play\play-1.2.3\python\lib\urllib.py", line 198, in open
    return self.open_unknown_proxy(proxy, fullurl, data)
  File "C:\programs\play\play-1.2.3\python\lib\urllib.py", line 217, in open_unknown_proxy
    raise IOError, ('url error', 'invalid proxy for %s' % type, proxy)
IOError: [Errno url error] invalid proxy for http: '&amp;lt;your proxy&amp;gt;:&amp;lt;your port&amp;gt;'
&lt;/module&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;


Then try ( in windows )

&lt;/code&gt;&lt;br /&gt;
&lt;pre style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 10px; max-height: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;
set http_proxy=http://&amp;lt;your proxy&amp;gt;:&amp;lt;your port&amp;gt;
&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;

it seems to want the "http://" prefix...&lt;/code&gt;&lt;/code&gt;&lt;div&gt;
&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;br /&gt;&lt;/code&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&amp;nbsp;Hope this helps!&lt;/code&gt;&lt;/code&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/MVb8AxfPrg0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/682039902943520957/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=682039902943520957&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/682039902943520957?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/682039902943520957?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/MVb8AxfPrg0/using-play-dependencies-behind-proxy.html" title="using play dependencies behind a proxy" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2012/01/using-play-dependencies-behind-proxy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUCRH47eSp7ImA9WhNUFU0.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-9222239249571470883</id><published>2012-01-26T07:48:00.000-08:00</published><updated>2013-01-06T12:31:05.001-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-06T12:31:05.001-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git" /><title>how to configure your git diff or merge tool</title><content type="html">I recently wanted to change the diff setting for git to use &lt;a href="http://www.sourcegear.com/diffmerge/"&gt;diff merge&lt;/a&gt;&amp;nbsp;in windows.&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;So I went googling around and I found a couple of very usefull Q/A on&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;StackOverflow web site.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/780425/how-do-i-setup-diffmerge-with-msysgit-gitk/783667#783667"&gt;http://stackoverflow.com/questions/780425/how-do-i-setup-diffmerge-with-msysgit-gitk/783667#783667&lt;/a&gt;

&lt;br /&gt;
&lt;div style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; margin-bottom: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"&gt;
&lt;a href="http://stackoverflow.com/questions/255202/how-do-i-view-git-diff-output-with-visual-diff-program"&gt;http://stackoverflow.com/questions/255202/how-do-i-view-git-diff-output-with-visual-diff-program&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is essentialy how is done.&amp;nbsp;&lt;/div&gt;
&lt;div style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; margin-bottom: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"&gt;
&lt;span style="background-color: transparent;"&gt;In&amp;nbsp;&lt;/span&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 5px; padding-right: 5px; padding-top: 1px; vertical-align: baseline;"&gt;~/.gitconfig&lt;/code&gt;&lt;span style="background-color: transparent;"&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;pre style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 10px; max-height: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;[merge]
  tool = diffmerge
[mergetool "diffmerge"]
  cmd = \"C:/Program Files/git/cmd/git-diffmerge-merge.sh\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
  trustExitCode = false&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
if you also want to have the diff command using diffmerge then add the following two lines&lt;br /&gt;
&lt;pre style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 10px; max-height: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;[diff]
  tool=diffmerge
[difftool "diffmerge"]
  cmd = \"C:/Program Files/SourceGear/Common/DiffMerge/sgdm.exe\"  \"$LOCAL\" \"$REMOTE\"&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
and use it like this&lt;br /&gt;
&lt;pre style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 10px; max-height: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;git difftool &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; margin-bottom: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"&gt;
I know it might sound strange to have a .sh extension in windows but, it is not a typo. It's correct.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Created the file&lt;span style="background-color: transparent;"&gt;&amp;nbsp;&lt;/span&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 1px; padding-left: 5px; padding-right: 5px; padding-top: 1px; vertical-align: baseline;"&gt;C:\Program Files\Git\cmd\git-diffmerge-merge.sh&lt;/code&gt;&lt;span style="background-color: transparent;"&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;pre style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 10px; max-height: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;#!/bin/sh

localPath="$2"
basePath="$1"
remotePath="$3"
resultPath="$4"

if [ ! -f $basePath ]
then
    basePath="~/diffmerge-empty"
fi

"C:/Program Files/SourceGear/Common/DiffMerge/sgdm.exe" --merge --result="$resultPath" "$localPath" "$basePath" "$remotePath" --title1="Mine" --title2="Merged: $4" --title3="Theirs"
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
and you're done!&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/WiH86vAl2EM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/9222239249571470883/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=9222239249571470883&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/9222239249571470883?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/9222239249571470883?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/WiH86vAl2EM/how-to-configure-your-git-diff-or-merge.html" title="how to configure your git diff or merge tool" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2012/01/how-to-configure-your-git-diff-or-merge.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMGQ3w-cCp7ImA9WhNXGU0.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-3356639464823071289</id><published>2011-10-27T04:53:00.000-07:00</published><updated>2012-12-07T09:13:42.258-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-07T09:13:42.258-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git" /><title>Understanding Git - Good references</title><content type="html">Git is getting more and more popular these days. Most of the open source project moved to GIT and the ones that didn't yet are in the process of doing it.&lt;br /&gt;
Github itself is a great place to share your code and collaborate with other people!&lt;br /&gt;
&lt;br /&gt;
Git is great but can be tricky at the beginning.&lt;br /&gt;
&lt;br /&gt;
There are a few things you need to get your head around , there are new concepts and "jumping" to the command section without reading the&amp;nbsp;introduction&amp;nbsp;is not always&amp;nbsp;a good idea, you'll have to go back to it. &lt;br /&gt;
&lt;br /&gt;
The one thing that really helped me was &lt;a href="http://excess.org/article/2008/07/ogre-git-tutorial/"&gt;this two videos&lt;/a&gt; here that I would strongly&amp;nbsp;recommend&amp;nbsp;you to watch.&lt;br /&gt;
I am the kind of guy that is suffering to sit at the chair watching a video for 2 hours but if you are struggling with GIT this is worth it.&lt;br /&gt;
&lt;br /&gt;
Also another great resource is &lt;a href="http://think-like-a-git.net/"&gt;think like a git&lt;/a&gt;&lt;br /&gt;
Once you are more familiar with the concepts (you can just jump to the command section) other good references are&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://book.git-scm.com/"&gt;git community book&lt;/a&gt;,&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gitref.org/"&gt;gitref&lt;/a&gt;,&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://schacon.github.com/git/everyday.html"&gt;everyday git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/315911/git-for-beginners-the-definitive-practical-guide"&gt; guide on stackoverflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/tagged/git?sort=votes&amp;amp;pagesize=15"&gt;Git questions on stackoverflow sorted by votes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/JoU2huoXEHU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/3356639464823071289/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=3356639464823071289&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/3356639464823071289?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/3356639464823071289?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/JoU2huoXEHU/understanding-git-good-references.html" title="Understanding Git - Good references" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/10/understanding-git-good-references.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEENRn8zeyp7ImA9WhdbE0o.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-666210111886275011</id><published>2011-10-11T16:14:00.000-07:00</published><updated>2011-10-11T16:44:57.183-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-11T16:44:57.183-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="scala" /><title>The power of three lines of scala</title><content type="html">I was looking at &lt;a href="http://projecteuler.net/problem=8"&gt;this problem&lt;/a&gt; on project Euler.net and I was amazed it only take 3 lines of scala code (with one being the number itself)!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:scala"&gt;val bigNum = "73167176531......"
def product(digits: String) = { digits.map(java.lang.String.valueOf(_).toInt).reduceLeft( (prod, c) =&amp;gt; prod*c)}
println(bigNum.sliding(5).toSeq.map(s=&amp;gt;product(s)).max)
&lt;/pre&gt;
&lt;br /&gt;
That's it!&lt;br /&gt;
Ok let me try to explain what that code does..&lt;br /&gt;
First row is the string copied from the website, so far...so good right&lt;br /&gt;
Second row is a definition of a function product that takes a String of digits and returns an Int.&lt;br /&gt;
The return type is inferred, the compiler will figure out it is an Int&lt;br /&gt;
&lt;br /&gt;
Let's see what each method call does and where are those methods!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:scala"&gt;digits.map(java.lang.String.valueOf(_).toInt)
&lt;/pre&gt;
&lt;code&gt;map &lt;/code&gt; is a function defined in &lt;a href="http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringOps"&gt;StringOps&lt;/a&gt; and there is an implicit convertion between String and StringOps.&lt;br /&gt;
It takes every char in the String and applies the provided function. In our case the function is transforming the char to a number.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:scala"&gt;java.lang.String.valueOf(_).toInt &lt;/pre&gt;
is just a short for &lt;br /&gt;
&lt;pre class="brush:scala"&gt;c =&amp;gt; java.lang.String.valueOf(c).toInt&lt;/pre&gt;
&lt;br /&gt;
The result of this first function is a Seq of Int. Then applying the &lt;a href="http://www.scala-lang.org/api/current/index.html#scala.collection.Seq"&gt;reduceLeft&lt;/a&gt; function we calculate the product of those digits.&lt;br /&gt;
&lt;code&gt;reduceLeft&lt;/code&gt; will take two elements at a time and apply the provided binary function and then moves right and applies the same function again till the last element is reached.&lt;br /&gt;
our function is simply multiplying elements.&lt;br /&gt;
&lt;br /&gt;
Cool so we know how to multiply elements.&lt;br /&gt;
&lt;br /&gt;
Now what we need to do is go through the string taking a block of 5 digits at a time, multiply them and calculate the maximum.&lt;br /&gt;
That is exactly what the last line is doing. The sliding function in &lt;a href="http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringOps"&gt;StringOps&lt;/a&gt; is taking a block of 5 elements (chars in our case) and returning an iterator over them.&lt;br /&gt;
The&lt;code&gt; toSeq &lt;/code&gt;method creates a sequence out of the passed iterator.&lt;br /&gt;
&lt;br /&gt;
At this stage we have something like&lt;code&gt; Seq["73167","31671","16717"..]&lt;/code&gt; &lt;br /&gt;
&lt;br /&gt;
All we need to do is map this elements to their product using our product function and then calculate the maximum so the last two functions couldn't be more expressive!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is probably not the best way to solve this problem, if you want to post yours you're welcome!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/sumOzA7K2B8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/666210111886275011/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=666210111886275011&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/666210111886275011?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/666210111886275011?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/sumOzA7K2B8/power-of-three-lines-of-scala.html" title="The power of three lines of scala" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/10/power-of-three-lines-of-scala.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEGSXg5eyp7ImA9WhNUFU0.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-6940774233390432528</id><published>2011-09-28T10:21:00.000-07:00</published><updated>2013-01-06T12:37:08.623-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-06T12:37:08.623-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="maven" /><title>Maven compiler level to java 6</title><content type="html">This took me more than 3 mins googling so I thought I'd post it to save some time if I'll need it again.&lt;br /&gt;
&lt;pre class="brush: xml"&gt;
&amp;lt;project&amp;gt;
 .....
 &amp;lt;build&amp;gt;
  &amp;lt;plugins&amp;gt;
   &amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;configuration&amp;gt;
     &amp;lt;source&amp;gt;1.6&amp;lt;/source&amp;gt;
     &amp;lt;target&amp;gt;1.6&amp;lt;/target&amp;gt;
    &amp;lt;/configuration&amp;gt;
   &amp;lt;/plugin&amp;gt;
  &amp;lt;/plugins&amp;gt;
 &amp;lt;/build&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;
&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/BP9EExvY3hQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/6940774233390432528/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=6940774233390432528&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/6940774233390432528?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/6940774233390432528?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/BP9EExvY3hQ/maven-compiler-level-to-java-6.html" title="Maven compiler level to java 6" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/09/maven-compiler-level-to-java-6.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkICQ3k_fSp7ImA9WhdVE0k.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-7260130377376477673</id><published>2011-09-18T03:09:00.000-07:00</published><updated>2011-09-18T03:09:22.745-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-18T03:09:22.745-07:00</app:edited><title>2011 Open Source Awards - Get ready to Vote</title><content type="html">Get ready to vote your favorite open source project!! &lt;br /&gt;
&lt;a href="http://www.packtpub.com/"&gt;Packt Publishing&lt;/a&gt; is organizing another contest to identify the excellence among Open Source projects, public votes for the finalists in each category were combined with ratings from a panel of Judges. &lt;br /&gt;
The Open Source Awards is a contest that aims to encourage, support, recognize and reward Open Source projects.&lt;br /&gt;
The contest has been running since 2006 and is regarded as one of the most established platforms for recognizing excellence amongst Open Source Software. Prize money given out since 2006 tops $100,000&lt;br /&gt;
&lt;br /&gt;
Voting goes from the 19th of September until the 31 of October and by entering your opinion you have a chance to win a kindle! &lt;br /&gt;
&lt;br /&gt;
Go on and check &lt;a href="https://www.packtpub.com/open-source-awards-home"&gt;this page&lt;/a&gt; 
&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/8RJLcrjpsGs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/7260130377376477673/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=7260130377376477673&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7260130377376477673?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7260130377376477673?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/8RJLcrjpsGs/2011-open-source-awards-get-ready-to.html" title="2011 Open Source Awards - Get ready to Vote" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/09/2011-open-source-awards-get-ready-to.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8MQ3c5cCp7ImA9WhNUFU0.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-4509312299171721149</id><published>2011-08-20T04:26:00.000-07:00</published><updated>2013-01-06T12:41:22.928-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-06T12:41:22.928-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lift" /><category scheme="http://www.blogger.com/atom/ns#" term="scala" /><title>Liftweb setup in 10 minutes - IDE and project configuration</title><content type="html">Scala is one of the coolest programming languages out there and Lift is a revolutionary web framework that really leverages many scala features.&lt;br /&gt;
&lt;br /&gt;
But it could be daunting at the beginning, even just getting your workspace setup.

In this article I will go through the basic setup of your IDE, it really takes a few minutes!&lt;br /&gt;
&lt;br /&gt;
Even though I've always been an eclipse person I'm using IDEA IntelliJ with scala cause I think is way superior.&lt;br /&gt;
Ok let's begin. You will need IntelliJ 10.5.1, Maven or SBT.&lt;br /&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;
Create the project with maven&lt;/h4&gt;
First step is to create the project and for that we will use lift maven archetype. For the persistence layer we will use the default lift mapper. Run this command

&lt;br /&gt;
&lt;pre&gt;mvn archetype:generate   -DarchetypeGroupId=net.liftweb   
  -DarchetypeArtifactId=lift-archetype-basic_2.8.1   
  -DarchetypeVersion=2.3 
  -DarchetypeRepository=http:/scala-tools.org/repo-snapshots 
  -DremoteRepositories=http://scala-tools.org/repo-snapshots 
  -DgroupId=com.playamatch  -DartifactId=web
&lt;/pre&gt;
You can also create a JPA based project running the same command with 
&lt;br /&gt;
&lt;pre&gt;
archetypeArtifactId=lift-archetype-jpa-basic_2.8.1
&lt;/pre&gt;
&lt;br /&gt;
You already have a full liftweb project! You can even run it with maven itself using the command&lt;br /&gt;
&lt;br /&gt;
mvn jetty-run&lt;br /&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;
Download and configure IntelliJ&lt;/h4&gt;
Next open IntelliJ and install the scala plugin. You need to go to File -&amp;gt; Setting. This is where you can access all the configuration options. The equivalent of Window -&amp;gt; Preferences in eclipse. 
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-qP2kY3PP2qI/Tkbag430bkI/AAAAAAAAAIU/uCgUjvlIIe0/s1600/IntelliJ1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="393" src="http://4.bp.blogspot.com/-qP2kY3PP2qI/Tkbag430bkI/AAAAAAAAAIU/uCgUjvlIIe0/s640/IntelliJ1.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
Now go to the plugins, pick scala right click "Download and Install" and once done restart the IDE. 
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-3xZEYt81Xqw/TkbcLFdvLuI/AAAAAAAAAIc/8eQ09qfg9vY/s1600/Intellij-plugins.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="401" src="http://4.bp.blogspot.com/-3xZEYt81Xqw/TkbcLFdvLuI/AAAAAAAAAIc/8eQ09qfg9vY/s640/Intellij-plugins.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
You should be able to see your code with syntax highlights and navigate through the classes already.&lt;br /&gt;
&lt;br /&gt;
If you want you can also download the SBT plugin for IDEA. In this tutorial I will use the command line.&lt;br /&gt;
&lt;br /&gt;
Another configuration change you might want to do if you are coming from eclipse if the shortcuts. IDEA comes with an eclipse profile that will allow you to keep using all the handy shortcuts you've learned so far. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-QNfg5cED7Q8/Tk8ITe-JtpI/AAAAAAAAAIg/74Ck8CwjHwQ/s1600/IJ-keymap.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="446" src="http://3.bp.blogspot.com/-QNfg5cED7Q8/Tk8ITe-JtpI/AAAAAAAAAIg/74Ck8CwjHwQ/s640/IJ-keymap.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;
Configure SBT&lt;/h4&gt;
I would recommend using SBT for your projects with the scala compiler is very fast ( well as fast as it gets really ;) ) Here I am using SBT 0.10.1&lt;br /&gt;
&lt;br /&gt;
You need to create a build.sbt in the project root folder. This is what mine looks like, it is pretty much the standard dependencies.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;/build.sbt &lt;/i&gt;&lt;br /&gt;
&lt;pre&gt;name := "liftplay"

scalaVersion := "2.8.1"

seq(webSettings: _*)



// If using JRebel uncomment next line
//jettyScanDirs := Nil


resolvers += "Java.net Maven2 Repository" at "http://download.java.net/maven/2/"


libraryDependencies ++= {

  val liftVersion = "2.3" // Put the current/latest lift version here

  Seq(

    "net.liftweb" %% "lift-webkit" % liftVersion % "compile-&amp;gt;default",

    "net.liftweb" %% "lift-mapper" % liftVersion % "compile-&amp;gt;default",

    "net.liftweb" %% "lift-wizard" % liftVersion % "compile-&amp;gt;default")

}



// Customize any further dependencies as desired

libraryDependencies ++= Seq(

  "org.eclipse.jetty" % "jetty-webapp" % "7.3.0.v20110203" % "jetty", // For Jetty 7

  //"org.mortbay.jetty" % "jetty" % "6.1.22" % "jetty,test", // For Jetty 6, add scope test to make jetty avl. for tests

  "org.scala-tools.testing" % "specs_2.9.0" % "1.6.8" % "test", // For specs.org tests

  "junit" % "junit" % "4.8" % "test-&amp;gt;default", // For JUnit 4 testing

  "javax.servlet" % "servlet-api" % "2.5" % "provided-&amp;gt;default",

  "com.h2database" % "h2" % "1.2.138", // In-process database, useful for development systems

  "ch.qos.logback" % "logback-classic" % "0.9.26" % "compile-&amp;gt;default" // Logging

)
&lt;/pre&gt;
&lt;br /&gt;
Then create another file under project/plugins (create these folders in your root project directory if you don't have them) called again build.sbt&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;/project/plugins/build.sbt &lt;/i&gt;&lt;br /&gt;
&lt;pre&gt;resolvers ++= Seq(

  "Web plugin repo" at "http://siasia.github.com/maven2",

  Resolver.url("Typesafe repository", new java.net.URL("http://typesafe.artifactoryonline.com/typesafe/ivy-releases/"))(Resolver.defaultIvyPatterns)

)



//Following means libraryDependencies += "com.github.siasia" %% "xsbt-web-plugin" % "0.1.0-&lt;sbt version=""&gt;""

libraryDependencies &amp;lt;+= sbtVersion(v =&amp;gt; "com.github.siasia" %% "xsbt-web-plugin" % ("0.1.0-"+v))
&lt;/sbt&gt;&lt;/pre&gt;
&lt;br /&gt;
last file is the build.properties under the project folder&lt;br /&gt;
&lt;i&gt;/project/build.properties &lt;/i&gt;&lt;br /&gt;
&lt;pre&gt;
project.organization=com.playamatch
project.name=liftplay
project.version=1.0-SNAPSHOT
sbt.version=0.10.1
def.scala.version=2.8.1
build.scala.versions=2.8.1
project.initialize=false
&lt;/pre&gt;
That's it. All you need to do now is an update to download all the dependencies&lt;br /&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;
Get dependencies and run application&lt;/h4&gt;
&lt;pre&gt;
sbt update
&lt;/pre&gt;
&lt;br /&gt;
and then you can run your new application

&lt;br /&gt;
&lt;pre&gt;sbt ~jetty-run
&lt;/pre&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;
Enable Debug for your application&lt;/h4&gt;
If you want to debug your application just add the following to your sbt script

&lt;br /&gt;
&lt;pre&gt;Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
&lt;/pre&gt;
&lt;br /&gt;
and then create a remote application debug configuration from Run -&amp;gt; Edit configurations. First check your defaults are like this then click on the plus sign
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-Vb-p-m4tgVI/Tk-VVhE6QCI/AAAAAAAAAIo/Dws4JTAX2hg/s1600/remote-debug" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="440" src="http://2.bp.blogspot.com/-Vb-p-m4tgVI/Tk-VVhE6QCI/AAAAAAAAAIo/Dws4JTAX2hg/s640/remote-debug" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
and name your run configuration!
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-6XcGddEWfOg/Tk-VVkBaU8I/AAAAAAAAAIw/K4VC44r20sA/s1600/remote-debug2" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="440" src="http://2.bp.blogspot.com/-6XcGddEWfOg/Tk-VVkBaU8I/AAAAAAAAAIw/K4VC44r20sA/s640/remote-debug2" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
Happy coding!!!


&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/uuaymbii2Zw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/4509312299171721149/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=4509312299171721149&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/4509312299171721149?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/4509312299171721149?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/uuaymbii2Zw/liftweb-setup-in-10-minutes-ide-and.html" title="Liftweb setup in 10 minutes - IDE and project configuration" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-qP2kY3PP2qI/Tkbag430bkI/AAAAAAAAAIU/uCgUjvlIIe0/s72-c/IntelliJ1.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/08/liftweb-setup-in-10-minutes-ide-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AMSXczfyp7ImA9WhdRGUo.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-7166466893936847452</id><published>2011-08-09T16:06:00.000-07:00</published><updated>2011-08-10T03:23:08.987-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-10T03:23:08.987-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="JBoss" /><category scheme="http://www.blogger.com/atom/ns#" term="Hibernate" /><title>Hibernate Gotchas!</title><content type="html">I've been using Hibernate for some time now and when I don't work on a hibernate project for a while I find myself doing the same mistakes I did the previous times&lt;br /&gt;
&lt;br /&gt;
So here is a sort of watch list for my self hopefully will be useful to someone else as well.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;







Implement hashCode and equals&lt;/h4&gt;
&lt;br /&gt;
You should always implement these methods in general but for your entities you should pay a bit more attention.The first thing you think when I say equals is probably to use the Id to distinguish between instance. Well, that's gonna cause you a lot of troubles.&lt;br /&gt;
You need to keep in mind that you are working with db entities and not normal POJOs.&lt;br /&gt;
&lt;br /&gt;
When Hibernate is fetching objects is your using collections and hence equals and hashCode to know if an object you are looking for is in the session. For new objects id will be null or 0.&lt;br /&gt;
That means when trying to save two objects of the same class the second is going to overwrite the first one.&lt;br /&gt;
Also when hibernate saves a new instance it will set the id, thus making it a different object while it is exactly the same.&lt;br /&gt;
You need to use some business keys. Unique codes are great but if you can't think of anything just use a meaningful field and some timestamp (like creation date) to make it unique.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://community.jboss.org/wiki/EqualsAndHashCode"&gt;This&lt;/a&gt; is a good reference if you want to understand a bit further what's happening.&lt;br /&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;







Careful with One-to-One and Many-to-One relations&lt;/h4&gt;
&lt;br /&gt;
This is something you really need to know.&lt;br /&gt;
When mapping a relation as One-to-One or Many-to-One on the "One" side of the relation you can't have lazy loading &lt;b&gt;unless &lt;/b&gt;you specify the field as not nullable.&lt;br /&gt;
&lt;br /&gt;
Why is that?&lt;br /&gt;
Essentially on the many side of the relation hibernate can use collection proxies and lazily load instances when required.&lt;br /&gt;
On the "One" side there is no collection interface but instead a reference to one of your model classes.&lt;br /&gt;
Hibernate can proxy that one as well but only if it is sure the reference will never be null!&lt;br /&gt;
So remember if you want to have lazy loading use the not null on the one side together with the lazy annotation (or xml equivalent).&lt;br /&gt;
If your relation can be null but you still really want to make it lazy then you have some options:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Create a value to represent that. For example if you have a relation like Person -&amp;amp;amp;amp;gt;Partner&amp;nbsp; just use a specific instance of Partner that means "no partner".&lt;/li&gt;
&lt;li&gt;Use build time instrumentation. Check &lt;a href="http://docs.jboss.org/hibernate/core/3.5/reference/en/html/performance.html#performance-fetching-lazyproperties"&gt;this&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Fake the one side using a List and getting the field with get(0)&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Read more on the &lt;a href="http://community.jboss.org/wiki/SomeExplanationsOnLazyLoadingone-to-one"&gt;hibernate documentation&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;




Enable the statement logging &lt;/h4&gt;
&lt;br /&gt;
This is the only way to verify Hibernate is really doing what you expect him to do. Luckily enough there are different logging parameters that you can use to find out what is happening both at the HQL or if you want at the SQL level.
You'll be surprised how many times hibernate is running queries and you did not except it.
Try to this from the very beginning and help the team understand the importance of having the best and least possible queries or you'll surely have performance issue when running the application on some real data.

To enable logging just set this property in the session configuration file&lt;br /&gt;
&lt;pre&gt;hibernate.show_sql=true
&lt;/pre&gt;
If you want to see it nicely formatted add&lt;br /&gt;
&lt;pre&gt;hibernate.format_sql=true
&lt;/pre&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;

Watch what goes in the toString method.&lt;/h4&gt;
This one is again related to what Hibernate fetches for you without you really being aware. Lots of times when you see queries but can't figure out why some lazy list is being loaded then check the toString method.&lt;br /&gt;
It might be the culprit!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
What are your hibernate gotchas? &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/XQvieww8SEA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/7166466893936847452/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=7166466893936847452&amp;isPopup=true" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7166466893936847452?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7166466893936847452?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/XQvieww8SEA/hibernate-gotchas.html" title="Hibernate Gotchas!" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>11</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/08/hibernate-gotchas.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MNRHY8cSp7ImA9WhdVE04.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-7630050842113285677</id><published>2011-05-17T05:04:00.000-07:00</published><updated>2011-09-18T02:51:35.879-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-18T02:51:35.879-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>How to create a simple jQuery plugin - jQuery Iconify</title><content type="html">I've been playing with &lt;a href="http://www.jquery.com"&gt;jQuery&lt;/a&gt; in the last few days and I'm pretty impressed with the power of this library.&lt;br /&gt;
I still remember few years ago when you had to do everything on the server side just because it was easier! &lt;br /&gt;
&lt;br /&gt;
Those days are gone.&lt;br /&gt;
&lt;br /&gt;
Beacuse the best way to learn&amp;nbsp; is to get your hands dirty I'm gonna show you how to create a simple plugin that I called 'iconify'.&lt;br /&gt;
&lt;br /&gt;
It is very simple and you can apply the same idea to create some custom plugins as well.&lt;br /&gt;
Essentially all the plugin does is takes an element on the page and wraps it into a div. Then put an icon next to it either left or right depending on some options.&lt;br /&gt;
&lt;br /&gt;
Through options you can also bind some events to the icon (like click, or double click).&lt;br /&gt;
&lt;br /&gt;
Let's see how is done.&lt;br /&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;Basic jQuery plugin&lt;br /&gt;
&lt;/h4&gt;&lt;br /&gt;
jQuery plugins have the following structure.&lt;br /&gt;
&lt;pre class="brush: js"&gt;(function($){
//
// Plugin definition goes here
//
})(jQuery);
&lt;/pre&gt;&lt;br /&gt;
Essentially you are creating a function running it and passing this function the jQuery object. &lt;br /&gt;
&lt;br /&gt;
You need to use this definition to make sure the $ function is the jQuery one. &lt;br /&gt;
&lt;br /&gt;
By passing jQuery to a function that defines the parameter as $, $ is guaranteed to reference jQuery within the body of the function.&lt;br /&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;Let user override defaults with $.extend&lt;br /&gt;
&lt;/h4&gt;&lt;br /&gt;
Now I'm going to use the $.extend() utility function to merge user options with default options. &lt;br /&gt;
&lt;br /&gt;
Also we guard against an options object that’s null or undefined with ||{}, which supplies an empty object if options evaluates to false (null and undefined do).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:js"&gt;var settings = $.extend({
   image: imagesPath + "/info_icon.png",
   activation: "hover"
   },options||{});
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;Now work on the matched nodes&lt;br /&gt;
&lt;/h4&gt;&lt;br /&gt;
As we are building a jQuery plugin you will use the standard jQuery selectors to identify the nodes you want to work on. So the way we'll be calling this plugin is&lt;br /&gt;
&lt;pre class="brush:js"&gt;$('.myCssClass').iconify('myImage.png');
&lt;/pre&gt;&lt;br /&gt;
This code will apply our icon to all the elements that have .myCssClass.&lt;br /&gt;
To do that in the plugin you will have to loop on this elements using the each function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:js"&gt;return this.each(function(){

// here goes the code that will be manipulation all matched nodes.

});
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4 class="dipHeader"&gt;The complete plugin code will look like this&lt;br /&gt;
&lt;/h4&gt;&lt;br /&gt;
I've added a couple of utility functions in there to copy the style from the matching element to the wrapper div. The rest is simply adding the icon and binding the event.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:js"&gt;/**
 * Add an icon to an element on the page
 * @param hash options:
 *  image  : String  -&gt; The path to the icon image to use. Either this or cssClass must be defined
 *  cssClass : String  -&gt; The cssClass to use. It assumes the image used as background for the class
 *  iconCss  : Hash  -&gt; Additional css styling for the icon
 *  position : String -&gt; Where you want to see the icon. Options are right, left. Default right
 *  bind  : Hash  -&gt; event: the event to bind to, callback: the callback function for the event
 * 
 */
(function($) {
 $.fn.iconify= function(options) {
  var settings = $.extend({
   image    : "n/a",
   cssClass   : "n/a",
   iconCss    : {},
   copyStyle   : true,
   position   : "right", /*right, left*/
   bind    : {event:'click', callback: function() {}}
   },options||{}
  );
  
  var copyStyle = function (element, icon, wrapper){
   elementWidth = element.outerWidth(true);
   elementHeight = element.outerHeight(true);
   
   iconWidth = icon.outerWidth(true);
   iconHeight = icon.outerHeight(true);
   

   wrapper.attr('style', element.attr('style'));
   element.css("margin","0");
   element.attr('style','display:inline')
   
   //should pick the max height
   wrapper.width(elementWidth + iconWidth);
   wrapper.height(elementHeight);

   
   allClasses = getClassNames(element);
   $.each(allClasses, function(n, value){
    wrapper.toggleClass(value);
    element.removeClass(value);
   });
  }
  
  
  var getClassNames = function(element) {
   if (name = element.attr("class")) {
    return name.split(" ");
   }else {
    return [];
   }
  }

  return this.each(function(){
   var self = $(this); 
   var wrapper = self.wrap($('&lt;div&gt;&lt;/div&gt;')).parent();
   var icon = null;
   
   

   // css class or image?
   if (settings.cssClass){
    icon = $("&lt;span&gt;&amp;nbsp;&lt;/span&gt;").attr("class",settings.cssClass);
   } else if (settings.image){
    icon = $("&lt;image/&gt;").attr("src",settings.image);
   }
 
   
   // position left or right?
   if (settings.position &amp;&amp; settings.position.length &gt; 0){
    var strPosLength = settings.position.length;
    if (settings.position.substring(strPosLength - 5, strPosLength) == 'right'){
     icon.insertAfter(this);
    }else {
     icon.insertBefore(this);
    }
   }
   
   //copies the element style to the wrapper
   copyStyle(self, icon, wrapper);
   
   // binds event to callback
   icon.bind(settings.bind.event, settings.bind.callback);
   icon.css(settings.iconCss);
  });

  
 };
})(jQuery);
&lt;/pre&gt;&lt;br /&gt;
Thanks for reading!&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/2NOHQs0fLU8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/7630050842113285677/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=7630050842113285677&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7630050842113285677?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7630050842113285677?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/2NOHQs0fLU8/how-to-create-simple-jquery-plugin.html" title="How to create a simple jQuery plugin - jQuery Iconify" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/05/how-to-create-simple-jquery-plugin.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYBQnozeyp7ImA9WhZREks.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-5381515801383268015</id><published>2011-04-02T14:29:00.000-07:00</published><updated>2011-04-08T03:55:53.483-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-08T03:55:53.483-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Play Framework" /><title>How the play framework test runner works</title><content type="html">After working for a while with the play framework we had the need to write better integration tests.&lt;br /&gt;
By better I mean easier to maintain.&lt;br /&gt;
I like selenium but there re-usability and maintenance issues. Anyway without going any further into details I had to figure out how the @tests page works.&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-N_k42M-xcYE/TZeanZn9QsI/AAAAAAAAAGM/MsLJRaRN94g/s1600/testRunner.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="420" src="http://3.bp.blogspot.com/-N_k42M-xcYE/TZeanZn9QsI/AAAAAAAAAGM/MsLJRaRN94g/s640/testRunner.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The @tests page for one of the sample applications&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
First thing let me assure you: there is no magic. Actually is quite easy to follow once you understand how the play works. The only complicated part is the selenium bit.&lt;br /&gt;
&lt;br /&gt;
TestRunner is one of the default modules in the play framework together with secure, crud and some others. You can find it under PLAY_HOME/modules. You can also browse the &lt;a href="https://github.com/playframework/play/tree/1.1.1"&gt;code&lt;/a&gt; on github.&lt;br /&gt;
&lt;br /&gt;
&lt;h4 style="background: none repeat scroll 0% 0% rgb(204, 204, 204); padding: 10px;"&gt;Adding the routes - plugin code &lt;br /&gt;
&lt;/h4&gt;&lt;br /&gt;
As far as I understand the module only contains a plugin a &lt;br /&gt;
Under testRunner there are four folders&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;src - the plugin source code&lt;/li&gt;
&lt;li&gt;public - contains all the static html as in every play project&lt;/li&gt;
&lt;li&gt;app - controllers and views&lt;/li&gt;
&lt;li&gt;firephoque - just a library folder&lt;/li&gt;
&lt;/ul&gt;Let's go into the details.&lt;br /&gt;
Under src there is a file called &lt;a href="https://github.com/playframework/play/blob/1.1.1/modules/testrunner/src/play.plugins"&gt;play.plugins&lt;/a&gt; that tells the framework the plugin implementation is &lt;a href="https://github.com/playframework/play/blob/1.1.1/modules/testrunner/src/play/modules/testrunner/TestRunnerPlugin.java"&gt;play.modules.testrunner.TestRunnerPlugin.&lt;/a&gt;&lt;br /&gt;
This class extends PlayPlugin and has 3 methods onLoad(), onRoutesLoaded(), onApplicationReady().&lt;br /&gt;
This methods are invoked by the framework itself...guess when? :)&lt;br /&gt;
onLoad() simply adds the test folder to the classpath for the application and for all the modules.&lt;br /&gt;
&lt;br /&gt;
onRoutesLoaded() adds the test routes to the application&lt;br /&gt;
&lt;pre class="brush: java"&gt;@Override
 public void onRoutesLoaded() {
    Router.addRoute("GET", "/@tests", "TestRunner.index");
    Router.addRoute("GET", "/@tests.list", "TestRunner.list");
    Router.addRoute("GET", "/@tests/{&amp;lt;.*&amp;gt;test}", "TestRunner.run");
    Router.addRoute("POST", "/@tests/{&amp;lt;.*&amp;gt;test}", "TestRunner.saveResult");
    Router.addRoute("GET", "/@tests/emails", "TestRunner.mockEmail");
 }
&lt;/pre&gt;&lt;br /&gt;
and the last one, onApplicationReady()  simply prints the test url to the console.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Note: This line is then used in auto-test mode to detect the application is ready. Look at &lt;a href="https://github.com/playframework/play/blob/1.1.1/framework/pym/play/commands/base.py"&gt;base.py&lt;/a&gt; lines 204-215&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
The other class in the same folder,called &lt;a href="https://github.com/playframework/play/blob/1.1.1/modules/testrunner/src/play/modules/testrunner/FirePhoque.java"&gt;FirePhoque.java&lt;/a&gt; is used in auto-test mode to simulate the browser.&lt;br /&gt;
&lt;br /&gt;
To summarise, so far we have the application started with some additional routes pointing at TestRunner methods.&lt;br /&gt;
&lt;br /&gt;
&lt;h4 style="background: none repeat scroll 0% 0% rgb(204, 204, 204); padding: 10px;"&gt;Where is all happening - controllers and views&lt;br /&gt;
&lt;/h4&gt;&lt;br /&gt;
Let's have a look at the &lt;a href="https://github.com/playframework/play/blob/1.1.1/modules/testrunner/app/controllers/TestRunner.java"&gt;TestRunner&lt;/a&gt; controller. &lt;br /&gt;
You can see there all the methods added as routes in TestRunnerPlugin. Let's look at what some of methods do.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;index() &lt;/b&gt;&lt;br /&gt;
is using &lt;a href="https://github.com/playframework/play/blob/1.1.1/framework/src/play/test/TestEngine.java"&gt;TestEngine&lt;/a&gt; to figure out which ones are unit test, functional tests and selenium tests. Then it just puts the three lists in the render scope and the view page &lt;a href="https://github.com/playframework/play/blob/1.1.1/modules/testrunner/app/views/TestRunner/index.html"&gt;index.html&lt;/a&gt; renders them nicely in what you see when you go to /@tests&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;list()&lt;/b&gt;&lt;br /&gt;
This is a list of all the tests rendered as text. As far as i know is only used by auto-test&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;run()&lt;/b&gt;&lt;br /&gt;
This is the method that actually runs the java tests and sends back the results.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;saveResult()&lt;/b&gt;&lt;br /&gt;
This method saves a file in the test-results folder for every test that has been executed&lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h4 style="background: none repeat scroll 0% 0% rgb(204, 204, 204); padding: 10px;"&gt;The java tests execution &lt;/h4&gt;Unit and functional test are easy enough to understand. If you want to have more details, look at the run method in &lt;a href="https://github.com/playframework/play/blob/1.1.1/framework/src/play/test/TestEngine.java"&gt;TestEngine&lt;br /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4 style="background: none repeat scroll 0% 0% rgb(204, 204, 204); padding: 10px;"&gt;The selenium tests execution&lt;br /&gt;
&lt;/h4&gt;&lt;br /&gt;
Now here comes the tricky part &lt;br /&gt;
&lt;br /&gt;
Files ending in .test.html are selenium tests and they are passed to the TestRunner controller as .test.html.suite.&lt;br /&gt;
&lt;br /&gt;
The controller simply execute&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;test = test.substring(0, test.length() - 6);
render("TestRunner/selenium-suite.html", test);
&lt;/pre&gt;&lt;br /&gt;
Now if you look at selenium-suite.html you'll be scratching your head because there is nothing else that a table with a row and a link to the test.&lt;br /&gt;
&lt;br /&gt;
To understand you need to look at &lt;a href="https://github.com/playframework/play/blob/1.1.1/modules/testrunner/app/views/TestRunner/index.html"&gt;index.html&lt;/a&gt; lines 362-380.&lt;br /&gt;
This code is simply loading the selenium-core runner (pure DHTML) in an iframe, is making it visible and is calling the Testrunner controller to get the result every 2 seconds until it either returns an HTTP 500 (for a test failure) or an HTTP 200 (you guessed, test passed)&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-iQYRIfHkJ5c/TZhHkK0RJuI/AAAAAAAAAGQ/DRugSRfYKgI/s1600/PlayTestRunner.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="480" src="http://1.bp.blogspot.com/-iQYRIfHkJ5c/TZhHkK0RJuI/AAAAAAAAAGQ/DRugSRfYKgI/s640/PlayTestRunner.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;a picture is worth a thousand words&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
The frame in the mean time calls the controller (lines 82-100) loads the html test as any other application page, using the TemplateLoader.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;That is why you can use tags in your selenium tests! Isn't that great?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Now the selenium-core runs the html test and calls the controller saveResult method (lines 120-131) that saves a file either .passed or .failed depending on the test outcome.&lt;br /&gt;
That will allow the flow in index.html to move on to the next test.&lt;br /&gt;
&lt;br /&gt;
Quite good isn't it?&lt;br /&gt;
&lt;br /&gt;
Thanks for reading, please leave any feedback / corrections you feel.&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/ChnlViP4F6Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/5381515801383268015/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=5381515801383268015&amp;isPopup=true" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/5381515801383268015?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/5381515801383268015?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/ChnlViP4F6Q/how-play-framework-test-runner-works.html" title="How the play framework test runner works" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-N_k42M-xcYE/TZeanZn9QsI/AAAAAAAAAGM/MsLJRaRN94g/s72-c/testRunner.png" height="72" width="72" /><thr:total>6</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/04/how-play-framework-test-runner-works.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYBR345fip7ImA9WhZTEUU.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-7602487791966442189</id><published>2011-03-15T02:59:00.000-07:00</published><updated>2011-03-15T02:59:16.026-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-15T02:59:16.026-07:00</app:edited><title>Agile software development recommendations for users and new adopters</title><content type="html">Let me begin by saying that I am an agile believer and as a team player I enjoy this methodology much more than the traditional waterfall methods.&lt;br /&gt;
&lt;br /&gt;
Agile is like a fashion these days. Its one of the buzz words, it's "cool"...and I think it actually is.&lt;br /&gt;
With&amp;nbsp;popularity&amp;nbsp;also comes&amp;nbsp;rumors, myths and&amp;nbsp;misunderstandings that often cause problems in agile projects and blames attributed to the process itself.&lt;br /&gt;
&lt;br /&gt;
There are many teams claiming to use agile without even knowing the &lt;a href="http://agilemanifesto.org/principles.html"&gt;manifesto&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Yes, it is&amp;nbsp;not be the answer to all software development problems, one size doesn't fit all, but before you adopt it in your project or blame it for not working please read this and if you have some feedback feel free to&amp;nbsp;leave a comment!&lt;br /&gt;
&lt;br /&gt;
&lt;h4 style="background: none repeat scroll 0% 0% rgb(204, 204, 204); padding: 10px;"&gt;If you are considering agile take into account&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="color: blue;"&gt;Project size. &lt;/span&gt;&lt;br /&gt;
It's easy to apply agile in a new project, relatively small ( tens $K), with traditional client-server architecture and clearly defined users/customers but ..&lt;br /&gt;
what about a re-write of an existing big project (hundreds or millions $) with distributed software and multiple stakeholders? Is hard to deal with that in agile methodologies...check&amp;nbsp;&lt;a href="http://www.gilb.com/blogpost130-7-truths-about-Agile-and-Scrum-that-people-don-t-want-to-hear-Part-3-of-7-Stakeout-Stakeholders-or-Stakeholders-will-stake-you-out-"&gt;this&lt;/a&gt;&amp;nbsp;article for more info.&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;Customer or product owner must be agile&lt;/span&gt;&lt;br /&gt;
If all your customer really wants is a product with a fixed number of features in a fixed time frame, then you are probably going to fail. You are anyway even if you don't use agile. But I guess the point is agile is not going to help.&lt;br /&gt;
In agile you have to&amp;nbsp;continuously&amp;nbsp;redefine the requirements, re-elaborate them,&amp;nbsp;re-prioritize&amp;nbsp;them. Your customer must know and accept that.&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;Your organization must be agile&lt;/span&gt;&lt;br /&gt;
No point going for an iteration based model if your company still requires all work to be signed-off in an upfront specification. To get the right value you need to be able to adapt ongoing work as it progresses.&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;Your team might not be ready&lt;/span&gt;&lt;br /&gt;
Yes, that's right the team might not be mature enough to be self-managing &amp;nbsp;and it is one of the points in the agile manifesto. You need to realize if you are going to start agile and lead accordingly.&amp;nbsp;(Very good article&amp;nbsp;&lt;a href="http://5whys.com/blog/the-3-maturity-stages-of-a-software-team-and-how-scrum-fails.html"&gt;here&lt;/a&gt;)&lt;br /&gt;
You might have to hold on and train / lead your team ( and yourself ) for some more time.&lt;br /&gt;
Agile approaches require a mentality shift. Simple things like saying something is "DONE" means is &amp;nbsp;production ready. It doesn't mean the code is done and now somebody else will have to make sure it works.&amp;nbsp;Your team needs to be mature enough to own and &amp;nbsp;understand what they are committing to.&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;Agile does NOT mean you are going to develop your software faster.&lt;/span&gt;&lt;br /&gt;
That must be clear to all project managers.&lt;br /&gt;
It increases business value and ROI because using agile the team focus on features that are prioritized by business value and incrementally deliver working software at regular interval. &lt;br /&gt;
Less features =&amp;gt; faster&lt;br /&gt;
If you just consider the total time, agile is going to take longer due to&amp;nbsp;continuous&amp;nbsp;code refactor&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;Don't do it just for the sake of it&lt;/span&gt;&lt;br /&gt;
Embrace agile only if you believe in it. Not because people say it works. &lt;br /&gt;
Or even worse just to tell your customers you are an 'agile' company.&lt;br /&gt;
There are lots of successful company that never used it.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;h4 style="background: none repeat scroll 0% 0% rgb(204, 204, 204); padding: 10px;"&gt;If you are already using agile then &lt;br /&gt;
&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="color: blue;"&gt;Make sure you have a clear and commonly accepted definition of DONE.&lt;/span&gt;&lt;br /&gt;
The whole team needs to understand the process. Make sure they are aware, understand and accept that.  Your sprint artifacts must be production ready. &lt;br /&gt;
Also remember that if your sprint outcome is not actually being deployed to production (for whatever reason) you are bending contract.&amp;nbsp;Just take it into account that "production" bugs might be lurking in your code.&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;Watch the technical debt&lt;/span&gt;&lt;br /&gt;
Very often the technical debt tends to build up over the sprints due to.  You need to closely monitor it and allocated time during your sprints  to skim it off. &lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;Don't let team members act as product owner&lt;/span&gt;&lt;br /&gt;
The product owner is the most important player. Is the one telling you want to do but most of all what to do first. The right prioritization of user stories will determine the success or failure of the project and only the owner should do it.&lt;br /&gt;
Sometimes if you have a large team, you might be tempted to have someone in your team (most likely the BA) wear the product owner's hat. &lt;br /&gt;
That can lead to a lot of problems and misunderstandings. One of the key points of the agile manifesto is "Customer collaboration over contract negotiation".&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;Your team is likely to be diverse&lt;/span&gt;Not every team member can take every story. Someone says agile is not junior developer friendly.&amp;nbsp;Well its a bit more than that. You might have different people specialized in different disciplines and that will create a lot of contention / dependencies that you need to deal with.&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;Spend appropriate time on your automation and&amp;nbsp;continuous&amp;nbsp;integration&lt;/span&gt;&lt;br /&gt;
Part of the agile process is to&amp;nbsp;continuously&amp;nbsp;build and integrate the software. Developers are meant to run tests all day long.&lt;br /&gt;
If your build takes 30 mins, your application server needs another 5 and so on then your productivity is really going to suffer. Spend some time to break off the application in smaller more maintainable pieces.&lt;br /&gt;
Don't drag along cause together with the productivity the team is going to run into the bad habit of not running or skipping the procedure.&lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;Go for the "simplest possible" but don't forget the design principles&lt;/span&gt;  &lt;br /&gt;
The idea here is to get feedback as soon as possible. So if your application is going to going to generate graphs, there is nothing wrong in having an excel based first version to be sure you understand what the customer wants.&lt;br /&gt;
What you need to be careful is that software architecture and design principles are not left out! &lt;/li&gt;
&lt;li&gt;&lt;span style="color: blue;"&gt;Don't forget non-functional requirements&lt;/span&gt;&lt;br /&gt;
User stories only talk about required function. The critical “how well” attributes are totally absent. Your stakeholders will expect them anyhow and that is when you are going to get in trouble.&lt;br /&gt;
All the things like performance, scalability are really making the difference these days. &amp;nbsp;Check &lt;a href="http://lifehacker.com/#%215499959/which-browser-should-i-use-firefox-or-chrome"&gt;why&lt;/a&gt; chrome is becoming more and more popular&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Thanks for reading this, your feedback is welcome!&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/2Kaf6w_Zs8U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/7602487791966442189/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=7602487791966442189&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7602487791966442189?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7602487791966442189?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/2Kaf6w_Zs8U/agile-software-development.html" title="Agile software development recommendations for users and new adopters" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/03/agile-software-development.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMAQno-eCp7ImA9WhZSFEU.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-5676165107017382426</id><published>2011-03-08T12:21:00.000-08:00</published><updated>2011-03-30T05:34:03.450-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-30T05:34:03.450-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Play Framework" /><title>Testing your Play! controllers</title><content type="html">Lets say you have a controller like this (from the &lt;a href="http://www.playframework.org/documentation/1.1.1/guide3"&gt;Play! documentation&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush :java"&gt;package controllers;
 
import java.util.*;
 
import play.*;
import play.mvc.*;
 
import models.*;
 
public class Application extends Controller {
 
    public static void index() {
        Post frontPost = Post.find("order by postedAt desc").first();
        List&lt;post&gt; olderPosts = Post.find(
            "order by postedAt desc"
        ).from(1).fetch(10);
        render(frontPost, olderPosts);
    }
 
}
&lt;/post&gt;&lt;/pre&gt;&lt;br /&gt;
And you want to write a test to &lt;b&gt;check the render parameters&lt;/b&gt; are correct, how do you do that?&lt;br /&gt;
&lt;br /&gt;
Well here is a little example&lt;br /&gt;
&lt;pre class="brush :java"&gt;public class ApplicationTest extends FunctionalTest{
 @Before
 public void before() {
  Fixtures.deleteAllModels();
  Fixtures.load("data.yml");
 }

 @Test
 public void testHomePageFirstPost() throws MalformedURLException {
  // Call the home page
  Response response = GET("/");
  
  // Verify that Matches.matchCreate() passed correct params to render().
  Post frontPost = (Post) getRenderParameter("frontPost");
  assertEquals(${value_from_yml}, frontPost.author.fullname);
  assertEquals(${value_from_yml}, frontPost.postedAt);
 }

 /**
  * Gets the parameter that was passed to render() method.
  * @param key
  * @return
  */
 public static Object getRenderParameter(String key) {
  RenderArgs current = Scope.RenderArgs.current();
  return current.data.get(key);
 }

}
&lt;/pre&gt;&lt;br /&gt;
You might want to put the getRenderParameter in a separate class to easily reuse it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you want to test a &lt;b&gt;controller method that take parameters&lt;/b&gt; is as easy.&lt;br /&gt;
&lt;br /&gt;
Let's assume you want to test a simple controller method in Users called getUserByUsername to make sure  the correct user is added to render when the form is submitted&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush :java"&gt;public class Users extends Controller {
 
 /**
 * Gets the user given his username
 */
    public static void getUserByUsername(String username) {
        Assert.notNull(user);
        User currentUser = User.find("byUsername", username).first();
        render(currentUser);
    }
 
}

&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
In this case the test would be &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush :java"&gt;public class UserLoginTest extends FunctionalTest{

 @Before
 public void before() {
  Fixtures.deleteAllModels();
  Fixtures.load("users.yml");
 }
 
 @Test
 public void testGetByUsername() {
  Map&amp;lt;String, String&amp;gt; params = new HashMap&amp;lt;String, String&amp;gt;();
  params.put("username", "user1");
  Response response = POST("/users/getbyusername", params, new HashMap&amp;lt;String, File&amp;gt;());
  User currentUser = (User) getRenderParameter(&amp;amp;quot;currentUser&amp;amp;quot;);
  assertEquals(${from_users.yml}, currentUser.name);
  assertEquals(${from_users.yml}, currentUser.email);
 }
}

&lt;/pre&gt;&lt;br /&gt;
Please feel free to comment!&lt;br /&gt;
&lt;br /&gt;
Thanks&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/4qXU0Y5HkUc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/5676165107017382426/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=5676165107017382426&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/5676165107017382426?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/5676165107017382426?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/4qXU0Y5HkUc/unit-test-your-play-controllers.html" title="Testing your Play! controllers" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/03/unit-test-your-play-controllers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UDSX84fSp7ImA9Wx9aE0o.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-4129940929543780018</id><published>2011-03-05T17:34:00.000-08:00</published><updated>2011-03-05T17:34:38.135-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-05T17:34:38.135-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>Run tasks in parallel and set your own time out</title><content type="html">Many times blocking method calls might cause problems in your applications.&lt;br /&gt;
If the code is waiting for some resource availablity and you cannot specify a timeout  option...well you're stuck!&lt;br /&gt;
&lt;br /&gt;
You might have seen this with javax.jms.Connection, you try to open a connection when the network is down and your application freezes. No exceptions or anything telling you what's wrong. &lt;br /&gt;
&lt;br /&gt;
Using the the java.util.concurrent api you can run the problematic code in a separate thread and wait for the completion or timeout of this execution.&lt;br /&gt;
&lt;br /&gt;
Here is some code calling a jms connection factory in a separate thread. &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java" &gt;private Connection getConnection() throws NamingException, JMSException {
 FutureTask&amp;lt;Connection&amp;gt; createConnectionTask = null;
 try {
  createConnectionTask = new FutureTask&amp;lt;Connection&amp;gt;(new Callable&amp;lt;Connection&amp;gt;() {
   @Override
   public Connection call() throws Exception {
    logger.debug(&amp;quot;Calling connection on the connection factory&amp;quot;);
    Connection connection = (Connection) connectionFactory.createConnection();
    return connection;
   }
  });
  // start task in a new thread
  new Thread(createConnectionTask).start();

  logger.debug(String.format(&amp;quot;Wait for the execution of createConnection to finish, timeout after %d ms&amp;quot;, CONNECTION_TIME_OUT));
  connection = createConnectionTask.get(CONNECTION_TIME_OUT, TimeUnit.MILLISECONDS);
 } catch (TimeoutException e) {
  JMSException jmsException = new JMSException(e.getMessage());
  jmsException.setLinkedException(e);
  throw jmsException;
 } 
 return connection;
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The main thread will create a &lt;code&gt;java.util.concurrent.FutureTask&lt;/code&gt; that returns the connection you need. &lt;br /&gt;
It'll wait a maximum of &lt;code&gt;CONNECTION_TIME_OUT&lt;/code&gt; milliseconds before throwing a TimeoutException. This way you can have complete control of your code execution!&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/mJhd_uy7wzI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/4129940929543780018/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=4129940929543780018&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/4129940929543780018?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/4129940929543780018?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/mJhd_uy7wzI/run-tasks-in-parallel-and-set-your-own.html" title="Run tasks in parallel and set your own time out" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/03/run-tasks-in-parallel-and-set-your-own.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMFSXwzfip7ImA9Wx9aFko.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-8842619165269312481</id><published>2011-03-04T10:37:00.000-08:00</published><updated>2011-03-09T04:40:18.286-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-09T04:40:18.286-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="maven" /><title>Reuse your test code in maven projects!</title><content type="html">Here is a quick tip if you are using maven.&lt;br /&gt;
If you create some test utility or simply want to reuse some test class in a different project you don't need to duplicate the code or put the code in the main section, just do this:&lt;br /&gt;
&lt;br /&gt;
In the project you have code to share add this section to you pom.xml &lt;br /&gt;
&lt;pre class = "brush: xml"&gt;&amp;lt;build&amp;gt;
 &amp;lt;plugins&amp;gt;
  &amp;lt;plugin&amp;gt;
   &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
   &amp;lt;artifactId&amp;gt;maven-jar-plugin&amp;lt;/artifactId&amp;gt;
   &amp;lt;version&amp;gt;2.2&amp;lt;/version&amp;gt;
   &amp;lt;executions&amp;gt;
    &amp;lt;execution&amp;gt;
     &amp;lt;goals&amp;gt;
      &amp;lt;goal&amp;gt;test-jar&amp;lt;/goal&amp;gt;
     &amp;lt;/goals&amp;gt;
    &amp;lt;/execution&amp;gt;
   &amp;lt;/executions&amp;gt;
  &amp;lt;/plugin&amp;gt;
 &amp;lt;/plugins&amp;gt;
&amp;lt;/build&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
and in the using project you want to use the test utilities add this&lt;br /&gt;
&lt;br /&gt;
&lt;pre class = "brush: xml"&gt;&amp;lt;project&amp;gt;
...
 &amp;lt;dependencies&amp;gt;
  &amp;lt;dependency&amp;gt;
   &amp;lt;groupId&amp;gt;com.myco.app&amp;lt;/groupId&amp;gt;
   &amp;lt;artifactId&amp;gt;foo&amp;lt;/artifactId&amp;gt;
   &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;
   &amp;lt;classifier&amp;gt;tests&amp;lt;/classifier&amp;gt;
   &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
  &amp;lt;/dependency&amp;gt;
 &amp;lt;/dependencies&amp;gt;
...
&amp;lt;/project&amp;gt;
&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/sNqDF-Khkco" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/8842619165269312481/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=8842619165269312481&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/8842619165269312481?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/8842619165269312481?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/sNqDF-Khkco/reuse-your-test-code-in-maven-projects.html" title="Reuse your test code in maven projects!" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/03/reuse-your-test-code-in-maven-projects.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8FSX8_eCp7ImA9Wx9aEEU.&quot;"><id>tag:blogger.com,1999:blog-3120163791981772447.post-7574814373251059455</id><published>2011-02-26T18:14:00.000-08:00</published><updated>2011-03-02T07:46:58.140-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-02T07:46:58.140-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Play Framework" /><title>Play! Framework deploy to cloudbees.com</title><content type="html">&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;I've been trying the &lt;a href="http://www.playframework.org/"&gt;Play framework&lt;/a&gt; in the last few weeks and I've to admit its a real pleasure to code in that environment.&lt;br /&gt;
Now, I want to share my experience with deploying a Play! application to &lt;a href="http://cloudbees.com/"&gt;cloudbees.com&lt;/a&gt;&lt;br /&gt;
These guys offer the platform as a service, you can build, test and deploy Java web applications in the cloud. I thought it was brilliant.&lt;br /&gt;
Register, for free (DEV tools seems to be free only till the end of Feb 2011) and you get a nice control panel from where you can create git/svn repositories, Jenkins (hudson) jobs, deploy you application create databases etc.&lt;br /&gt;
&lt;br /&gt;
Here are some of the steps you need in order to get your Play! application running there.&lt;br /&gt;
&lt;br /&gt;
I'm using play 1.1.1 &lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Edit your play application.conf&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;# The production deployment information
%production.db=java:/comp/env/jdbc/${project_name}

%production.db.url=jdbc:cloudbees://${db_name}
%production.db.driver=com.cloudbees.jdbc.Driver
%production.db.user=${db_username}
%production.db.pass=${db_password}
%production.jpa.dialect=org.hibernate.dialect.MySQLDialect
&lt;/pre&gt;&lt;br /&gt;
What I didn't find on the &lt;a href="http://www.playframework.org/documentation/1.1.1/production"&gt;Play! documentation&lt;/a&gt; was the first line to specify the JNDI entry&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Create the database&lt;/b&gt;&lt;br /&gt;
from the website you can easily create a database &lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://lh4.ggpht.com/_WQxB4TYctGM/TWml-v3c_iI/AAAAAAAAAE8/MKuiMs9nim4/%5BUNSET%5D.jpg?imgmax=800" style="max-width: 800px;" /&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;br /&gt;
&lt;b&gt;Create the cloudbees resource file&lt;/b&gt;&lt;br /&gt;
Create a folder war/WEB-INF in your Play! project ( if you don't have it ) and create a file called cloudbees-web.xml that looks like this&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;br /&amp;gt;&amp;lt;?xml version="1.0"?&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;cloudbees-web-app xmlns="http://www.cloudbees.com/xml/webapp/1"&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;resource name="jdbc/${project_name}" auth="Container" type="javax.sql.DataSource"&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;param name="username" value="${db_username}" /&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;param name="password" value="${db_password}" /&amp;gt;&amp;lt;br /&amp;gt;  &amp;lt;param name="url" value="jdbc:cloudbees://${db_name}" /&amp;gt;&amp;lt;br /&amp;gt; &amp;lt;/resource&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;/cloudbees-web-app&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;/pre&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;br /&gt;
&lt;b&gt;Generate your database DDL&lt;/b&gt;&lt;br /&gt;
Add the module db to your application&lt;br /&gt;
&lt;pre&gt;module.db=${play.path}/modules/db-1.1.1&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
and then run the command&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;play db:export --%production&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
You might get an &lt;code&gt;javax.naming.NoInitialContextException&lt;/code&gt;, if you do comment out the line&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;#%production.db=java:/comp/env/jdbc/${project_name}&lt;/pre&gt;&lt;br /&gt;
in the application.conf &lt;br /&gt;
&lt;br /&gt;
You might also get some sort of command not found error. Make sure you install db-1.1.1. I think if you don't specify the version it'll get version 1.0.1&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;br /&gt;
&lt;b&gt;Create your remote db&lt;/b&gt;&lt;br /&gt;
This took me some time to figure out. I thought there was some sort of phpMyAdmin but instead you need to use your own MySql client. So on the cloudbees website if you look under &lt;br /&gt;
RUN@Cloud &amp;gt; Databases &amp;gt;Manage &amp;gt;${your_db} in the Overview section you can find server name, port, schema and username.&lt;br /&gt;
Open your client ( I've used &lt;a href="http://www.mysql.com/downloads/workbench/#downloads"&gt;MySql workbench&lt;/a&gt; ) and copy in there the sql generated at the previous step&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;br /&gt;
&lt;b&gt;Build your app&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;play war ${path to your play project} -o ${war name}  --%production --zip&lt;/pre&gt;&lt;br /&gt;
This will generate the for file for production&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;br /&gt;
&lt;b&gt;Deploy your app&lt;/b&gt;&lt;br /&gt;
I used the &lt;a href="https://cloudbees.zendesk.com/entries/414109-cloudbees-sdk"&gt;cloudbees sdk&lt;/a&gt; and works very well. &lt;br /&gt;
Just download it and the first time you use it, it will ask you for some keys that you can find on cloudbees under Account &amp;gt; Security Keys. Put them in and you are ready to go.&lt;br /&gt;
To deploy your application run the command&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;bees app:deploy -a login/yourProject ${war file}&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The cool thing is that the bees deploy command will calculate the difference between the last war and the one you are uploading and will only upload that delta!&lt;br /&gt;
&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DevelopmentInProgress/~4/T8NCdIgg7Aw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.devinprogress.info/feeds/7574814373251059455/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3120163791981772447&amp;postID=7574814373251059455&amp;isPopup=true" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7574814373251059455?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3120163791981772447/posts/default/7574814373251059455?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DevelopmentInProgress/~3/T8NCdIgg7Aw/play-framework-deploy-to-cloudbeescom.html" title="Play! Framework deploy to cloudbees.com" /><author><name>Andrea Salvadore</name><uri>https://plus.google.com/112694301113643906382</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh5.googleusercontent.com/-KpLJbXnIOuI/AAAAAAAAAAI/AAAAAAAACNI/8wXuwyUNuKo/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_WQxB4TYctGM/TWml-v3c_iI/AAAAAAAAAE8/MKuiMs9nim4/s72-c/%5BUNSET%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>6</thr:total><feedburner:origLink>http://www.devinprogress.info/2011/02/play-framework-deploy-to-cloudbeescom.html</feedburner:origLink></entry></feed>
