<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1149178966400721843</id><updated>2012-02-16T09:41:48.896+01:00</updated><title type='text'>In Code We Trust Inc</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-1583299545999609762</id><published>2011-11-04T21:38:00.008+01:00</published><updated>2011-11-05T10:21:41.115+01:00</updated><title type='text'>100 days of Whole30, my personal summary</title><content type='html'>We interrupt the general nerdiness of this blog with a little experience report of my whole30 lifestyle change. A 30 day "diet" designed to improve your health and maybe loose some weight in the process (&lt;a href="http://whole9life.com/"&gt;http://whole9life.com/&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;I started at the end of July, weighing a solid 96,5kg, probably 20cm too short for that weight - and I'm 42 so it's getting sooo hard to get rid of.&lt;br /&gt;&lt;br /&gt;Whole30 is about eating natural ingredients, preferably organic. No sugar, alcohol, wheat or anything containing any "E"'s. Just 3 daily meals of real, natural food. I've been 100% faithful in the whole period, eating organic and the highest quality I can find here in Oslo.&amp;nbsp; All along these 100 days I've been running 7 km three times a week.&lt;br /&gt;&lt;br /&gt;Day for day, this is what happened:&lt;br /&gt;&lt;br /&gt;Day 5: Out shopping at IKEA with wife, I realize I feel really energized; damn good! Feeling good at IKEA is a first for me, ever.&lt;br /&gt;&lt;br /&gt;Day 8: My sense of smell returned 100%.&lt;br /&gt;&amp;nbsp;&amp;nbsp; Having chronic tonsil &amp;amp; sinus infections, I removed tonsils and surgically opened sinus canals 3 years ago. In those three years, I have had like 25% normal sense of smell (I could wash the toilets with 20% chlorine and not notice it!). All of a sudden I started smelling all kinds of things.&lt;br /&gt;&lt;br /&gt;Day 10: My blood pressure goes up.&lt;br /&gt;&amp;nbsp;&amp;nbsp; I've always been borderline high blood pressure, most of the time *at* the treatment limit. Unfortunately I seem to not tolerate /any/ blood pressure medication, my body seems to reject them each time I use them. So, in line with doctor's orders I start with medicine for enough to get my pressure down (5 days, give or take).&lt;br /&gt;&lt;br /&gt;Day 14: I am quite angry&lt;br /&gt;&amp;nbsp;&amp;nbsp; My wife complains that I am easily agitated. I know this too, but I also feel it is different from the insane rage I could get if I followed something like the cambridge diet.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Day 16: I stop blood pressure medication, back at my "usual" borderline level. (This is according to doctor's orders; please follow your own doctor on this! If I stay on /any/ blood pressure medication for 14 days I collapse)&lt;br /&gt;&lt;br /&gt;Day 18: I feel great.&lt;br /&gt;&lt;br /&gt;Day 20: My blood pressure drops by 15 (over/under). I have never had this low blood pressure, ever. (This has no connection to the medication I quit a few days earlier, the medication only brings me immediately below the treatment treshold) My new blood pressure is "normal." I've /never/ had "normal"&amp;nbsp; &lt;b&gt;ever&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Day 25: Wife still complains I'm easily agitated&lt;br /&gt;&lt;br /&gt;Day 30: I'm about 5 kg down&lt;br /&gt;&lt;br /&gt;Day 40-50: I feel great. My mood is fantastic. Colleagues at work start commenting that I'm in a fantastic mood. They've been informed and curious since day 1, but I think it's becoming clearly obvious to everyone that there is change going on. &lt;br /&gt;&lt;br /&gt;Day 60: Wife says I seem to be happy.&lt;br /&gt;&lt;br /&gt;Day 70: I feel fucking marvellous, and we're talking mental state. I've never tried cocaine, but this must be what it's like. (Ok, probably not, but this is healthy!)&lt;br /&gt;&lt;br /&gt;Day 80: Wife says I seem extremely happy.&lt;br /&gt;&lt;br /&gt;Day 100: Officially "done" with the "diet" part. Drinking my first glass of wine &amp;amp; eating sushi. I'm not sure what I'll do next but today I added organic red wine and sushi to my diet; if I can add those two things I'll be satisfied for quite some more time. 10kg down.&lt;br /&gt;&lt;br /&gt;There's one thing I'm still unsure about; and that's ketosis. I seem to be going in &amp;amp; out of ketosis all of the time, and I'm probably eating too much or too little carbs. There's a lot of transitional issues involved in going into ketosis (bad breath being perhaps the most notable). It seems like ketosis is good for losing weight, but I assume it won't be necessary now that I'm approaching an acceptable weight.&lt;br /&gt;&lt;br /&gt;I know my colleagues will be starting whole30 soon. In thirty days you can find out what impact your current eating has on your health. How can you &lt;i&gt;not&lt;/i&gt; take just 30 days ? I took 100 ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-1583299545999609762?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/1583299545999609762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2011/11/100-days-of-whole30-my-personal-summary.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/1583299545999609762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/1583299545999609762'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2011/11/100-days-of-whole30-my-personal-summary.html' title='100 days of Whole30, my personal summary'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-4917195537090004445</id><published>2011-08-09T11:13:00.007+02:00</published><updated>2011-08-10T14:06:08.115+02:00</updated><title type='text'>Your new password</title><content type='html'>I was fed up with having a zillion passwords. Worst of all, we don't have any insight into what kind of security the websites you access employ, so happy anarchists like LulzSec and Anonymous can run away with your master password if you're not careful. &lt;br /&gt;&lt;br /&gt;So instead of a password, I ended up with the following algorithm; &lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Second letter in the domain name (Or last letter), in uppercase&lt;/li&gt;&lt;li&gt;&lt;first domain="" in="" letter="" name=""&gt;&lt;constant a="" digit="" ending="" in=""&gt;&lt;the domain="" in="" name="" number="" of="" the="" wovels=""&gt;&lt;second caps="" domain="" in="" letter=""&gt;Constant part. Starting with one or more captialized letters, ending with a digit. 6 chars or more. You may choose to look at&amp;nbsp;&lt;/second&gt;&lt;/the&gt;&lt;/constant&gt;&lt;/first&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px; line-height: 18px;"&gt;&lt;a class="ot-anchor" href="http://www.baekdal.com/tips/password-security-usability" style="color: #3366cc; cursor: pointer; text-decoration: none;"&gt;http://www.baekdal.com/tips/password-security-usability&lt;/a&gt;&amp;nbsp;for this bit.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;first domain="" in="" letter="" name=""&gt;&lt;constant a="" digit="" ending="" in=""&gt;&lt;the domain="" in="" name="" number="" of="" the="" wovels=""&gt;&lt;second caps="" domain="" in="" letter=""&gt;A digit 1 (increase this for sites that require password change)&lt;/second&gt;&lt;/the&gt;&lt;/constant&gt;&lt;/first&gt;&lt;/li&gt;&lt;li&gt;&lt;first domain="" in="" letter="" name=""&gt;&lt;constant a="" digit="" ending="" in=""&gt;&lt;the domain="" in="" name="" number="" of="" the="" wovels=""&gt;&lt;second caps="" domain="" in="" letter=""&gt;The number of vowels (or consonants, or [A-F] or whatever  in the domain name)&lt;/second&gt;&lt;/the&gt;&lt;/constant&gt;&lt;/first&gt;&lt;/li&gt;&lt;li&gt;First letter in domain name, lowercase&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://www.blogger.com/post-edit.g?blogID=1149178966400721843&amp;amp;postID=4917195537090004445"&gt; &lt;/a&gt; &lt;br /&gt;&lt;br /&gt;The constant part should probably contain at least one "special" character like % { or whatever, simply because sites may start requiring this. But think about accessibility for this character on phones etc. &lt;br /&gt;&lt;br /&gt;A couple of key points about this algorithm: All digits are grouped together, as for capital letters. Some devices (iPhone etc) require additional touches to switch to upper case or numeric keyboards, so group them together. &lt;br /&gt;&lt;br /&gt;The "domain name" is the last word before .com/.org. &lt;br /&gt;&lt;br /&gt;I keep the constant part about 6 chars, to make 10 digits total. You might consider going for 12 total. &lt;br /&gt;&lt;br /&gt;In some places you may be likely to give away your password (this may  happen to me at work sometimes). In those cases you can use a different  constant-part or simply a totally different password, at least I always  know these things up-front.&lt;br /&gt;&lt;br /&gt;Think it sounds like a hassle ? I feel the hassle every time I encounter a site where I haven't used this pattern yet, you get used to it.... This password should be strong enough to last the rest of my life. (Lol, I know that's not going to happen). &lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-4917195537090004445?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/4917195537090004445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2011/08/your-new-password.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/4917195537090004445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/4917195537090004445'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2011/08/your-new-password.html' title='Your new password'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-2429894919383667871</id><published>2011-04-18T21:12:00.005+02:00</published><updated>2011-04-18T21:30:36.066+02:00</updated><title type='text'>Watch that @Autowired</title><content type='html'>Those who follow me on &lt;a href="http://twitter.com/#%21/krosenvold"&gt;Twitter&lt;/a&gt;, will see that I just submitted a patch for &lt;a href="https://jira.springsource.org/browse/SPR-6870"&gt;SPR-6870&lt;/a&gt;. Great patch if you're running something like a web-based application with lots of non-singleton scoped components. You might save a server or more by applying that patch and the spring context starts quite a bit faster too.&lt;br /&gt;&lt;br /&gt;So while you're waiting 20 minutes for spring to compile, just look out for one more thing:&lt;br /&gt;&lt;br /&gt;Don't autowire into arrays/collections unless the containing component is a singleton. Spring does not do a very good job of caching that stuff (it sucks, actually).&lt;br /&gt;&lt;br /&gt;So if your non-singleton scoped  classes (or junit tests - like we had ;) contain something like&lt;br /&gt;&lt;br /&gt;@Autowired&lt;br /&gt;private MyFud[] myFuds;&lt;br /&gt;&lt;br /&gt;Just make a separate singleton object that encapsulates the array/list and wire that into your  controller class / junit test instead. Bang you're safe.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-2429894919383667871?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/2429894919383667871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2011/04/watch-that-autowired.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/2429894919383667871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/2429894919383667871'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2011/04/watch-that-autowired.html' title='Watch that @Autowired'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-658016889162095893</id><published>2010-12-26T17:06:00.011+01:00</published><updated>2010-12-27T16:18:15.045+01:00</updated><title type='text'>Maven Surefire 2.7.1</title><content type='html'>Todays release of surefire 2.7.1 is an important milestone for me. Lets start out with what the 2.7 series has to offer&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Multiple run-orders for tests now supported&lt;br /&gt;The runOrder attribute lets you specify alphabetical, reversealphabetical, random, hourly (alphabetical on even hours, reverse alphabetical on odd hours) and filesystem. Odd/Even for hourly is determined at the time the of scanning the classpath, meaning it could change during a multi-module build.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Faster, smaller&lt;br /&gt;About 1/3 of the total download size of 2.6. I get quite a lot of feedback saying it's significantly faster too; your mileage will vary.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Parallel JUnit&lt;br /&gt;Surefire is now totally self-contained and no longer uses ConfigurableParallelComputer for anything. Real execution times per test are also reported. It won't get much better than this.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Severe memory/resource leak fixed for those of you who have console output.&lt;br /&gt;The more your tests were writing to stdout/stderr, the worse the problem was. This one has been here since 2.4 ;)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Pluggable/Selectable providers&lt;br /&gt;Surefire is a framework for forking and reporting with a few additional features, such  as directory scanning services. Until 2.7, this has all been wired together in one monolithic slab of code with test-providers ( TestNG, junit3/4/4.7) seemingly independent but in reality all welded together by massive dependencies and strange divisions of labor. No more. 2.7.X makes it possible to write your own providers. Best of all there's really not much work you need to do to create one.&lt;br /&gt;Need a "fork every 20 tests" provider? Fork one of the existing ones and make it yourself on github, probably in less than an hour. This also means we will be closing some of the more exotic requests as won't fix, since you can just do it yourself.&lt;br /&gt;Read about it &lt;a href="http://maven.apache.org/plugins/maven-surefire-plugin/examples/providers.html"&gt;here&lt;/a&gt; and &lt;a href="http://maven.apache.org/plugins/maven-surefire-plugin/api.html"&gt;here for the api&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;JDK 1.3 fork-compatibility restored.&lt;br /&gt;I ended up doing this just for the sheer heck of it; kind of a challenge. Pardon the language.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;There's &lt;a href="http://www.mail-archive.com/users@maven.apache.org/msg115334.html"&gt;other issues&lt;/a&gt; fixed &lt;a href="http://maven.40175.n5.nabble.com/ANN-Maven-Surefire-Plugin-2-7-1-Released-td3318695.html"&gt;too&lt;/a&gt;, but these are the highlights.&lt;br /&gt;&lt;br /&gt;* Why ?&lt;br /&gt;I started programming on my C64 when I was 13 and I've been coding passionately ever since. I went to university and when I finished developing software became my day job. And although I keep my code clean, professional software development is also a lot about making deliveries with trade-offs and sometimes compromises. And we move on. If it doesn't come back to haunt us, it was probably good enough - no matter how frustrated you felt when making it.&lt;br /&gt;&lt;br /&gt;Not so with my Open Source work. There I will only do stuff that somehow is the most excellent work I am capable of. It's the hobbyist computing returned, but my capacity is oh so infinitely different from when I was a teenager. Several OSS companies have offered me jobs, which I have turned down. If I was to take that I somehow feel I'd be taking the hobby as work once more.&lt;br /&gt;&lt;br /&gt;So how does all of this relate to surefire? Until recently, surefire has been real messy code. While the basic design contains some interesting and pretty sophisticated stuff, it was basically a big mess. Huge classes with 400 line long methods is the trending topic. It was code without any discernible shape or form; mutable state mutating at every opportunity. All this mostly due to different people working on it at different points in time.&lt;br /&gt;&lt;br /&gt;I've seen this happen, even with the best of people working together, and I will not dwell further as to the reasons for this. But I love working with the structure of code, and I think programming is communication; me talking to you - disconnected in time and space.&lt;br /&gt;&lt;br /&gt;So I refactor. And I think. Sometimes I can think about a change for a week, code it in few hours only to realize it was wrong and throw it all away. Sometimes I can discover midway that there is a more important angle on solving the problem; something totally different is more important and will have bigger impact on future change. And I just stash away everything and do The Thing I Now Know Is Right. Repeat until satisifed.&lt;br /&gt;&lt;br /&gt;I spent months of spare time working with surefire 2.7 this way. I think the results are pretty amazing; the plugin is basically transformed into clean code. Every year around Christmas time, I tend to bring &lt;a href="http://www.amazon.com/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X"&gt;this book&lt;/a&gt; to the fireplace. It's still one of the most amazing books written about how to think code. Kent has rewritten this book for Java several times, but I still recommend the Smalltalk version - even if you never programmed smalltalk. And take a look at surefire trunk. There's still work to do. Make a patch. Merry xmas.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-658016889162095893?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/658016889162095893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2010/12/maven-surefire-271.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/658016889162095893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/658016889162095893'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2010/12/maven-surefire-271.html' title='Maven Surefire 2.7.1'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-2325463145784138675</id><published>2010-02-19T09:11:00.007+01:00</published><updated>2010-02-20T20:36:31.943+01:00</updated><title type='text'>Concurrency in maven ?</title><content type='html'>Within the maven community, there has been a push towards parallelizing maven itself&lt;br /&gt;to achieve better build performance within multi-module reactor builds. A number of strategies have been tried, and the main two strategies are: Parallel reactor mode (uses module dependency graph to schedule builds that can be built in concurrently side-by side). The other strategy is known as "weave" mode, and it traverses the modules phase-by-phase instead of module-by module (you can read about it &lt;a href="http://docs.codehaus.org/display/MAVENUSER/Weave+mode+characteristics"&gt;here&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Both have "fully" functional implementations available, and weave mode is quite a lot  faster than parallel mode. The code is available at http://github.com/krosenvold/maven3. Just build and run with -Dmaven.threads.experimental=4&lt;br /&gt;&lt;br /&gt;So what is this post about ? I am the primary author of "weave" mode, and for the last weeks I've been searching for an elusive goal: 1000 consecutive green builds of 1 single project on my CI environment.&lt;br /&gt;&lt;br /&gt;Initially I was quite afraid of the thread safety issues withing maven; after all retromounting concurrency to any non-concurrent code can be a daunting task. Fortunately there is a lot of state that is /copied/ in maven reactor mode. From a concurrency perspective, this saves the day. &lt;br /&gt;&lt;br /&gt;So why am I not getting my 1000 greens ? Every 3-400 builds it would fail, with strange errors. I asked a &lt;a href="http://stackoverflow.com/questions/2280651/what-is-the-javac-java-file-system-concurrency-contract/2287734#2287734"&gt;few questions&lt;/a&gt; (and &lt;a href="http://stackoverflow.com/questions/2292764/what-concurrency-works-with-the-java-file-system"&gt;this one&lt;/a&gt;) on stackoverflow.com. It's the file system. The java file system &lt;br /&gt;has &lt;span style="font-style:italic;"&gt;no&lt;/span&gt; guarantees of /anything/ when it comes to concurrency. The only thing you can be sure about is that the single thread that wrote the file can also read it afterwards.&lt;br /&gt;&lt;br /&gt;javac uses the file system. And I was quite baffled by this; in weave mode the javacs are invoked on a pretty tight schedule; they typically come within just a few ms of each other. Every now and then the downstream javac would complain about "bad class files" from the upstream javac. But the scheduling is done properly, and the first javac /was/ done.  How to solve it ? Turn on "forkMode" in maven for javac.&lt;br /&gt;&lt;br /&gt;I had a chat with the nice folks at #kernel and they told me that all contents of a file should be concurrently visible to /everyone/ upon close() in a modern linux kernel. When I turned on forkMode in javac the problem went away. Because forkMode=true basically delegates the visibility issues to the os. &lt;br /&gt;&lt;br /&gt;You /can/ try this yourself if you check out from github and try to build a project. It works best if you do a "mvn -Dmaven.threads.experimental=4 clean install", since that'll write a lot of files.&lt;br /&gt;&lt;br /&gt;I'm still scratching my head about what to do with this; given that forking delegates visibility to the underlying os one could just fork everything all the time. Or find some other option.. Suggestions ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-2325463145784138675?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/2325463145784138675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2010/02/concurrency-in-maven.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/2325463145784138675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/2325463145784138675'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2010/02/concurrency-in-maven.html' title='Concurrency in maven ?'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-1765045644691707344</id><published>2010-01-14T09:58:00.024+01:00</published><updated>2010-01-28T15:16:34.208+01:00</updated><title type='text'>Run your junit tests concurrently with maven, junit (and maybe also spring3) in 5 minutes or less!</title><content type='html'>Surefire 2.5 is released, and it contains the concurrent junit patches. In this post I'll give the quick rundown of how to try out your current maven based build in a concurrent fashion. Just a few initial thoughts:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Will my tests run concurrently ?&lt;/h2&gt;&lt;br /&gt;Probably not, as is. Most existing test fixtures that people use have singletons and shared state that needs to be fixed first. This may be everything from a shared file, shared TCP/IP port or a static member variable in some base class that can't be static any more.&lt;br /&gt;&lt;br /&gt;It took me about a day to fix these things in my current project. My project is large and complex. using all sorts of dark spring magics. Your mileage may vary.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;What performance gain can I expect ?&lt;/h2&gt;&lt;br /&gt;For an IO-bound test (integration test/selenium test etc), the sky's the limit ;)&lt;br /&gt;&lt;br /&gt;For a fairly optimized unit-test set, expect little or no gain - maybe 15-20%. &lt;br /&gt;The reason for this is that until jdk7, all classloading and all classpath bound resource access is synchronized across the VM. Running unit tests is &lt;em&gt;mostly&lt;/em&gt; about classloading and classpath resources :( If your unit-tests have other kinds of I/O bindings you may be luckier.&lt;br /&gt;&lt;br /&gt;If you're using spring inside your test fixtures (like we do), you can probably squeeze a few drops of speed out of it by making lazy-init==true globally. You're going to test it all anyway, right ?&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;How to do it!&lt;/h2&gt;&lt;br /&gt;Make sure you upgrade to surefire-2.5:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; &amp;lt;plugin&gt;&lt;br /&gt;     &amp;lt;groupId&gt;org.apache.maven.plugins&amp;lt;/groupId&gt; &lt;br /&gt;     &amp;lt;artifactId&gt;maven-surefire-plugin&amp;lt;/artifactId&gt;&lt;br /&gt;     &amp;lt;version&gt;2.5&amp;lt;/version&gt;&lt;br /&gt; &amp;lt;/plugin&gt;&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Make sure you upgrade to junit 4.8.1 (still not in maven central repo, install locally):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; &amp;lt;dependency&gt;&lt;br /&gt;     &amp;lt;groupId&gt;junit&amp;lt;/groupId&gt;&lt;br /&gt;     &amp;lt;artifactId&gt;junit&amp;lt;/artifactId&gt;&lt;br /&gt;     &amp;lt;version&gt;4.8.1&amp;lt;/version&gt;&lt;br /&gt;     &amp;lt;scope&gt;test&amp;lt;/scope&gt;&lt;br /&gt;  &amp;lt;/dependency&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(You /can/ use 4.7 but it still has a couple of concurrency bugs in it that were fixed in 4.8.1)&lt;br /&gt;&lt;br /&gt;Fix your surefire configuration:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &amp;lt;plugin&gt;&lt;br /&gt;      &amp;lt;groupId&gt;org.apache.maven.plugins&amp;lt;/groupId&gt;&lt;br /&gt;      &amp;lt;artifactId&gt;maven-surefire-plugin&amp;lt;/artifactId&gt;&lt;br /&gt;      &amp;lt;configuration&gt;&lt;br /&gt;          ....&lt;br /&gt;          &amp;lt;parallel&gt;classes&amp;lt;/parallel&gt;&lt;br /&gt;      &amp;lt;/configuration&gt;&lt;br /&gt;  &amp;lt;/plugin&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Legal values for parallel are "classes, methods or both". Now you can run, but you should probably read the rest of this post first...&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Classes, methods or both ?&lt;/h2&gt;&lt;br /&gt;From a concurrency perspective, "classes" is probably the easiest to start with, since it will probably run into the smallest number of troubles in your test fixtures.  I really recommend you try to get both working, since you'll probably need to identify any additional issues raised by using "methods". You want a test-suite you can trust, right ?&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The fine print&lt;/h2&gt;&lt;br /&gt;One drawback of the current default concurrency implementation in junit is that it does not allow you to constrain threads, which is desirable for almost all use cases I am aware of. But junit is extendable, and I have made a supplemental add-on that allows threads to be configured too. Surefire knows to invoke this one if it's present on your classpath, meaning you'll get additional options available:&lt;br /&gt;&lt;br /&gt;The configurable-parallel-computer still has a few issues that are unsolved, so you&lt;br /&gt;may consider dropping by the &lt;a href="http://github.com/krosenvold/configurable-parallel-computer/issues"&gt;issue tracker to check if these will bother you before adding it to your project&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;git clone http://github.com/krosenvold/configurable-parallel-computer.git&lt;br /&gt;cd configurable-parallel-computer&lt;br /&gt;mvn install&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &amp;lt;dependency&gt;&lt;br /&gt;     &amp;lt;groupId&gt;org.jdogma.junit&amp;lt;/groupId&gt;&lt;br /&gt;     &amp;lt;artifactId&gt;configurable-parallel-computer&amp;lt;/artifactId&gt;&lt;br /&gt;     &amp;lt;version&gt;1.5&amp;lt;/version&gt;&lt;br /&gt;     &amp;lt;scope&gt;test&amp;lt;/scope&gt;&lt;br /&gt;  &amp;lt;/dependency&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &amp;lt;plugin&gt;&lt;br /&gt;      &amp;lt;groupId&gt;org.apache.maven.plugins&amp;lt;/groupId&gt;&lt;br /&gt;      &amp;lt;artifactId&gt;maven-surefire-plugin&amp;lt;/artifactId&gt;&lt;br /&gt;      &amp;lt;configuration&gt;&lt;br /&gt;          ....&lt;br /&gt;          &amp;lt;parallel&gt;classes&amp;lt;/parallel&gt;&lt;br /&gt;          &amp;lt;threadCount&gt;2&amp;lt;/threadCount&gt;&lt;br /&gt;      &amp;lt;/configuration&gt;&lt;br /&gt;  &amp;lt;/plugin&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can also use the setting "perCoreThreadCount", which scales threadcount per CPU core.&lt;br /&gt;&lt;br /&gt;The configurable-parallel-computer project also contains a better output demultiplexer than the one in surefire (which has a ketchup-bottle behaviour). Surefire knows about this one too, so adding configurable-parallel-computer to your classpath will give you smooth project output. I'm sure we'll get the improved version into surefire at some later time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Spring&lt;/h2&gt;&lt;br /&gt;If you're using spring you need to use a forked version of spring-test. The patch I submitted to spring is targeted for 3.1, whatever that may mean in practice:&lt;br /&gt;&lt;br /&gt;git clone http://github.com/krosenvold/org.springframework.test.git &lt;br /&gt;cd org.springframework.test&lt;br /&gt;mvn install&lt;br /&gt;&lt;br /&gt;You need to replace your dependency on "spring-test" to the forked version:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;dependency&gt;&lt;br /&gt;   &amp;lt;groupId&gt;org.rosenvold.springframework&amp;lt;/groupId&gt;&lt;br /&gt;   &amp;lt;artifactId&gt;spring-test&amp;lt;/artifactId&gt;&lt;br /&gt;   &amp;lt;version&gt;3.0.0.RELEASE&amp;lt;/version&gt;&lt;br /&gt;   &amp;lt;scope&gt;test&amp;lt;/scope&gt;&lt;br /&gt;&amp;lt;/dependency&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Remember to also suppress the transitively dependent spring-test artifacts, like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;dependency&gt;&lt;br /&gt;  &amp;lt;groupId&gt;org.springframework&amp;lt;/groupId&gt;&lt;br /&gt;  &amp;lt;artifactId&gt;spring-aspects&amp;lt;/artifactId&gt;&lt;br /&gt;  &amp;lt;version&gt;3.0.0.RELEASE&amp;lt;/version&gt;&lt;br /&gt;  &amp;lt;exclusions&gt;&lt;br /&gt;     &amp;lt;exclusion&gt;&lt;br /&gt;          &amp;lt;groupId&gt;org.springframework&amp;lt;/groupId&gt;&lt;br /&gt;          &amp;lt;artifactId&gt;spring-test&amp;lt;/artifactId&gt;&lt;br /&gt;     &amp;lt;/exclusion&gt;&lt;br /&gt;  &amp;lt;/exclusions&gt;&lt;br /&gt;&amp;lt;/dependency&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Make sure mvn dependency:tree does not contain the spring version of spring-test. Any inclusion of the 3.0 artifact WILL get you into trouble.&lt;br /&gt;&lt;br /&gt;If you're using a Mock Session Scope based on the Spring Session Scope (with a custom ContextLoader), you need to make sure you override the synchronized methods in the base class with your own implementations, or your tests may deadlock on the session scope. This is a real bug in spring, but one that probably does not occur to often in real-life scenarios; but quite a lot when running concurrent tests.&lt;br /&gt;&lt;br /&gt;Off you go !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-1765045644691707344?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/1765045644691707344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2010/01/run-your-junit-tests-concurrently-with.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/1765045644691707344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/1765045644691707344'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2010/01/run-your-junit-tests-concurrently-with.html' title='Run your junit tests concurrently with maven, junit (and maybe also spring3) in 5 minutes or less!'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-4381278544586957729</id><published>2009-10-05T12:43:00.004+02:00</published><updated>2009-10-06T06:22:03.296+02:00</updated><title type='text'>Concurrent junit with maven and spring3 updated for RC1</title><content type='html'>To celebrate the release of spring rc1, I have updated the patches and the procedure for building custom versions of junit, surefire and spring3. Spring had about 500 commits since I created the initial patchset, and they were no longer applying cleanly.&lt;br /&gt;&lt;br /&gt;The instructions in my original blogpost now reflect the revised procedure, and in about 20 minutes you can have it all up &amp; running. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The original instructions can be found &lt;a href="http://incodewetrustinc.blogspot.com/2009/07/run-your-junit-tests-in-parallel-with.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-4381278544586957729?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/4381278544586957729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2009/10/concurrent-junit-with-maven-and-spring3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/4381278544586957729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/4381278544586957729'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2009/10/concurrent-junit-with-maven-and-spring3.html' title='Concurrent junit with maven and spring3 updated for RC1'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-6185762158380001574</id><published>2009-10-05T10:06:00.007+02:00</published><updated>2009-10-05T11:16:16.013+02:00</updated><title type='text'>Memo to self: How to patch an open source CVS/SVN project with GIT</title><content type='html'>Most CVS/SVN open source projects will prefer patches to be submitted as follows:&lt;br /&gt;&lt;br /&gt;1. First patch contains a failing test&lt;br /&gt;2. Second patch contains bugfix/improvement and possibly additional testcases and maybe also changes to the initial failing test case&lt;br /&gt;&lt;br /&gt;The smart way to do this with git is as follows:&lt;br /&gt;&lt;br /&gt;1. Clone project, if it's a SVN project use github's git-svn import (*much* perferred to using git svn clone yourself)&lt;br /&gt;2. Create an initial feature branch &lt;span style="font-weight:bold;"&gt;masterForGit&lt;/span&gt;, where you add stuff that is nice for working this project in a git environment; typically a .gitignore file and any local scripts you need to be able to work with the project. Make sure this project compiles well and does not add unwanted files to git before proceeding (git does not handle empty directories same way as svn so you may need to correct this in this branch)&lt;br /&gt;3. Create a feature branch &lt;span style="font-weight:bold;"&gt;failingTest&lt;/span&gt; based on &lt;span style="font-weight:bold;"&gt;masterForGit&lt;/span&gt;. In this branch you create the original failing &lt;br /&gt;test what will be submitted as proof.&lt;br /&gt;4. Create a feature branch &lt;span style="font-weight:bold;"&gt;bugFix&lt;/span&gt; that is branched off &lt;span style="font-weight:bold;"&gt;failingTest&lt;/span&gt;. In this branch you fix the bug and add any subsequent test cases.&lt;br /&gt;5. When you're all done, you typically do diff between &lt;span style="font-weight:bold;"&gt;failingTest&lt;/span&gt; and &lt;span style="font-weight:bold;"&gt;masterForGit&lt;/span&gt; to get the patch file for "proof" bug. Then you diff &lt;span style="font-weight:bold;"&gt;bugFix&lt;/span&gt; and &lt;span style="font-weight:bold;"&gt;failingTest&lt;/span&gt; to get fix-patch. Since you created the "masterForGit" branch initially, none of the patches get polluted with temp-stuff you did locally.&lt;br /&gt;&lt;br /&gt;And, if you end up maintaining this patchset, you can just update from svn through github and merge through all of your branches. Easy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-6185762158380001574?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/6185762158380001574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2009/10/memo-to-self-how-to-patch-open-source.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/6185762158380001574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/6185762158380001574'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2009/10/memo-to-self-how-to-patch-open-source.html' title='Memo to self: How to patch an open source CVS/SVN project with GIT'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-3270966034671668031</id><published>2009-10-01T21:49:00.006+02:00</published><updated>2009-10-01T21:59:19.107+02:00</updated><title type='text'>Status of concurrency patches</title><content type='html'>AspectJ 1.6.6 is released and contains the patch I submitted there. 1 patch down.&lt;br /&gt;&lt;br /&gt;The main patch for spring is scheduled for release 3.1. The patch no longer applies cleanly, but I will be updating it fairly soon, probably some time over the weekend. I may also try to publish a forked org.springframework.test to some maven repo by the time 3.0 goes release.&lt;br /&gt;&lt;br /&gt;Surefire is another story. I am not sure anyone is actively maintaining this plugin any more. Anyone know any committers ? I have been considering forking the surefire plugin permanently and remove cruft, it sure has a lot of it.&lt;br /&gt;&lt;br /&gt;As for the patches to junit itself they are submitted but still not accepted. There may be possible workarounds for this that I'll can consider when I revise the patches.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-3270966034671668031?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/3270966034671668031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2009/10/status-of-concurrency-patches.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/3270966034671668031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/3270966034671668031'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2009/10/status-of-concurrency-patches.html' title='Status of concurrency patches'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-5867651663565541179</id><published>2009-07-05T13:17:00.003+02:00</published><updated>2009-07-05T13:29:23.558+02:00</updated><title type='text'>Are four cores required to surpass one ?</title><content type='html'>My recent post about running unit tests in parallel has led to some interesting food for thought:&lt;br /&gt;&lt;br /&gt;When running regular unit tests, running with 2 cores seems to be no faster than one core. 4 cores (and arguably a newer CPU architecture) had a significant impact, where performance nearly doubled. The hyperthreaded quad-core i7 920 was *slower* than a 3Ghz core 2 duo when running single threaded, but nearly twice as fast in a multithreaded scenario. What's happening ?&lt;br /&gt;&lt;br /&gt;I looked into the issue with jprofiler, but there is no obvious lock contention or other clearly visible bottleneck. The only explanation I can think of so far is this:&lt;br /&gt;&lt;br /&gt;The test I was running was extremely simplistic, and there was no real cpu requirement in running the test methods. So the overhead of creating thread pools and all that actually amounts to just as much computation as running the tests. Likely ? &lt;br /&gt;&lt;br /&gt;After my summer vacation, I will try to find out. I probably need to run with more realistic test cases. I figured I'd build surefire with threads, because thats a fairly heavy build. In the mean time, your thoughts are welcome.&lt;br /&gt;&lt;br /&gt;From legoland,&lt;br /&gt;&lt;br /&gt;Kristian&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-5867651663565541179?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/5867651663565541179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2009/07/are-four-cores-required-to-surpass-one.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/5867651663565541179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/5867651663565541179'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2009/07/are-four-cores-required-to-surpass-one.html' title='Are four cores required to surpass one ?'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-1252912558182964763</id><published>2009-07-01T12:42:00.085+02:00</published><updated>2010-01-17T22:24:21.450+01:00</updated><title type='text'>Run your junit tests in parallel (with spring 3.0 and maven)</title><content type='html'>&lt;h2&gt;Swimming in a sea of patches...&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Note; Most of the content in this post has been surpassed by &lt;a href="http://incodewetrustinc.blogspot.com/2010/01/run-your-junit-tests-concurrently-with.html"&gt;a newer entry&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you're willing to apply a few patches, you can now run your junit tests in parallel. There are two main use-cases for this; one is to make your regular unit tests run faster, the other is for io-bound tests, where you want to run several in parallel because you're waiting for external systems.&lt;br /&gt;&lt;br /&gt;Just to whet your appetite, here are some numbers from a testcase (running 1000 instances of a simple unit-test-class):&lt;br /&gt;&lt;br /&gt;Legend:&lt;br /&gt;SC = SingleThreadedComputer (Computer, Junit47-snapshot class)&lt;br /&gt;PC = ParallelComputer (ParallelComputer, Junit4.7-snapshot class)&lt;br /&gt;CPC = ConfigurableParallelComputer (My project, see references)&lt;br /&gt;C=Classes (one thread per class)&lt;br /&gt;M=Methods (one thread per method)&lt;br /&gt;&lt;table border="1" cellpadding="4" cellspacing="0"&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;td&gt;Core 2 duo 3.14Ghz&lt;/td&gt;&lt;br /&gt;&lt;td&gt;Intel i7 920&lt;/td&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;SC&lt;/td&gt;&lt;br /&gt;&lt;td&gt;203&lt;/td&gt;&lt;br /&gt;&lt;td&gt;451&lt;/td&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;PC(Classes, Method, Unlimited threads)&lt;/td&gt;&lt;br /&gt;&lt;td&gt;406&lt;/td&gt;&lt;br /&gt;&lt;td&gt;806&lt;/td&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;CPC(Methods,16 threads)&lt;/td&gt;&lt;br /&gt;&lt;td&gt;218&lt;/td&gt;&lt;br /&gt;&lt;td&gt;214&lt;/td&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;CPC(Classes, Unlimited threads)&lt;/td&gt;&lt;br /&gt;&lt;td&gt;203&lt;/td&gt;&lt;br /&gt;&lt;td&gt;116&lt;/td&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;CPC(Classes,Methods, Unlimited threads)&lt;/td&gt;&lt;br /&gt;&lt;td&gt;266&lt;/td&gt;&lt;br /&gt;&lt;td&gt;147&lt;/td&gt;&lt;br /&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;b&gt;Running time in ms, 1000 simple tests&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The table shows that for most dual-core solutions, running with parallel threads is currently never any faster than running non-threaded. Switching to the brand-new Intel i7 (4 hyperthreaded cores) has a marked effect, where simple unit test performance is doubled.&lt;br /&gt;&lt;br /&gt;The lack of punch does, of course, change the moment your tests start doing IO (Integration tests, selenium tests and other web-tests).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The juicy stuff&lt;/b&gt;&lt;br /&gt;svn co https://svn.openqa.org/svn/selenium-rc&lt;br /&gt;&lt;br /&gt;Second build with mvn clean install: 102 seconds.&lt;br /&gt;With 80 threads class-parallel on the i7: 37 seconds.&lt;br /&gt;&lt;br /&gt;Class-parallel works easily on most tests.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;A sea of patches&lt;/h2&gt;&lt;br /&gt;Getting all of this to work was not without its problems, though. To get this running, I had to patch just about half the libraries in use in my current stack. Furthermore, there's a huge difference between getting it to run and getting it to run without hiccups - every time. These patches insure that your infrastructure works as it should, but are your tests concurrent ?&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Patches involved&lt;/h2&gt;&lt;br /&gt;See below for how to apply these patches in a simple manner.&lt;br /&gt;Spring (3.0 trunk):&lt;br /&gt;&lt;a href="http://jira.springframework.org/browse/SPR-5863"&gt;http://jira.springframework.org/browse/SPR-5863&lt;/a&gt;&lt;br /&gt;AspectJ: Patch trunk with this patch (if using spring) &lt;span style="font-weight:bold;"&gt;(This patch is included in version 1.6.6)&lt;/span&gt;&lt;br /&gt;&lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281654"&gt;https://bugs.eclipse.org/bugs/show_bug.cgi?id=281654&lt;/a&gt;&lt;br /&gt;Junit4.7:&lt;br /&gt;Several patches needed for thread safety:&lt;br /&gt;&lt;a href="http://github.com/KentBeck/junit/issues#issue/16"&gt;http://github.com/KentBeck/junit/issues#issue/16&lt;/a&gt;&lt;br /&gt;&lt;a href="http://github.com/KentBeck/junit/issues#issue/18"&gt;http://github.com/KentBeck/junit/issues#issue/18&lt;/a&gt;&lt;br /&gt;Maven: You need a patched version of surefire that supports junit 4.7:&lt;br /&gt;&lt;a href="http://jira.codehaus.org/browse/SUREFIRE-555"&gt;http://jira.codehaus.org/browse/SUREFIRE-555&lt;/a&gt;&lt;br /&gt;You'll also probably want to be using the ConfigurableParallelComputer instead of the ParallelComputer that's included with JUnit.&lt;br /&gt;&lt;a href="git://github.com/krosenvold/configurable-parallel-computer.git"&gt;git://github.com/krosenvold/configurable-parallel-computer.git&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;With these patches in place you're smooth sailing ;)&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Applying the patches&lt;/h2&gt;&lt;br /&gt;Note: If you did this on the pre rc1 version of this patchset, I recommend that you start from a fresh copy of everything this time.&lt;br /&gt;If you're using maven you could try this sequence:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;git clone git://github.com/krosenvold/spring-framework-concurrent-junit-patch.git&lt;br /&gt;git clone git://github.com/krosenvold/junit.git&lt;br /&gt;git clone git://github.com/krosenvold/configurable-parallel-computer.git&lt;br /&gt;git clone git://github.com/krosenvold/spring-test.git&lt;br /&gt;git clone git://github.com/krosenvold/spring-concurrency-test.git&lt;br /&gt;cd junit&lt;br /&gt;ant&lt;br /&gt;cd ../spring-framework-concurrent-junit-patch&lt;br /&gt;./installJunit&lt;br /&gt;cd ../spring-test&lt;br /&gt;mvn install&lt;br /&gt;cd ../configurable-parallel-computer&lt;br /&gt;mvn install&lt;br /&gt;cd ../spring-framework-concurrent-junit-patch&lt;br /&gt;./checkoutSurefire&lt;br /&gt;./buildSureFire&lt;br /&gt;./applySureFirePatch&lt;br /&gt;./buildSureFire&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd ../spring-concurrency-test&lt;br /&gt;mvn install # Test project to verify that everything is ok&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Your new versions&lt;/h2&gt;&lt;br /&gt;JUnit should be modified to 4.7-CONCURRENT&lt;br /&gt;spring-test should have version number 3.0.0.RC1-CONCURRENT&lt;br /&gt;Surefire should be modified to 2.5-SNAPSHOT&lt;br /&gt;&lt;b&gt;You must update your aspectj version to 1.6.6 in your project. Spring does a transitive &lt;br /&gt;include on 1.6.5&lt;/b&gt;&lt;br /&gt;You can see the version number for the spring artifacts when building spring. Probably something like 3.0.0.BUILD-20091005102426 &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Maven surefire settings&lt;/h2&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;          &amp;lt;plugin&gt;&lt;br /&gt;              &amp;lt;artifactid&gt;maven-surefire-plugin&amp;lt;/artifactid&gt;&lt;br /&gt;              &amp;lt;version&gt;2.5-SNAPSHOT&amp;lt;/version&gt;&lt;br /&gt;              &amp;lt;configuration&gt;&lt;br /&gt;                  &amp;lt;parallel&gt;classes&amp;lt;/parallel&gt;&lt;br /&gt;                  &amp;lt;useUnlimitedThreads&gt;true&amp;lt;/useUnlimitedThreads&gt;&lt;br /&gt;                  &amp;lt;threadCount&gt;80&amp;lt;/threadCount&gt;&lt;br /&gt;                  &amp;lt;perCoreThreadCount&gt;true&amp;lt;/perCoreThreadCount&gt;&lt;br /&gt;              &amp;lt;/configuration&gt;&lt;br /&gt;          &amp;lt;/plugin&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;UnlimitedThreads knocks out threadCount and perCoreThreadCount.&lt;br /&gt;&lt;br /&gt;Look at the various "install" scripts to see the version numbers of the artifacts.&lt;br /&gt;Simple, eh ?&lt;br /&gt;&lt;br /&gt;And while we're at it: Half of the work with patching these projects has been about fighting with version control systems and custom made build scripts. So please; switch to GIT and maven: I can build any maven project without reading as much as a readme file. Maven allows me as a casual bystander to *easily* make contributions; I never need to read that 4 page "how to build" manual! Git is the only version control tool that respects my right/duty to patch, change and upgrade other projects. It allows me to do all these things without having to *ask* anyone. Repeat after me: Git and maven encourages free collaboration; a key idea of open source, right ?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://twitter.com/krosenvold"&gt;http://twitter.com/krosenvold&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-1252912558182964763?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/1252912558182964763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2009/07/run-your-junit-tests-in-parallel-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/1252912558182964763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/1252912558182964763'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2009/07/run-your-junit-tests-in-parallel-with.html' title='Run your junit tests in parallel (with spring 3.0 and maven)'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-6397286065671456901</id><published>2008-10-09T20:21:00.006+02:00</published><updated>2008-10-09T23:01:54.364+02:00</updated><title type='text'>Using ajax transaction counts in selenium tests</title><content type='html'>Sometimes your "only hope" in making a selenium web test stable is to keep track of the number of ajax requests that have happened on the client side.&lt;br /&gt;&lt;br /&gt;An example of this is the ajax request that normally returns exactly the same html as was present in the dom before the request. Although this may sound stupid, there are legitimate situations for this.&lt;br /&gt;&lt;br /&gt;My test would look like this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt; int transactionNumer = selenium.getCurrentAjaxTransactionNumber();&lt;br /&gt; selenium.clickLink("SomeLink");&lt;br /&gt; selenium.waitForAjaxTransactionNumberChange(transactionNumer);&lt;br /&gt;-- rest of test ---&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This test is free from timing issues, because it will not  proceed to the rest of the test before the ajax request is completed.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public int getCurentAjaxTransactionNumber() {&lt;br /&gt;    String eval = selenium.getEval("window.ajaxRequestNumber");&lt;br /&gt;    return Integer.parseInt( eval);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In my ajax.js file, which wraps prototype, I will typically include two lines like this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;window.ajaxRequestNumber = 0;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now you will have to find a way to patch into your ajax framework to update this value. For prototype, this would work:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Ajax.Responders.register({&lt;br /&gt; onComplete: function() {&lt;br /&gt;   window.ajaxRequestNumber++;&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now you can track request numbers, and yes - they start with value 0 on page load.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-6397286065671456901?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/6397286065671456901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2008/10/using-ajax-transaction-counts-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/6397286065671456901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/6397286065671456901'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2008/10/using-ajax-transaction-counts-in.html' title='Using ajax transaction counts in selenium tests'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1149178966400721843.post-6843306638584945563</id><published>2008-06-11T09:21:00.000+02:00</published><updated>2008-06-11T11:11:00.594+02:00</updated><title type='text'>Detecting javascript errors with selenium</title><content type='html'>I've only found out how to do this by including a few javascript functions that get included in the code. I have made no attempt to remove this from production code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;window.onerror = function(){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    if (sessionStorage){ // Mozilla only&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        var cnt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        if (sessionStorage.errcnt){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            cnt = parseInt(sessionStorage.errcnt);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        } else {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            cnt = 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        cnt++;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        sessionStorage.errcnt = cnt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    return false;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;function hadJavaScriptError(){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    if (sessionStorage){ // Mozilla only&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        if (sessionStorage.errcnt){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            delete sessionStorage.errcnt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            return true;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    return false;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Somewhere in your selenium test you can put this check:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;String hadJserror = getSelenium().getEval("window.hadJavaScriptError()");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;assertFalse("Page had a javascript error, this error has occured somewhere during the test.", Boolean.parseBoolean(hadJserror));&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've put this straight after a common waitForPageToLoad function that we are using, please note that if you do so, it must be &lt;span style="font-style:italic;"&gt;after &lt;/span&gt;the call to waitForPageToLoad.&lt;br /&gt;&lt;br /&gt;Note that the javascript code uses mozilla session store (and probably IE8) to actually keep a persistent count of javascript errors. I'm sure some "userData" for IE could be used for older IE versions&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1149178966400721843-6843306638584945563?l=incodewetrustinc.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://incodewetrustinc.blogspot.com/feeds/6843306638584945563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://incodewetrustinc.blogspot.com/2008/06/detecting-javascript-errors-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/6843306638584945563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1149178966400721843/posts/default/6843306638584945563'/><link rel='alternate' type='text/html' href='http://incodewetrustinc.blogspot.com/2008/06/detecting-javascript-errors-with.html' title='Detecting javascript errors with selenium'/><author><name>Kristian Rosenvold</name><uri>http://www.blogger.com/profile/04391691189663382144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_-zRRsjtD5W0/SNOohsYXevI/AAAAAAAAAAM/SVYGYw_sSxc/S220/litePortrett.gif'/></author><thr:total>0</thr:total></entry></feed>
