<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DEAHRXYzfCp7ImA9WhRaFEw.&quot;"><id>tag:blogger.com,1999:blog-24611184</id><updated>2012-02-16T10:25:34.884-08:00</updated><category term="xml" /><category term="scala" /><category term="podcast" /><category term="StAX" /><category term="java" /><category term="programming" /><category term="jdo" /><category term="socialnetworks" /><category term="gwt" /><category term="monitoring" /><category term="open source" /><category term="Thrift" /><category term="linkedin" /><category term="javaposse" /><category term="protobuf" /><category term="Google App Engine" /><category term="test" /><category term="guic" /><category term="guice" /><category term="ibm" /><category term="groovy" /><category term="spring" /><category term="twitter" /><category term="OHF" /><category term="Eclipse" /><category term="Mac" /><category term="voldemort" /><category term="kaching" /><category term="testing" /><category term="j2ee" /><category term="work" /><category term="conferences" /><category term="xstream" /><category term="json" /><category term="Books" /><title>Wondering around</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.eishay.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.eishay.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>118</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/WonderingAround" /><feedburner:info uri="wonderingaround" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DEINRns-fip7ImA9WhRaFE0.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-2604709575584848365</id><published>2012-02-16T00:12:00.000-08:00</published><updated>2012-02-16T07:36:37.556-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-16T07:36:37.556-08:00</app:edited><title>Testing javascript with Play Framework 2.0 and JsTestDriver</title><content type="html">At &lt;a href="http://www.qwallet.com/"&gt;qwallet&lt;/a&gt;&amp;nbsp;we're building an extensive javascript application backed up by a Scala on&amp;nbsp;&lt;a href="http://www.playframework.org/2.0"&gt;Play 2.0&lt;/a&gt;&amp;nbsp;backend. Since I'm using IntelliJ IDEA for the scala development, I'm using it for javascript as well. The nice bonus that comes with that is &lt;a href="http://plugins.intellij.net/plugin/?id=4468"&gt;IntelliJ's integration&lt;/a&gt; with &lt;a href="http://code.google.com/p/js-test-driver/wiki/IntelliJPlugin"&gt;JsTestDriver&lt;/a&gt;.&lt;br /&gt;
While working on the javascript app I have it&amp;nbsp;constantly&amp;nbsp;tested on three captured browsers:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-IYdsLWKTgmA/Tzy0yd1OVUI/AAAAAAAABK4/2u5mI8xOwu4/s1600/server.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="105" src="http://3.bp.blogspot.com/-IYdsLWKTgmA/Tzy0yd1OVUI/AAAAAAAABK4/2u5mI8xOwu4/s400/server.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
The test console shows the test results (super fast) and any console output that got fetched from the browser, e.g:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-CDyQpVkCRhU/Tzy1FNhDTiI/AAAAAAAABLA/ZYSJTpS4iXw/s1600/test_rez.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="118" src="http://4.bp.blogspot.com/-CDyQpVkCRhU/Tzy1FNhDTiI/AAAAAAAABLA/ZYSJTpS4iXw/s400/test_rez.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
In the above test example you can see all tests are passing on firefox and chrome, but fail on safari. The sample has three test cases, the expanded one has two test methods. If there's an error, the stack trace is clickable and intellij will take you right to the line of the error. The tests are pretty fast, 6ms on chrome for this small subset means there's some room to grow.&lt;br /&gt;
The extra sweetness of Play2.0 is the auto &lt;a href="https://github.com/playframework/Play20/wiki/AssetsGoogleClosureCompiler"&gt;compilation of javascript files&lt;/a&gt;. In dev mode the JsTestDriver is serving the library files and test cases to the browser and the application files are served through the Play2.0 application. Play will recompile the files as it detects change. It gives an extra coverage as in many cases the compiler catches things that I may have missed when writing the test.&lt;br /&gt;
&lt;script src="https://gist.github.com/1843026.js?file=gistfile1.txt"&gt;
&lt;/script&gt;&lt;br /&gt;
On CI mode there is no need to pipe the javascript files through play as the files are compiled once. Not that its much faster this way, but it reduces the need of having play running in the background. As we're going to have qwallet operating in &lt;a href="http://prezi.com/l4hsfyhmmajx/continuous-deployment-at-wealthfront-qcon-san-francisco-2010/"&gt;Continuous Deployment mode&lt;/a&gt;, testing all parts of the application is&amp;nbsp;crucial. JsTestDriver bundled with the closure compiler&amp;nbsp;provides a nice component in the testing strategy with its fast dev mode unit testing.&lt;br /&gt;
&lt;br /&gt;
BTW, we're hiring. If you're interested, shoot us an email to jobs@qwallet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-2604709575584848365?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/veSlS6WDMmw" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/2604709575584848365?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/2604709575584848365?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/veSlS6WDMmw/testing-javascript-with-play-framework.html" title="Testing javascript with Play Framework 2.0 and JsTestDriver" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-IYdsLWKTgmA/Tzy0yd1OVUI/AAAAAAAABK4/2u5mI8xOwu4/s72-c/server.jpg" height="72" width="72" /><feedburner:origLink>http://www.eishay.com/2012/02/testing-javascript-with-play-framework.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EDR3o7fCp7ImA9WhRTEUs.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-3183928781299517247</id><published>2011-11-01T10:46:00.000-07:00</published><updated>2011-11-01T10:47:56.404-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-01T10:47:56.404-07:00</app:edited><title>Throw undeclared checked exception in Java, take II</title><content type="html">Wrapping is in many times a necessity as you may not be able to throw a declared exception for contract restrictions or want to reduce boiler plate code. Wrapping an exception with a RuntimeException is sub optimal, takes more resources and clutter the logs with unnecessary stack traces, makes you look for the root cause.
Loved Alexey's idea about &lt;a href="http://aragozin.blogspot.com/2011/10/java-how-to-throw-undeclared-checked.html"&gt;throwing undeclared checked exception in Java&lt;/a&gt;. Here is a small twist on that AnyThrow class:
&lt;script src="https://gist.github.com/1331303.js"&gt;&lt;/script&gt;

Now I can do 
&lt;script src="https://gist.github.com/1331307.js"&gt;&lt;/script&gt;

So the compiler and the reader knows I'm breaking the flow with an exception. The stack trace does not have the AnyThrow in it and the "return null" there is only to trick the compiler.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-3183928781299517247?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/CPxkHaxJ98k" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/3183928781299517247?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/3183928781299517247?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/CPxkHaxJ98k/throw-undeclared-checked-exception-in.html" title="Throw undeclared checked exception in Java, take II" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2011/11/throw-undeclared-checked-exception-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cNQH07eip7ImA9WhdUF0s.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-963893161189140114</id><published>2011-10-04T15:57:00.000-07:00</published><updated>2011-10-04T15:58:11.302-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-04T15:58:11.302-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="j2ee" /><category scheme="http://www.blogger.com/atom/ns#" term="test" /><category scheme="http://www.blogger.com/atom/ns#" term="guic" /><title>Testing Guice can init servlets</title><content type="html">Sequel to the prev post, binding servlets is not enough. You must make sure that Guice can initiate them. For example, a common error is not binding servlets as singleton, there you get exceptions like &lt;pre class="brush: java;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;ServletException: Servlets must be bound as singletons. Key[type=my.servlet.FooServlet, annotation=[none]] was not bound in singleton scope.&lt;/pre&gt;
Here's a way to test for all servlets in Guice context
&lt;script src="https://gist.github.com/1263088.js"&gt;&lt;/script&gt;
When calling init on the filter it would init all servlets in context.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-963893161189140114?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/_U3GdKnbYlo" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/963893161189140114?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/963893161189140114?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/_U3GdKnbYlo/testing-guice-can-init-servlets.html" title="Testing Guice can init servlets" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2011/10/testing-guice-can-init-servlets.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkACQ304eip7ImA9WhdUF0s.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-250484320403304262</id><published>2011-10-04T14:46:00.000-07:00</published><updated>2011-10-04T14:46:02.332-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-04T14:46:02.332-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="guice" /><category scheme="http://www.blogger.com/atom/ns#" term="j2ee" /><title>Testing Guice Servlet bindings</title><content type="html">Evan if you work with Servlet (for the record, I hate j2ee) and Jersey you can still enjoy Guice. &lt;br /&gt;
Unfortunately its not that evident how to test that the ServletBinder is binding your servlets to the right place. Here is a small Assert class that does that. &lt;br /&gt;
&lt;script src="https://gist.github.com/1262898.js"&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-250484320403304262?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/2VeLWG92yUE" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/250484320403304262?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/250484320403304262?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/2VeLWG92yUE/testing-guice-servlet-bindings.html" title="Testing Guice Servlet bindings" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2011/10/testing-guice-servlet-bindings.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcBQH85cCp7ImA9Wx5TEE0.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-6450697739463570689</id><published>2010-07-24T12:34:00.000-07:00</published><updated>2010-07-24T12:34:11.128-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-24T12:34:11.128-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="kaching" /><title>Continuous Deployment at kaChing</title><content type="html">In my last visit to Israel I visited IBM Research, Outbrain and Answers.com. Over there we discussed kaChing's culture, working methodologies and tools. The talk focused on continuous deployment and lean startup and was based on &lt;a href="http://eng.kaching.com/2010/06/iterate-like-whirling-dervish.html"&gt;Pascal's&lt;/a&gt; and &lt;a href="http://eng.kaching.com/2010/05/deployment-infrastructure-for.html"&gt;David's&lt;/a&gt; posts at &lt;a href="http://eng.kaching.com/"&gt;kaChing Eng Blog&lt;/a&gt;.&lt;br /&gt;
Here is the presentation, using the fantastic Prezi tool.&lt;br /&gt;
&lt;center&gt;&lt;br /&gt;
&lt;div class="prezi-player"&gt;&lt;style media="screen" type="text/css"&gt;
.prezi-player { width: 550px; } .prezi-player-links { text-align: center; }
&lt;/style&gt;&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" height="400" id="prezi_5zm8xplapff2" name="prezi_5zm8xplapff2" width="550"&gt;&lt;param name="movie" value="http://prezi.com/bin/preziloader.swf"/&gt;&lt;param name="allowfullscreen" value="true"/&gt;&lt;param name="allowscriptaccess" value="always"/&gt;&lt;param name="bgcolor" value="#ffffff"/&gt;&lt;param name="flashvars" value="prezi_id=5zm8xplapff2&amp;amp;lock_to_path=0&amp;amp;color=ffffff&amp;amp;autoplay=no"/&gt;&lt;embed id="preziEmbed_5zm8xplapff2" name="preziEmbed_5zm8xplapff2" src="http://prezi.com/bin/preziloader.swf" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="550" height="400" bgcolor="#ffffff" flashvars="prezi_id=5zm8xplapff2&amp;amp;lock_to_path=0&amp;amp;color=ffffff&amp;amp;autoplay=no"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;div class="prezi-player-links"&gt;&lt;a href="http://prezi.com/5zm8xplapff2/continuous-deployment/" title="Introducing the Continuous Deployment concept with background about testing, monitoring, tools and culture requirements."&gt;Continuous Deployment&lt;/a&gt; on &lt;a href="http://prezi.com/"&gt;Prezi&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-6450697739463570689?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/cZ_xkh2JNG4" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/6450697739463570689?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/6450697739463570689?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/cZ_xkh2JNG4/continuous-deployment-at-kaching.html" title="Continuous Deployment at kaChing" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2010/07/continuous-deployment-at-kaching.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUESHc-eSp7ImA9WxFUEEQ.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-251169861745568408</id><published>2010-06-20T21:06:00.000-07:00</published><updated>2010-06-20T21:06:49.951-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-20T21:06:49.951-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="scala" /><title>Scala on Eclipse without the plugin</title><content type="html">The Scala supported IDE is one of the few pain points of developers who want to start using Scala in their Java project. On existing long term project developed by a team its hard to step in and introduce a new language that is not supported by the existing IDE. On way to go about it is to hid the fact that you use Scala from the Java world by using one way dependency injection. Still, if you wish to truly absorb Scala into your existing java environment then you'll soon introduced cross language dependencies.&lt;br /&gt;
&lt;br /&gt;
Most of our team is using Eclipse as the main IDE, its incrimental compilation in Java with its tight JUnit integration are great for fast &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD programming&lt;/a&gt;. Unfortunately the Eclipse Scala plugin is not there yet, it may hangs the IDE and messes up Java compilation -&amp;nbsp;especially&amp;nbsp;in&amp;nbsp;large (more then 1000 source files) Java/Scala projects. Though the plugin is getting better over time some developers would find the plugin as a majore drag on their productivity.&lt;br /&gt;
For developers who do not write Scala at all or rather edit Scala with other editors, you can use this alternate path which lets them work on their Java or Scala code without messing with the plugin.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;b&gt;Compile&amp;nbsp;Scala&amp;nbsp;Eclipse project without Scala Plugin&amp;nbsp;&lt;/b&gt;&lt;/div&gt;1. Add a compilation script to your project.&lt;br /&gt;
The Following script is using the &lt;a href="http://www.scala-lang.org/docu/files/tools/fsc.html"&gt;Fast Scala Compiler (fsc)&lt;/a&gt;. The fsc is a compilation server which always run in the background, as in a warm &lt;a href="http://www.scala-lang.org/docu/files/tools/scalac.html"&gt;scalac&lt;/a&gt; always ready to receive new work. Is will reduce compilation time dramatically.&lt;br /&gt;
The classpath for compilation is taken from the Eclipse project .classpath file. You may take the source directory from there as well if you wish (exercise to the reader).&lt;br /&gt;
The params are not passed to the fsc in the command line since in my project's case the line is too long for the OS to handle. The alternative is to put it into a file and let fsc handle it for you.&lt;br /&gt;
&lt;pre class="brush: bash;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;#!/bin/sh
# Create a classpath from the eclipse .classpath file
lib=`grep classpathentry .classpath | grep "kind=\"lib\"" | tr -d '\t' | sed 's/.*path=\"\(.*[^src]\.jar\)\".*/\1/' | grep -v classpathentry`
CLASSPATH=`echo ${lib} | sed 's/ /:/g' `  

# point SCALA_HOME to Scala home (might want to add it to your project as well)  
export SCALA_HOME=lib-tools/scala-2.8.0

# java opts for your compilation server
export JAVA_OPTS="-client -Xmx1024M -Xms256M -XX:PermSize=128m -Xss2M -XX:MaxPermSize=256m -Xverify:none -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled"

DEST=target/bin-scala
mkdir -p $DEST

SCALAC_PROPERTIES=scalac.properties
echo "-classpath $CLASSPATH:target/bin" &amp;gt; $SCALAC_PROPERTIES
echo "-d $DEST -deprecation" &amp;gt;&amp;gt; $SCALAC_PROPERTIES
find src srctest -name *.java -o -name *.scala &amp;gt;&amp;gt; scalac.properties

time $SCALA_HOME/bin/fsc @$SCALAC_PROPERTIES &amp;amp;
&lt;/pre&gt;2. Eclipse classpath&lt;br /&gt;
Add the scalac destination directory ($DEST) to the .eclipse classpath&lt;br /&gt;
&lt;br /&gt;
3. Add the fsc builder to your project&lt;br /&gt;
Open the project properties and add the script above to the list of builders. &lt;br /&gt;
Set the working directory to be your project root directory.&lt;br /&gt;
&lt;br /&gt;
5. Set the builder properties&lt;br /&gt;
Run it in the background when needed:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_O9TJAb-LjDE/TB7ewbsgX4I/AAAAAAAAAno/irOWCsszkZg/s1600/Screen+shot+2010-06-20+at+8.35.52+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_O9TJAb-LjDE/TB7ewbsgX4I/AAAAAAAAAno/irOWCsszkZg/s320/Screen+shot+2010-06-20+at+8.35.52+PM.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"&gt;&lt;b&gt;Add Scala syntax highlighting editor for Eclipse&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Even without the Scala plugin refactoring and debugging capabilities you can write some decent Scala code with the help of syntax highlighting for better readability. There are two options:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: verdana, geneva, helvetica, arial, sans-serif; font-size: 13px;"&gt;The color editor which use jEdit modes.&amp;nbsp;&lt;a href="http://github.com/djspiewak"&gt;Daniel Spiewak&lt;/a&gt; added a&lt;a href="http://github.com/djspiewak/jedit-modes/blob/master/scala.xml"&gt; Scala mode&lt;/a&gt; to it,&amp;nbsp;unfortunately&amp;nbsp;the plugin doesn't seem to work with Eclipse 3.6.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: verdana, geneva, helvetica, arial, sans-serif; font-size: 13px;"&gt;&lt;span class="highlight" style="background-attachment: initial; background-clip: initial; background-color: #ffff66; background-image: initial; background-origin: initial;"&gt;The &lt;a href="http://colorer.sourceforge.net/eclipsecolorer/"&gt;Colorer take5 project&lt;/a&gt;&lt;/span&gt;&amp;nbsp;which works fine on my Eclipse on the Mac. It does not have a Scala mode yet but you can grab one at http://github.com/eishay/eclipsecolorer_scala&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;It gives you a lightweight way (with its pros and cons) to write Scala in Eclipse.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-251169861745568408?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/RpxKtRGdhZI" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/251169861745568408?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/251169861745568408?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/RpxKtRGdhZI/scala-on-eclipse-without-plugin.html" title="Scala on Eclipse without the plugin" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_O9TJAb-LjDE/TB7ewbsgX4I/AAAAAAAAAno/irOWCsszkZg/s72-c/Screen+shot+2010-06-20+at+8.35.52+PM.png" height="72" width="72" /><feedburner:origLink>http://www.eishay.com/2010/06/scala-on-eclipse-without-plugin.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMMQHg4fCp7ImA9WxFWEE4.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-1784129299019885663</id><published>2010-05-28T00:08:00.000-07:00</published><updated>2010-05-28T00:08:01.634-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-28T00:08:01.634-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="scala" /><category scheme="http://www.blogger.com/atom/ns#" term="conferences" /><title>InfoQ talk "Absorbing Scala in the Java Ecosystem"</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;a href="http://4.bp.blogspot.com/_O9TJAb-LjDE/S_9rdlDonsI/AAAAAAAAAm4/eiUlR1O3LLs/s1600/qcon.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S_9rdlDonsI/AAAAAAAAAm4/eiUlR1O3LLs/s320/qcon.jpg" /&gt;&lt;/a&gt;About six months after, InfoQ released the video of the &lt;a href="http://www.infoq.com/presentations/Absorbing-Scala-in-the-Java-Ecosystem"&gt;"Absorbing Scala in the Java Ecosystem"&lt;/a&gt; talk I gave at QCon San Francisco 2009.&lt;br /&gt;
The event was great though it feels funny looking at myself talking.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-1784129299019885663?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/Mosh_312Ops" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/1784129299019885663?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/1784129299019885663?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/Mosh_312Ops/infoq-talk-absorbing-scala-in-java.html" title="InfoQ talk &quot;Absorbing Scala in the Java Ecosystem&quot;" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_O9TJAb-LjDE/S_9rdlDonsI/AAAAAAAAAm4/eiUlR1O3LLs/s72-c/qcon.jpg" height="72" width="72" /><feedburner:origLink>http://www.eishay.com/2010/05/infoq-talk-absorbing-scala-in-java.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UESXk8fCp7ImA9Wx5VFEo.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-3181197052188058490</id><published>2010-04-15T20:54:00.000-07:00</published><updated>2010-10-07T11:13:28.774-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-07T11:13:28.774-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Findbugs, Hudson and Pizza Driven Development (PDD)</title><content type="html">Original post at the &lt;a href="http://eng.kaching.com/2010/04/findbugs-husdon-and-pizza-driven.html"&gt;kaChing Eng Blog&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_O9TJAb-LjDE/S8fdCj8MFkI/AAAAAAAAAlo/hMCsAxIKnNc/s1600/FindBugs.gif" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="178" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S8fdCj8MFkI/AAAAAAAAAlo/hMCsAxIKnNc/s200/FindBugs.gif" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;As you may know, &lt;a href="https://www.kaching.com/"&gt;kaChing&lt;/a&gt; is an test driven engineering organization. Test driven is not an option, its a must. We move fast and push code to production few dozens of times &lt;b&gt;a day&lt;/b&gt; in a five minutes release cycle, so we must have high confidence in our code.&lt;br /&gt;
In complex systems there is no end to testings, each test system is an another line of defense which eventually gets broken but the more you have, the less chances bugs will reach production. We do not have QA team and do not want to have one, the reasoning is that if a human is involved in testing then there is a higher chance of missing things and you simply can't test all the site dozens of times a day.&lt;br /&gt;
&lt;br /&gt;
Lately we decided to add a yet another line of defense: Code Static Analysis (e.g. &lt;a href="http://findbugs.sourceforge.net/"&gt;Findbugs&lt;/a&gt;, &lt;a href="http://pmd.sourceforge.net/"&gt;PMD&lt;/a&gt; and &lt;a href="http://pmd.sourceforge.net/cpd.html"&gt;CPD&lt;/a&gt;). We decided to start with Findbugs which has a great &lt;a href="http://ant.apache.org/"&gt;ANT&lt;/a&gt;&amp;nbsp;task and &lt;a href="http://wiki.hudson-ci.org/display/HUDSON/FindBugs+Plugin"&gt;Hudson plugin&lt;/a&gt; (both of these we use). The problem with these tools is that they're producing tons of warnings and most organizations ignore them after since they're too noisy to deal with.&lt;br /&gt;
&lt;br /&gt;
David V. from &lt;a href="http://www.testdriven.com/"&gt;testdriven.com&lt;/a&gt; recommended: "&lt;a href="http://sbender.net/~scott/tshirt.jpg"&gt;Pizza Driven Development&lt;/a&gt;" (aka PDD) which works as following:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_O9TJAb-LjDE/S8fdKYbtR0I/AAAAAAAAAlw/DRfFDPzRtEc/s1600/tcrn442l.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S8fdKYbtR0I/AAAAAAAAAlw/DRfFDPzRtEc/s200/tcrn442l.jpg" width="174" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;i&gt;Step one&lt;/i&gt;: Order Pizza. Most engineers would commit on doing something if it will get them Pizza. For the minority that would not be seduced by Pizza, good old fashion violence would do.&lt;br /&gt;
&lt;i&gt;Step two&lt;/i&gt;: Give each member of the team two cards. Go over the list of rules with the team and have them vote on them. Voting is done using the cards where:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;No cards: I think the rule is stupid and we should filter it out in the findbugsExclude.xml&lt;/li&gt;
&lt;li&gt;One card: The rule is important but not critical.&lt;/li&gt;
&lt;li&gt;Two cards: The rule is super important and we should fix it right away.&lt;/li&gt;
&lt;/ul&gt;The test sherif them creates three lists using the voting and the team works on fixing the "must fix" list which should have no more then few dozens of issues so it can be all fixed in couple of hours. Once you have that done the findbugs build is green and we're ready to go.&lt;br /&gt;
&lt;br /&gt;
Next step is having hudson run findbugs on every post commit so the build is considered to be broken if a new findbugs issue is introduced. The engineer who introduced the issue must either filter the class from that rule in the xml file or fix the bug as a first priority. Since the engineers get a notification few minutes after the commit then they are probably still messing with the code and its easy for them to fix it on the spot.&lt;br /&gt;
&lt;br /&gt;
In the next few weeks we are adding a new rule from the "not critical" list every few days. The goal is to have all the rules we think are important without the common "its to noisy, lets ignore it" approche. Only&amp;nbsp;after we're done with that we're going to add the next static&amp;nbsp;analysis&amp;nbsp;tool to build. The good thing about these tools and hudson is that you can run them in parallel to the unit/integration tests, on another machine, so they won't slow down the overall release cycle.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-3181197052188058490?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/RDZxvjqY_uc" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/3181197052188058490?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/3181197052188058490?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/RDZxvjqY_uc/findbugs-husdon-and-pizza-driven.html" title="Findbugs, Hudson and Pizza Driven Development (PDD)" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_O9TJAb-LjDE/S8fdCj8MFkI/AAAAAAAAAlo/hMCsAxIKnNc/s72-c/FindBugs.gif" height="72" width="72" /><feedburner:origLink>http://www.eishay.com/2010/04/findbugs-husdon-and-pizza-driven.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A08CSXs6cCp7ImA9WxFSE0U.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-8874115067769099557</id><published>2010-04-15T20:51:00.000-07:00</published><updated>2010-04-15T20:51:08.518-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-15T20:51:08.518-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Testing with Hibernate</title><content type="html">&lt;a href="http://eng.kaching.com/2010/04/testing-with-hibernate.html"&gt;Original post at the kaChing Eng Blog&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Some of the unit tests I wrote lately involved setting up a data setup in the DB and testing the code using and mutating it. To make it clear, the DB is an in memory DB so the setup is super fast without IO slowdowns. Its very easy to do the setup using hibernate but the problem comes when you set a large collection of objects and a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;"java.sql.BatchUpdateException: failed batch"&lt;/span&gt; is being thrown. The frustrating point there is that hibernate won't let you know what exactly went wrong, even if you set your logger to "trace" level. &lt;br /&gt;
&lt;br /&gt;
In order to solve it you can add the following to the system properties of that test:&lt;br /&gt;
&lt;pre class="brush: bash;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;-Dhibernate.statement_cache.size=0 
-Dhibernate.jdbc.batch_size=0 
-Dhibernate.jdbc.use_scrollable_resultset=false 
-Dhibernate.bytecode.use_reflection_optimizer=false 
-Dhibernate.show_sql=true&lt;/pre&gt;It will execute the statements one by one and will give more precise details of what went wrong.&lt;br /&gt;
Note: you do &lt;b&gt;NOT&lt;/b&gt; want to use these properties in production or in the continuance integration (CI) environment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-8874115067769099557?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/AxI58VoNNBs" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/8874115067769099557?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/8874115067769099557?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/AxI58VoNNBs/testing-with-hibernate.html" title="Testing with Hibernate" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2010/04/testing-with-hibernate.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcEQXc7cSp7ImA9WxBVF08.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-3404931511753350592</id><published>2010-02-20T19:46:00.000-08:00</published><updated>2010-02-20T19:46:40.909-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-20T19:46:40.909-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Parallelizing JUnit test runs</title><content type="html">Original post at the &lt;a href="http://eng.kaching.com/2010/02/parallelizing-junit-test-runs.html"&gt;kaChing engineering blog&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Test runs should be as fast as possible in order to allow a lean development cycle. One of the applications is a &lt;a href="http://timothyfitz.wordpress.com/2009/02/10/continuous-deployment-at-imvu-doing-the-impossible-fifty-times-a-day/"&gt;Continuous Deployment&lt;/a&gt; (see &lt;a href="http://www.slideshare.net/startuplessonslearned/2010-02-19-the-lean-startup-webstock-2010"&gt;Lean Startup&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
Using strong multi-core machines to run tests is not enough since most unit tests are using a single thread per test. Apart of reducing IO to minimum, having tests running in parallel is required to squeeze the juice of of the machine. Additional value from Parallelizing JUnit test runs is ensuring that tests have no dependency between each other.&lt;br /&gt;
&lt;br /&gt;
The way we implemented parallel test runs is creating an &lt;a href="http://ant.apache.org/"&gt;ANT&lt;/a&gt; target with a &lt;a href="http://ant.apache.org/manual/CoreTasks/parallel.html"&gt;parallel task&lt;/a&gt; containing N &lt;a href="http://ant.apache.org/manual/OptionalTasks/junit.html"&gt;JUnit tasks&lt;/a&gt; where &lt;i&gt;N == number of cores&lt;/i&gt;. For example:&lt;pre class="brush: xml;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;&amp;lt;parallel&amp;gt;
      &amp;lt;junit printsummary="yes" haltonfailure="yes" fork="true" maxmemory="${maxmemory}" showoutput="yes"&amp;gt;
        &amp;lt;jvmarg value="-XX:MaxPermSize=${permMem}"/&amp;gt;
        &amp;lt;jvmarg value="-Xms${minMem}"/&amp;gt;
        &amp;lt;jvmarg value="-Xmx${maxmemory}"/&amp;gt;
        &amp;lt;classpath refid="classpath.test" /&amp;gt;
        &amp;lt;formatter type="xml" usefile="true" /&amp;gt;
        &amp;lt;test name="com.kaching.GroupedTests$GroupA" todir="${testTargetJunit}" unless="testcase"/&amp;gt;
      &amp;lt;/junit&amp;gt;
      &amp;lt;junit printsummary="yes" haltonfailure="yes" fork="true" maxmemory="${maxmemory}" showoutput="yes"&amp;gt;
        &amp;lt;jvmarg value="-XX:MaxPermSize=${permMem}"/&amp;gt;
        &amp;lt;jvmarg value="-Xms${minMem}"/&amp;gt;
        &amp;lt;jvmarg value="-Xmx${maxmemory}"/&amp;gt;
        &amp;lt;classpath refid="classpath.test" /&amp;gt;
        &amp;lt;formatter type="xml" usefile="true" /&amp;gt;
        &amp;lt;test name="com.kaching.GroupedTests$GroupB" todir="${testTargetJunit}" unless="testcase"/&amp;gt;
      &amp;lt;/junit&amp;gt;
  ...
     &amp;lt;/parallel&amp;gt;
&lt;/pre&gt;The GroupedTests$GroupX are classes extending &lt;a href="http://junit.org/apidocs/junit/framework/TestCase.html"&gt;TestCase&lt;/a&gt; with a &lt;i&gt;public static Test suite()&lt;/i&gt;. The suite() method creates a &lt;a href="http://junit.org/apidocs/junit/framework/TestSuite.html"&gt;JUnit test suite&lt;/a&gt; on the fly by loading all the tests in scope and filtering them out. If for example there are four cores, therefore you would like to have a group of four suites each running fourth of the tests. The suits are using a java.util.Random seeded with the commit revision number. Using the Random object we decide on placing test cases in suits. &lt;pre class="brush: java;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;random.nextInt(numOfTestSuites) == testSuiteId&lt;/pre&gt;Therefore a testcase goes to a single suite and they are evenly distributed between suites. Randomness in assigning test cases to suites (and therefore to processes) gives us some reassurance that there are no dependencies between tests.&lt;br /&gt;
&lt;br /&gt;
As a result we have the tests running about twice as fast as they did before, in the range of 2 min, 20 sec for about 4.6k tests for one of our components, including code fetch from source repository, clean, build, and test suite setup time. It gives us a nice 100% test machine utilization and faster commit to production deployment cycle (about four minutes).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-3404931511753350592?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/QK4oCUxebNo" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/3404931511753350592?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/3404931511753350592?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/QK4oCUxebNo/parallelizing-junit-test-runs.html" title="Parallelizing JUnit test runs" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2010/02/parallelizing-junit-test-runs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08NQn4-cSp7ImA9WxBWEEQ.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-4876552266508955197</id><published>2010-02-01T22:24:00.000-08:00</published><updated>2010-02-01T22:24:53.059-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-01T22:24:53.059-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="kaching" /><category scheme="http://www.blogger.com/atom/ns#" term="work" /><category scheme="http://www.blogger.com/atom/ns#" term="voldemort" /><title>Benchmarking Voldemort on SSD with production data</title><content type="html">Its not a secret kaChing is using Voldemort in production. As our data set and grows larger we wish to figure out what is the best bang for the buck in terms of hardware investment. Would it be migrating our 32bit machines to 64bit ones and have more memory available for them or using SSD? There are good reasons why one may be better then the other but the only way to know is to test. Yes, we believe that Test Driven Development (TDD) applies to building system as well as coding.&lt;br /&gt;
 &lt;br /&gt;
The time John invested the time in creating the tool (written in Scala btw) to parse the logs and get the graphs had quickly payed itself. In John's post &lt;a href="http://eng.kaching.com/2010/01/voldemort-in-wild.html"&gt;Voldemort in the Wild&lt;/a&gt; he wrote about the initial settings he created to test the changes before we actually did them and some of the initial result. The results are unique to our own system, which is the best thing about them. You may get different results for different load, usage patterns, data size, cluster setup.&lt;br /&gt;
&lt;br /&gt;
There are more tunings we played with, waiting to John's next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-4876552266508955197?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/ObBEzEHQhBg" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/4876552266508955197?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/4876552266508955197?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/ObBEzEHQhBg/benchmarking-voldemort-on-ssd-with.html" title="Benchmarking Voldemort on SSD with production data" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2010/02/benchmarking-voldemort-on-ssd-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNRXk_fCp7ImA9WxBQFk8.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-3624645680169585400</id><published>2010-01-09T23:49:00.000-08:00</published><updated>2010-01-15T23:31:34.744-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-15T23:31:34.744-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="kaching" /><category scheme="http://www.blogger.com/atom/ns#" term="work" /><title>Complement TDD with MDA</title><content type="html">Original post at the &lt;a href="http://eng.kaching.com/2010/01/complement-tdd-with-mda.html"&gt;kaChing Eng Blog&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Test Driven Development (aka &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt;) is &lt;a href="http://search.twitter.com/search?q=%23TDD"&gt;on the rise&lt;/a&gt;. Good developers understand that code with no proper testing is dead code. You can't trust it to do what you want and its hard to change.&lt;br /&gt;
I'm a strong believer in &lt;a href="http://en.wikiquote.org/wiki/Edsger_W._Dijkstra"&gt;Dijkstra's observation&lt;/a&gt; that "Program testing can be a very effective way to show the presence of bugs, but it is hopelessly inadequate for showing their absence."&lt;br /&gt;
&lt;br /&gt;
Dijkstra's statement doesn't contradict TDD. The test is testing a limited state machine. We do hope will cover the bloody battlefield of production confronting live data from users but &lt;strike&gt;if&lt;/strike&gt; when we find the users did something unexpected which broke our software, we add a test emulating the users behavior and fix the problem.&lt;br /&gt;
&lt;br /&gt;
Introducing Monitoring Driven Architecture (aka MDA)!  &lt;br /&gt;
MDA is a second line of defense for TDD. MDA means that you bake monitoring into your architecture. Once you have MDA and the software is written in a monitorable (it &lt;b&gt;is&lt;/b&gt; a word) way, you can have a faster detection of problems and auto roll back of faulty code. On the other hand, it is not uncommon that a small number of users suffer from a problem which manifests itself in some NPE thrown in one of the logs once in a blue moon and the operations team finds about it after a long while.&lt;br /&gt;
&lt;br /&gt;
This is why I'm so excited about John's new &lt;a href="http://eng.kaching.com/2010/01/flexible-log-monitoring-with-scribe.html"&gt;Flexible Log Monitoring with Scribe, Esper, and Nagios&lt;/a&gt; deployment. It means that when we do find a problem we'll of course fix it but in addition make sure we express it in the logs and have our monitoring tools pick it up and send alerts about its existent without counting on anyone to manually look at the logs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-3624645680169585400?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/8Q0NQVEXeys" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/3624645680169585400?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/3624645680169585400?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/8Q0NQVEXeys/complement-tdd-with-mda.html" title="Complement TDD with MDA" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2010/01/complement-tdd-with-mda.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QFQn0zcSp7ImA9WxBRGEk.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-8025573293265400501</id><published>2010-01-06T22:21:00.000-08:00</published><updated>2010-01-06T22:21:53.389-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-06T22:21:53.389-08:00</app:edited><title>Outbrain's Password Recovery Mail</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_O9TJAb-LjDE/S0V9YeCvvJI/AAAAAAAAAhA/IQm-6TODHtc/s1600-h/Outbrain+logo+-+240x45.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S0V9YeCvvJI/AAAAAAAAAhA/IQm-6TODHtc/s320/Outbrain+logo+-+240x45.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;I forgot my &lt;a href="http://www.outbrain.com/"&gt;Outbrain&lt;/a&gt; password and got this nice recovery email in return:&lt;br /&gt;
&lt;blockquote&gt;From: Outbrain CEO &amp;lt;****@outbrain.com&amp;gt;&lt;br /&gt;
Hi eishay,&lt;br /&gt;
&lt;br /&gt;
Click on the following link to reset your password:&lt;br /&gt;
http://www.outbrain.com/ResetPassword?ticket=****&lt;br /&gt;
You will be prompted to choose a new password for your account. &lt;br /&gt;
&lt;br /&gt;
Feel free to drop me a note with any questions you have.&lt;br /&gt;
&lt;br /&gt;
Thanks, &lt;br /&gt;
Yaron Galai,&lt;br /&gt;
outbrain CEO&lt;br /&gt;
&lt;/blockquote&gt;First time I notice a "system" email coming from a human that you can actually reply to, nevertheless the CTO of the company. Its an interesting concept, especially since I'm not a paying costumer. Yaron explained their take on it &lt;a href="http://twitter.com/YaronGalai/statuses/7431393025"&gt;in this tweet&lt;/a&gt;:&lt;br /&gt;
&lt;blockquote&gt;@&lt;a class="tweet-url username" href="http://twitter.com/eishay"&gt;eishay&lt;/a&gt; Cool!... we have a rule here @&lt;a class="tweet-url username" href="http://twitter.com/Outbrain"&gt;Outbrain&lt;/a&gt; - all system emails must go out from an email of a human being. I hate all the info@ BS...&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
I found the approach very appealing, but can it scale? What is the max # of users it can support? &lt;br /&gt;
I assume its about the type of uses as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-8025573293265400501?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/_6qOpjeybwg" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/8025573293265400501?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/8025573293265400501?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/_6qOpjeybwg/outbrains-password-recovery-mail.html" title="Outbrain's Password Recovery Mail" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_O9TJAb-LjDE/S0V9YeCvvJI/AAAAAAAAAhA/IQm-6TODHtc/s72-c/Outbrain+logo+-+240x45.jpg" height="72" width="72" /><feedburner:origLink>http://www.eishay.com/2010/01/outbrains-password-recovery-mail.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUEQngycSp7ImA9WxBRGEk.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-8911579691037851994</id><published>2010-01-06T21:39:00.000-08:00</published><updated>2010-01-06T21:46:43.699-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-06T21:46:43.699-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="conferences" /><title>Reflection on 2009</title><content type="html">This post is only to myself. Nothing interesting, just few personal notes.&lt;br /&gt;
&lt;br /&gt;
The last year was very interesting!&lt;br /&gt;
Working in both &lt;a href="http://www.linkedin.com/in/eishay"&gt;LinkedIn&lt;/a&gt; and &lt;a href="http://www.kaching.com/"&gt;kaChing&lt;/a&gt; was/is a great experience. These are two fantastic companies, with very bright future, leading in their own fields and with amazingly talented engineers.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://farm3.static.flickr.com/2595/4124867279_86aa97ae4e_b.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="150" src="http://farm3.static.flickr.com/2595/4124867279_86aa97ae4e_b.jpg" width="200" /&gt;&lt;/a&gt;The &lt;a href="http://www.eishay.com/2009/07/speaking-at-two-sessions-in.html"&gt;SiliconValley CodeCamp '09&lt;/a&gt; was a lot of fun. Had a full room and got high speaker evaluation and some candidates to kaChine (yes, we're still hiring). &lt;br /&gt;
&lt;br /&gt;
The other talk was at &lt;a href="http://qconsf.com/sf2009/speaker/Eishay+Smith"&gt;QCon&lt;/a&gt; which was exciting. There where so many people that we had to move to a larger room that was packed as well :-)&lt;br /&gt;
Got some nice feedback via twitter &lt;a href="http://twitter.com/stromhylden/status/5866056042"&gt;twit&lt;/a&gt; &lt;a href="http://twitter.com/jgc94131/status/5877889927"&gt;twit&lt;/a&gt; &lt;a href="http://twitter.com/al3xandru/status/5866122721"&gt;twit&lt;/a&gt; &lt;a href="http://twitter.com/anderson_leite/status/5865814215"&gt;twit&lt;/a&gt; &lt;a href="http://twitter.com/olabini/status/5864866401"&gt;twit&lt;/a&gt; &lt;a href="http://twitter.com/deanwampler/status/5864858883"&gt;twit&lt;/a&gt; &lt;a href="http://twitter.com/Sadache/status/5877595377"&gt;twit&lt;/a&gt; &lt;a href="http://twitter.com/otaviof/status/5865843196"&gt;twit&lt;/a&gt; &lt;a href="http://img49.yfrog.com/i/930.jpg/"&gt;twit&lt;/a&gt;.&lt;br /&gt;
&lt;a href="http://m.reversim.com/reversim.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="52" src="http://m.reversim.com/reversim.jpg" width="48" /&gt;&lt;/a&gt;&lt;br /&gt;
It was great to do three sessions with the &lt;a href="http://www.reversim.com/"&gt;Reversim&lt;/a&gt; podcast (in Hebrew) about &lt;a href="http://www.reversim.com/2009/04/16-scala.html"&gt;Scala&lt;/a&gt;, &lt;a href="http://www.reversim.com/2009/12/47-scalability.html"&gt;scalability&lt;/a&gt; and &lt;a href="http://www.reversim.com/2009/12/49.html"&gt;startups&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The open source &lt;a href="http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking"&gt;serialization comparison project&lt;/a&gt; had significantly grown, it now has a dozen committers who contributed something in some point in time and still helping to update the project.&lt;br /&gt;
Overall I had lots of fun, and feel like 2010 is going to be even better !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-8911579691037851994?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/uFxdrMBX8bo" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/8911579691037851994?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/8911579691037851994?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/uFxdrMBX8bo/reflection-on-2009.html" title="Reflection on 2009" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm3.static.flickr.com/2595/4124867279_86aa97ae4e_t.jpg" height="72" width="72" /><feedburner:origLink>http://www.eishay.com/2010/01/reflection-on-2009.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYCSH0_eCp7ImA9WxBRFUQ.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-4267054106126625478</id><published>2010-01-02T20:45:00.000-08:00</published><updated>2010-01-03T23:29:29.340-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-03T23:29:29.340-08:00</app:edited><title>Subversion Backup</title><content type="html">Posted on the &lt;a href="http://eng.kaching.com/2010/01/subversion-backup.html"&gt;kaChing Eng Blog&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Yes, we're using Subversion. I know that distributed version control systems (e.g. Git) are cool and we might get there sometime, but for misc reasons we're still using SVN. For the records, some of us are using GIT-SVN and we're working and releasing from trunk (part of a the lean startup methodology) so the branching merging is less of an issue.&lt;br /&gt;
I did some work to migrate our repository and spent some time to setup our SVN repo. Here are some bits and pieces I collected from scattered sites or made up myself to facilitate the SVN backup. Hope it will help anyone starting from scratch. &lt;br /&gt;
&lt;br /&gt;
For the backup I'm using the great &lt;a href="http://code.google.com/p/svnautobackup/"&gt;svnbackup&lt;/a&gt; script. Here are parts of our script (launched by crontab):&lt;br /&gt;
&lt;pre class="brush: bash;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;now=$(date +%F)
svnbackup.sh --out-dir $OUT_DIR --file-name $FILE_NAME -v $REPO_LOCATION
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
    mail -s "ERROR: SVN backup on $now" $KACHING_OPS
    exit 1
fi
&lt;/pre&gt;Then the script sync's up the backup directory with S3 and verifies that the content of the last_saved file matches the last revision from SVN which it gets using&lt;br /&gt;
&lt;pre class="brush: bash;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;last_revision=$(svn -q --limit=1 log https://chb2.kcprod.info:4242/svn/backend | head -2 | tail -1 | cut -c 2-6)&lt;/pre&gt;Backup is not enough, we must constantly test that when the time comes we'll be able to use it. Therefor we added a script, triggered by &lt;a href="http://www.nagios.org/"&gt;Nagios&lt;/a&gt;, to run on another machine and try to do a full repo rebuild from scratch.&lt;br /&gt;
The first thing the script is doing is to brute force clean up the repo: &lt;br /&gt;
&lt;pre class="brush: bash;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;rm -rf $SVN_REPO
svnadmin create $SVN_REPO&lt;/pre&gt;Then do a S3 sync to get all the backup files and load the files into the svn repo in the right order:&lt;br /&gt;
&lt;pre class="brush: bash;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;for file in $(ls $SVN_BACKUP_FILES_DIR/*.bzip2 | sort -t '-' -k 4 -n)
do 
  bzip2 -dc $file | svnadmin load $SVN_REPO
done&lt;/pre&gt;Next step is getting few revisions and checking that their attributes (e.g. comments) match in both live and backup test repos.&lt;br /&gt;
&lt;br /&gt;
p.s.&lt;br /&gt;
Just because I'm paranoid we're also have an svn sync on an SVN slave server our second data center where every commit is backed-up on the fly and some of our systems (e.g. &lt;a href="http://www.websvn.info/"&gt;WebSVN&lt;/a&gt;) are reading from it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-4267054106126625478?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/BSTzkDYFkn8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/4267054106126625478?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/4267054106126625478?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/BSTzkDYFkn8/subversion-backup.html" title="Subversion Backup" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2010/01/subversion-backup.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYMRns-eyp7ImA9WxBREEo.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-9081660508920984183</id><published>2009-12-29T00:59:00.000-08:00</published><updated>2009-12-29T00:59:47.553-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-29T00:59:47.553-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="scala" /><title>Attaching a Java debugger to the Scala REPL</title><content type="html">Originally posted on the &lt;a href="http://eng.kaching.com/2009/12/attaching-java-debugger-to-scala-repl.html"&gt;kaChing Eng Blog&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I'm using the Scala REPL to play around with java libraries and check their runtime behaviors. One of the things I'm using it for is to check how &lt;a href="http://project-voldemort.com/"&gt;Voldemort's&lt;/a&gt; client is behaving in different setups. For one of the checks I wanted to trace the client threads with an IDE debugger.&lt;br /&gt;
To attach a debugger to the Scala REPL all you need to do is to export the debugger values into JAVA_OPTS:&lt;br /&gt;
&lt;pre class="brush: bash;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;export JAVA_OPTS='-Xdebug -Xrunjdwp:transport=dt_socket,address=1773,server=y,suspend=n'&lt;/pre&gt;Run your scala REPL and attach your debugger to port 1773. Done.&lt;br /&gt;
&lt;br /&gt;
(*) Tested with scala 2.7&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-9081660508920984183?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/e5rgabhEK5A" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/9081660508920984183?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/9081660508920984183?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/e5rgabhEK5A/attaching-java-debugger-to-scala-repl.html" title="Attaching a Java debugger to the Scala REPL" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2009/12/attaching-java-debugger-to-scala-repl.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAMSHY8cCp7ImA9WxBTE0k.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-1715119699274999142</id><published>2009-12-09T00:53:00.000-08:00</published><updated>2009-12-09T00:53:09.878-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-09T00:53:09.878-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="kaching" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="monitoring" /><title>Baking availability SLA into the code</title><content type="html">This is a copy of the post I made on the &lt;a href="http://eng.kaching.com/2009/12/baking-availability-sla-into-code.html"&gt;kaChing engineering blog&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Availability and Partition Tolerance are essential for many distributed systems. A simple (though not comprehensive) way to measure both is using response time SLAs between services as implied from &lt;a href="http://pl.atyp.us/wordpress/?author=30"&gt;Jeff Darcy&lt;/a&gt;'s &lt;a href="http://pl.atyp.us/wordpress/?p=2521"&gt;observation&lt;/a&gt;:&lt;br /&gt;
&lt;blockquote&gt;Lynch (referring to the &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.20.1495&amp;amp;rep=rep1&amp;amp;type=pdf"&gt;2002 SIGACT paper&lt;/a&gt;) also makes the point that unbounded delay is indistinguishable from failure. Time is therefore an essential component of these definitions (a point made even more explicitly in the &lt;a href="http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html"&gt;Dynamo paper&lt;/a&gt;).&lt;br /&gt;
&lt;/blockquote&gt;At &lt;a href="http://www.kaching.com/"&gt;kaChing&lt;/a&gt; we think that SLAs is something that should be baked into the code so the developer will have to think of while creating the service contact. For that reason we created a @ResponseTime annotation for out internal services:&lt;pre class="brush: java;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;@Retention(RUNTIME)
@Target({ TYPE })
public @interface ResponseTime {
  long warn();
  long error();
  TimeUnit unit() default MILLISECONDS;
}&lt;/pre&gt;A typical service query for online requests is annotated with&lt;pre class="brush: java;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;@ResponseTime(warn = 100, error = 200)&lt;/pre&gt;Where the time depends on the services constraints, access to resources for example. A ping query for example has a &lt;pre class="brush: java;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;@ResponseTime(warn = 2, error = 4)&lt;/pre&gt;and an offline analytics call may take hours &lt;pre class="brush: java;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;@ResponseTime(warn = 10, error = 15, unit = HOURS)&lt;/pre&gt;Nevertheless, every request should have an SLA and the developer must think of it when writing the implementation.&lt;br /&gt;
Once we have this tool the SLA of subsequent services (B, C &amp; D) a service (A) needs to call can statically be computed to verify that no path in the tree of subsequent services calls exceeds the root service (A) SLA. In other other words, for service queries A, B, C &amp; D. If A calls (B and B calls C) and in parallel A calls D then we should have SLA(A) &gt; max (SLA(B) + SLA(C), SLA (D)).&lt;br /&gt;
kaChing's service query container sample the time it takes for every call using &lt;a href="http://perf4j.codehaus.org/"&gt;perf4j&lt;/a&gt; and logs times and SLA violations to local disk. If the query's time exceeds the warning threshold it will be logged accordingly, but if the error threshold is broken then the container will try to terminate the query. Terminating the query is a bit harsh, but the since our client timeout is using the SLA as well then most chances are that the client gave up on the query and either retried (service queries are &lt;a href="http://en.wikipedia.org/wiki/Idempotence"&gt;Idempotent&lt;/a&gt;) or aborted. Another reason to shoot down a runaway query that exceeds the SLA error time is that it may be locking or consuming resources from other queries and slowing the whole system down.&lt;br /&gt;
The perf4j messages are also piped through a log4j socket appender (async buffers in each side of the pipe) to a central hub. The hub then does statistics on the aggregated times, it loads the SLAs of the queries and checks that the cluster is not violating its SLA. The central hub can then send a daily report on SLAs and real time alerts pinpointing a slower then expected service. Keeping the reports and comparing them to historical reports are helping to see an improvement or regression in every part of the site.&lt;br /&gt;
&lt;br /&gt;
This monitoring technique is only a small portion of the automated system operation a small startup must have in order to stay flexible. Stay tuned for more monitoring automation posts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-1715119699274999142?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/ealHr-BTspA" height="1" width="1"/&gt;</content><link rel="enclosure" type="text/html" href="http://eng.kaching.com/2009/12/baking-availability-sla-into-code.html" length="0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/1715119699274999142?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/1715119699274999142?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/ealHr-BTspA/baking-availability-sla-into-code.html" title="Baking availability SLA into the code" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2009/12/baking-availability-sla-into-code.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQAQHg4eip7ImA9WxNWEk0.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-5019273532943019381</id><published>2009-10-10T13:08:00.000-07:00</published><updated>2009-10-10T13:42:21.632-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-10T13:42:21.632-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="kaching" /><title>Looking for a passionate Systems Engineer !</title><content type="html">Not a typical post, but I might as well use this platform to promote it. Come join the best startup ever !&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.kaching.com/"&gt;kaChing&lt;/a&gt; is an investing talent marketplace where individual investors gain access to the best investing talent on the Web. An SEC registered investment adviser, kaChing enables customers to mirror automatically the trades of the "kaChing Geniuses" who have an Investing IQ of 140 or greater. The company's investors include Marc Andreessen, Jeff Jordan, CEO of Open Table (OPEN) and former president of PayPal, and retired partners from Benchmark Capital and Kleiner Perkins Caufield &amp;amp; Byers.&lt;br /&gt;&lt;br /&gt;Join a stellar engineering team whose team members worked on massive &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_O9TJAb-LjDE/StDwo_468ZI/AAAAAAAAAgQ/SjByhYIYiw0/s1600-h/2dd2ac0.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 100px; height: 31px;" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/StDwo_468ZI/AAAAAAAAAgQ/SjByhYIYiw0/s200/2dd2ac0.png" alt="" id="BLOGGER_PHOTO_ID_5391073341098094994" border="0" /&gt;&lt;/a&gt;backend infrastructure, Gmail's high performance frontend, the Native Scala Compiler with Prof. Odersky and more. We are test-driven and have a continuous integration process that lets us achieve a 5 minute build and release cycle.&lt;br /&gt;&lt;br /&gt;Job description:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; In charge of the backend of a revolutionary web site doing large scale high availability deployments and configuration management using open source software.&lt;/li&gt;&lt;li&gt;Keeping the system having a fully automated release cycle, continues testing and monitoring. &lt;/li&gt;&lt;li&gt;Build tools for monitoring, security, systems management and deployment if the available ones are not enough.&lt;/li&gt;&lt;li&gt;Help engineers architect the next levels of the system and making sure it stays agile and easily absorb high capacity.&lt;/li&gt;&lt;/ul&gt;Qualifications&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Extremely smart and self motivated&lt;/li&gt;&lt;li&gt;Passion for test-driven development and automated functional QA&lt;/li&gt;&lt;li&gt;         Live and breathe performance&lt;/li&gt;&lt;li&gt;         Thinks out of the conventional box of IT management&lt;/li&gt;&lt;li&gt;         Experience with databases, preferable MySQL&lt;/li&gt;&lt;li&gt;         Good knowledge about monitoring and deployment tools&lt;/li&gt;&lt;li&gt;         Good knowledge about network and distributed computing&lt;/li&gt;&lt;li&gt;         Expert in at least one scripting language and know at least one more&lt;/li&gt;&lt;li&gt;         Ability to work independently&lt;/li&gt;&lt;li&gt;         A BS in computer science or related fields&lt;/li&gt;&lt;/ul&gt;I'll soon add a link to the official page.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-5019273532943019381?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/wV2QKaRoAQg" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/5019273532943019381?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/5019273532943019381?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/wV2QKaRoAQg/looking-for-passionate-systems-engineer.html" title="Looking for a passionate Systems Engineer !" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_O9TJAb-LjDE/StDwo_468ZI/AAAAAAAAAgQ/SjByhYIYiw0/s72-c/2dd2ac0.png" height="72" width="72" /><feedburner:origLink>http://www.eishay.com/2009/10/looking-for-passionate-systems-engineer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUERH85cSp7ImA9WxNWFUg.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-6374798913017722495</id><published>2009-10-07T22:35:00.000-07:00</published><updated>2009-10-14T12:56:45.129-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-14T12:56:45.129-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="protobuf" /><category scheme="http://www.blogger.com/atom/ns#" term="kaching" /><category scheme="http://www.blogger.com/atom/ns#" term="voldemort" /><title>Speeding up with Voldemort and Protobuf</title><content type="html">In order to supply some of the analytics behind &lt;a href="http://www.kaching.com/"&gt;kaChing&lt;/a&gt; we have a some nice number crunching processes working over piles of financial data. The end results are displayed on the site (e.g. the &lt;a href="http://www.kaching.com/investors/find"&gt;find investors&lt;/a&gt; page).&lt;br /&gt;
&lt;br /&gt;
The post is about one of such services which for the sake of this post I'll refer to as the SuperCruncher. In the first iteration we grabbed the data straight from the DB into the SuperCruncher. Needless to say, relational databases are not handling stress nicely and a pattern of fast iteration over all of the DB kills it very fast. Results of first iteration: 25 hours of computing. &lt;br /&gt;
&lt;br /&gt;
Since we couldn't manage to squeeze more hours into the day we run a second iteration.&lt;br /&gt;
&lt;span style="font-weight: bold;"&gt;&lt;a href="http://project-voldemort.com/"&gt;Voldemort&lt;/a&gt; &amp;amp; &lt;a href="http://code.google.com/p/protobuf/"&gt;Protobuf&lt;/a&gt; for the rescue!&lt;/span&gt; &lt;br /&gt;
Though we have piles of data to compute, some of the data does not change though we do need to read it each time. We shoved the data into a Protobuf data structure which made the binary size considerably smaller, and pushed the protobuf into Voldemort. We used the Voldamort &lt;a href="http://project-voldemort.com/javadoc/all/voldemort/serialization/protobuf/ProtoBufSerializer.html"&gt;ProtoBufSerializer&lt;/a&gt; which provides an extremely simple way to store and use protobufs. &lt;br /&gt;
So essentially Voldemort in this case is used as a persistent cache to store normalized data. When reading the date the SuperCruncher first check it it exist in the naturally sharded Voldemort cluster and gets the delta from the DB.&lt;br /&gt;
Using Voldemort and Protobuf the I/O problem vanished, the SuperCruncher became four times faster (!) and bounced the performance ball back to the CPU. Cutting down CPU time is usually easier then cutting on I/O and indeed we managed to make the running time considerably faster in later iterations (hint: Joda Time &amp;amp; GC).&lt;br /&gt;
&lt;br /&gt;
Shameless promo: &lt;span style="font-weight: bold;"&gt;kaChing is hiring!&lt;/span&gt;&lt;br /&gt;
We are looking for an world class Systems Engineer.&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/_O9TJAb-LjDE/Ss2OkNxWPDI/AAAAAAAAAgI/yTgvtdJBK5o/s1600-h/2dd2ac0.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5390121081855425586" src="http://2.bp.blogspot.com/_O9TJAb-LjDE/Ss2OkNxWPDI/AAAAAAAAAgI/yTgvtdJBK5o/s320/2dd2ac0.png" style="cursor: pointer; float: right; height: 31px; margin: 0pt 0pt 10px 10px; width: 100px;" /&gt;&lt;/a&gt;&lt;br /&gt;
Our release cycle is 5 minute long, we release from the branch and have 100% tests passing on all time therefore we do not need a typical sysops person. We are looking for an excellent engineer to run, architect and automate the system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-6374798913017722495?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/3fh8bZDPKRc" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/6374798913017722495?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/6374798913017722495?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/3fh8bZDPKRc/getting-to-spead-using-volaemort-and.html" title="Speeding up with Voldemort and Protobuf" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_O9TJAb-LjDE/Ss2OkNxWPDI/AAAAAAAAAgI/yTgvtdJBK5o/s72-c/2dd2ac0.png" height="72" width="72" /><feedburner:origLink>http://www.eishay.com/2009/10/getting-to-spead-using-volaemort-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QCRn4yeSp7ImA9WxNXFk4.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-3680992003313923389</id><published>2009-10-03T21:23:00.000-07:00</published><updated>2009-10-03T21:42:47.091-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-03T21:42:47.091-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Google App Engine" /><category scheme="http://www.blogger.com/atom/ns#" term="gwt" /><category scheme="http://www.blogger.com/atom/ns#" term="jdo" /><category scheme="http://www.blogger.com/atom/ns#" term="scala" /><category scheme="http://www.blogger.com/atom/ns#" term="conferences" /><title>Scala @ Silicon Valley Code Camp</title><content type="html">Had a great day at the Silicon Valley Code Camp. Gave couple of talks about Scala and met lots of interesting people. Here are the slides for the talks I gave.&lt;br /&gt;&lt;div style="text-align: center;"&gt;Absorbing Scala Into Java Ecosystem&lt;br /&gt;&lt;iframe src="http://docs.google.com/present/embed?id=dcfpvtwg_72dp52knfd&amp;amp;size=m" frameborder="0" height="451" width="555"&gt;&lt;/iframe&gt;&lt;br /&gt;A First Look at Scala on Google App Engine&lt;br /&gt;&lt;iframe src="http://docs.google.com/present/embed?id=dcfpvtwg_73hgx99wcj&amp;amp;size=m" frameborder="0" height="451" width="555"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-3680992003313923389?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/gDdLVWaJcVY" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/3680992003313923389?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/3680992003313923389?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/gDdLVWaJcVY/scala-silicon-valley-code-camp.html" title="Scala @ Silicon Valley Code Camp" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2009/10/scala-silicon-valley-code-camp.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0EAQX8yeCp7ImA9WxNXFU4.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-5895424328866855367</id><published>2009-10-02T17:21:00.000-07:00</published><updated>2009-10-02T18:00:40.190-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-02T18:00:40.190-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="kaching" /><title>kaChing on Yahoo! Homepage</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_O9TJAb-LjDE/SsaZR0BHWEI/AAAAAAAAAf8/_NNGupM-4Wc/s1600-h/Screen+shot+2009-10-02+at+5.19.42+PM.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 383px;" src="http://3.bp.blogspot.com/_O9TJAb-LjDE/SsaZR0BHWEI/AAAAAAAAAf8/_NNGupM-4Wc/s400/Screen+shot+2009-10-02+at+5.19.42+PM.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5388162535495522370" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;pre class="brush: scala;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;println("Hello kaChing!")&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-5895424328866855367?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/cHNWD9TaYUU" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/5895424328866855367?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/5895424328866855367?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/cHNWD9TaYUU/kaching-on-yahoo-homepage.html" title="kaChing on Yahoo! Homepage" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_O9TJAb-LjDE/SsaZR0BHWEI/AAAAAAAAAf8/_NNGupM-4Wc/s72-c/Screen+shot+2009-10-02+at+5.19.42+PM.png" height="72" width="72" /><feedburner:origLink>http://www.eishay.com/2009/10/kaching-on-yahoo-homepage.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQNRHc4fyp7ImA9WxNQFU0.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-1100853357721102274</id><published>2009-09-20T20:25:00.000-07:00</published><updated>2009-09-20T20:39:55.937-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-20T20:39:55.937-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="kaching" /><category scheme="http://www.blogger.com/atom/ns#" term="conferences" /><title>Off to a new adventure</title><content type="html">Had a great couple of years at &lt;a href="http://www.linkedin.com/in/eishay"&gt;LinkedIn&lt;/a&gt; and now I'm off to a new adventure in the valley of silicon. This time its a great web startup called &lt;a href="http://www.kaching.com/"&gt;KaChing&lt;/a&gt; which I'm sure you'll hear more about in the next few months.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.killerstartups.com/data/upload/StartUps/Logo/115000_thumbs/111308_logo_thumb.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 150px; height: 50px;" src="http://www.killerstartups.com/data/upload/StartUps/Logo/115000_thumbs/111308_logo_thumb.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So I might be a bit quiet for a while working with great technology but if you happen to be around come and meet me at the &lt;a href="http://www.siliconvalley-codecamp.com/Sessions.aspx?ForceSortBySessionTime=true&amp;id=210"&gt;Silicon Valley Code Camp&lt;/a&gt;!&lt;br /&gt;I'll go back now to work on the &lt;a href="http://project-voldemort.com/"&gt;Voldamort&lt;/a&gt; &amp; &lt;a href="http://code.google.com/p/protobuf/"&gt;Protobuf&lt;/a&gt; integration.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-1100853357721102274?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/Wftj8_GRrD4" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/1100853357721102274?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/1100853357721102274?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/Wftj8_GRrD4/off-to-new-adventure.html" title="Off to a new adventure" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2009/09/off-to-new-adventure.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQESXg8eCp7ImA9WxJaGUo.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-5903517802545071925</id><published>2009-08-10T23:16:00.000-07:00</published><updated>2009-08-10T23:31:48.670-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-10T23:31:48.670-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="protobuf" /><category scheme="http://www.blogger.com/atom/ns#" term="json" /><title>Protobuf JSON Serializer is great, but a bit slow</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.aykew.com/images/aboutwork/speed.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 121px; height: 87px;" src="http://www.aykew.com/images/aboutwork/speed.jpg" alt="" border="0" /&gt;&lt;/a&gt;Run a small benchmark with the fresh new &lt;a href="http://code.google.com/p/protobuf-java-format/"&gt;protobuf-java-format&lt;/a&gt;. The &lt;a href="http://code.google.com/p/thrift-protobuf-compare/source/browse/trunk/tpc/src/serializers/ProtobufJsonSerializer.java"&gt;ProtobufJsonSerializer&lt;/a&gt; code is nice and trivial, greatly increasing the portability of protobuf and its capabilities to communicate with services that can't use the protobuf native parsing libraries.&lt;br /&gt;Alas, it also comes with some price. Unfortunately, this new (still early) version of the library is very slow compared to other serialization libraries. See the full &lt;a href="http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking"&gt;benchmarking wiki page&lt;/a&gt; for more info.  &lt;br /&gt;&lt;pre class="brush: bash;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;               Obj create, Serialization, Deserializtn,  Total Time, Size&lt;br /&gt;protobuf      , 421.14250,    3738.75000,   2471.25000,  6631.14250, 217&lt;br /&gt;json (jackson), 235.45000,    3196.50000,   4934.25000,  8366.20000, 304&lt;br /&gt;JsonMarshaller, 237.79000,   18107.00000,  24715.75000, 43060.54000, 298&lt;br /&gt;protobuf-json , 431.94000,   19933.25000, 102577.75000,122942.94000, 389&lt;/pre&gt;&lt;br /&gt;&lt;img src="http://chart.apis.google.com/chart?chtt=timeCreate&amp;amp;chf=c%7C%7Clg%7C%7C0%7C%7CFFFFFF%7C%7C1%7C%7C76A4FB%7C%7C0%7Cbg%7C%7Cs%7C%7CEFEFEF&amp;amp;chs=800x100&amp;amp;chd=t:235.45,431.94,237.79,421.1425&amp;amp;chds=0,662&amp;amp;chxl=0:%7Cprotobuf%7CJsonMarshaller%7Cprotobuf-json%7Cjson%20%28jackson%29&amp;amp;lklk&amp;amp;chdlp=t&amp;amp;chco=660000%7C660033%7C660066%7C660099%7C6600CC%7C6600FF%7C663300%7C663333%7C663366%7C663399%7C6633CC%7C6633FF%7C666600%7C666633%7C666666&amp;amp;cht=bhg&amp;amp;chbh=10&amp;amp;chxt=y&amp;amp;nonsense=aaa.png" /&gt;&lt;br /&gt;&lt;img src="http://chart.apis.google.com/chart?chtt=timeSer&amp;amp;chf=c%7C%7Clg%7C%7C0%7C%7CFFFFFF%7C%7C1%7C%7C76A4FB%7C%7C0%7Cbg%7C%7Cs%7C%7CEFEFEF&amp;amp;chs=800x100&amp;amp;chd=t:3196.5,19933.25,18107.0,3738.75&amp;amp;chds=0,22486&amp;amp;chxl=0:%7Cprotobuf%7CJsonMarshaller%7Cprotobuf-json%7Cjson%20%28jackson%29&amp;amp;lklk&amp;amp;chdlp=t&amp;amp;chco=660000%7C660033%7C660066%7C660099%7C6600CC%7C6600FF%7C663300%7C663333%7C663366%7C663399%7C6633CC%7C6633FF%7C666600%7C666633%7C666666&amp;amp;cht=bhg&amp;amp;chbh=10&amp;amp;chxt=y&amp;amp;nonsense=aaa.png" /&gt;&lt;br /&gt;&lt;img src="http://chart.apis.google.com/chart?chtt=timeDSer&amp;amp;chf=c%7C%7Clg%7C%7C0%7C%7CFFFFFF%7C%7C1%7C%7C76A4FB%7C%7C0%7Cbg%7C%7Cs%7C%7CEFEFEF&amp;amp;chs=800x100&amp;amp;chd=t:4934.25,102577.75,24715.75,2471.25&amp;amp;chds=0,67348&amp;amp;chxl=0:%7Cprotobuf%7CJsonMarshaller%7Cprotobuf-json%7Cjson%20%28jackson%29&amp;amp;lklk&amp;amp;chdlp=t&amp;amp;chco=660000%7C660033%7C660066%7C660099%7C6600CC%7C6600FF%7C663300%7C663333%7C663366%7C663399%7C6633CC%7C6633FF%7C666600%7C666633%7C666666&amp;amp;cht=bhg&amp;amp;chbh=10&amp;amp;chxt=y&amp;amp;nonsense=aaa.png" /&gt;&lt;br /&gt;&lt;img src="http://chart.apis.google.com/chart?chtt=totalTime&amp;amp;chf=c%7C%7Clg%7C%7C0%7C%7CFFFFFF%7C%7C1%7C%7C76A4FB%7C%7C0%7Cbg%7C%7Cs%7C%7CEFEFEF&amp;amp;chs=800x100&amp;amp;chd=t:8366.2,122942.94,43060.54,6631.1425&amp;amp;chds=0,90500&amp;amp;chxl=0:%7Cprotobuf%7CJsonMarshaller%7Cprotobuf-json%7Cjson%20%28jackson%29&amp;amp;lklk&amp;amp;chdlp=t&amp;amp;chco=660000%7C660033%7C660066%7C660099%7C6600CC%7C6600FF%7C663300%7C663333%7C663366%7C663399%7C6633CC%7C6633FF%7C666600%7C666633%7C666666&amp;amp;cht=bhg&amp;amp;chbh=10&amp;amp;chxt=y&amp;amp;nonsense=aaa.png" /&gt;&lt;br /&gt;&lt;img src="http://chart.apis.google.com/chart?chtt=length&amp;amp;chf=c%7C%7Clg%7C%7C0%7C%7CFFFFFF%7C%7C1%7C%7C76A4FB%7C%7C0%7Cbg%7C%7Cs%7C%7CEFEFEF&amp;amp;chs=800x100&amp;amp;chd=t:304.0,389.0,298.0,217.0&amp;amp;chds=0,604&amp;amp;chxl=0:%7Cprotobuf%7CJsonMarshaller%7Cprotobuf-json%7Cjson%20%28jackson%29&amp;amp;lklk&amp;amp;chdlp=t&amp;amp;chco=660000%7C660033%7C660066%7C660099%7C6600CC%7C6600FF%7C663300%7C663333%7C663366%7C663399%7C6633CC%7C6633FF%7C666600%7C666633%7C666666&amp;amp;cht=bhg&amp;amp;chbh=10&amp;amp;chxt=y&amp;amp;nonsense=aaa.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-5903517802545071925?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/BCYlSEzeqw8" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/5903517802545071925?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/5903517802545071925?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/BCYlSEzeqw8/protobuf-json-serializer-is-great-but.html" title="Protobuf JSON Serializer is great, but a bit slow" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2009/08/protobuf-json-serializer-is-great-but.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIFQXc9cCp7ImA9WxJaGUs.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-928550330850154699</id><published>2009-08-10T21:53:00.000-07:00</published><updated>2009-08-10T22:11:50.968-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-10T22:11:50.968-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="scala" /><title>EasyMock IArgumentMatcher with Scala Howto</title><content type="html">Its pretty trivial if you're a Scala savvy, but for the learners it might be a bit tricky. First thing, you should probably first get familiar with the &lt;a href="http://easymock.org/api/easymock/2.4/org/easymock/IArgumentMatcher.html"&gt;java way of using IArgumentMatcher&lt;/a&gt;. To use it you should have a static method that calls EasyMock.reportMatcher with your implementation of IArgumentMatcher. To archive that you must create the method in an object. Its a workaround for not having static methods in Scala. Then implement the matcher, pattern matching is lots of help here, and remember that in Scala AnyRef is equivalent to Java's Object.&lt;br /&gt;&lt;pre class="brush: scala;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;object TestMyClazz {&lt;br /&gt;  /**&lt;br /&gt;   * for EZMock argument matcher&lt;br /&gt;   */&lt;br /&gt;  def eqMyClazz(obj: MyClazz) : MyClazz = {&lt;br /&gt;    EasyMock.reportMatcher(new MyClazzMatcher(obj))&lt;br /&gt;    null&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  class MyClazzMatcher(obj: MyClazz) extends IArgumentMatcher {&lt;br /&gt;    def matches(actual: AnyRef): Boolean = actual match {&lt;br /&gt;      case actual: MyClazz  =&gt; //check things...&lt;br /&gt;      case null =&gt; //is null ok?&lt;br /&gt;      case _ =&gt; false&lt;br /&gt;    }&lt;br /&gt;    def appendTo(buffer: StringBuffer) : Unit = buffer append "some text..."&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;Done, now you just need to call eqMyClazz() with your expected value.&lt;pre class="brush: scala;tab-size: 2; smart-tabs: true; toolbar: false; gutter: false; first-line:1;"&gt;someObj.useMyClazz(eqMyClazz(expectedObjectOfMyClazz))&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-928550330850154699?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/zGluHbQpgJs" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/928550330850154699?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/928550330850154699?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/zGluHbQpgJs/easymock-iargumentmatcher-with-scala.html" title="EasyMock IArgumentMatcher with Scala Howto" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2009/08/easymock-iargumentmatcher-with-scala.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04BQH8-fip7ImA9WxJaGUs.&quot;"><id>tag:blogger.com,1999:blog-24611184.post-6903948736419251487</id><published>2009-08-10T21:23:00.000-07:00</published><updated>2009-08-10T21:45:51.156-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-10T21:45:51.156-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="scala" /><category scheme="http://www.blogger.com/atom/ns#" term="conferences" /><title>Speaking at the QCon San Francisco '09 "Absorbing Scala"</title><content type="html">Funny thing happened to me,&lt;br /&gt;I checked out the new Google search engine on their sandbox url.&lt;br /&gt;On of the things I searched for is my &lt;a href="http://www2.sandbox.google.com/#hl=en&amp;amp;q=eishay"&gt;own name&lt;/a&gt; (very modest of me, I know...). I was a bit surprised to see I'm going to talk at &lt;a href="http://qconsf.com/sf2009/speaker/Eishay+Smith"&gt;QCon San Francisco 2009&lt;/a&gt; about "Absorbing Scala". I remember discussing it a long while ago but it kinda trailed off and I forgot about it. They did got &lt;a href="http://www.linkedin.com/in/eishay"&gt;my current title&lt;/a&gt; wrong, not that it matters too much.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.c-h-i.org/images/logos/logo_qcon.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 179px; height: 74px;" src="http://www.c-h-i.org/images/logos/logo_qcon.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Anyway, its a yet another practical use of google search :-)&lt;br /&gt;&lt;br /&gt;Hope there'll be more Scala nuts in the crowd to quiet down the other Language Zealot (by the way, I do love the groovy).&lt;br /&gt;&lt;br /&gt;See you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24611184-6903948736419251487?l=www.eishay.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/WonderingAround/~4/WiU2VrZTZPo" height="1" width="1"/&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/6903948736419251487?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/24611184/posts/default/6903948736419251487?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WonderingAround/~3/WiU2VrZTZPo/speaking-at-qcon-san-francisco-09.html" title="Speaking at the QCon San Francisco '09 &quot;Absorbing Scala&quot;" /><author><name>Eishay Smith</name><uri>http://www.blogger.com/profile/09443096006184006852</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="30" height="32" src="http://4.bp.blogspot.com/_O9TJAb-LjDE/S44K61181wI/AAAAAAAAAj0/oYGO2xz_kf4/S220/eishay.png" /></author><feedburner:origLink>http://www.eishay.com/2009/08/speaking-at-qcon-san-francisco-09.html</feedburner:origLink></entry></feed>

