<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='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' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-8795604888160975763</atom:id><lastBuildDate>Mon, 21 May 2012 14:26:54 +0000</lastBuildDate><category>hibernate</category><category>agilece</category><category>TDD</category><category>RFP</category><category>agile</category><category>java</category><category>git</category><category>wicket</category><category>h2</category><category>spring</category><category>craftsmanship</category><category>conference</category><category>bash</category><category>presentation</category><title>Solid Craft</title><description>fighting chaos in the Dark Age of Technology</description><link>http://blog.solidcraft.eu/</link><managingEditor>noreply@blogger.com (Jakub Nabrdalik)</managingEditor><generator>Blogger</generator><openSearch:totalResults>39</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-7839730142167059836</guid><pubDate>Mon, 21 May 2012 14:26:00 +0000</pubDate><atom:updated>2012-05-21T16:26:54.044+02:00</atom:updated><title>GeeCON 2012 review</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-PurR5QM-D8M/T7pNEbIsjjI/AAAAAAAADVE/IRHvBdQmVCs/s1600/_1010536.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="150" src="http://2.bp.blogspot.com/-PurR5QM-D8M/T7pNEbIsjjI/AAAAAAAADVE/IRHvBdQmVCs/s200/_1010536.jpg" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Bruce Almighty!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;a href="http://2012.geecon.org/"&gt;GeeCON 2012&lt;/a&gt; is over. This year I've decided to go for 3 days, where the first one was a „University day”, and the other two were regular conference days. „University day” is a misleading name, you'd think it's something for students, for beginners perhaps. The idea, as far as I know, was to have a day full of workshops, but as there was just one bring-your-own-laptop TDD workshop, it turned out to be a „normal” conference day, with 2h talks.&lt;br /&gt;
&lt;br /&gt;
Now, „normal” doesn't mean bad. Quite the opposite.&lt;br /&gt;
&lt;br /&gt;
As usually, this is my little review of the conference. Take into account, that with up to 5 parallel tracks, I've seen no more than 25% of the whole event.&lt;br /&gt;
&lt;br /&gt;
Wojtek Erbetowski, pointed out, that as we gain knowledge, it's getting harder and harder to find something amazing at a conference. I was overwhelmed with new knowledge, the first time I went to one, but since I try to keep up to date, since I visit up to six conferences every year, and since speakers tend to give the same talks all over the country, I consider a conference fruitful if I take one thing that can help me in a substantial way.&lt;br /&gt;
&lt;br /&gt;
I'm happy to report, that it was the case with GeeCON.&lt;br /&gt;
&lt;br /&gt;
University Day started for me with Dierk König talking about concurrent programming in Groovy (&lt;a href="http://gpars.codehaus.org/"&gt;GPars&lt;/a&gt; library). Dierk is a commiter to GPars and a co-author of „Groovy in Action”. Chances are, that if you're using Groovy, you already know the lib, but if you don't, it's got pretty a lot of ways to deal with parallel programming without touching threading manually. It's got STM (Software Transactional Memory), Actors, Agents, Communicating Sequential Processes (CSP), dataflow stuff and more. There's even a thing called &lt;a href="http://www.gpars.org/guide/guide/7.%20Dataflow%20Concurrency.html#7.6%20KanbanFlow"&gt;KanbanFlow&lt;/a&gt;. Yeah, the Kanban in name is not accidental. And the best part: all of this is relativly easy to understand and use.&lt;br /&gt;
&lt;br /&gt;
His talk was good, but to tell the truth, I've seen a GPars presentation at GeeCON 2011, by Václav Pech (&lt;a href="http://2011.geecon.org/materials/presentations/2011_Vaclav_Pech_concurrency_geecon.pdf"&gt;„Pick low-hanging fruit"&lt;/a&gt;), and even though Václav had just an hour, I think his talk was better.&lt;br /&gt;
&lt;br /&gt;
Unfortunatelly, the following Dierk's talk: „Pro Groovy”, was both short (just 1h), and shallow. Dierk was talking about &lt;a href="http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations"&gt;Abstract Syntax Tree transformations&lt;/a&gt;, but while I hoped for a show of how to write AST Transformations, Dierk managed only to show a few build in annotations, that were handled by them.&lt;br /&gt;
&lt;br /&gt;
I wish Dierk was available for a whole day. If you are a planning a conference and thinking about whom to invite, please consider asking Dierk and giving him a whole day for a really pro workshop.&amp;nbsp; That would make my day.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;a href="http://2012.geecon.org/speakers/gavin-king"&gt;Gavin King&lt;/a&gt; and &lt;a href="http://2012.geecon.org/speakers/st%C3%A9phane-%C3%A9pardaud"&gt;Stéphane Épardaud&lt;/a&gt; were introducing us to Ceylon, a new programming language on the JVM. If you are wondering, why should you care about this one, you shouldn't. Give it a few years, and check again. The talk was nice, though.&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/-sAB5ScIW7ws/T7pN4elgBEI/AAAAAAAADVU/-FnsVTIaBuc/s1600/_1010533.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="150" src="http://4.bp.blogspot.com/-sAB5ScIW7ws/T7pN4elgBEI/AAAAAAAADVU/-FnsVTIaBuc/s200/_1010533.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
Then came &lt;a href="http://2012.geecon.org/speakers/bruce-eckel"&gt;Bruce Eckel&lt;/a&gt; with „Atomic Scala”. Bruce is writing a new book, and the idea he has is to create something for complete newbies in programming, allowing them to learn Scala as the first programming language. The goal is noble, but that means you shouldn't probably buy it, because it's way faster to explain a lot of language constructs comparing to another language you know, than to explain it from the ground up. Bruce's talk was too basic even for such a dumbass as me.&lt;br /&gt;
&lt;br /&gt;
Bruce also gave the opening talk “The Power of Hybridization”, the next day, and thought it lacked a thesis (Bruce had to finish at about 70%), his deep, multilingual perspective and tons of anecdotes, made it very interesting to me. By the way, if you've read about how slides should look like (no text-reading, only slogans, full screen pictures, etc.) Bruce is doing exactly the opposite thing. Nobody cares, when you have something to tell, though.&lt;br /&gt;
&lt;br /&gt;
I'll skip &lt;a href="http://2012.geecon.org/speakers/ivar-jacobson"&gt;Ivar Jacobson&lt;/a&gt;'s “Liberating the Essence...” talk, as it lacked.. the essence. I'll also skip &lt;a href="http://2012.geecon.org/speakers/gavin-king"&gt;Gavin King&lt;/a&gt;'s “Ceylon: the thinking behind a new language”, as it was just the same thing as with any other Java-replacement language I know of.&amp;nbsp; Let's move to &lt;a href="http://2012.geecon.org/speakers/adam-bien"&gt;Adam Bien&lt;/a&gt; talking Web Containers and Java EE. &lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-y4BFFJyrkG4/T7pOaxlszXI/AAAAAAAADVc/oXN7-fEaXJk/s1600/DSC_0189.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/-y4BFFJyrkG4/T7pOaxlszXI/AAAAAAAADVc/oXN7-fEaXJk/s200/DSC_0189.JPG" width="150" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Terminator @pub in Poznań&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
Adam Bien is a Java Rock Star, Champion, expert, writer, consultant and what else, so you'd correctly assume, his perspective will be very orthodox, especially when you consider that there were at least 4 other languages represented at the conference (Scala, Groovy, Ceylon, Kotlin). But he made a point – the main reason we take all those libs/languages, we change EE containers to web containers + frameworks, is that we do not know Java EE 6 well enough (before 6, using pure Java EE was masochism at best). And then we tend to reimplement/rediscover the things Java EE has already solved.&lt;br /&gt;
&lt;br /&gt;
The thing he misses, though, is that it's easier to learn and use those “other” technologies, than do proper Java EE. And yes, after years of corpo-failures, programmers tend to be biased against Java EE.&amp;nbsp; Thus, while Java EE is finally good, and it makes perfect sense to stay with Java EE, if you are a Java EE master-blaster, I doubt you'll be as productive as with for example Grails. You'll do good to pick whatever you'd like to learn, and learn it throughly.&lt;br /&gt;
&lt;br /&gt;
Adam's talk was refreshing. Apart from guys from SoftwareMill, I haven't seen anyone talking about Java EE 6 with such expertise and sanity.&lt;br /&gt;
&lt;br /&gt;
And then came my favorite talk. &lt;a href="http://2012.geecon.org/speakers/sam-newman"&gt;Sam Newman&lt;/a&gt; from Thoughtworks, talked about design and architecture with emphasis on rapid release. &lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-pd62TgCbbgY/T7pOqGczvpI/AAAAAAAADVk/bAMs852EGV0/s1600/DSC_0199.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="150" src="http://3.bp.blogspot.com/-pd62TgCbbgY/T7pOqGczvpI/AAAAAAAADVk/bAMs852EGV0/s200/DSC_0199.JPG" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Wojtek Erbetowski showing a prototype &lt;br /&gt;
of an operating system on top &lt;br /&gt;
of a prototype of a hardware&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
There aren't many talks about architecture at Java conferences. In fact, there are hardly any. I guess&amp;nbsp; it's easier to fill one hour showing some language basics or a library, than to explain and explore an architecture and its consequences.&amp;nbsp; Thoughtworks was present at 33rd, with &lt;a href="http://2012.33degree.org/speaker/show/48"&gt;James Lewis&lt;/a&gt; and micro services, and I see that the lessons they've learned, are being propagated to other projects. I won't go into details of micro services, as I've already done that &lt;a href="http://blog.solidcraft.eu/2012/03/33rd-degree-day-2-review.html"&gt;reviewing James' talk&lt;/a&gt;. Sam was happy to present a case of how to use system decomposition (micro-services at a service per Bounded Context level), and what the effects are. &lt;br /&gt;
&lt;br /&gt;
Some of his learned lessons were:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;beware of shared lib and serialization protocols (evil for microservices)&lt;/li&gt;
&lt;li&gt;do not send internal representation of data across the wire (things change)&lt;/li&gt;
&lt;li&gt;fuck WSDL, go with simple XML, Xpath, and let every service prepare stub-tests, so you can safely change the schema when you want to&lt;/li&gt;
&lt;li&gt;codify the contract between services with writing a test (the reason is the same as above)&lt;/li&gt;
&lt;li&gt;do not share database between services; you'll make it impossible to evolve them independently; you can use one database with different schemas&lt;/li&gt;
&lt;li&gt;data should be owned by the service it uses (similar to above)&lt;/li&gt;
&lt;/ul&gt;
When I say I'm interested, and that I see potential here, I really mean it. I'm about to lead a development of a bank system, implementing such an approach. We are already using many small, dedicated to single purpose apps, written in different technologies (Java + Spring MVC, Scala + Play), that communicate via RESTful HTTP, and we are going to expand on that concept. We'll see whether we can keep it so simple as Thoughtworks implies. I'll let you know when we have some outcomes.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-yeb5E6NWGKk/T7pNsDKFnOI/AAAAAAAADVM/_yLxjJa115k/s1600/_1010596.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="150" src="http://4.bp.blogspot.com/-yeb5E6NWGKk/T7pNsDKFnOI/AAAAAAAADVM/_yLxjJa115k/s200/_1010596.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
I was hopping between presentations for the next hour, as I have either already seen then somwhere else, or was uninspired after a few minutes. Then I went for &lt;a href="http://2012.geecon.org/speakers/james-williams"&gt;James Williams&lt;/a&gt;, talking about Ratpack. I really feel sorry for James, he made quite a trip here, but as this was the last presentation this day, and he had guys like Bruce Eckel as an alternative, not many people showed up.&lt;br /&gt;
&lt;br /&gt;
I've started the last of the conference with &lt;a href="http://2012.geecon.org/speakers/thomas-sundberg"&gt;Thomas Sundberg&lt;/a&gt; and his rather basic talk about all the wrong things we can do to fail a project. As there was nothing new to me, I left early. Then I moved to &lt;a href="http://2012.geecon.org/speakers/kevlin-henney"&gt;Kevlin Henney&lt;/a&gt; to listen about OOP in Java (deja-vu? not really), and to &lt;a href="http://2012.geecon.org/speakers/tomasz-kowalczewski"&gt;Tomasz Kowalczewski&lt;/a&gt; talk about Closures in Java 8. That was similar to&lt;a href="http://2012.33degree.org/speaker/show/13"&gt; Simon Ritter at 33rd&lt;/a&gt;, but focused solely on Closures. Great talk, nice stuff, Tomasz did great work, though it's a bit disappointing that functions are not going to be first class citizens. Yet.&lt;br /&gt;
&lt;br /&gt;
Oh, well, no reason to go back from Groovy, I guess.&lt;br /&gt;
&lt;br /&gt;
And then there was &lt;a href="http://2012.geecon.org/speakers/piotr-gabryanczyk"&gt;Piotr Gabryanczyk&lt;/a&gt; with Scala, Akka and Camel. That was also a great talk, showing simplicity of programming using those technologies. I wonder how it fits Thoughtworks' micro-services, or are we getting too close to ESB and single point of bullshit that way.&lt;br /&gt;
&lt;br /&gt;
Kevlin Henney closed the conference with examples of cool code. His talk was fantastic, funny, and inspiring. Especially examples. One of the best closing talks I've seen. Thanks.&lt;br /&gt;
&lt;br /&gt;
And there were parties. But that's a completely different story.&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/-TvzmkYvwrJI/T7pMbsBCWAI/AAAAAAAADU8/QE_krBsj6UI/s1600/DSC_0192.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="480" src="http://4.bp.blogspot.com/-TvzmkYvwrJI/T7pMbsBCWAI/AAAAAAAADU8/QE_krBsj6UI/s640/DSC_0192.JPG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Saturday was for &lt;span class="strongText empText"&gt;&lt;a class="mainSectionMoreLink" href="http://2012.geecon.org/openspaces"&gt;Open Spaces&lt;/a&gt;, lead by Bruce Eckel, but I couldn't attend.&lt;a class="mainSectionMoreLink" href="http://2012.geecon.org/openspaces"&gt;&lt;span class="mainSectionText" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt; &lt;br /&gt;
&lt;br /&gt;
PS: Some pictures are courtesy of Michał Lewandowski. I've totally forgotten my camera.&lt;br /&gt;
&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/8795604888160975763-7839730142167059836?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2012/05/geecon-2012-review.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-PurR5QM-D8M/T7pNEbIsjjI/AAAAAAAADVE/IRHvBdQmVCs/s72-c/_1010536.jpg' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-6466846546716357368</guid><pubDate>Sun, 25 Mar 2012 17:09:00 +0000</pubDate><atom:updated>2012-03-25T19:09:22.187+02:00</atom:updated><title>33rd Degree day 3 review</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
At the last day of the conference, I've decided to skip the first presentations, and get some sleep instead. I was afraid that Venkat's show is going to be too basic, I will see Jacek Laskowski talking about closure at 4Developers, which I'm kind of supervising from the Java perspective. As an afterthought, I should have gone to see "Static Code Analysis and AST Transformations" by &lt;a href="http://2012.33degree.org/speaker/show/59"&gt;Hamlet D'Arcy&lt;/a&gt;, as I really like this guy and the topic is intriguing at least, but I didn't want to intoxicate myself more with coffee, and really needed to get some sleep.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style="text-align: left;"&gt;
MongoDB: Scaling Web Application&lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-0yqK22mzeLo/T29Ljc9O88I/AAAAAAAACqs/FjICD88DU8w/s1600/CIMG5740.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="150" src="http://1.bp.blogspot.com/-0yqK22mzeLo/T29Ljc9O88I/AAAAAAAACqs/FjICD88DU8w/s200/CIMG5740.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
The first talk I've seen was by                 &lt;a href="http://2012.33degree.org/speaker/show/16"&gt;Ken Sipe&lt;/a&gt;. It was a very interesting case study, and I love case studies. They give you a real perspective, unlike the product-half-marketing that some authors are doing, and unlike self-marketing that some "professional" speakers perform.&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Ken had an interesting project at hand: a Facebook like social service, that deals with politic, named &lt;a href="http://www.govote.com/"&gt;GoVote&lt;/a&gt;. Half of the presentation was a bit basic, with simple CRUD syntax, but when Ken started to talk about modeling, it got interesting.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Ken used Grails as the web framework and went through several plugins/libs to get him to the performance and efficiency he needed. Every one of them failed, except for GSP, which is a thing worth reflecting about. His lesson was not really surprising: you should not use any abstracts (ORM?), when playing with document databases. He sticked to GORM because of how fast his problems were solved on the mailing list and bug tracker, but GORM doesn't really give you the resolution you want, when dealing with tree structures composed of documents.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
My favourite part, albeit short, was about modeling. Ken managed to get ONE hit to DB per dynamic web page, something I've always dreamed of. His advice was to focus on use cases, and design document model with use cases in mind. You get a sign of bad design, when you find nested joins (hitting more than once for the data), and you can usually get away with tags, instead. Interesting stuff, I hope to verify that soon.&lt;/div&gt;
&lt;h3 style="text-align: left;"&gt;
HTML5 For Developers&lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-D7gAJrBITrE/T29OZ_kNJmI/AAAAAAAACq0/7W4h5IqWFPM/s1600/CIMG5747.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="150" src="http://1.bp.blogspot.com/-D7gAJrBITrE/T29OZ_kNJmI/AAAAAAAACq0/7W4h5IqWFPM/s200/CIMG5747.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;a href="http://2012.33degree.org/speaker/show/51"&gt;Nathaniel Schutta&lt;/a&gt; had a large presentation at hand, nothing he kind fit into only one hour, so he gave us a choice: what do we want to hear about. It turned out, the audience was most interested into Web Workers, local web storage and Canvas. Each had their caveats.&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Web workers allow to get some much needed concurrency&amp;nbsp; into heavy GUI (or game engines, I guess), work with a simple API where you can handle errors and spawn new workers.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Local storage is unfortunately limited by default to 5MB, and you may get unsuccessful persuading the user to change it. Apart from that, it's a simple key-value store (both Strings), with storage events (think on-insert etc.), but current implementations handle those not without some problems.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Canvas was quite interesting. Though it has a very simple API, and only basic primitives implemented, I've already bought a 500 pages long book about it (and that's without any info on all the libs build on top of it).&lt;/div&gt;
&lt;h3 style="text-align: left;"&gt;
Ending keynotes&lt;/h3&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
There were three ending keynotes, one from                 &lt;a href="http://2012.33degree.org/speaker/show/51"&gt;Nathaniel Schutta&lt;/a&gt;,                 &lt;a href="http://2012.33degree.org/speaker/show/7"&gt;Jurgen Appelo&lt;/a&gt; and the last from                 &lt;a href="http://2012.33degree.org/speaker/show/8"&gt;Robert C. Martin&lt;/a&gt;. As expected, those were entertaining, though unless you've been sleeping through the last three years in a cave, you would not be surprised by both craftsman. Jurgen, however, was quite a different animal.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
His talk, titled "How to Change the World", was based on his book "Management 3.0" and his work afterwards. I've been interested in the mechanics of change, since I've been trying to change with more or less luck, all the companies I've worked for. Jurgen has a lot to say in that matter, and I've been wrong on so many levels in my attitude towards change, that the talk was very refreshing.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
You can take a look at his presentation here:&lt;/div&gt;
&lt;div id="__ss_9444890" style="width: 425px;"&gt;
&lt;b style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/jurgenappelo/how-to-change-the-world-9444890" target="_blank" title="How to Change the World"&gt;How to Change the World&lt;/a&gt;&lt;/b&gt; &lt;iframe frameborder="0" height="355" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/9444890" width="425"&gt;&lt;/iframe&gt; &lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Overall, while it's too early to say whether that was the best JVM conference in Poland this year, I can recommend 33rd on all grounds. I feel I can bet blindly on it next year. Grzegorz Duda delivers enormous knowledge in so little time and so little money.&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-6466846546716357368?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2012/03/33rd-degree-day-3-review.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-0yqK22mzeLo/T29Ljc9O88I/AAAAAAAACqs/FjICD88DU8w/s72-c/CIMG5740.JPG' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-5206382489639234372</guid><pubDate>Sun, 25 Mar 2012 16:23:00 +0000</pubDate><atom:updated>2012-03-25T19:12:30.795+02:00</atom:updated><title>33rd Degree day 2 review</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Second day of 33rd had no keynotes, and thus was even more intense. A good conference is a conference, where every hour you have a hard dilemma, because there are just too many interesting presentations to see. 33rd was definitely such a conference, and the seconds day really shined.&lt;br /&gt;
&lt;br /&gt;
There were two workshops going on through the day, one about JEE6 and another about parallel programming in Java. I was considering both, but decided to go for presentations instead. Being on the Spring side of the force, I know just as much JEE as I need, and with fantastic &lt;a href="http://gpars.codehaus.org/"&gt;GPars&lt;/a&gt; (which has Fork/Join, actors, STM , and much more), I won't need to go back to Java concurrency for a while.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style="text-align: left;"&gt;

GEB - Very Groovy browser automation&lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-NSJoDRNd3is/T28WO940iDI/AAAAAAAACpk/t9_-Bnc03zE/s1600/CIMG5690.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="150" src="http://1.bp.blogspot.com/-NSJoDRNd3is/T28WO940iDI/AAAAAAAACpk/t9_-Bnc03zE/s200/CIMG5690.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a href="http://2012.33degree.org/speaker/show/26"&gt;Luke Daley&lt;/a&gt; works for Gradleware, and apart from being cheerful Australian, he's a commiter to Grails, Spock and a guy behind &lt;a href="http://www.gebish.org/"&gt;Geb&lt;/a&gt;, a&amp;nbsp; browser automation lib using WebDriver, similar to Selenium a bit (though without IDE and other features).&lt;br /&gt;
&lt;br /&gt;
I have to admit, there was a time where I really hated Selenium. It just felt so wrong to be writing tests that way, slow, unproductive and against the beauty of TDD. For years I've been treating frontend as a completely different animal. Uncle Bob once said at a Ruby conference: "I'll tell you what my solution to frontend tests is: I just don't". But then, you can only go so far with complex GUIs without tests, and once I've started working with Wicket and its test framework, my perspective changed. If Wicked has one thing done right, it's the frontend testing framework. Sure tests are slow, on par with integration tests, but it is way better than anything where the browser has to start up front, and I could finally do TDD with it.&lt;br /&gt;
&lt;br /&gt;
Working with Grails lately, I was more than eager to learn a proper way to do these kind of tests with Groovy.&lt;br /&gt;
&lt;br /&gt;
GEB looks great. You build your own API for every page you have, using CSS selectors, very similar to jQuery, and then write your tests using your own DSL. Sounds a bit complicated, but assuming you are not doing simple HTML pages, this is probably the way to go fast. I'd have to verify that on a project though, since with frontend, too many things look good on paper and than fall out in code.&lt;br /&gt;
&lt;br /&gt;
The presentation was great, Luke managed to answer all the questions and get people interested. On a side note, WebDriver may become a W3C standard soon, which would really easy browser manipulation for us. Apart from thing I expected Geb to have, there are some nice surprises like working with remote browsers (e.g. IE on remote machine), dumping HTML at the end of the test and even making screenshots (assuming you are not working with headless browser).&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style="text-align: left;"&gt;

Micro services - Java, the Unix Way&lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-M4ICHZZBFyQ/T28kASzKnZI/AAAAAAAACps/oNsp0XN9D_w/s1600/CIMG5696.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="150" src="http://2.bp.blogspot.com/-M4ICHZZBFyQ/T28kASzKnZI/AAAAAAAACps/oNsp0XN9D_w/s200/CIMG5696.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;a href="http://2012.33degree.org/speaker/show/48"&gt;James Lewis&lt;/a&gt; works for ThoughtWorks and gave a presentation, for which alone it was worth to go to Krakow. No, seriously, that was a gem I really didn't see coming. Let me explain what it was about and then why it was such a mind-opener.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
ThoughtWorks had a client, a big investment bank, lots of cash, lots of requirements. They spent five weeks getting the analysis done on the highest possible level, without getting into details yet (JEDI: just enough design initially). The numbers were clear: it was enormous, it will take them forever to finish, and what's worse, requirements were contradictory. The system had to have all three guarantees of the CAP theorem, a thing which is PROVED to be impossible.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
So how do you deal with such a request? Being ThoughtWorks you probably never say "we can't", and having an investment bank for a client, you already smell the mountains of freshly printed money. This isn't something you don't want to try, it's just scary and challenging as much as it gets.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
And then, looking at the requirements and drawing initial architecture, they've reflected, that there is a way to see the light in this darkness, and not to end up with one, monstrous application, which would be hard to finish and impossible to maintain. They have analyzed flows of data, and came up with an idea.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-3Cb6PwJ5vuw/T28kU6qs47I/AAAAAAAACp0/3CFwgl50GAs/s1600/CIMG5698.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="111" src="http://4.bp.blogspot.com/-3Cb6PwJ5vuw/T28kU6qs47I/AAAAAAAACp0/3CFwgl50GAs/s200/CIMG5698.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
What if we create several applications, each so small, that you can literally "fit it in your head", each communicating with a simple web protocol (Atom), each doing one thing and one thing only, each with it's own simple embedded web server, each working on it's own port, and finding out other services through some location mechanism. What if we don't treat the web as an external environment for our application, but instead build the system as if it was inside the web, with the advantages of all the web solutions, like proxies, caches, just adding a small queue before each service, to be able to turn it off and on, without loosing anything. And we could even use a different technology, with different pair of CAP guarantees, for each of those services/applications.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Now let me tell you why it's so important for me.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
If you read this blog, you may have noticed the subtitle "fighting chaos in the Dark Age of Technology". It's there, because for my whole IT life I've been pursuing one goal: to be able to build things, that would be easy to maintain. Programming is a pure pleasure, and as long as you stay near the "hello world" kind of complexity, you have nothing but fun. If we ever feel burned out, demotivated or puzzled, it's when our systems grow so much, that we can no longer understand what's going on. We lose control. And from that point, it's usually just a way downward, towards complete chaos and pain.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-FN5ZuJP0JiE/T28kjW1gt5I/AAAAAAAACp8/1WPDkJxh5gc/s1600/CIMG5703.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="111" src="http://3.bp.blogspot.com/-FN5ZuJP0JiE/T28kjW1gt5I/AAAAAAAACp8/1WPDkJxh5gc/s200/CIMG5703.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
All the architecture, all the ideas, practices and patterns, are there for just this reason - to move the border of complexity further, to make the size of "possible to fit in your head" larger. To postpone going into chaos. To bring order and understanding into our systems.&lt;/div&gt;
And that really works. With TDD, DDD, CQRS I can build things which are larger in terms of features, and simpler in terms of complexity. After discovering and understanding the methods (XP, Scrum/Kanbad) my next mental shift came with Domain Driven Design. I've learned the building block, the ideas and the main concept of Bounded Contexts. And that you can and should use a different architecture/tools for each of them, simplifying the code with the usage patterns of that specific context in your ming.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
That has changed a lot in my life. No longer I have to choose one database, one language and one architecture for the whole application. I can divide and conquer, choose what I want to sacrifice and what advantages I want here, in this specific place of my app, not worrying about other places where it won't fit.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;a href="http://2.bp.blogspot.com/-f15mV0kpG8U/T28kym4ZKkI/AAAAAAAACqE/C9hxgy77SYk/s1600/CIMG5705.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="111" src="http://2.bp.blogspot.com/-f15mV0kpG8U/T28kym4ZKkI/AAAAAAAACqE/C9hxgy77SYk/s200/CIMG5705.JPG" width="200" /&gt;&lt;/a&gt;But there is one problem in here: the limit of technologies I'm using, to keep the system simple, and not require omnipotence to be able to maintain, to fix bugs or implement Change Requests.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
And here is the accidental solution, ThoughtWorks' micro services bring: if you system is build of the web, of small services that do one thing only, and communicate through simple protocol (like Atom), there is little code to understand, and in case of bugs or Change Requests, you can just tear down one of the services. and build it anew.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;a href="http://3.bp.blogspot.com/-HsbLJZklOV4/T28l1C69t1I/AAAAAAAACqM/JcqD0D05XG8/s1600/CIMG5710.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="111" src="http://3.bp.blogspot.com/-HsbLJZklOV4/T28l1C69t1I/AAAAAAAACqM/JcqD0D05XG8/s200/CIMG5710.JPG" width="200" /&gt;&lt;/a&gt;James called that "Small enough to throw them away. Rewrite over maintain". Now, isn't that a brilliant idea? Say you have a system like that, build over seven years ago, and you've got a big bag of new requests from your client. Instead of re-learning old technologies, or paying extra effort to try to bring them up-to-date (which is often simply impossible), you decide which services you are going to rewrite using the best tools of your times, and you do it, never having to dig into the original code, except for specification tests.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Too good to be true? Well, there are caveats. First, you need DevOps in your teams, to get the benefits of the web inside your system, and to build in the we as opposite to against it. Second, integration can be tricky. Third, there is not enough of experience with this architecture, to make it safe. Unless... unless you realize, that UNIX was build this way, with small tools and pipes.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
That, perhaps. is the best recommendation possible.&lt;/div&gt;
&lt;h3 style="text-align: left;"&gt;

Concurrency without Pain in Pure Java &lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-rL5LEdcgVDE/T28oUVKk3EI/AAAAAAAACqU/AQy0duMI4-8/s1600/CIMG5724.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="150" src="http://3.bp.blogspot.com/-rL5LEdcgVDE/T28oUVKk3EI/AAAAAAAACqU/AQy0duMI4-8/s200/CIMG5724.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Throughout the whole conference, Grzegorz Duda had a publicly accessible wall, with sticky notes and two sides: what's bad and what's good. One of the note on the "bad" side was saying: "Sławek Sobótka and Paweł Lipiński at the same time? WTF?".&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
I had the same thought. I wanted to see both. I was luckier though, since I'm pretty sure I'll yet be able too see their presentations this year, as 33rd is the first conference in a long run of conferences planned for 2012. Not being able to decide which one to see, I've decided to go for &lt;a href="http://2012.33degree.org/speaker/show/3"&gt;Venkat Subramaniam&lt;/a&gt; and his talk about concurrency. Unless we are lucky at 4Developers, we probably won't see Venkat again this year.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Unfortunately for me, the talk ("show" seems like a more proper word), was very basic, and while very entertaining, not deep enough for me. Venkat used Closure STM to show how bad concurrency is in pure Java, and how easy it is with STM. What can I say, it's been repeated so often, it's kind of obvious by now.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Venkat didn't have enough time to show the Actor model in Java. That's sad, as the further his talk, the more interesting it was. Perhaps there should be a few 90min sessions next year?&lt;/div&gt;
&lt;h3 style="text-align: left;"&gt;

Smarter Testing with Spock&lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-ulPR1A5lD_U/T29D0jTnRZI/AAAAAAAACqc/nDU4xSvPNPc/s1600/CIMG5731.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="150" src="http://3.bp.blogspot.com/-ulPR1A5lD_U/T29D0jTnRZI/AAAAAAAACqc/nDU4xSvPNPc/s200/CIMG5731.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
After the lunch, I had a chance to go for Sławek Sobótka again, but this time I've decided to listen to one of the commiters of &lt;a href="http://code.google.com/p/spock/"&gt;Spock&lt;/a&gt;, the best thing in testing world since Mockito.&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Not really convinced? Gradle is using Spock (not surprisingly), Spring is starting to use Spock. I've had some experience with Spock, and it was fabulous. We even had a Spock workshop at TouK, lately. I wanted to see what &lt;a href="http://2012.33degree.org/speaker/show/26"&gt;Luke Daley&lt;/a&gt; can teach me in an hour.&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
That was a time well spent. Apart from things I knew already, Luke explained how to share state between tests (@Shared), how to verify exceptions (thrown()), keep old values of variables (old()), how to parametrize description with @Unroll and #parameterName, how to set up data from db or whatever with &amp;lt;&amp;lt;, and a bit more advanced trick with mocking mechanism. Stubbing with closures was especially interesting.&lt;/div&gt;
&lt;h3 style="text-align: left;"&gt;

What's new in Groovy 2.0?&lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-AwJlH8zK4Mw/T29EBSGG0YI/AAAAAAAACqk/ZhXi9dfOXYw/s1600/CIMG5733.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="150" src="http://3.bp.blogspot.com/-AwJlH8zK4Mw/T29EBSGG0YI/AAAAAAAACqk/ZhXi9dfOXYw/s200/CIMG5733.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;a href="http://2012.33degree.org/speaker/show/12"&gt;Guillaume Laforge&lt;/a&gt; is the project lead of Groovy and his presentation was the opposite to what we could see earlier about next versions of Java. Most visible changes were already done in 1.8, with all the AST transformations, and Guillaume spent some time re-introducing them, but then he moved to 2.0, and here apart from multicatch in "throw", the major thing is static compilation and type checking.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
We are in the days, were the performance difference between Java and Groovy falls to a mere 20%.&amp;nbsp; That's really little compared to where it all started from (orders of magnitude). That's cool. Also, after reading some posts and successful stories about &lt;a href="http://code.google.com/p/groovypptest/"&gt;Groovy++&lt;/a&gt; use, I'd really like to try static compilation with this language&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Someone from the audience asked a good question. Why not use Groovy++ as the base for static compilation instead. It turned out that Groovy++ author was also there. The main reason Guillaume gave, were small differences in how they want to handle internal things. If static compilation works fine with 2.0, Groovy++ may soon die, I guess.&lt;/div&gt;
&lt;h3 style="text-align: left;"&gt;

Scala for the Intrigued&lt;/h3&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
For the last talk this day, I've chosen a bit of Scala, by                 &lt;a href="http://2012.33degree.org/speaker/show/3"&gt;Venkat Subramaniam&lt;/a&gt;. That was unfortunately a completely basic introduction, and after spending 15 minutes listening about differences between var and val, I've left to get prepared to the BOF session, which I had with Maciek Próchniak.&lt;/div&gt;
&lt;h3 style="text-align: left;"&gt;

BOF: Beautiful failures&lt;/h3&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
I'm not in the position to review my own talk, and conclude whether it's failure was beautiful or not, but there is one things I've learned from it.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Never, under none circumstances, never drink five coffees the day you give a talk. To keep my mind active without being overwhelmed by all the interesting knowledge, I drank those five coffees, and to my surprise, when the talk started, the adrenaline shot brought me over the level, where you loose your breath, your pulse, and you start to loose control over your own voice. Not a really nice experience. I've had the effects of caffeine intoxication for the next two days. Lesson learned, I'm staying away from black beans for some time.&lt;br /&gt;
If you want the slides, you can find them &lt;a href="https://docs.google.com/presentation/d/107rlO-hPHKbOGDKVh3OLAaY9NimVZTXP0oA2Ur99KYo/edit"&gt;here&lt;/a&gt;.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
And that was the end of the day. We went to the party, to the afterparty, we got drunk, we got the soft-reset of our caches, and there came another day of the conference.&lt;br /&gt;
&lt;br /&gt;
You can find my review from the last day in &lt;a href="http://blog.solidcraft.eu/2012/03/33rd-degree-day-3-review.html"&gt;here&lt;/a&gt;. &lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-5206382489639234372?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2012/03/33rd-degree-day-2-review.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-NSJoDRNd3is/T28WO940iDI/AAAAAAAACpk/t9_-Bnc03zE/s72-c/CIMG5690.JPG' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-5919267883079412575</guid><pubDate>Sat, 24 Mar 2012 14:43:00 +0000</pubDate><atom:updated>2012-03-25T18:24:26.083+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>conference</category><category domain='http://www.blogger.com/atom/ns#'>presentation</category><title>33rd Degree day 1 review</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;a href="http://2012.33degree.org/"&gt;33rd Degree&lt;/a&gt; is over. After the one last year, my expectations were very high, but Grzegorz Duda once again proved he's more than able to deliver. With up to five tracks (most of the time: four presentations + one workshop), and ~650 attendees,&amp;nbsp; there was a lot to see and a lot to do, thus everyone will probably have a little bit different story to tell. Here is mine.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style="text-align: left;"&gt;
    Twitter: From Ruby on Rails to the JVM &lt;/h3&gt;
&lt;h3 style="text-align: left;"&gt;
    &lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-2BrQH57a_ZA/T222etlBCpI/AAAAAAAACl8/3tdZj46oICs/s1600/CIMG5582.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img alt="Raffi Krikorian talking about Twitter and JVM" border="0" height="110" src="http://4.bp.blogspot.com/-2BrQH57a_ZA/T222etlBCpI/AAAAAAAACl8/3tdZj46oICs/s200/CIMG5582.JPG" title="Raffi Krikorian talking about Twitter and JVM" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
The conference started with&amp;nbsp;                 &lt;a href="http://2012.33degree.org/speaker/show/17"&gt;Raffi Krikorian&lt;/a&gt; from Twitter, talking about &lt;a href="http://2012.33degree.org/talk/show/24"&gt;their use for JVM&lt;/a&gt;. Twitter was build with Ruby but with their performance management a lot of the backend was moved to Scala, Java and Closure. Raffi noted, that for Ruby programmers Scala was easier to grasp than Java, more natural, which is quite interesting considering how many PHP guys move to Ruby these days because of the same reasons. Perhaps the path of learning Jacek Laskowski once described (Java -&amp;gt; Groovy -&amp;gt; Scala/Closure) may be on par with PHP -&amp;gt; Ruby -&amp;gt; Scala. It definitely feels like Scala is the holy grail of languages these days.&lt;br /&gt;
&lt;br /&gt;
Raffi also noted, that while JVM delivered speed and a concurrency model to Twitter stack, it wasn't enough, and they've build/customized their own Garbage Collector. My guess is that Scala/Closure could also be used because of a nice concurrency solutions (STM, immutables and so on).&lt;br /&gt;
&lt;br /&gt;
Raffi pointed out, that with the scale of Twitter, you easily get 3 million hits per second, and that means you probably have 3 edge cases every second. I'd love to learn listen to lessons they've learned from this.&lt;br /&gt;
&lt;h3 style="text-align: left;"&gt;
    &amp;nbsp;&lt;/h3&gt;
&lt;h3 style="text-align: left;"&gt;
    Complexity of Complexity &lt;/h3&gt;
&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/-3Sev8LH1aYs/T223W_E9YvI/AAAAAAAACmE/sxZode9NURM/s1600/CIMG5585.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="111" src="http://2.bp.blogspot.com/-3Sev8LH1aYs/T223W_E9YvI/AAAAAAAACmE/sxZode9NURM/s200/CIMG5585.JPG" width="200" /&gt;&lt;/a&gt;The second keynote of the first day, was &lt;a href="http://2012.33degree.org/speaker/show/16"&gt;Ken Sipe&lt;/a&gt; talking about complexity. He made a good point that there is a difference between complex and complicated, and that we often recognize things as complex only because we are less familiar with them. This goes more interesting the moment you realize that the shift in last 20 years of computer languages, from the "Less is more" paradigm (think Java, ASM) to "More is better" (Groovy/Scala/Closure), where you have more complex language, with more powerful and less verbose syntax, that is actually not more complicated, it just looks less familiar.&lt;br /&gt;
&lt;br /&gt;
So while 10 years ago, I really liked Java as a general purpose language for it's small set of rules that could get you everywhere, it turned out that to do most of the real world stuff, a lot of code had to be written. The situation got better thanks to libraries/frameworks and so on, but it's just patching. New languages have a lot of stuff build into, which makes their set of rules and syntax much more complex, but once you get familiar, the real world usage is simple, faster, better, with less traps laying around, waiting for you to fall.&lt;br /&gt;
&lt;br /&gt;
Ken also pointed out, that while Entity Service Bus looks really simple on diagrams, it's usually very difficult and complicated to use from the perspective of the programmer. And that's probably why it gets chosen so often - the guys selling/buying it, look no deeper than on the diagram.&lt;br /&gt;
&lt;h3 style="text-align: left;"&gt;
    &amp;nbsp;&lt;/h3&gt;
&lt;h3 style="text-align: left;"&gt;
    Pointy haired bosses and pragmatic programmers: Facts and Fallacies of Software Development&lt;/h3&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/--fqORscTooo/T2237pHGd2I/AAAAAAAACmM/jdBR4J0b4vI/s1600/CIMG5596.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img alt="Venkat Subramaniam with Dima" border="0" height="111" src="http://1.bp.blogspot.com/--fqORscTooo/T2237pHGd2I/AAAAAAAACmM/jdBR4J0b4vI/s200/CIMG5596.JPG" title="Venkat Subramaniam with Dima" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Dima got lucky. Or maybe not.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;
&lt;a href="http://2012.33degree.org/speaker/show/3"&gt;Venkat Subramaniam&lt;/a&gt; is the kind of a speaker that talk about very simple things in a way, which makes everyone either laugh or reflect. Yes, he is a showman, but hey, that's actually good, because even if you know the subject quite well, his talks are still very entertaining.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
This talk was very generic (here's my thesis: the longer the title, the more generic the talk will be), interesting and fun, but at the end I'm unable to see anything new I'd have learned, apart from the distinction between Dynamic vs Static and Strong vs Weak typing, which I've seen the last year, but managed to forgot. This may be a very interesting argument for all those who are afraid of Groovy/Ruby, after bad experience with PHP or Perl.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3 style="text-align: left;"&gt;
    Build Trust in Your Build to Deployment Flow! &lt;/h3&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;
&lt;a href="http://2012.33degree.org/speaker/show/42"&gt;Frederic Simon&lt;/a&gt; talked about DevOps and deployment, and that was a miss in my&amp;nbsp; schedule, because of two reasons. First, the talk was aimed at DevOps specifically, and while the subject is trendy lately, without big-scale problems, deployment is a process I usually set up and forget about. It just works, mostly because I only have to deal with one (current) project at a time.&amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-2qOe2Z508-s/T229y6PTsTI/AAAAAAAACmc/kn2ppVh-Su8/s1600/CIMG5618.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="150" src="http://1.bp.blogspot.com/-2qOe2Z508-s/T229y6PTsTI/AAAAAAAACmc/kn2ppVh-Su8/s200/CIMG5618.JPG" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Not much love for Dart.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
Second, while Frederic has a fabulous accent and a nice, loud voice, he tends to start each sentence loud and fade the sound at the end. This, together with mics failing him badly, made half of the presentation hard to grasp unless you were sitting in the first row.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
I'm not saying the presentation was bad, far from it, it just clearly wasn't for me.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
I've left a few minutes before the end, to see how many people came to Dart presentation by &lt;a href="http://2012.33degree.org/speaker/show/55"&gt;Mike West&lt;/a&gt;. I was kind of interested, since I'm following Warsaw Google Technology User Group and heard a few voices about why I should pay attentions to that new Google language. As you can see from the picture on the right, the majority tends to disagree with that opinion.&lt;/div&gt;
&lt;h3 style="text-align: left;"&gt;
    &amp;nbsp;&lt;/h3&gt;
&lt;h3 style="text-align: left;"&gt;
    Non blocking, composable reactive web programming with Iteratees&lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-AFAY3S28Mis/T23Fk07AtjI/AAAAAAAACms/MfmMQy9g9k0/s1600/CIMG5626.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="111" src="http://3.bp.blogspot.com/-AFAY3S28Mis/T23Fk07AtjI/AAAAAAAACms/MfmMQy9g9k0/s200/CIMG5626.JPG" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;a href="http://2012.33degree.org/speaker/show/43"&gt;Sadek Drobi's&lt;/a&gt; talk about Iteratees in Play 2.0 was very refreshing. Perhaps because I've never used Play before, but the presentation was flawless, with well explained problems, concepts and solutions.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
Sadek started with a reflection on how much CPU we waste waiting for IO in web development, then moved to Play's Iteratees, to explain the concept and implementation, which while very different from the that overused Request/Servlet model, looked really nice and simple. I'm not sure though, how much the problem is present when you have a simple service, serving static content before your app server. Think apache (and faster) before tomcat. That won't fix the upload/download issue though, which is beautifully solved in Play 2.0&lt;/div&gt;
&lt;br /&gt;
&lt;h3 style="text-align: left;"&gt;
    The Future of the Java Platform: Java SE 8 &amp;amp; Beyond&lt;/h3&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;
&lt;a href="http://2012.33degree.org/speaker/show/13"&gt;Simon Ritter&lt;/a&gt; is an intriguing fellow. If you take a glance at his work history (AT&amp;amp;T UNIX System Labs -&amp;gt; Novell -&amp;gt; Sun -&amp;gt; Oracle), you can easily see, he's a heavy weight player.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
His presentation was rich in content, no corpo-bullshit. He started with a bit of history of JCP and how it looks like right now, then moved to the most interesting stuff, changes. Now I could give you a summary here, but there is really no point: you'd be much better taking look at the slides. There are only 48 of them, but everything is self-explanatory.&lt;/div&gt;
&lt;div id="__ss_10074753" style="width: 425px;"&gt;
&lt;b style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/JAX_London/keynote-to-java-se-8-and-beyond-simon-ritter" target="_blank" title="To Java SE 8 and Beyond! | Simon Ritter"&gt;To Java SE 8 and Beyond! | Simon Ritter&lt;/a&gt;&lt;/b&gt; &lt;iframe frameborder="0" height="355" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/10074753" width="425"&gt;&lt;/iframe&gt; &lt;/div&gt;
While I'm very disappointed with the speed of changes, especially when compared to the C# world, I'm glad with the direction and the fact that they finally want to BREAK the compatibility with the broken stuff (generics, etc.).&amp;nbsp; Moving to other languages I guess I won't be the one to scream "My god, finally!" somewhere in 2017, though. All the changes together look very promising, it's just that I'd like to have them like... now? Next year max, not near the heat death of the universe.&lt;br /&gt;
&lt;br /&gt;
Simon also revealed one of the great mysteries of Java, to me: &lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;i&gt;The original idea behind JNI was to make it hard to write, to discourage people form using it. &lt;/i&gt;&lt;/blockquote&gt;
On a side note, did you know Tegra3 has actually 5 cores? You use 4 of them, and then switch to the other one, when you battery gets low.&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style="text-align: left;"&gt;
    BOF: Spring and CloudFoundry&lt;/h3&gt;
&lt;br /&gt;
Having most of my folks moved to see "Typesafe stack 2.0" fabulously organized by &lt;a href="http://2012.33degree.org/speaker/show/60"&gt;Rafał Wasilewski&lt;/a&gt; and&amp;nbsp; &lt;a href="http://www.linkedin.com/in/wojtekerbetowski"&gt;Wojtek Erbetowski&lt;/a&gt; (with both of whom I had a pleasure to travel to the conference) and knowing it will be recorded, I've decided to see what &lt;a href="http://2012.33degree.org/speaker/show/36"&gt;Josh Long&lt;/a&gt; has to say about CloudFoundry, a subject I find very intriguing after the de facto fiasco of Google App Engine.&lt;br /&gt;
&lt;br /&gt;
The audience was small but vibrant, mostly users of Amazon EC2, and while it turned out that Josh didn't have much, with pricing and details not yet public, the fact that Spring Source has already created their own competition (Could Foundry is both an Open Source app and a service), takes a lot from my anxiety.&lt;br /&gt;
&lt;br /&gt;
For the review of the second day of the conference, go &lt;a href="http://blog.solidcraft.eu/2012/03/33rd-degree-day-2-review.html"&gt;here&lt;/a&gt;.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-5919267883079412575?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2012/03/33rd-degree-day-1-review.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-2BrQH57a_ZA/T222etlBCpI/AAAAAAAACl8/3tdZj46oICs/s72-c/CIMG5582.JPG' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-8493104236211351109</guid><pubDate>Mon, 19 Mar 2012 13:35:00 +0000</pubDate><atom:updated>2012-03-19T14:35:24.382+01:00</atom:updated><title>Beautiful Failures at 33rd Degree</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;a href="http://2012.33degree.org/"&gt;33rd in Kraków&lt;/a&gt;, is rolling baby.&lt;br /&gt;
&lt;br /&gt;
Tomorrow, together with Maciek Próchniak, we are giving a talk about failures.&lt;br /&gt;
&lt;br /&gt;
There is a problem with failures withing our culture, and by our, I mean central and eastern Europe. In San Fransisco, there are regular meetings, called Mobile Monday, where speakers start by saying how many start ups they have failed, and it’s been seen as a their reference to wisdom. At the very end, they’ve learned a lot from all this failures. And it’s not limited only to San Francisco or Mobile Monday. It’s their culture, every failure gets you smarter. In US it's OK to fail.&lt;br /&gt;
&lt;br /&gt;
Have you heard a story about a Japanese train controller that committed suicide, when two trains in a row have been late because of his mistakes? The Europe may not be that extreme, but it’s still at least inappropriate to admit, that you ever made a mistake.&lt;br /&gt;
&lt;br /&gt;
If we never admit, if we never reflect, we never learn. So we are changing the rules for an hour. There is nothing good or bad without a context, and we would like to share the circumstances under which things don’t work. &lt;br /&gt;
&lt;br /&gt;
Things like:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;shared responsibility&lt;/li&gt;
&lt;li&gt;self organized teams&lt;/li&gt;
&lt;li&gt;gamification&lt;/li&gt;
&lt;li&gt;open source&lt;/li&gt;
&lt;li&gt;metaprogramming&lt;/li&gt;
&lt;li&gt;‘enterprise’ technologies&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
See yoy there.&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/8795604888160975763-8493104236211351109?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2012/03/beautiful-failures-at-33rd-degree.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-407218151626498050</guid><pubDate>Mon, 23 Jan 2012 20:08:00 +0000</pubDate><atom:updated>2012-01-23T23:49:26.978+01:00</atom:updated><title>How to get to TouK</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;This Tuesday, architect-wannabe group has it's meeting at TouK at 18:00. Since TouK is not an easy company to find, here's the video tutorial Piotr Przybylak asked for. It starts at Rondo Zesłańców Syberyjskich (driving from north). Hope it helps.&lt;br /&gt;
&lt;br /&gt;
Thanks to Maciej Próchniak for participation :) &lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/5e7J7SY0NtA/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/5e7J7SY0NtA?version=3&amp;f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;embed width="460" height="320"  src="http://www.youtube.com/v/5e7J7SY0NtA?version=3&amp;f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;And here is a map:&lt;br /&gt;
&lt;iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.pl/maps?f=d&amp;amp;source=s_d&amp;amp;saddr=Aleja+Prymasa+Tysi%C4%85clecia&amp;amp;daddr=Nieznana+droga&amp;amp;geocode=FcPHHAMd6NI_AQ%3BFYGyHAMd_M8_AQ&amp;amp;sll=52.215588,20.964961&amp;amp;sspn=0.01132,0.022788&amp;amp;vpsrc=6&amp;amp;hl=pl&amp;amp;mra=mift&amp;amp;mrsp=0&amp;amp;sz=16&amp;amp;ie=UTF8&amp;amp;ll=52.215588,20.964961&amp;amp;spn=0.01132,0.022788&amp;amp;t=m&amp;amp;output=embed"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;small&gt;&lt;a href="http://maps.google.pl/maps?f=d&amp;amp;source=embed&amp;amp;saddr=Aleja+Prymasa+Tysi%C4%85clecia&amp;amp;daddr=Nieznana+droga&amp;amp;geocode=FcPHHAMd6NI_AQ%3BFYGyHAMd_M8_AQ&amp;amp;sll=52.215588,20.964961&amp;amp;sspn=0.01132,0.022788&amp;amp;vpsrc=6&amp;amp;hl=pl&amp;amp;mra=mift&amp;amp;mrsp=0&amp;amp;sz=16&amp;amp;ie=UTF8&amp;amp;ll=52.215588,20.964961&amp;amp;spn=0.01132,0.022788&amp;amp;t=m" style="color:#0000FF;text-align:left"&gt;Show larger map&lt;/a&gt;&lt;/small&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/8795604888160975763-407218151626498050?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2012/01/how-to-get-to-touk.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-1787867644618660556</guid><pubDate>Thu, 12 Jan 2012 14:22:00 +0000</pubDate><atom:updated>2012-01-13T01:19:59.141+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>bash</category><category domain='http://www.blogger.com/atom/ns#'>git</category><title>Bash'ing your git deployment</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Chuck Norris deploys after every commit. Smart men deploy after every successful build on their Continuous Integration server. Educated men, deploy code directly from their distributed version control systems. I, being neither, had to write my deployment script in bash.&lt;br /&gt;
&lt;br /&gt;
We're using git and while doing so I wanted us to:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;deploy from working copy, but...&lt;/li&gt;
&lt;li&gt;make sure that you can deploy only if you committed everything&lt;/li&gt;
&lt;li&gt;make sure that you can deploy only if you pushed everything upstream&lt;/li&gt;
&lt;li&gt;tag the deployed hash&lt;/li&gt;
&lt;li&gt;display changelog (all the commits between two last tags)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Here are some BASH procedures I wrote on the way, if you need them:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;make sure that you can deploy only if you committed everything&lt;/b&gt;&lt;br /&gt;
&lt;pre class="brush: bash"&gt;verifyEverythingIsCommited() {
    gitCommitStatus=$(git status --porcelain)
    if [ "$gitCommitStatus" != "" ]; then
        echo "You have uncommited files."
        echo "Your git status:"
        echo $gitCommitStatus
        echo "Sorry. Rules are rules. Aborting!"
        exit 1
    fi
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;make sure that you can deploy only if you pushed everything upstream&lt;/b&gt;&lt;br /&gt;
&lt;pre class="brush: bash"&gt;verifyEverythingIsPushedToOrigin() {
    gitPushStatus=$(git cherry -v)
    if [ "$gitPushStatus" != "" ]; then
        echo "You have local commits that were NOT pushed."
        echo "Your 'git cherry -v' status:"
        echo $gitPushStatus
        echo "Sorry. Rules are rules. Aborting!"
        exit 1
    fi
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;tag the deployed hash&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Notice: my script takes first parameter as the name of the server to deploy to (this is $1 passed to this procedure). Also notice, that 'git push' without the '--tags' does not push your tags.&lt;br /&gt;
&lt;pre class="brush: bash"&gt;tagLastCommit() {
    d=$(date '+%y-%m-%d_%H-%M-%S')
    git tag "$1_$d"
    git push --tags
}
&lt;/pre&gt;&lt;br /&gt;
This creates nice looking tags like these:&lt;br /&gt;
preprod_12-01-11_15-16-24&lt;br /&gt;
prod_12-01-12_10-51-33&lt;br /&gt;
test_12-01-11_15-11-10&lt;br /&gt;
test_12-01-11_15-53-42&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;display changelog (all the commits between two last tags)&lt;/b&gt;&lt;br /&gt;
&lt;pre class="brush: bash"&gt;printChangelog() {
    echo "This is changelog since last deploy. Send it to the client."
    twoLastHashesInOneLine=$(git show-ref --tags -s | tail -n 2 | tr "\\n" "-");
    twoLastHashesInOneLineWithThreeDots=${twoLastHashesInOneLine/-/...};
    twoLastHashesInOneLineWithThreeDotsNoMinusAtTheEnd=$(echo $twoLastHashesInOneLineWithThreeDots | sed 's/-$//');
    git log --pretty=oneline --no-merges --abbrev-commit  $twoLastHashesInOneLineWithThreeDotsNoMinusAtTheEnd
}
&lt;/pre&gt;&lt;br /&gt;
The last command gives you a nice log like this:&lt;br /&gt;
e755c63 deploy: fix for showing changelog from two first tags instead of two last ones&lt;br /&gt;
926eb02 pringing changelog between last two tags on deployment&lt;br /&gt;
34478b2 added git tagging to deploy&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/8795604888160975763-1787867644618660556?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2012/01/bashing-your-git-deployment.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>3</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-960460022730937495</guid><pubDate>Thu, 12 Jan 2012 13:24:00 +0000</pubDate><atom:updated>2012-01-12T16:02:15.106+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>spring</category><title>Atom Feeds with Spring MVC</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;How to add feeds (Atom) to your web application with just two classes? &lt;br /&gt;
How about Spring MVC?&lt;br /&gt;
&lt;br /&gt;
Here are my assumptions:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;you are using Spring framework&lt;/li&gt;
&lt;li&gt;you have some entity, say “News”, that you want to publish in your feeds&lt;/li&gt;
&lt;li&gt;your "News" entity has creationDate, title, and shortDescription&lt;/li&gt;
&lt;li&gt;you have some repository/dao, say "NewsRepository", that will return the news from your database&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;you want to write as little as possible&lt;/li&gt;
&lt;li&gt;you don't want to format Atom (xml) by hand&lt;/li&gt;
&lt;/ul&gt;You actually do NOT need to use Spring MVC in your application already. If you do, skip to step 3.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Step 1: add Spring MVC dependency to your application&lt;/b&gt;&lt;br /&gt;
With maven that will be: &lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-webmvc&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;3.1.0.RELEASE&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Step 2: add Spring MVC DispatcherServlet&lt;/b&gt;&lt;br /&gt;
With web.xml that would be: &lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;servlet&amp;gt;
    &amp;lt;servlet-name&amp;gt;dispatcher&amp;lt;/servlet-name&amp;gt;
    &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;
    &amp;lt;init-param&amp;gt;
        &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
        &amp;lt;param-value&amp;gt;classpath:spring-mvc.xml&amp;lt;/param-value&amp;gt;
    &amp;lt;/init-param&amp;gt;
    &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
&amp;lt;/servlet&amp;gt;
&amp;lt;servlet-mapping&amp;gt;
    &amp;lt;servlet-name&amp;gt;dispatcher&amp;lt;/servlet-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/feed&amp;lt;/url-pattern&amp;gt;
&amp;lt;/servlet-mapping&amp;gt;
&lt;/pre&gt;Notice, I set the url-pattern to “/feed” which means I don't want Spring MVC to handle any other urls in my app (I'm using a different web framework for the rest of the app).  I also give it a brand new contextConfigLocation, where only the mvc configuration is kept.&lt;br /&gt;
&lt;br /&gt;
Remember that, when you add a DispatcherServlet to an app that already has Spring (from ContextLoaderListener for example), your context is inherited from the global one, so you should not create beans that exist there again, or include xml that defines them. Watch out for Spring context getting up twice, and refer to spring or servlet documentation to understand what's happaning. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Step 3. add ROME – a library to handle Atom format&lt;/b&gt;&lt;br /&gt;
With maven that is: &lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;net.java.dev.rome&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;rome&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Step 4. write your very simple controller&lt;/b&gt;  &lt;br /&gt;
&lt;pre class="brush: java"&gt;@Controller
public class FeedController {
    static final String LAST_UPDATE_VIEW_KEY = "lastUpdate";
    static final String NEWS_VIEW_KEY = "news";
    private NewsRepository newsRepository;
    private String viewName;

    protected FeedController() {} //required by cglib

    public FeedController(NewsRepository newsRepository, String viewName) {
        notNull(newsRepository); hasText(viewName);
        this.newsRepository = newsRepository;
        this.viewName = viewName;
    }

    @RequestMapping(value = "/feed", method = RequestMethod.GET)        
    @Transactional
    public ModelAndView feed() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName(viewName);
        List&amp;lt;News&amp;gt; news = newsRepository.fetchPublished();
        modelAndView.addObject(NEWS_VIEW_KEY, news);
        modelAndView.addObject(LAST_UPDATE_VIEW_KEY, getCreationDateOfTheLast(news));
        return modelAndView;
    }

    private Date getCreationDateOfTheLast(List&amp;lt;News&amp;gt; news) {
        if(news.size() &amp;gt; 0) {
            return news.get(0).getCreationDate();
        }
        return new Date(0);
    }
}
&lt;/pre&gt;And here's a test for it, in case you want to copy&amp;amp;paste (who doesn't?):&lt;br /&gt;
&lt;pre class="brush: java"&gt;@RunWith(MockitoJUnitRunner.class)
public class FeedControllerShould {
    @Mock private NewsRepository newsRepository;
    private Date FORMER_ENTRY_CREATION_DATE = new Date(1);
    private Date LATTER_ENTRY_CREATION_DATE = new Date(2);
    private ArrayList&amp;lt;News&amp;gt; newsList;
    private FeedController feedController;

    @Before
    public void prepareNewsList() {
        News news1 = new News().title("title1").creationDate(FORMER_ENTRY_CREATION_DATE);
        News news2 = new News().title("title2").creationDate(LATTER_ENTRY_CREATION_DATE);
        newsList = newArrayList(news2, news1);
    }

    @Before
    public void prepareFeedController() {
        feedController = new FeedController(newsRepository, "viewName");
    }

    @Test
    public void returnViewWithNews() {
        //given
        given(newsRepository.fetchPublished()).willReturn(newsList);
        
        //when
        ModelAndView modelAndView = feedController.feed();
        
        //then
        assertThat(modelAndView.getModel())
                .includes(entry(FeedController.NEWS_VIEW_KEY, newsList));
    }

    @Test
    public void returnViewWithLastUpdateTime() {
        //given
        given(newsRepository.fetchPublished()).willReturn(newsList);

        //when
        ModelAndView modelAndView = feedController.feed();

        //then
        assertThat(modelAndView.getModel())
                .includes(entry(FeedController.LAST_UPDATE_VIEW_KEY, LATTER_ENTRY_CREATION_DATE));
    }

    @Test
    public void returnTheBeginningOfTimeAsLastUpdateInViewWhenListIsEmpty() {
        //given
        given(newsRepository.fetchPublished()).willReturn(new ArrayList&amp;lt;News&amp;gt;());

        //when
        ModelAndView modelAndView = feedController.feed();

        //then
        assertThat(modelAndView.getModel())
                .includes(entry(FeedController.LAST_UPDATE_VIEW_KEY, new Date(0)));
    }
}
&lt;/pre&gt;Notice: here, I'm using fest-assert and mockito. The dependencies are:  &lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;dependency&amp;gt;
 &amp;lt;groupId&amp;gt;org.easytesting&amp;lt;/groupId&amp;gt;
 &amp;lt;artifactId&amp;gt;fest-assert&amp;lt;/artifactId&amp;gt;
 &amp;lt;version&amp;gt;1.4&amp;lt;/version&amp;gt;
 &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
 &amp;lt;groupId&amp;gt;org.mockito&amp;lt;/groupId&amp;gt;
 &amp;lt;artifactId&amp;gt;mockito-all&amp;lt;/artifactId&amp;gt;
 &amp;lt;version&amp;gt;1.8.5&amp;lt;/version&amp;gt;
 &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Step 5. write your very simple view&lt;/b&gt; &lt;br /&gt;
Here's where all the magic formatting happens. Be sure to take a look at all the methods of Entry class, as there is quite a lot you may want to use/fill.&lt;br /&gt;
&lt;pre class="brush: java"&gt;import org.springframework.web.servlet.view.feed.AbstractAtomFeedView;
[...]

public class AtomFeedView extends AbstractAtomFeedView {
    private String feedId = "tag:yourFantastiSiteName";
    private String title = "yourFantastiSiteName: news";
    private String newsAbsoluteUrl = "http://yourfanstasticsiteUrl.com/news/"; 

    @Override
    protected void buildFeedMetadata(Map&amp;lt;String, Object&amp;gt; model, Feed feed, HttpServletRequest request) {
        feed.setId(feedId);
        feed.setTitle(title);
        setUpdatedIfNeeded(model, feed);
    }

    private void setUpdatedIfNeeded(Map&amp;lt;String, Object&amp;gt; model, Feed feed) {
        @SuppressWarnings("unchecked")
        Date lastUpdate = (Date)model.get(FeedController.LAST_UPDATE_VIEW_KEY);
        if (feed.getUpdated() == null || lastUpdate != null || lastUpdate.compareTo(feed.getUpdated()) &amp;gt; 0) {
            feed.setUpdated(lastUpdate);
        }
    }

    @Override
    protected List&amp;lt;Entry&amp;gt; buildFeedEntries(Map&amp;lt;String, Object&amp;gt; model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        @SuppressWarnings("unchecked")
        List&amp;lt;News&amp;gt; newsList = (List&amp;lt;News&amp;gt;)model.get(FeedController.NEWS_VIEW_KEY);
        List&amp;lt;Entry&amp;gt; entries = new ArrayList&amp;lt;Entry&amp;gt;();
        for (News news : newsList) {
            addEntry(entries, news);
        }
        return entries;
    }

    private void addEntry(List&amp;lt;Entry&amp;gt; entries, News news) {
        Entry entry = new Entry();
        entry.setId(feedId + ", " + news.getId());
        entry.setTitle(news.getTitle());
        entry.setUpdated(news.getCreationDate());
        entry = setSummary(news, entry);
        entry = setLink(news, entry);
        entries.add(entry);
    }

    private Entry setSummary(News news, Entry entry) {
        Content summary = new Content();
        summary.setValue(news.getShortDescription());
        entry.setSummary(summary);
        return entry;
    }

    private Entry setLink(News news, Entry entry) {
        Link link = new Link();
        link.setType("text/html");
        link.setHref(newsAbsoluteUrl + news.getId()); //because I have a different controller to show news at http://yourfanstasticsiteUrl.com/news/ID
        entry.setAlternateLinks(newArrayList(link));
        return entry;
    }

}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Step 6. add your classes to your Spring context&lt;/b&gt;  &lt;br /&gt;
I'm using xml approach. because I'm old and I love xml. No, seriously, I use xml because I may want to declare FeedController a few times with different views (RSS 1.0, RSS 2.0, etc.).&lt;br /&gt;
&lt;br /&gt;
So this is the forementioned spring-mvc.xml&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"&amp;gt;

    &amp;lt;bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"&amp;gt;
        &amp;lt;property name="mediaTypes"&amp;gt;
            &amp;lt;map&amp;gt;
                &amp;lt;entry key="atom" value="application/atom+xml"/&amp;gt;
                &amp;lt;entry key="html" value="text/html"/&amp;gt;
            &amp;lt;/map&amp;gt;
        &amp;lt;/property&amp;gt;
        &amp;lt;property name="viewResolvers"&amp;gt;
            &amp;lt;list&amp;gt;
                &amp;lt;bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/&amp;gt;
            &amp;lt;/list&amp;gt;
        &amp;lt;/property&amp;gt;
    &amp;lt;/bean&amp;gt;

    &amp;lt;bean class="eu.margiel.pages.confitura.feed.FeedController"&amp;gt;
        &amp;lt;constructor-arg index="0" ref="newsRepository"/&amp;gt;
        &amp;lt;constructor-arg index="1" value="atomFeedView"/&amp;gt;
    &amp;lt;/bean&amp;gt;

    &amp;lt;bean id="atomFeedView" class="eu.margiel.pages.confitura.feed.AtomFeedView"/&amp;gt;
&amp;lt;/beans&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
And you are done.&lt;br /&gt;
&lt;br /&gt;
I've been asked a few times before to put all the working code in some public repo, so this time it's the other way around. I've describe things that I had already published, and you can grab the commit from the &lt;a href="https://bitbucket.org/margielm/confitura/changeset/7aa954b68d53"&gt;bitbucket&lt;/a&gt;.&lt;a href="https://bitbucket.org/margielm/confitura/changeset/7aa954b68d53"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Hope that helps.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-960460022730937495?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2012/01/atom-feeds-with-spring-mvc.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-1232661247362806680</guid><pubDate>Tue, 20 Sep 2011 15:56:00 +0000</pubDate><atom:updated>2011-09-20T17:59:18.422+02:00</atom:updated><title>JBoss Envers and Spring transaction managers</title><description>I've stumbled upon a bug with my configuration for JBoss Envers today, despite having integration tests all over the application. I have to admit, it casted a dark shadow of doubt about the value of all the tests for a moment. I've been practicing TDD since 2005, and frankly speaking, I should have been smarter than that.&lt;br /&gt;
&lt;br /&gt;
My fault was simple. I've started using Envers the right way, with exploratory tests and a prototype. Then I've deleted the prototype and created some integration tests using in-memory H2 that looked more or less like this example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;@Test
public void savingAndUpdatingPersonShouldCreateTwoHistoricalVersions() {
    //given
    Person person = createAndSavePerson();
    String oldFirstName = person.getFirstName();
    String newFirstName = oldFirstName + &amp;quot;NEW&amp;quot;;

    //when
    updatePersonWithNewName(person, newFirstName);

    //then
    verifyTwoHistoricalVersionsWereSaved(oldFirstName, newFirstName);
}

private Person createAndSavePerson() {
    Transaction transaction = session.beginTransaction();
    Person person = PersonFactory.createPerson();
    session.save(person);
    transaction.commit();
    return person;
}    

private void updatePersonWithNewName(Person person, String newName) {
    Transaction transaction = session.beginTransaction();
    person.setFirstName(newName);
    session.update(person);
    transaction.commit();
}

private void verifyTwoHistoricalVersionsWereSaved(String oldFirstName, String newFirstName) {
    List&amp;lt;Object[]&amp;gt; personRevisions = getPersonRevisions();
    assertEquals(2, personRevisions.size());
    assertEquals(oldFirstName, ((Person)personRevisions.get(0)[0]).getFirstName());
    assertEquals(newFirstName, ((Person)personRevisions.get(1)[0]).getFirstName());
}

private List&amp;lt;Object[]&amp;gt; getPersonRevisions() {
    Transaction transaction = session.beginTransaction();
    AuditReader auditReader = AuditReaderFactory.get(session);
    List&amp;lt;Object[]&amp;gt; personRevisions = auditReader.createQuery()
            .forRevisionsOfEntity(Person.class, false, true)
            .getResultList();
    transaction.commit();
    return personRevisions;
}
&lt;/pre&gt;&lt;br /&gt;
Because Envers inserts audit data when the transaction is commited (in a new temporary session), I thought I have to create and commit the transaction manually. And that is true to some point. &lt;br /&gt;
&lt;br /&gt;
My fault was that I didn't have an end-to-end integration/acceptance test, that would call to entry point of the application (in this case a service which is called by GWT via RPC), because then I'd notice, that the Spring @Transactional annotation, and calling transaction.commit() are two, very different things.&lt;br /&gt;
&lt;br /&gt;
Spring @Transactional annotation will use a transaction manager configured for the application. Envers on the other hand is used by subscribing a listener to hibernate's SessionFactory like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;&amp;lt;bean id=&amp;quot;sessionFactory&amp;quot; class=&amp;quot;org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean&amp;quot; &amp;gt;        
...
 &amp;lt;property name=&amp;quot;eventListeners&amp;quot;&amp;gt;
     &amp;lt;map key-type=&amp;quot;java.lang.String&amp;quot; value-type=&amp;quot;org.hibernate.event.EventListeners&amp;quot;&amp;gt;
         &amp;lt;entry key=&amp;quot;post-insert&amp;quot; value-ref=&amp;quot;auditEventListener&amp;quot;/&amp;gt;
         &amp;lt;entry key=&amp;quot;post-update&amp;quot; value-ref=&amp;quot;auditEventListener&amp;quot;/&amp;gt;
         &amp;lt;entry key=&amp;quot;post-delete&amp;quot; value-ref=&amp;quot;auditEventListener&amp;quot;/&amp;gt;
         &amp;lt;entry key=&amp;quot;pre-collection-update&amp;quot; value-ref=&amp;quot;auditEventListener&amp;quot;/&amp;gt;
         &amp;lt;entry key=&amp;quot;pre-collection-remove&amp;quot; value-ref=&amp;quot;auditEventListener&amp;quot;/&amp;gt;
         &amp;lt;entry key=&amp;quot;post-collection-recreate&amp;quot; value-ref=&amp;quot;auditEventListener&amp;quot;/&amp;gt;
     &amp;lt;/map&amp;gt;
 &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;

&amp;lt;bean id=&amp;quot;auditEventListener&amp;quot; class=&amp;quot;org.hibernate.envers.event.AuditEventListener&amp;quot; /&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Envers creates and collects something called AuditWorkUnits whenever you update/delete/insert audited entities, but audit tables are not populated until something calls AuditProcess.beforeCompletion, which makes sense. If you are using org.hibernate.transaction.JDBCTransaction manually, this is called on commit() when notifying all subscribed javax.transaction.Synchronization objects (and enver's AuditProcess is one of them).&lt;br /&gt;
&lt;br /&gt;
The problem was, that I used a wrong transaction manager.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;&amp;lt;bean id=&amp;quot;transactionManager&amp;quot; class=&amp;quot;org.springframework.jdbc.datasource.DataSourceTransactionManager&amp;quot; &amp;gt;
    &amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;dataSource&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
This transaction manager doesn't know anything about hibernate and doesn't use org.hibernate.transaction.JDBCTransaction. While Synchronization is an interface from javax.transaction package, DataSourceTransactionManager doesn't use it (maybe because of simplicity, I didn't dig deep enough in org.springframework.jdbc.datasource), and thus Envers works fine except not pushing the data to the database.&lt;br /&gt;
&lt;br /&gt;
Which is the whole point of using Envers.&lt;br /&gt;
&lt;br /&gt;
Use right tools for the task, they say. The whole problem is solved by using a transaction manager that is well aware of hibernate underneath.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;&amp;lt;bean id=&amp;quot;transactionManager&amp;quot; class=&amp;quot;org.springframework.orm.hibernate3.HibernateTransactionManager&amp;quot; &amp;gt;
    &amp;lt;property name=&amp;quot;sessionFactory&amp;quot; ref=&amp;quot;sessionFactory&amp;quot;/&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Lesson learned: always make sure your acceptance tests are testing the right thing. If there is a doubt about the value of your tests, you just don't have enough of them,&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-1232661247362806680?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/09/jboss-envers-and-spring-transaction.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-6250807521683503568</guid><pubDate>Sun, 11 Sep 2011 10:34:00 +0000</pubDate><atom:updated>2011-09-12T16:48:27.688+02:00</atom:updated><title>NoSQL devmeeting in Warsaw</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
I've spent this Saturday at &lt;a href="http://devmeetings.pl/trainings/bazy-nosqlowe-naturalny-storage-aplikacji-jsowych#c112"&gt;NoSQL devmeeting&lt;/a&gt; in Warsaw, organized by Adam Lider, Piotr Zwoliński and lead by David de Rosier. At first I was reluctant to go, as my level of js mastery is clearly negative, and I have only theoretical knowledge about NoSQL databases, but as Maciej Próchniak noticed, these are exactly the reasons why I should.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;a href="http://1.bp.blogspot.com/-QFB0aAngoDY/TmyM1BqgnfI/AAAAAAAABiM/eFcrVmHhl28/s1600/CIMG4758.JPG" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="300" src="http://1.bp.blogspot.com/-QFB0aAngoDY/TmyM1BqgnfI/AAAAAAAABiM/eFcrVmHhl28/s400/CIMG4758.JPG" width="400" /&gt;&lt;/a&gt;The meeting started at 9am and lasted till 9pm (though I had to leave at 7pm), with one-hour break for lunch. David began with a gentle but fantastic introduction to CouchDB, MongoDB, Cassandra and Redis, after which we were split into groups of 3-4, each taking one of the databases aforementioned. Our task was simple: with four big MySQL (partitioned) dumps on the local SVN, we were to migrate the data to our NoSQL DB and then prepare a simple twitter application in any language we want, preferably javascript using Node.js.&lt;br /&gt;
&lt;br /&gt;
Our group took the hard way of playing with Node.js, easing it up with the choice of MongoDB (as it seems to have the best community and thus support). Node.js was more of an obstacle than help, mainly because of it asynchronous nature, but it's quite possible that we just don't know how to write good code in it. We definitely didn't try much, being fine with “hey, it works!”, which is just right for the kind of hacking/prototyping we were into.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
We had no problems with MongoDB. With Barack Obama's 9 million followers in mind, we settled on the best model early, choosing eventual consistency and data duplication in the name of simplicity and query performance.&lt;br /&gt;
&lt;br /&gt;
Because I had to go two hours early, I've missed the part where we were to test the performance and try our luck with replication, but nonetheless this Saturday was clearly awesome. I loved the hackengarded at &lt;a href="http://33degree.org/"&gt;33rd Degree&lt;/a&gt;, but devmeetings are even more fabulous. The formula is superb. If I were to add anything, it would be an open review of each application at the end. I'm really curious how other teams did it.&lt;br /&gt;
&lt;br /&gt;
Checkout &lt;a href="http://devmeetings.pl/"&gt;devmeetings web page&lt;/a&gt; and if you have a chance to visit one, definitely go for it. It's great, it's free, and it's one of the best ways to learn something useful fast.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-Vzc6LQ0AAdE/TmyMoFogsDI/AAAAAAAABiE/CrfgYfUQnZQ/s1600/CIMG4753.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://3.bp.blogspot.com/-Vzc6LQ0AAdE/TmyMoFogsDI/AAAAAAAABiE/CrfgYfUQnZQ/s400/CIMG4753.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-6250807521683503568?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/09/nosql-devmeeting-in-warsaw.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-QFB0aAngoDY/TmyM1BqgnfI/AAAAAAAABiM/eFcrVmHhl28/s72-c/CIMG4758.JPG' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-2796234500600455545</guid><pubDate>Mon, 05 Sep 2011 11:47:00 +0000</pubDate><atom:updated>2011-09-07T14:53:51.872+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>RFP</category><title>How to write a good Request for Proposal</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;a name="HowToWriteAGoodRequestForProposal"&gt;&lt;/a&gt;&lt;br /&gt;
For the last month and a half, I've been busy writing offers in reply to Requests for Proposal (RFP) from many different companies: startups, big corporations and everything in between. Since the level of those RFPs vary, and since the quality of RFP always influences the price you get, I'd like to share a few tips, about how to write a good RFP without any knowledge in analysis, and how to get the lowest possible price.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
What is a Request for Proposal &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Simply put, it's a description of a non-existing system, for which software developers usually answer with a formal offer. &lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;(RFP) The publication by a prospective software&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; purchaser of details of the required system in order to&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; attract offers by software developers to supply it.&amp;nbsp; Software&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; development under contract starts with the selection of the&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; software developer by the customer.&amp;nbsp; A request for proposal&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (also called in Britain an "invitation to tender") is the&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; beginning of the selection process.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Bennatan, E.M., "Software Project Management", 2nd edition,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; McGraw-Hill International, 1992].&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Most RFPs require a fixed-price on the offer, because the buyer wants to know how much will it costs to make the system, and be able to compare both the potential value and prices.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;For whom it may concern...&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Before I get into details, bear in mind, these advices were written for projects up to a few man-years in size/scope. For anything bigger I'd strongly suggest starting with a short analysis as a separate project. Probably done by some other company. Beware of pure consulting companies though – they cost a lot and without the battlefield experience, often fail to create anything worth the money. Sometimes even jeopardizing projects with their choice of poor technologies and architectures. You'll be much safer asking a good software company, which is also able to provide the solution, to do the analysis.&lt;br /&gt;
&lt;br /&gt;
It's a pity but I've seen consultants working against their customers or against developers, for very trivial reason, coming directly from human psychology. Maslow's hierarchy of needs puts “respect by others” before morality, and a typical consultant without up to date battlefield experience, will never be respected by developers. So instead of helping, he'll do anything to make himself feel important, like fighting for features no one needs, or insisting on using SOA where it's completely useless. I've even seen whole projects, created for customers who couldn't understand them, wouldn't need them, and would abandon them right after spending a few men years in money and effort to create them, just because some out-of-place consultant used words like cloud and synergy to charm the CEO.&lt;br /&gt;
&lt;br /&gt;
Beware of anyone who speaks about synergy. Chances are, they already lost their connection with reality. Save yourself a lot of trouble and hire a real software provider to do the analysis instead.&lt;br /&gt;
&lt;br /&gt;
This post may also be useless, if you do not need a fixed-price offer and you have a trusted software company, that will play fair with you. But that's not common, unfortunately. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Why is the quality of RFP significant for the price?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In an ideal world, you just have to say that you need a developer's assistance, and some analyst will come to you to write down what you really want. Even things you are not aware of. In the ideal world, analysts work for free.&lt;br /&gt;
&lt;br /&gt;
But in the real world, resources are limited, and if you need something worth 300 man-days, the company usually doesn't want to risk more than 10 man-days (two people per week) before you decide whether you want to pay or not. 10 man-days may seem like a lot, except when you need to make a prototype, technology reconnaissance, understand the domain and propose valid estimations and formal documents, it's really not.&lt;br /&gt;
&lt;br /&gt;
This is the reason, why the developer often cannot have more than one or two meetings with the client before the offer is finished.&amp;nbsp; This is the reason why the quality of your RFP is crucial&lt;br /&gt;
&lt;br /&gt;
The less informative your request is, the higher the price will be. To understand that, you need to understand where the price on an offer comes from.&amp;nbsp; It usually consist of at least three components:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;the effort counted in man-days (function points and so on are finally translated to man-days at the end anyway)&lt;/li&gt;
&lt;li&gt;the margin, that the provider has to have, to pay for all the costs not directly connected with the project (this is where you pay for the offer itself)&lt;/li&gt;
&lt;li&gt;the uncertainty or fear&lt;/li&gt;
&lt;/ul&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;
The margin depends on many things, being lower mostly for companies that hire more developers than marketing/management people (which explains, why big companies are often so expansive, and why agile software houses like to stay small). &lt;br /&gt;
&lt;br /&gt;
The effort depends on the technology chosen, the internal experience of a company in given technology, the method (SCRUM being cheaper than full RUP with all the bells and whistles, but not that much compared to Open Unified Process, for example) and whatever libraries the company already has on hand.&lt;br /&gt;
&lt;br /&gt;
The uncertainty is where a large part of the price is placed. &lt;br /&gt;
&lt;br /&gt;
See, the company sending a formal offer for a fixed-price project, usually is bond by law, and has no way to change it later. The theory says our estimations at the beginning of the analysis may go wrong up to 400%. I've personally seen a project where the initial estimation of nine man-weeks turned out to be four man-years. Or another one, that turned from 42 man-months into 252. These are big differences that can bring a company down, and to cope with that, software providers have to have an uncertainty margin in their estimations. &lt;br /&gt;
&lt;br /&gt;
And you, as a client, do not want that.&lt;br /&gt;
&lt;br /&gt;
You don't want that, because either the price will be higher than possible (if their effort estimations were right, but risk factor too high), or the provider may go out of business (if estimations were very wrong) in which case you are screwed anyway. &lt;br /&gt;
&lt;br /&gt;
If you think you want to trick them just a bit to get the software for just a little under the cost, think again, because software companies in case of an emergency often try to reduce one thing which wasn't set in stone in the offer and is most difficult to verify: quality.&lt;br /&gt;
&lt;br /&gt;
You see, the famous tetrahedron of cost-scope-time-quality is wrong. It doesn't work that way. Not for software at least.&lt;br /&gt;
&lt;br /&gt;
I'll skip the trivial cost-time phenomena for a moment, we all know that adding more women won't bring the baby faster. Each project has a sweet spot in number of developers, above which the cost rises exponentially. Let me show you something different. Let me explain how quality works.&lt;br /&gt;
&lt;br /&gt;
Most developers usually work on one quality level – their maximum, which of course may be quite low anyway, but is still their top. A good developer will use all the techniques he is proficient with, A/B/TDD, self-documenting code, prototyping etc. because Uncle Bob is right saying, that the only way to go really fast is to go well. And we all hate debugging anyway.&lt;br /&gt;
&lt;br /&gt;
So the developer works at one quality level. Unless someone comes in and tells him to hurry up no matter what. And that someone may be a PM in panic, that can clearly see now, that the initial estimation was wrong, and the only way to not lose too much money is to cut wherever possible.&lt;br /&gt;
&lt;br /&gt;
This is a risky way, short sighted way, but may work if it slips by your acceptance tests. And so you, the client, are going to pay for it later, in change requests. And it works better, the bigger the customer is, the further away the guy accepting features is from the stakeholder and the user. &lt;br /&gt;
&lt;br /&gt;
Which explains why so many IT projects for public administration are totally fucked up.&lt;br /&gt;
&lt;br /&gt;
Some desperate companies even go so far, as to deliberately give you a price under the cost, knowing that they will charge insane amount of money on change requests later. But there is a solution to that: require all the providers to sell you non-obfuscated source code, with automatic tests, and make sure it's clear with them, that you will choose a company supporting the solution later. That should make them think twice.&lt;br /&gt;
&lt;br /&gt;
So you don't want to screw the provider, because at the end you will screw yourself. You want the best deal for your bucks, low support cost and you want to have o good relationship with the developer after the project is done, because trust is the biggest value in every business.&lt;br /&gt;
&lt;br /&gt;
Let's bring the price as low as possible, without loosing anything, by reducing fear and uncertainty with a few simple tips.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Use cases (interaction) instead of lists and screens&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You don't need to be a software analyst to be in need of a software solution, and so you may want to describe the idea for the software, that is in your mind, using screens, list of nouns and so on.&amp;nbsp; Analysts have discovered that the best way to write down requirements, is to use User Stories or informal Use-Cases (for the rest of this post, I'll forget about any formal differences between those two).&lt;br /&gt;
&lt;br /&gt;
What are those things? You don't need to read “Writing effective use cases” by Alistair Cockburn (though it is a great book), you just need to remember one thing:&amp;nbsp; describe interactions between the system and everything around it (users and other systems).&lt;br /&gt;
&lt;br /&gt;
Don't think about HOW user interface looks like, think about WHAT the user can do with it. &lt;br /&gt;
&lt;br /&gt;
I'll give you an example. If you write something like this&lt;/div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;user management panel&lt;/li&gt;
&lt;/ul&gt;&lt;div style="text-align: left;"&gt;there is a big uncertainty factor, because the implementation of this small otherwise task, may vary by 300%, depending on your actual needs.&amp;nbsp; But if you write something like this:&lt;/div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;administrator can delete users, change their roles, change their passwords, search them by email and login, and see their details&lt;/li&gt;
&lt;/ul&gt;&lt;div style="text-align: left;"&gt;my uncertainty drops close to zero, because I know exactly what I need and what I need not to implement.&lt;br /&gt;
&lt;br /&gt;
So write about&amp;nbsp; interactions the&amp;nbsp; system in your mind has with it's users and with other systems. And don't even try to be formal – it's not needed.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
No integration without interaction (and protocols)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
What do you think when you see something like this&lt;/div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;SSO integration&lt;/li&gt;
&lt;/ul&gt;&lt;div style="text-align: left;"&gt;That seems simple. SSO stands for Single Sign On, so we probably need to authenticate the user, right? Too bad that the real requirement looks like this:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;the user logs in to the system through our SSO, and if the user wants to register (sign-up), he should also be added through our SSO API with GUI in the portal&lt;/li&gt;
&lt;/ul&gt;Ha! So it's a bit more than logging in. But is it enough to estimate the effort and keep the fear margin close to zero?&lt;br /&gt;
&lt;br /&gt;
No.&lt;br /&gt;
&lt;br /&gt;
Because SSO is just a concept. There is no information about the actual protocol. And there are plenty on the market. Maybe it's Kerberos or NTLM? Or maybe it's OpenID? OAuth2 anybody? Or maybe it's LDAP, and we already have tons of libraries for that, no implementation needed. Or maybe, god forbid, it's some CORBA service that remembers the times when dragons and demons ruled the earth.&lt;br /&gt;
&lt;br /&gt;
This is a simple rule for requesting integration features: write about the INTERACTION (what the system wants to do from the business point of view) and about the PROTOCOL underneath. That's the minimum needed.&lt;br /&gt;
&lt;br /&gt;
And if you have some experience with given system/protocol, write those too, whether it's bad or good. That will help a lot, especially for proprietary technologies. If your lawyers allow for that, send us the docs or a code sample. Nothing is as risky as integration with a third-party that we know nothing about.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Write what you don't know&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;
With all the focus on putting all the knowledge you have about the system in the request, it's just as crucial to put there what you do not know.&lt;br /&gt;
&lt;br /&gt;
When people think about a fixed-price project, they usually think about a single price, but that's not the way it has to be. You may need the fixed-price to be able to compare different offers and make you feel safe, but it doesn't mean, you cannot have options.&lt;br /&gt;
&lt;br /&gt;
There is no way to make all the decisions before the project is started. Agile suggests to postpone making decisions to the last possible moment, because then, you know more and are able to make it more consciously. If you have a few ways to solve a given business problem, and do not see which one is better right away, you can ask us to estimate both solutions. If their costs differ, it may help you to choose. If not, let's leave it for later, just assume one of them is used.&lt;br /&gt;
&lt;br /&gt;
Options are good. We can even prepare a proposal with two or three stages, where with the first one, you'll get your working software with all crucial features, with the second all non-crucial features will be implemented, and we will leave the bells and whistles for the third stage. In fact, these is what we usually do. &lt;br /&gt;
&lt;br /&gt;
We have short cycles, we can get you new features on production every week, since our sprints are week long. Don't be afraid to write down what you don't know, or what you cannot decide yet on. We will prepare a few options and we will have that in mind, when creating the proposal.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;No more unidentified TLAs&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Even with my limited skills, I really like English, the lingua franca of IT. It's simple, elegant, and everything sounds better in it. But it has one big issue, polluting it from the mid-twenties: acronyms. And our industry is so full of them, it makes you want to Fornicate Under Consent of King.&lt;br /&gt;
&lt;br /&gt;
It's easy to call the customer and get them all right, finally, but do you really want to have so much time wasted (multiply TLAs by number of providers)? Remember, that the guys preparing an offer for you, also have just this much time, and they could spend it on lowering uncertainty/cost of some other part of your project, instead on guessing TLAs. Please, save us and yourself the trouble, and every first time you use a given TLA (three letter acronym), add a full name in the parenthesis. &lt;br /&gt;
&lt;br /&gt;
You know, it's not that big of a problem that we need to spend more time, finding out what you had on your mind, it's just that if there is a mistake, it's going to be painful. And there'll be mistakes, finally, because TLAs overlap, even in given context, and having so many of them, it's statistically unlikely we will always get everything right.&lt;br /&gt;
&lt;br /&gt;
Things get much worse, when the request for proposal mixes two or three languages (which is inevitable, unless the whole document is in English), because on top of English acronyms, we get German acronyms, Polish acronyms, and short names of products from vendors that no longer exists. It's an invitation for error. And you don't want us to be wrong with the estimation.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ask for CVs: companies are names, people are skills.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Some of our customers ask for Curriculum Vitae for every single person on the project. It's a great idea, because at the very end, it's not a company that creates software, it's the developer. Developers change their jobs quite often, and you may end up hiring a company with good references in the domain, only to find out, that the team is completely fresh to the subject. &lt;br /&gt;
&lt;br /&gt;
It may be as well, the other way around: getting a proposal from a company with absolutely no references, only to find out that it's started by experienced veterans, who left the other software provider, to create their own business. &lt;br /&gt;
&lt;br /&gt;
Skills matter, asking questions costs you nothing, so go ahead and ask for CVs, unless you want to find out that your critical project is created by two containers of first year students, that got hired for&amp;nbsp; a summer internship.&lt;br /&gt;
&lt;br /&gt;
A software house, having a lot of projects going, may not be able to guarantee that the developers in the offer will be there when you finally make up your mind to sign the contract, but should still provide you with potential CVs. And if it won't... well, have a lot of diapers ready because a few containers of freshmen are coming your way.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Meaningful performance expectations&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Performance requirements are included in nearly every request for proposal, and that's cool, because more often than not, the possible architecture depends on the traffic (number of messages, calls or users). I&amp;nbsp; don't need to be lightning fast for your 50 Intranet users, and a handful of messages per minute, I can focus on productivity and keep the price low. I may need to use CQRS with a fast no-SQL cache/database, eventual consistency, queues, partitioning and Hadoop with MapReduce, if&amp;nbsp; you want to have bazillions of users per second with possibility of tens-of-bazillions the next year on your existing hardware configuration. And that's a completely different effort.&lt;br /&gt;
&lt;br /&gt;
Or I may be required to present a hardware configuration that will do the trick with response time &amp;lt; 1 sec. Either way I need to know what your expectations are, but I need a bit more than&lt;/div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;expected number of users: 50 000&lt;/li&gt;
&lt;/ul&gt;&lt;div style="text-align: left;"&gt;Where are those users from? How is the traffic distributed throughout the day, week and month? What is a typical use case scenario? Finally: what are the expected peaks and how important is the response time for your business?&lt;br /&gt;
&lt;br /&gt;
You may not be able to answer, that's fine, but if you cannot, how do you expect us to guarantee the performance?&lt;br /&gt;
&lt;br /&gt;
Sometimes I read something like: up to 50 requests per second in peaks on SPARC M8000 with 16 processors. These are valid requirements, knowing that those 16 processors have 64 cores together, I know that if I keep the response time at less than a second for a request on one core, I should be fine. And that doesn't seem like a problem event though I can't prove it, because I only have access to Intel's Xeons and the software doesn't exist yet. I can still prepare a little benchmark or a proof-of-concept. Here I keep my risk factor low.&lt;br /&gt;
&lt;br /&gt;
But 50 000 users on three AMD's Opterons? Hell if I know. I've been building sites for 2mln users on that configuration, so it looks fine, but the question is what peaks look like? So I'm going to add a bit to cover that risk, and a few days at least for optimization.&lt;br /&gt;
&lt;br /&gt;
If you want to have the price low in the offer you get, either write the details about peaks or don't ask for a guarantee. Ask for performance and give your expectations, and we'll keep that in mind and do everything to get you that performance, but guarantees are possible only when we can prove something, and more often than not, we can't. Usually it's just a bet, so you'll be paying extra for this risk. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Bird's eye view is nice, details are crucial&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Sometimes the system in scope is so large, that the request is for just a part of it. It's a good idea to get your potential providers to understand the big picture, but it's even more important to make it clear, what your expectation as to their job is. &lt;br /&gt;
&lt;br /&gt;
We had a request for a system that looked like a hardware plus embedded software solution. We were going to reject it, not even trying, because we don't do hardware, and our skills with given embedded technology is negligible. But a question remained: why would they even send us this request, knowing very well what we do, and what we don't. Trying to figure it, we found out, that our job would be only to prepare an integration point and all the embedded software would be written by another company, waiting for us to give them an API.&lt;br /&gt;
&lt;br /&gt;
When you are describing the ecosystem the software is going to live in, make sure you are clear as to what a given software house is supposed to create. Otherwise, you may not get an answer at all from some of them, giving you less choice.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;How much do you have (for startups only)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
With startups, the first question I always ask is: how much money do you have?&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Funny, isn't? The whole point of a request for proposal is to find out, how much would the system cost from different providers, and yet I ask for how much they want to spend at the very beginning.&lt;br /&gt;
&lt;br /&gt;
And while I would always like to know it, when preparing an offer, I'm only asking startups.&lt;br /&gt;
&lt;br /&gt;
Why?&lt;br /&gt;
&lt;br /&gt;
Because, existing companies are more flexible with their money. The software is there to help them achieve their business goal and if they need to invest more, to get more, they may go for it. Startups usually don't have that choice. Startups have an idea, that will hopefully bring tons of money, and they have some initial funding, that has to be enough.&lt;br /&gt;
&lt;br /&gt;
So I need to know, what part of the funding is for IT, so that I can find a solution that may be acceptable. If the money seems like no-way for all the requirements, maybe we can split them into two: one part to get the business going, the other, when you finally start making some money. It's easier to find additional funding, when you can at least cover your costs. Or perhaps, we need to change a non-crucial part of your business idea for the first year, the cut the cost dramatically, and get you going. Maybe we can get you an off-the-shelf open source system for the parts that do not build your market advantage on. There ale plenty of possibilities.&lt;br /&gt;
&lt;br /&gt;
I've also seen a few lucky startups, that couldn't invest too little in the IT of their business, because the investor wasn't interested in spending a mere few hundred thousand, to get a million back. The investor wanted to spend a few million to get back a few hundred million. &lt;br /&gt;
&lt;br /&gt;
That's cool with me, but let me know from the start, because then, I'll go for solutions better fitting your capabilities.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Call me / email me if you can't write it formally&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Frankly speaking, if I was the owner of the software house responding to requests for proposal, I wouldn't have&amp;nbsp; balls to sign half the contracts we do.&amp;nbsp; At least with corporations. Most of the requests have ugly sections, from even uglier lawyers, that generally require you to sell your soul and your wife, in case the other side requires it.&lt;br /&gt;
&lt;br /&gt;
You know how long one can negotiate a Non-Disclosure Agreement, before finally getting the request for proposal? A month. That's how long it takes, before the lawyer finally understands, that he cannot prohibit us from working for ALL THE OTHER companies in the world, just because he wishes so.&lt;br /&gt;
&lt;br /&gt;
Anyway, apart from legal formalities, corporations often have their request templates polluted with all sorts of smelly stuff, that implies a starting cost.&lt;br /&gt;
&lt;br /&gt;
For example, an Intranet application template is being used for a public Internet application, and as a result we are asked to prepare a formal end-user documentation in doc format. Seriously? Come on, find me a single user that would download and read a doc before using the site. Can we get you a context help instead (which we will implement anyway)?&lt;br /&gt;
&lt;br /&gt;
And the answer is: no ;)&lt;br /&gt;
&lt;br /&gt;
No ;) Means we, the corporation, need a formal doc document because this is the way some consulting company (gaaah!) years ago decided, and charged us a million for preparing these templates, and it's not in my power to change that, but ;) also means nobody's going to read it, and you can produce those docs from the context help, if that brings the price down. And yes, in my private opinion, context help will be of much better use than a doc.&lt;br /&gt;
&lt;br /&gt;
Same story with RUP. Do you guys really need that? Is Open Unified Process (which adopts the core of RUP, while being more agile) enough? Sometimes you do not care, it's just the template that says RUP.&lt;br /&gt;
&lt;br /&gt;
The easiest way to keep the price low is to call us. Tell us what you really don't care about, and what is there just because of the consulting company.&lt;br /&gt;
&lt;br /&gt;
I'd be scared to sign a document which obliges me to formal things I won't do (I've done that once, and now I have to, theoretically: “consult all important life decisions with the bank”), but my bosses have more experience in that matter (or just cojones) and understanding with our clients, for whom we've been working from their very beginning.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Everything changes (be agile or be dead)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It's quite embarrassing, that even in 2011, some companies literally stick to the offer. It may be because of fear and the potential legal consequences, but this is not the way it should be and it's not the way we work.&lt;br /&gt;
&lt;br /&gt;
If you do not play dirty, good software houses will always welcome change. Let us make decision whether we can handle it within our budget, and if we can, we won't bother you with an official change request (CR) or invoice/agreement for every change. If we won't, let us find a cheaper way, to meet your business needs. We are here to cooperate, and we want to have you happy at the end of the project, because we want you to trust us. We are playing on the same side. At the end of the day, we want you to flourish, and we want to sent us another request for proposal, when you'll be in a need of another software solution.&lt;br /&gt;
&lt;br /&gt;
We will make you secure, by selling you well written sources and using open-sourced libraries, by creating tons of tests, so that another company can easily take over the support if you wish so.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
This is all old news, Open Source movement and Agile movement, have been here so long it should be crystal clear, it's better to play together this way.&lt;br /&gt;
&lt;br /&gt;
If you have a negative experience with a company over-charging you for changes, just don't send them another request for proposal, but don't think everybody behaves like that. &lt;br /&gt;
&lt;br /&gt;
Or maybe, you just bought under-priced software, and the company is getting back the money this way? Hmmm....&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-2796234500600455545?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/09/how-to-write-good-request-for-proposal.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-4941939373435329605</guid><pubDate>Fri, 15 Apr 2011 11:58:00 +0000</pubDate><atom:updated>2011-04-15T14:01:36.618+02:00</atom:updated><title>How to test Spring session scoped beans</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
I wanted to use the http session just as a repository (database/files), to keep facebook access token for currently logged user. While I can manipulate session directly, another option is to declare the class as a session scoped bean in Spring.  Something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;public class RepositoryOnHttpSession {
    private String facebookAccessToken;

    public FacebookTemplate getFacebookTemplate() {
        return new FacebookTemplate(facebookAccessToken);
    }

    public void setFacebookAccessToken(String facebookAccessToken) {
        this.facebookAccessToken = facebookAccessToken;
    }    
}
&lt;/pre&gt;
&lt;pre class="brush: java"&gt;&amp;lt;bean id="repositoryOnHttpSession" class="pl.touk.storytelling.infrastructure.repositories.RepositoryOnHttpSession" scope="session"&amp;gt;
    &amp;lt;aop:scoped-proxy/&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;
&amp;lt;aop:scoped-proxy/&amp;gt; makes Spring IoC container create a cglib proxy, and inject that to other singleton type beans instead. All nice and cool, except integration tests (which get Spring IoC container to inject all the dependencies) are blowing up with:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;java.lang.IllegalStateException: No Scope registered for scope 'session'&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
While there's a lot of solutions to be googled (including redeclaring the object as a prototype/sinlgeton for test context, injecting mock http session and request), the easiest way to have a simple thread-bound session scope is just to declare it in the &lt;b&gt;TEST&lt;/b&gt; IoC configuration, like below. Just keep in mind that junit fires all tests in a single thread by default, so the state is persisted between tests. You may need to clean it up in @After.&lt;br /&gt;
&lt;pre class="brush: java"&gt;&amp;lt;bean class="org.springframework.beans.factory.config.CustomScopeConfigurer"&amp;gt;
    &amp;lt;property name="scopes"&amp;gt;
        &amp;lt;map&amp;gt;
            &amp;lt;entry key="session"&amp;gt;
                &amp;lt;bean class="org.springframework.context.support.SimpleThreadScope"/&amp;gt;
            &amp;lt;/entry&amp;gt;
        &amp;lt;/map&amp;gt;
    &amp;lt;/property&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-4941939373435329605?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/04/how-to-test-spring-session-scoped-beans.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>4</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-5835018028915359428</guid><pubDate>Fri, 01 Apr 2011 12:01:00 +0000</pubDate><atom:updated>2011-04-01T15:27:54.513+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>spring</category><title>Spring Security by example: OpenID (login via gmail)</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
This is a part of a simple Spring Security tutorial:&lt;br&gt;
&lt;br&gt;
1. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-set-up-and.html"&gt;Set up and form authentication &lt;/a&gt;&lt;br&gt;
2. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-user-in.html"&gt;User in the backend (getting logged user, authentication, testing)&lt;/a&gt;&lt;br&gt;
3. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing-web.html"&gt;Securing web resources&lt;/a&gt;&lt;br&gt;
4. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing.html"&gt;Securing methods&lt;/a&gt;&lt;br&gt;
5. &lt;b&gt;OpenID (login via gmail)&lt;/b&gt;&lt;br&gt;
6. OAuth2 (login via Facebook)&lt;br&gt;
7. Writing on Facebook wall with Spring Social&lt;br&gt;
&lt;br&gt;
OpenID is to form authentication, what DVCS is to centralized version control system.&lt;br&gt;
&lt;br&gt;
Ok, but without the technical mumbo-jumbo: OpenID allows the user to use one account (like Gmail) to login to other services (websites) without having to remember anything and without worries about password security.&lt;br&gt;
&lt;br&gt;
Easy enough?&lt;br&gt;
&lt;br&gt;
And the best part is: chances are, you already have an account which is a provider to OpenID. Are you registered on Gmail, Yahoo, or even Blogger? You can already use it to login to other sites.&lt;br&gt;
&lt;br&gt;
But why would you? Isn&amp;#39;t login/password good enough?&lt;br&gt;
&lt;br&gt;
Have you ever wondered whether the service you are logging to, uses one-way password hashing or keeps the password as open text? Most users do not create password per site because they cannot remember more than, let&amp;#39;s say, three passwords. If one site keeps their password as open text, they are practically screwed. And more often than not, it&amp;#39;s the site that has the worst (or non-existing) security. Welcome to hell: all your bases are belong to us.&lt;br&gt;
&lt;br&gt;
By the way, I know of only one site, which does SHA hashing on the client side (in javascript), so that the server has no way of knowing what the real password is: sprezentuj.pl&lt;br&gt;
&lt;br&gt;
Kudos for that, though it smells like overengineering a bit :)&lt;br&gt;
&lt;br&gt;
OpenID is pretty simple, and the process description at &lt;a href="http://en.wikipedia.org/wiki/OpenID"&gt;Wikipedia&lt;/a&gt; is practically everything you need, but as they say, one picture is worth 1000 words, so let&amp;#39;s look at a  picture. There is a loot you can find with google, but most of them are in big-arrows-pointing-some-boxes-notation, and I find easier to read a sequence diagram, so here is my take on it:&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;&lt;a href="http://blog.solidcraft.eu/2011/04/spring-security-by-example-openid-login.html#more"&gt;Read more »&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-5835018028915359428?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/04/spring-security-by-example-openid-login.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-yfS2BamMjzY/TZW0GY0vJCI/AAAAAAAABGM/tos0wq9YgW4/s72-c/jnbOpenIdDiagram+v2.png' height='72' width='72'/><thr:total>11</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-5622510864366091317</guid><pubDate>Fri, 01 Apr 2011 09:26:00 +0000</pubDate><atom:updated>2011-04-01T11:27:46.024+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>spring</category><title>Read emails from imap with Spring Intergration</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
What&amp;#39;s the easiest way to read emails from IMAP account in Java? Depends what your background is. If you have any experience in Apache Camel, ServiceMix, Mule, you already know the answer. If you don&amp;#39;t, and your application is using Spring already, Spring-Integration may be the solution for you.&lt;br&gt;
&lt;br&gt;
It&amp;#39;s not a one-liner like what you could do with Camel, but it&amp;#39;s still quite easy to understand.&lt;br&gt;
&lt;br&gt;
Spring Integration has &lt;a href="http://static.springsource.org/spring-integration/reference/htmlsingle/"&gt;great docs&lt;/a&gt; and there are &lt;a href="http://java.dzone.com/articles/spring-integration-hands-0"&gt;nice tutorials&lt;/a&gt; around, but if you just want to get it running first and dig into the docs later, here is a quick example for you.&lt;br&gt;
&lt;br&gt;
To make it work, you need three steps:&lt;br&gt;
&lt;/div&gt;&lt;a href="http://blog.solidcraft.eu/2011/04/read-emails-from-imap-with-spring.html#more"&gt;Read more »&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-5622510864366091317?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/04/read-emails-from-imap-with-spring.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-569068469560889670</guid><pubDate>Wed, 30 Mar 2011 16:37:00 +0000</pubDate><atom:updated>2011-03-30T18:44:21.362+02:00</atom:updated><title>How to get to Agile Warsaw (Aenima)</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;a href="http://agilewarsaw.com/"&gt;Agile Warsaw&lt;/a&gt; is a great, open group, but there is one problem with where all the meetings take place: it's easy to get lost in the building if you have never been to &lt;a href="http://aenima.pl/"&gt;Aenima&lt;/a&gt; before. Together with Piotr Modrzyk we've recorder a short video, that may help a bit all the newcomers.&lt;br /&gt;
&lt;br /&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/xrO2x5LpDXE/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/xrO2x5LpDXE?f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" /&gt;



&lt;param name="bgcolor" value="#FFFFFF" /&gt;



&lt;embed width="640" height="532" src="http://www.youtube.com/v/xrO2x5LpDXE?f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-569068469560889670?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/03/how-to-get-to-agile-warsaw-aenima.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-9050914799910749577</guid><pubDate>Wed, 30 Mar 2011 15:52:00 +0000</pubDate><atom:updated>2011-08-17T11:43:13.224+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>spring</category><title>Spring Security by example: securing methods</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
This is a part of a simple Spring Security tutorial:&lt;br&gt;
&lt;br&gt;
1. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-set-up-and.html"&gt;Set up and form authentication &lt;/a&gt;&lt;br&gt;
2. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-user-in.html"&gt;User in the backend (getting logged user, authentication, testing)&lt;/a&gt;&lt;br&gt;
3. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing-web.html"&gt;Securing web resources&lt;/a&gt;&lt;br&gt;
4. &lt;b&gt;Securing methods&lt;/b&gt;&lt;br&gt;
5. &lt;a href="http://blog.solidcraft.eu/2011/04/spring-security-by-example-openid-login.html"&gt;OpenID (login via gmail)&lt;/a&gt;&lt;br&gt;
6. OAuth2 (login via Facebook)&lt;br&gt;
7. Writing on Facebook wall with Spring Social&lt;br&gt;
&lt;br&gt;
Securing web resources is all nice and cool, but in a well designed application it&amp;#39;s more natural to secure methods (for example on backend facade or even domain objects). While we may get away with role-based authorization in many intranet business applications, nobody will ever handle assigning roles to users in a public, free to use Internet service.  We need authorization based on rules described in our domain.&lt;br&gt;
&lt;br&gt;
For example: there is a service &lt;a href="http://alterstory.com/"&gt;AlterStory&lt;/a&gt;, that allows cooperative writing of stories, where one user is a director (like a movie director), deciding which chapter proposed by other authors should make it to the final story.  &lt;br&gt;
&lt;br&gt;
The method for accepting chapters, looks like this:&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;&lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing.html#more"&gt;Read more »&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-9050914799910749577?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>9</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-6373407245786783271</guid><pubDate>Wed, 30 Mar 2011 14:23:00 +0000</pubDate><atom:updated>2011-04-01T15:23:59.456+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>spring</category><title>Spring Security by example: securing web resources</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
This is a part of a simple Spring Security tutorial:&lt;br&gt;
&lt;br&gt;
1. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-set-up-and.html"&gt;Set up and form authentication &lt;/a&gt;&lt;br&gt;
2. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-user-in.html"&gt;User in the backend (getting logged user, authentication, testing)&lt;/a&gt;&lt;br&gt;
3. &lt;b&gt;Securing web resources&lt;/b&gt;&lt;br&gt;
4. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing.html"&gt;Securing methods&lt;/a&gt;&lt;br&gt;
5. &lt;a href="http://blog.solidcraft.eu/2011/04/spring-security-by-example-openid-login.html"&gt;OpenID (login via gmail)&lt;/a&gt;&lt;br&gt;
6. OAuth2 (login via Facebook)&lt;br&gt;
7. Writing on Facebook wall with Spring Social&lt;br&gt;
&lt;br&gt;
Securing web resources means making sure that only users with granted authority will be able to visit given URL.&lt;br&gt;
&lt;br&gt;
Let&amp;#39;s say we have a page “protected.html” that should be accessed only by our admin. First thing we have to do, is to define which URLs are  protected and which are accessible for anonymous user. We do that by adding intercept-url tags and a decision manager to the http tag:
&lt;br&gt;
&lt;/div&gt;&lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing-web.html#more"&gt;Read more »&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-6373407245786783271?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing-web.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-4544529857996623196</guid><pubDate>Wed, 30 Mar 2011 13:02:00 +0000</pubDate><atom:updated>2011-06-01T17:29:00.407+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>spring</category><title>Spring Security by example: user in the backend, testing</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
This is a part of a simple Spring Security tutorial:&lt;br&gt;
&lt;br&gt;
1. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-set-up-and.html"&gt;Set up and form authentication &lt;/a&gt;&lt;br&gt;
2. &lt;b&gt;User in the backend (getting logged user, authentication, testing)&lt;/b&gt;&lt;br&gt;
3. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing-web.html"&gt;Securing web resources&lt;/a&gt;&lt;br&gt;
4. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing.html"&gt;Securing methods&lt;/a&gt;&lt;br&gt;
5. &lt;a href="http://blog.solidcraft.eu/2011/04/spring-security-by-example-openid-login.html"&gt;OpenID (login via gmail)&lt;/a&gt;&lt;br&gt;
6. OAuth2 (login via Facebook)&lt;br&gt;
7. Writing on Facebook wall with Spring Social&lt;br&gt;
&lt;br&gt;
While login by form, OpenID, OAuth2 and so on may be cool, we may often need to do login/logout in the backend. Finally, we will need a way to get currently logged user. Working with Spring Security, we may do all of that using two classes: SecurityContextHolder and AuthenticationManager. Instead of explaining their API (docs are better) let me show you an implementation of an easy to use service. Our interface looks like this:&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;&lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-user-in.html#more"&gt;Read more »&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-4544529857996623196?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/03/spring-security-by-example-user-in.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-3957840659556666864</guid><pubDate>Mon, 28 Mar 2011 16:36:00 +0000</pubDate><atom:updated>2011-08-22T13:32:14.740+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>spring</category><title>Spring Security by example: set up and form authentication</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Spring Security (former Acegi) is a Java library that handles authorization and authentication in web applications. Documentation on the project &lt;a href="http://static.springsource.org/spring-security/site/"&gt;web site&lt;/a&gt; is, as expected from Spring Source, easy to read and use. I have a feeling though, that most of us first search Google for a fast, technology tutorial, before reading the docs, so in this little article I&amp;#39;m going to show you a few things Spring Security can do, give you a few hints and code snippets I have, after using it a little bit here and there. I&amp;#39;m not going to explain everything throughly, that&amp;#39;s what docs are for, but what is here should help to get you started (or decide whether you want to).&lt;br&gt;
&lt;br&gt;
Since this is quite a lot of text for a blog post.&lt;br&gt;
&lt;br&gt;
Here is the plan:&lt;br&gt;
&lt;br&gt;
1. &lt;b&gt;Set up and form authentication &lt;/b&gt;&lt;br&gt;
2. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-user-in.html"&gt;User in the backend (getting logged user, authentication, testing)&lt;/a&gt;&lt;br&gt;
3. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing-web.html"&gt;Securing web resources&lt;/a&gt;&lt;br&gt;
4. &lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-securing.html"&gt;Securing methods&lt;/a&gt;&lt;br&gt;
5. &lt;a href="http://blog.solidcraft.eu/2011/04/spring-security-by-example-openid-login.html"&gt;OpenID (login via gmail)&lt;/a&gt;&lt;br&gt;
6. OAuth2 (login via Facebook)&lt;br&gt;
7. Writing on Facebook wall with Spring Social&lt;br&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;&lt;/div&gt;&lt;a href="http://blog.solidcraft.eu/2011/03/spring-security-by-example-set-up-and.html#more"&gt;Read more »&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-3957840659556666864?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/03/spring-security-by-example-set-up-and.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>5</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-4717627171446278772</guid><pubDate>Sun, 06 Feb 2011 18:46:00 +0000</pubDate><atom:updated>2011-02-08T00:20:48.287+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>agile</category><category domain='http://www.blogger.com/atom/ns#'>craftsmanship</category><title>Animating Developers, 4 months later</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Four months ago I had a chance to present Agile Skills Project and experiments we do at TouK, to create a learning ecosystem and culture of constant improvement. Time to report progress of our experiments.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Map of New Ideas&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
The request came from our HQ (Headquarters, which is our group of main company owners): lets use Jira to gather ideas and initiatives about how to improve our company. You know, Keizen style.&lt;br /&gt;
&lt;br /&gt;
The reasoning is, that though some people, including myself, always loudly present their opinions, new concepts, and basically try to change the company from the ground up (whether the stakeholders like it or not), others need some encouragement and a safe way to suggest ideas for improvement. &lt;br /&gt;
&lt;br /&gt;
Our map of new ideas is a simple Jira project, where anybody can suggest anything he/she thinks is worthwhile. The new idea is verified by a group responsible for deciding whether it's in line with company's profile and possible with our current resources. If so, the idea and needed resources, are assigned to someone who, from now on, is responsible for making it happen. It doesn't have to be the person proposing the idea, but quite often it is. The ideas are also grouped by the area they correspond to, one from culture, evolution, fitness, relations, survival or contribution.&lt;br /&gt;
&lt;br /&gt;
As for the moment, our statistics look as follow:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;Proposed: 36&lt;/li&gt;
&lt;li&gt;Selected: 6 (waiting for a victim)&lt;/li&gt;
&lt;li&gt;Assigned: 8 (but not started yet)&lt;/li&gt;
&lt;li&gt;Ongoing: 6&lt;/li&gt;
&lt;li&gt;Refused: 1&lt;/li&gt;
&lt;li&gt;Finished: 26&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;
Things that appear on the map vary, including for example other experiments described here (Weekly Workshops, OCRs), open sourcing some libraries, drawing diagrams of all the systems we create for our main clients (very useful for new developers) or creating database environment for regression tests on Oracle.&lt;br /&gt;
&lt;br /&gt;
As you see, it goes quite well, and I believe it's a great way to get your developers involved in the company improvement. As a side effect, people feel they have more influence over where the company is heading, which is always good and gives a nice motivational kick (“Hey look, now I'm not only building software, I'm building my company as well!”).&lt;br /&gt;
&lt;br /&gt;
Thing to remember: this is a map for company-wide ideas. In the beginning there was a confusion over whether stuff about how to improve one's project/team should be here, but since our teams are self-organized, there is no need to involve the rest of our company. The power is in one's hands anyway.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;Weekly Workshops&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Every Friday at 4pm, we have a one hour long technology workshop open to everyone. It usually takes the form of a lecture, with slides, some coding, and examples, but the form is open. Other features are not, and that is very important for it's success.&lt;br /&gt;
&lt;br /&gt;
This is a concept I've borrowed from Supermedia Interactive, when Piotr Szarwas was still the head of the development department and my boss. I'm sure it's popular in many companies, but Piotr taught me how to do it correctly.&lt;br /&gt;
&lt;br /&gt;
The goal is to share knowledge and learn new things.&lt;br /&gt;
&lt;br /&gt;
The date and time are set in stone. Every Friday, 4pm. It's during our work hours, so we had to choose time, which won't stop or slow down our normal development. Since our sprints are week long, Friday 4pm is usually after the retrospective anyway. Let's face it: at 4pm on Friday, we are either busy putting down some fires, learning, or slacking off anyway.&lt;br /&gt;
&lt;br /&gt;
Everyone can present anything, as long as there are people who want to listen to. We keep a calendar on confluence for coordination. We also have a page with suggested topics, where people put things they would like to listen about, for others to pick up and investigate. One rule is very important thought: if we do not have a volunteer for next Friday, we are going to pick one. &lt;br /&gt;
&lt;br /&gt;
Yes, the participation (as a lecturer) is mandatory for everyone. It basically means, each developer should give at least one lecture per year. No excuses.&lt;br /&gt;
&lt;br /&gt;
At first, there was some turmoil about that. People do not like to be forced to do anything. But the first drawing showed that it's a good idea. Randomly chosen people were giving great presentations. The reason is, that everyone has something interesting to show, it's just that a carrot of general appreciation is not enough sometimes. Sometimes you also need a stick. That's how a human mind works.&lt;br /&gt;
&lt;br /&gt;
So what are our workshops about? Here are a few topic examples:&lt;/div&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;Clojure – lisp for java programmers.&lt;/li&gt;
&lt;li&gt;Rapid Application&amp;nbsp; Development using Grails and Vaadin&lt;/li&gt;
&lt;li&gt;Smartclient: RAD even faster.&lt;/li&gt;
&lt;li&gt;Apache Hadoop and projects around it.&lt;/li&gt;
&lt;li&gt;JBoss Envers – easy entity auditing&lt;/li&gt;
&lt;li&gt;How to get users from Gmail and Facebook: OAuth 2.0, OpenId, Spring Security and Spring Social in web applications&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: left;"&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Weekly OCRs&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I've already described that&amp;nbsp; in &lt;a href="http://blog.solidcraft.eu/2010/05/open-code-review.html"&gt;here&lt;/a&gt; so I'm not going to repeat myself. What has changed, is that we have it on a weekly basis, we have it split in two: java and database OCRs separately, and that we have designated people responsible for making it happen (not for leading the meeting, but for choosing a victim, if there is no volunteer).&lt;br /&gt;
&lt;br /&gt;
Java OCRs are held on Friday at 3pm, for all the same reasons as given above for workshops.&lt;br /&gt;
&lt;br /&gt;
I've noticed that some people see it as a chance to brainstorm and refactor some really troublesome code, they work with, which they normally do not want or have no time to touch. That is a great idea, and since we use our own code for OCRs, and since we actually try to commit the changes, it's more like getting help for your project, than only sharing some thoughts.&lt;br /&gt;
&lt;br /&gt;
Database teams do it in a little different way, but not being there, I'm not inclined to explain it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Quest system during work hours&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The quest ecosystem described on &lt;a href="http://www.agileskillsproject.org/quests"&gt;Agile Skills Project web site&lt;/a&gt;, about which I've been talking on &lt;a href="http://blog.solidcraft.eu/2010/10/video-from-my-presentation-at-agile.html"&gt;Agile Warsaw&lt;/a&gt; is a great self-motivational tool, but the question we had, was how a company can help people get it started? My idea was, that having everyone choose his own mentor and booking an hour a month to talk with him about the progress or lack thereof, can do the trick. But that assumes, people are working back home to meet their goals, which is not true for everyone. Witek Wolejszo wanted to check whether making it a work-time activity will spread the technique to those, who don't want to use their free time.&lt;br /&gt;
&lt;br /&gt;
Eight people with different background and free time activity were chosen for a month long experiment, where they would choose an educational goal and try to achieve it within working hours.&lt;br /&gt;
&lt;br /&gt;
The feedback was generally negative. People complained for these main obstacles:&lt;br /&gt;
&lt;br /&gt;
low quest priority (everything for the client is more important) ends with process starvation &lt;br /&gt;
quests as defined were things to be done alone, and we prefer working with other people (pairs)&lt;br /&gt;
no motivation from quest done for yourself only, when it doesn't have an immediate use and no one else is waiting for the outcomes&lt;br /&gt;
&lt;br /&gt;
At the same time people didn't think it was a totally bad idea, but would rather like, if quests were somehow corresponding to our current products and projects and had defined timeboxes.&lt;br /&gt;
&lt;br /&gt;
This made us close the experiment and start with two others, described below. We do not know yet how these will work out.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Task exchange board.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When creating a backlog for a project, there are usually some tasks for which the domain knowledge available to team members is not needed. This include investigation into new libraries and technologies (spikes), setting up things very technology oriented (auditing by Jboss Envers, excel export via&amp;nbsp; Apache POI, etc.), creating black-box and/or open source libraries, writing proof of concepts or collecting and releasing some tools from the project as an Open Source libraries. All those tasks are candidates for Task Exchange Board.&lt;br /&gt;
&lt;br /&gt;
When a backlog is done, the team can decide which tasks to put onto the board. These should be estimated like on a sprint planning, should have a defined time expectation or a timebox (in case of spikes) and Definition of Done.&lt;br /&gt;
&lt;br /&gt;
Once on the Board, anyone in the company, even from different project or department, as long as he has enough time (i.e. his PM/team leader has nothing against it), can pick up an interesting task and do it using the budget of the team which created the task.&lt;br /&gt;
&lt;br /&gt;
This way, people can do something important and interesting in a new technology, on full time, without changing the current project. If you have enough of what you are doing, this may be a productive brake for you. If you are currently only supporting some existing project or waiting for bug reports, why not to do something interesting and learn something new on the way? This may be a equivalent&amp;nbsp; of a quest for those, who do not have any time at home.&lt;br /&gt;
&lt;br /&gt;
These tasks, may also be done by members of the team which created them. &lt;br /&gt;
&lt;br /&gt;
One important thing has to be understood: since the team creating the task doesn't know who is going to take it, it's up to the guy taking the task, to finish within or before estimated time. Basically, if you are not sure you can finish this on time, or do not want to risk spending your free hours on it, don't take it. This should not slow down the development time. If it did, no team would put another task on the board.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What technologies you want to work with?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_VliUFo33M5Y/TU7p8BdtZBI/AAAAAAAABFw/OllqdRV4p7Q/s1600/CIMG4292small.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="200" src="http://4.bp.blogspot.com/_VliUFo33M5Y/TU7p8BdtZBI/AAAAAAAABFw/OllqdRV4p7Q/s200/CIMG4292small.jpg" width="150" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;This time-fridge contains &lt;br /&gt;
technologies we do not use anymore.&lt;br /&gt;
ZX-Spectrum, Commodore 64,&lt;br /&gt;
Commodore 128; Amstrad, &lt;br /&gt;
Macbook Air...&lt;br /&gt;
Old kind of stuff.&lt;br /&gt;
We are an old company :) &lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
We have a team of guys responsible for assigning people to new projects or moving them between existing. This team has a sky level view on what's currently going on in the whole company, all new and planned projects.&lt;br /&gt;
&lt;br /&gt;
So far, the team was making up decisions based on their own perspective of what one is capable of. We wanted to change it a bit, to make TouK a better place for people who feel a rush on some technology, so we created a confluence page, where everyone can submit what technologies he would like to work with.&lt;br /&gt;
&lt;br /&gt;
Now, this looks very simple, but frankly speaking, I wasn't aware (and I believe nobody else was) of how often some of technologies would be mentioned by different people. As an effect, we can see now, that we have a lot of developers wanting to take part in a full-Grails, Java free project. While in theory, every team can decide for itself, what technologies it uses, seldom someone would take such a drastic, risky step, as changing the language for the whole project. By gathering information about what people would like to work with, we can create a team very dedicated and motivated to use some technology. That may pay off pretty well.&lt;br /&gt;
&lt;br /&gt;
We shall see, whether the guys assigning people to projects, will take that into account.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;More to go&lt;/b&gt;&lt;br /&gt;
There is a lot of stuff, we haven't tried yet. This includes for example mentoring, RPG character cards, exchanging knowledge with other companies by switching developers for a few days. Hopefully, I'll have more to report in a few months.&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-4717627171446278772?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/02/animating-developers-4-months-later.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_VliUFo33M5Y/TU7p8BdtZBI/AAAAAAAABFw/OllqdRV4p7Q/s72-c/CIMG4292small.jpg' height='72' width='72'/><thr:total>8</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-8936949318011489419</guid><pubDate>Tue, 18 Jan 2011 14:37:00 +0000</pubDate><atom:updated>2011-01-18T16:54:08.092+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>hibernate</category><category domain='http://www.blogger.com/atom/ns#'>h2</category><title>Hibernate hbm2ddl won't create schema before creating tables</title><description>&lt;b&gt;Situation&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I have a local H2 in memory database for integration tests and an Oracle db for production. I do not control the Oracle DB model. The in memory H2 database is created automatically by adding&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;&amp;lt;prop key="hibernate.hbm2ddl.auto"&amp;gt;update&amp;lt;/prop&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
to hibernate properties in AnnotationSessionFactoryBean. The definition of the entity stored in DB points to a schema&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;@Entity
@Table(name = "business_operations", schema = "sowa")
public class BusinessOperation {
...
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The problem&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When creating the H2 database, Hibernate won't create the schema before creating tables. As a result it will show errors when trying to create the tables in non existing schema and fail in any query (queries will be run with sowa.business_operations).&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;2011-01-18 15:13:30,884 INFO [org.hibernate.tool.hbm2ddl.SchemaUpdate] - Running hbm2ddl schema update
2011-01-18 15:13:30,885 INFO [org.hibernate.tool.hbm2ddl.SchemaUpdate] - fetching database metadata
2011-01-18 15:13:30,915 INFO [org.hibernate.tool.hbm2ddl.SchemaUpdate] - updating schema
2011-01-18 15:13:30,927 INFO [org.hibernate.tool.hbm2ddl.DatabaseMetadata] - table not found: business_operations
2011-01-18 15:13:30,941 ERROR [org.hibernate.tool.hbm2ddl.SchemaUpdate] - Unsuccessful: create table sowa.business_operations 
2011-01-18 15:13:30,942 ERROR [org.hibernate.tool.hbm2ddl.SchemaUpdate] - 
Schema "SOWA" not found;
&lt;/pre&gt;
&lt;br /&gt;
Turns out this bug is reported and open since 2006: &lt;a href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-1853"&gt;link&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The solution&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The solution to this problem is to create the schema before hibernate's hbm2ddl turns on. That would be easy with H2 if we could tell H2 to initialize itself like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;database.url=jdbc:h2:mem:;INIT=RUNSCRIPT FROM 'src/main/resources/scripts/create.sql';
&lt;/pre&gt;
&lt;br /&gt;
All seems nice, except H2 RUNSCRIPT FROM command doesn't work with relative resources as you may expect. Fortunatelly INIT allows us to give any commands, not just point to a script, so this little change will solve the problem:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;database.url=jdbc:h2:mem:;INIT=create schema IF NOT EXISTS sowa&amp;nbsp;&lt;/pre&gt;
&lt;br /&gt;
Yeah, I know it's obvious and simple stupid, but looking at all the questions on all the mailing lists in google I may have just saved a little bit of somebody's time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-8936949318011489419?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2011/01/hibernate-hbm2ddl-wont-create-schema.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>4</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-5491443573406127525</guid><pubDate>Sun, 31 Oct 2010 12:31:00 +0000</pubDate><atom:updated>2011-05-03T19:40:55.814+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><title>Google Guava v07 examples</title><description>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;a href="http://code.google.com/p/guava-libraries/"&gt;&lt;/a&gt;We have something called Weekly Technology Workshops at TouK, that is, every Friday at 16:00 somebody has a presentation for everyone willing to come. We present stuff we learn and work on at home, but we also have a bulletin board with topics that people would like to listen about. Last week Maciej Próchniak had a talk about &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt;, this time a few folks asked for an introduction to &lt;a href="http://code.google.com/p/guava-libraries/"&gt;Google Guava libraries&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Since this was a dead simple task, I was happy to deliver.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;WTF is Guava?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It's a set of very simple, basic classes, that you end up writing yourself anyway. Think in terms of Apache commons, just by Google. Just to make your life a little bit easier.&lt;br /&gt;
&lt;br /&gt;
There is an early (v04) &lt;a href="http://guava-libraries.googlecode.com/files/Guava_for_Netflix_.pdf"&gt;presentation&lt;/a&gt; and there was &lt;a href="http://blog.mocna-kawa.com/2010/06/javarsovia-lekcja-stylu-slajdy/"&gt;a different one&lt;/a&gt; (in Polish) at Javarsowia 2010 by &lt;a href="http://blog.mocna-kawa.com/"&gt;Wiktor Gworek&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
At the time of writing this, the latest version is v07, it's been mavenized and is available at a &lt;a href="http://repo1.maven.org/maven2/com/google/guava/guava/"&gt;public maven repo&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Here's a quick review of a few interesting things. Don't expect anything fancy though, Guava is very BASIC.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;@VisibleForTesting &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A simple annotation that tells you why a particular property access restriction has been relaxed.&lt;br /&gt;
&lt;br /&gt;
A common trick to use in testing is to relax access restrictions to default for a particular property, so that you can use it in a unit test, which resides in the same package (though in different catalog). Whether you thing it's good or bad, remember to give a hint about that to the developer.&lt;br /&gt;
&lt;br /&gt;
Consider:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:java"&gt;public class User {
    private Long id;
    private String firstName;
    private String lastName;
    String login; 
&lt;/pre&gt;
&amp;nbsp;Why is login package scoped?&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:java"&gt;public class User {
    private Long id;
    private String firstName;
    private String lastName;
    @VisibleForTesting String login;&lt;/pre&gt;
Ah, that's why.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;Preconditions&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Guava has a few preconditions for defensive programming (Design By Contract), but they are not quite as good as what Apache Commons / Spring framework has. One thing interesting is that Guava solution returns the object, so could be inlined. Consider:&lt;br /&gt;
&lt;br /&gt;
Using hand written preconditions:&lt;br /&gt;
&lt;pre class="brush:java"&gt;public User(Long id, String firstName, String lastName, String login) {
        validateParameters(id, firstName, lastName, login);
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.login = login.toLowerCase();
    }

    private void validateParameters(Long id, String firstName, String lastName, String login) {
        if(id == null ) {
            throw new IllegalArgumentException("id cannot be null");
        }

        if(firstName == null || firstName.length() == 0) {
            throw new IllegalArgumentException("firstName cannot be empty");
        }

        if(lastName == null || lastName.length() == 0) {
            throw new IllegalArgumentException("lastName cannot be empty");
        }

        if(login == null || login.length() == 0) {
            throw new IllegalArgumentException("login cannot be empty");
        }
    } &lt;/pre&gt;
&lt;br /&gt;
Using guava preconditions:&lt;br /&gt;
&lt;pre class="brush:java"&gt;public void fullyImplementedGuavaConstructorWouldBe(Long id, String firstName, String lastName, String login) {
        this.id = checkNotNull(id);
        this.firstName = checkNotNull(firstName);
        this.lastName = checkNotNull(lastName);
        this.login = checkNotNull(login);

        checkArgument(firstName.length() &amp;gt; 0);
        checkArgument(lastName.length() &amp;gt; 0);
        checkArgument(login.length() &amp;gt; 0);
    }&lt;/pre&gt;
(Thanks Yom for noticing that checkNotNull must go before checkArgument, though it makes it a bit unintuitive)&lt;br /&gt;
&lt;br /&gt;
Using spring or apache commons preconditions (the use looks exactly the same for both libraries):&lt;br /&gt;
&lt;pre class="brush:java"&gt;public void springConstructorWouldBe(Long id, String firstName, String lastName, String login) {
        notNull(id); hasText(firstName); hasText(lastName); hasText(login);
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.login = login;
    } &lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;CharMatcher&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
For people who hate regexp or just want a simple and good looking object style pattern matching solution.
&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
And/or ease of use&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:java"&gt;        String input = "This invoice has an id of 192/10/10";
        CharMatcher charMatcher = CharMatcher.DIGIT.or(CharMatcher.is('/'));
        String output = charMatcher.retainFrom(input);
&lt;/pre&gt;
&amp;nbsp;output is: 192/10/10
&lt;br /&gt;
&lt;br /&gt;
Negation:&lt;br /&gt;
&lt;pre class="brush:java"&gt;        String input = "DO NOT scream at me!";
        CharMatcher charMatcher = CharMatcher.JAVA_LOWER_CASE.or(CharMatcher.WHITESPACE).negate();
        String output = charMatcher.retainFrom(input);
&lt;/pre&gt;
&amp;nbsp;output is: DONOT!
&lt;br /&gt;
&lt;br /&gt;
Ranges:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;        String input = "DO NOT scream at me!";
        CharMatcher charMatcher = CharMatcher.inRange('m', 's').or(CharMatcher.is('a').or(CharMatcher.WHITESPACE));
        String output = charMatcher.retainFrom(input);
&lt;/pre&gt;
output is:    sram a m&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Joiner / Splitter&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
As the names suggest, it's string joining/splitting done the right way, although I find the inversion of calls a bit... oh well, it's java.
&lt;br /&gt;
&lt;pre class="brush:java"&gt;        String[] fantasyGenres = {"Space Opera", "Horror", "Magic realism", "Religion"};
        String joined = Joiner.on(", ").join(fantasyGenres);
&lt;/pre&gt;
Output:  Space Opera, Horror, Magic realism, Religion
&lt;br /&gt;
&lt;br /&gt;
You can skip nulls:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;        String[] fantasyGenres = {"Space Opera", null, "Horror", "Magic realism", null, "Religion"};
        String joined = Joiner.on(", ").skipNulls().join(fantasyGenres);
&lt;/pre&gt;
Output:  Space Opera, Horror, Magic realism, Religion
&lt;br /&gt;
&lt;br /&gt;
You can fill nulls:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;        String[] fantasyGenres = {"Space Opera", null, "Horror", "Magic realism", null, "Religion"};
        String joined = Joiner.on(", ").useForNull("NULL!!!").join(fantasyGenres);
&lt;/pre&gt;
Output:  Space Opera, NULL!!!, Horror, Magic realism, NULL!!!, Religion
&lt;br /&gt;
&lt;br /&gt;
You can join maps
&lt;br /&gt;
&lt;pre class="brush:java"&gt;        Map&amp;lt;Integer, String&amp;gt; map = newHashMap();
        map.put(1, "Space Opera");
        map.put(2, "Horror");
        map.put(3, "Magic realism");
        String joined = Joiner.on(", ").withKeyValueSeparator(" -&amp;gt; ").join(map);
&lt;/pre&gt;
Output:  1 → Space Opera, 2 → Horror, 3 → Magic realism
&lt;br /&gt;
&lt;br /&gt;
Split returns Iterable instead of JDK arrays:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;        String input = "Some very stupid data with ids of invoces like 121432, 3436534 and 8989898 inside";
        Iterable&amp;lt;String&amp;gt; splitted = Splitter.on(" ").split(input);
&lt;/pre&gt;
Split does fixed length splitting, although you cannot give a different length for each “column” which makes it's use a bit limited while parsing some badly exported excels.
&lt;br /&gt;
&lt;pre class="brush:java"&gt;        String input =
                "A  1  1  1  1\n" +
                "B  1  2  2  2\n" +
                "C  1  2  3  3\n" +
                "D  1  2  5  3\n" +
                "E  3  2  5  4\n" +
                "F  3  3  7  5\n" +
                "G  3  3  7  5\n" +
                "H  3  3  9  7";
        Iterable&amp;lt;String&amp;gt; splitted = Splitter.fixedLength(3).trimResults().split(input);
&lt;/pre&gt;
You can use CharMatcher while splitting
&lt;br /&gt;
&lt;pre class="brush:java"&gt;        String input = "Some very stupid data with ids of invoces like 123231/fv/10/2010, 123231/fv/10/2010 and 123231/fv/10/2010";
        Iterable&amp;lt;String&amp;gt; splitted = Splitter.on(CharMatcher.DIGIT.negate())
                                            .trimResults()
                                            .omitEmptyStrings()
                                            .split(input);&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Predicates / Functions&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
Predicates alone are not much, it's just an interface with a method that returns true, but if you combine predicates with functions and Collections2 (a guava class that simplifies working on collections), you get a nice tool in your toolbox.
&lt;br /&gt;
&lt;br /&gt;
But let's start with basic predicate use. Imagine we want to find whether there are users who have logins with digits inside. The inocation would be (returns boolean):
&lt;br /&gt;
&lt;pre class="brush:java"&gt;Predicates.in(users).apply(shouldNotHaveDigitsInLoginPredicate);
&lt;/pre&gt;
And the predicate looks like that
&lt;br /&gt;
&lt;pre class="brush:java"&gt;public class ShouldNotHaveDigitsInLoginPredicate implements Predicate&amp;lt;User&amp;gt; {
    @Override
    public boolean apply(User user) {
        checkNotNull(user);
        return CharMatcher.DIGIT.retainFrom(user.login).length() == 0;
    }    
}       
&lt;/pre&gt;
Now lets add a function that will transform a user to his full name:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;public class FullNameFunction implements Function&amp;lt;User, String&amp;gt; {
    @Override
    public String apply(User user) {
        checkNotNull(user);
        return user.getFirstName() + " " + user.getLastName();
    }    
}
&lt;/pre&gt;
You can invoke it using static method transform:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;List&amp;lt;User&amp;gt; users = newArrayList(new User(1L, "sylwek", "stall", "rambo"),
  new User(2L, "arnold", "schwartz", "commando"));

List&amp;lt;String&amp;gt; fullNames = transform(users, new FullNameFunction()); 
&lt;/pre&gt;
And now lets combine predicates with functions to print names of users that have logins which do not contain digits:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;List&amp;lt;User&amp;gt; users = newArrayList(new User(1L, "sylwek", "stall", "rambo"), 
  new User(2L, "arnold", "schwartz", "commando"), 
  new User(3L, "hans", "kloss", "jw23"));

Collection&amp;lt;User&amp;gt; usersWithoutDigitsInLogin = filter(users, new ShouldNotHaveDigitsInLoginPredicate());
String names = Joiner.on("\n").join( transform(usersWithoutDigitsInLogin, new FullNameFunction()) );
&lt;/pre&gt;
&lt;br /&gt;
What we do not get: &lt;a href="http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29"&gt;fold (reduce)&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Tuple"&gt;tuples&lt;/a&gt;. Oh well, you'd probably turn to &lt;a href="http://functionaljava.org/"&gt;Java Functional Library&lt;/a&gt; anyway, if you wanted functions in Java, right?
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;CaseFormat&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
Ever wanted to turn those ugly &lt;a href="http://pear.php.net/"&gt;PHP Pear&lt;/a&gt; names into nice java/cpp style with one liner? No? Well, anyway, you can:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;String pearPhpName = "Really_Fucked_Up_PHP_PearConvention_That_Looks_UGLY_because_of_no_NAMESPACES";
String javaAndCPPName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL , pearPhpName);
&lt;/pre&gt;
Output: ReallyFuckedUpPhpPearconventionThatLooksUglyBecauseOfNoNamespaces&lt;br /&gt;
&lt;br /&gt;
But since Oracle has taken over Sun, you may actually want to turn those into sql style, right?
&lt;br /&gt;
&lt;pre class="brush:java"&gt;        String sqlName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, javaAndCPPName);&amp;nbsp;&lt;/pre&gt;
Output: really_fucked_up_php_pearconvention_that_looks_ugly_because_of_no_namespaces&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Collections&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Guava has a superset of &lt;a href="http://code.google.com/p/google-collections/"&gt;Google collections library 1.0&lt;/a&gt;, and this indeed is a very good reason to include this dependency in your poms. I won't even try to describe all the features, but just to point out a few nice things:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;you have an Immutable version of pretty much everything&lt;/li&gt;
&lt;li&gt;you get a few nice static and statically typed methods on common types like Lists, Sets, Maps, ObjectArrays, which include:&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;easy way of creating based on return type: e.g. newArrayList&lt;/li&gt;
&lt;li&gt;transform (way to apply functions that returns Immutable version)&lt;/li&gt;
&lt;li&gt;partition (paging)&lt;/li&gt;
&lt;li&gt;reverse&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
And now for a few more interesting collections.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Mutlimaps&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
Mutlimap is basically a map that can have many values for a single key. Ever had to create a Map&amp;lt;T1, Set&amp;lt;T2&amp;gt;&amp;gt; in your code? You don't have to anymore.
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:java"&gt;Multimap&amp;lt;Integer, String&amp;gt; multimap = HashMultimap.create();
        multimap.put(1, "a");
        multimap.put(2, "b");
        multimap.put(3, "c");
        multimap.put(1, "a2"); 
&lt;/pre&gt;
There are of course immutable implementations as well: ImmutableListMultimap, ImmutableSetMultomap, etc.
&lt;br /&gt;
&lt;br /&gt;
You can construct immutables either in line (up to 5 elements) or using a builder:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;Multimap&amp;lt;Integer, String&amp;gt; multimap = ImmutableSetMultimap.of(1, "a", 2, "b", 3, "c", 1, "a2"); 
Multimap&amp;lt;Integer, String&amp;gt; multimap = new ImmutableSetMultimap.Builder&amp;lt;Integer, String&amp;gt;()
        .put(1, "a")
        .put(2, "b")
        .put(3, "c")
        .put(1, "a2")
        .build();
&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;BiMap&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
BiMap is a map that have only unique values. Consider this:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;@Test(expected = IllegalArgumentException.class)
public void biMapShouldOnlyHaveUniqueValues() {
 BiMap&amp;lt;Integer, String&amp;gt; biMap = HashBiMap.create();
 biMap.put(1, "a");
 biMap.put(2, "b");
 biMap.put(3, "a"); //argh! an exception
} 
&lt;/pre&gt;
That allows you to inverse the map, so the values become key and the other way around:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;BiMap&amp;lt;Integer, String&amp;gt; biMap = HashBiMap.create();
biMap.put(1, "a");
biMap.put(2, "b");
biMap.put(3, "c");

BiMap&amp;lt;String, Integer&amp;gt; invertedMap = biMap.inverse();
&lt;/pre&gt;
Not sure what I'd actually want to use it for.
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Constraints&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
This allows you to add constraint checking on a collection, so that only values which pass the constraint may be added. 
&lt;br /&gt;
&lt;br /&gt;
Imagine we want a collections of users with first letter 'r' in their logins.
&lt;br /&gt;
&lt;pre class="brush:java"&gt;Constraint&amp;lt;User&amp;gt; loginMustStartWithR = new Constraint&amp;lt;User&amp;gt;() {
    @Override
    public User checkElement(User user) {
        checkNotNull(user);
        
        if(!user.login.startsWith("r")) {
            throw new IllegalArgumentException("GTFO, you are not Rrrrrrrrr");
        }

        return user;
    }
};    
&lt;/pre&gt;
And now for a test:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;@Test(expected = IllegalArgumentException.class)
public void shouldConstraintCollection() {
 //given
 Collection&amp;lt;User&amp;gt; users = newArrayList(new User(1L, "john", "rambo", "rambo"));
 Collection&amp;lt;User&amp;gt; usersThatStartWithR = constrainedCollection(users, loginMustStartWithR);

 //when
 usersThatStartWithR.add(new User(2L, "arnold", "schwarz", "commando"));
}
&lt;/pre&gt;
You also get notNull constraint out of the box:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;//notice it's not an IllegalArgumentException :( 
@Test(expected = NullPointerException.class)
public void notNullConstraintShouldWork() {
 //given
 Collection&amp;lt;Integer&amp;gt; users = newArrayList(1);
 Collection&amp;lt;Integer&amp;gt; notNullCollection = constrainedCollection(users, notNull());

 //when
 notNullCollection.add(null);
} 
&lt;/pre&gt;
Thing to remember: constraints are not checking the data already present in a collection.
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt; Tables &lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
Just as expected, a table is a collection with columns, rows and values. No more Map&amp;lt;T1, Map&amp;lt;T2, T3&amp;gt;&amp;gt; I guess. The usage is simple and you can transpose:
&lt;br /&gt;
&lt;pre class="brush:java"&gt;Table&amp;lt;Integer, String, String&amp;gt; table = HashBasedTable.create();
table.put(1, "a", "1a");
table.put(1, "b", "1b");
table.put(2, "a", "2a");
table.put(2, "b", "2b");

Table transponedTable = Tables.transpose(table);
&lt;/pre&gt;
That's all, folks. I didn't present util.concurent, primitives, io and net packages, but you probably already know what to expect.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-5491443573406127525?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2010/10/googole-guava-v07-examples.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>12</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-4455918564903023094</guid><pubDate>Sun, 17 Oct 2010 13:46:00 +0000</pubDate><atom:updated>2010-10-18T12:52:11.131+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>conference</category><title>Java Developers' Day 2010 review</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_VliUFo33M5Y/TLr6s2vdXAI/AAAAAAAAA5k/LDSUBTlGQqs/s1600/CIMG0888small.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://2.bp.blogspot.com/_VliUFo33M5Y/TLr6s2vdXAI/AAAAAAAAA5k/LDSUBTlGQqs/s200/CIMG0888small.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;
On the 7-8th of October 2010, Cracow held &lt;a href="http://10.jdd.org.pl/"&gt;Java Developers' Day&lt;/a&gt; conference. This year it was two days long, so I guess they'll have to think about changing the name. My expectations weren't very high. First of all, I've heard an opinion that JDD is getting worse every year. Second, for the same price as &lt;a href="http://blog.solidcraft.eu/2010/05/geecon-2010-general-impressions.html"&gt;GeeCON&lt;/a&gt; you got only one track. Third some of the lectures seemed really uninspiring. &lt;br /&gt;
&lt;br /&gt;
For example, I was afraid, that the one about Flex is going to be the same one I've seen on &lt;a href="http://blog.solidcraft.eu/2010/03/4developers-2010-review.html"&gt;4Developers&lt;/a&gt;, half a year ago in Poznań. And, of course, there was the one most controversial to all the people I had a chance speaking with, the sponsored lecture from Wipro Technologies, titled: “Wipro in Europe and development opportunities on Polish market”.&lt;br /&gt;
&lt;br /&gt;
Doesn't sound like something you'd like to listen to on a Java conference, does it? More like an advertisement, to me.&lt;br /&gt;
&lt;br /&gt;
Fortunately, my doubts were mostly unfounded.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/_VliUFo33M5Y/TLr6vR1gtPI/AAAAAAAAA5o/0UvyB-D_7r0/s1600/CIMG0886small.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/_VliUFo33M5Y/TLr6vR1gtPI/AAAAAAAAA5o/0UvyB-D_7r0/s200/CIMG0886small.jpg" width="150" /&gt;&lt;/a&gt;&lt;/div&gt;
The first day started a little earlier than planned, with Bill Burke talk about RESTful Java. Quite nice, I must say, as long as you have no idea what &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt; means, as half of the lecture was very basic. The other part was about &lt;a href="http://en.wikipedia.org/wiki/JAX-RS"&gt;JAX-RS&lt;/a&gt; (and RESTEasy implementation), and that's where it got my attention. I haven't had a chance to use JAX-RS yet, but the simplicity and efficiency of it is very appealing. I'll have to give it a shot, especially when .NET/Java web service integration is sometimes very painful.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_VliUFo33M5Y/TLr6yQfxnWI/AAAAAAAAA5s/X1Cx3Be7fg4/s1600/CIMG0891small.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://3.bp.blogspot.com/_VliUFo33M5Y/TLr6yQfxnWI/AAAAAAAAA5s/X1Cx3Be7fg4/s200/CIMG0891small.jpg" width="150" /&gt;&lt;/a&gt;&lt;/div&gt;
The second talk,&amp;nbsp; “Java programming in days of multi-core processors”, by &lt;a href="http://www.angelikalanger.com/"&gt;Angelika Langer&lt;/a&gt;, was gorgeous. Maybe it's because of my limited experience in concurrency, maybe because Angelika presented a more in-depth view on the things happening under the hood, than I am used to, and maybe because she threw away the incorrect model most books present. What I'm sure about, is that Angelika is a great trainer and speaker, with vast knowledge and expertise.&amp;nbsp; It was a pure pleasure to listen to her and I can only hope to be so passionate and sharp at her age.&lt;br /&gt;
&lt;br /&gt;
Not that she's that old, mind you. It's just that terms like “burned-out” and “tired” do not seem to have anything to do with her.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_VliUFo33M5Y/TLr61T_BBOI/AAAAAAAAA5w/X81hMYkvAhQ/s1600/CIMG0895small.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;
Then there was Jarosław Błąd from e-point, talking about performance tests in JEE. That was also quite nice, though a little too basic. I wish the speaker could show us a little more real case scenarios and stories, as it was obvious he had a lot of interesting thoughts on that matter, but probably because of NDAs, he decided to go with more theoretical and generic information instead. Anyway, this was a sponsored talk done right. Thanks e-point for not leaving us with just advertisements.&lt;br /&gt;
&lt;br /&gt;
After the lunch came the hit of the day, Ted Neward talk about functional programming for busy developer. A few slides passed by, when Ted asked the audience, whether we would rather see presentation or life coding. Guess what the answer was.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_VliUFo33M5Y/TLr63TdO6CI/AAAAAAAAA50/bskD3q-Rcms/s1600/CIMG0899small.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/_VliUFo33M5Y/TLr63TdO6CI/AAAAAAAAA50/bskD3q-Rcms/s200/CIMG0899small.jpg" width="150" /&gt;&lt;/a&gt;&lt;/div&gt;
The great thing about the lecture was that Ted didn't use anything more than standard Java, to show us the benefits of thinking in terms of functional languages. The examples were practical, with stuff you can really find from time to time in your code, and the advantages clear and explicit. Somewhere in the middle of the show, Ted said, that he wants us to remember, that we do not have to use anything fancy like Scala, to start solving some classes of problems in a much better way. I only wish he had more time on his hands, but I was lucky to sign in for Scala workshops with him on Friday.&lt;br /&gt;
&lt;br /&gt;
I didn't go for Flex presentation, partially because of the beforementioned doubts, partially because I've met some friends and speakers on the way. I really wish I could be there, on their lectures, especially on &lt;a href="http://acidbits.org/blog/"&gt;Łukasz Kuczera&lt;/a&gt; talk about Lift+Comet and Łukasz Szydło presentation about Apprenticeship, but I could either do that or go for the workshop with Ted Neward, and after what Ted had shown us a few hours before, I was sure his workshop will be a mind opener.&lt;br /&gt;
&lt;br /&gt;
And here is for all those anxious about just one track on JDD10. There were actually two on Friday, if you count the workshops, and even though that doesn't seem like much, the quality of what Ted had to offer, beat up the disadvantage of not being able to change every session for something different.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://1.bp.blogspot.com/_VliUFo33M5Y/TLr66vXbDBI/AAAAAAAAA54/1gdCfLqawmk/s1600/CIMG0904small.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="200" src="http://1.bp.blogspot.com/_VliUFo33M5Y/TLr66vXbDBI/AAAAAAAAA54/1gdCfLqawmk/s200/CIMG0904small.jpg" width="150" /&gt;&lt;/a&gt;The last lecture on Thursday was “Brave changes: how to make new ideas happen”, given by &lt;a href="http://lindarising.org/"&gt;Linda Rising&lt;/a&gt;. While not Java specific, that was quite interesting to me, mostly because of the latest changes I've been part of at TouK (both my own initiatives that you can read about &lt;a href="http://blog.solidcraft.eu/2010/09/agile-skills-project-at-my-company.html"&gt;here&lt;/a&gt; and &lt;a href="http://blog.solidcraft.eu/2010/10/video-from-my-presentation-at-agile.html"&gt;here&lt;/a&gt;, and overall works on defining company goals and vision). Thing to remember: what your audience is eating is more important than what they are listening to. Scary but true.&lt;br /&gt;
&lt;br /&gt;
Then there was the integration party. And as expected from programmers, Nintendo Wii had a much bigger take than girls :)&lt;br /&gt;
&lt;br /&gt;
For three hours on Friday, I've been enjoying Ted Neward's Scala workshops. I won't give you much details, except it was really great, since Witek Wołejszo wrote a &lt;a href="http://touk.pl/blog/2010/10/11/scala-for-java-programmers/"&gt;nice summary&lt;/a&gt; already.&lt;br /&gt;
&lt;br /&gt;
And I didn't dare to go for “Wipro in Europe and development opportunities on Polish market”. I was afraid, that my positive experience from JDD10 could be a bit reduced.&lt;br /&gt;
&lt;br /&gt;
Overall, another great conference. Thanks to Witek Wołejszo, Piotr Przybyłek and Tomasz Dziurko for this interesting trip.
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/_VliUFo33M5Y/TLr6_6CuE2I/AAAAAAAAA6A/7dU23vnKtVQ/s1600/CIMG0925small.jpg" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://3.bp.blogspot.com/_VliUFo33M5Y/TLr6_6CuE2I/AAAAAAAAA6A/7dU23vnKtVQ/s200/CIMG0925small.jpg" width="200" /&gt;&lt;/a&gt;
&lt;a href="http://1.bp.blogspot.com/_VliUFo33M5Y/TLr69rdtz9I/AAAAAAAAA58/wlWY3MPig5g/s1600/CIMG0914small.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://1.bp.blogspot.com/_VliUFo33M5Y/TLr69rdtz9I/AAAAAAAAA58/wlWY3MPig5g/s200/CIMG0914small.jpg" width="200" /&gt;&lt;/a&gt;
&lt;a href="http://3.bp.blogspot.com/_VliUFo33M5Y/TLr7B-al52I/AAAAAAAAA6E/h8KFsmyc82g/s1600/CIMG0929small.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="150" src="http://3.bp.blogspot.com/_VliUFo33M5Y/TLr7B-al52I/AAAAAAAAA6E/h8KFsmyc82g/s200/CIMG0929small.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-4455918564903023094?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2010/10/java-developers-day-2010-review.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_VliUFo33M5Y/TLr6s2vdXAI/AAAAAAAAA5k/LDSUBTlGQqs/s72-c/CIMG0888small.jpg' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-1845245818295680182</guid><pubDate>Wed, 13 Oct 2010 17:00:00 +0000</pubDate><atom:updated>2010-10-14T01:54:03.260+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>wicket</category><title>Wicket form submit not safe for redirecting to intercept page</title><description>&lt;b&gt;The problem&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When you have a form, that anybody can see, but only logged on users can POST, you may want to redirect the user to the login page, and back to the form after login&lt;br /&gt;
&lt;br /&gt;
Using wicket 1.3/1.4, if you do that using redirectToInterceptPage(loginPage) or RestartResponseAtInterceptPageException, after returning, the client will loose all the data entered to the form.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The details&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this happens, is because of how redirectToInterceptPage works. It saves the URL of the requested page, and later, when continueToOriginalDestination is called, it redirects the client to the saved URL using GET. When the last call from the client was a non-ajax POST to the form, the client will be redirected without any posted data. Wicket will handle the situation issuing&amp;nbsp; HTTP 302 and redirecting the user again, but all the data is already lost.&lt;br /&gt;
&lt;br /&gt;
The funny thing is that the data is actually getting to the form, because of the first POST, but then it's overwritten with nulls on the redirected GET. To make it clear, here's the HTTP conversation:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:java"&gt;Client: POST http://localhost:8080/test?wicket:interface=:3:form::IFormSubmitListener:: (post to the form)
Server: HTTP 302 Moved Temporarily (the input was parsed, the model was updated, but you are being redirected to the login page because of redirectToInterceptPage or exception)
Client: GET http://localhost:8080/?wicket:interface=:4:::: 
Server: HTTP 200 OK (server is responding with the login page)
Client: POST  https://localhost:8443/j_spring_security_check.... (post login and password, here using spring security)
Server: HTTP 302 Moved Temporarily (validation is done. Now you are redirected from spring security to the page with wicket redirectToInterceptPage)
Client: GET https://localhost:8443/redirectAfterLogin  (here  redirectToInterceptPage is called)
Server: HTTP 302 Moved Temporarily (you are being redirected the original URL)
Client: GET http://localhost:8080/test?wicket:interface=:3:form::IFormSubmitListener:: (the same URL as the first POST but this time without post data. now your form is being submitted again, but with nulls instead of entered data)
Server: HTTP 302 Moved Temporarily (being redirected by wicket, because of Redirect After Post pattern)
Client: GET http://localhost:8080/?wicket:interface=:3:1::: (back on the form page)
Server: HTTP 200 OK (the form is empty by now)
&lt;/pre&gt;
&lt;br /&gt;
As you see, if wicket would not redirect you at the end to the url requested by POST, but to the one called by last GET before the original POST, your data would be there.&lt;br /&gt;
&lt;br /&gt;
The &lt;a href="https://issues.apache.org/jira/browse/WICKET-1703"&gt;issue&lt;/a&gt; was reported two years ago. Doesn't look like it's getting fixed any time soon.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The walkaround&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
If you can require your users to be logged in before you show them the form, you are safe. If not, you can submit the form by AJAX. This will solve the problem, because wicket will recognize, that it cannot redirect the user to the AJAX POST target (&amp;lt;ajax-response&amp;gt; is not exactly what the user would like to have rendered in the browser), and will redirect with GET to the URL of the last page instead, which was also requested by GET. And since the data was converted to the form model in the first POST (line 1), all is well.&lt;br /&gt;
&lt;br /&gt;
And in case you don't want to have a partial page update via AJAX, but would rather like to render the whole page, all you need to do is add setResponsePage(getPage()) to your button. For example like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush:java"&gt;    class AjaxSendButton extends AjaxFallbackButton {
        public AjaxSendButton(String id, Form form) {
            super(id, form);
        }

        @Override
        protected void onSubmit(AjaxRequestTarget target, Form form) {
            //process your form input here
            setResponsePage(getPage());
        }
    }
&lt;/pre&gt;
&lt;br /&gt;
Now your ajax form behaves just like a non ajax form, but can be redirected to an intercept page&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The catch&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When submitting forms via AJAX you have to be aware, that your form may be submitted without your submit button being clicked on. This may have unforseen consequences. For the whole problem description and a solution go &lt;a href="http://richard-wilkinson.co.uk/2008/04/05/how-to-stop-non-ajax-form-submits-in-wicket/"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-1845245818295680182?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2010/10/wicket-form-submit-not-safe-for.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8795604888160975763.post-1556226042085200439</guid><pubDate>Tue, 05 Oct 2010 19:34:00 +0000</pubDate><atom:updated>2010-10-05T21:46:13.322+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>agile</category><category domain='http://www.blogger.com/atom/ns#'>presentation</category><title>Video from my presentation at Agile Warsaw</title><description>Here's the video from my presentation and the discussion about &lt;a href="http://www.agileskillsproject.org/"&gt;Agile Skills Project&lt;/a&gt; and our experiments in motivating developers at my company, that I had a chance to show at &lt;a href="http://groups.google.com/group/agile-warsaw"&gt;Agile Warsaw&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
 Do not ask my why the camera is 100% time focused on the wall, I have no freaking idea :) The voices are there, and that matters.&lt;br /&gt;
&lt;br /&gt;
You can either watch it on Parleys:&lt;a href="http://parleys.com/d/2019"&gt; http://parleys.com/d/2019&lt;/a&gt; or right here. Be warned: it's in Polish.&lt;br /&gt;
&lt;br /&gt;
&lt;object height="443" width="474"&gt;&lt;param name="movie" value="http://www.parleys.com/share/parleysshare2.swf?pageId=2019"&gt;



&lt;/param&gt;
&lt;param name="allowFullScreen" value="true"&gt;



&lt;/param&gt;
&lt;param name="pageId" value="2019"&gt;



&lt;/param&gt;
&lt;embed src="http://www.parleys.com/share/parleysshare2.swf?pageId=2019" type="application/x-shockwave-flash" allowfullscreen="true" width="474" height="443"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8795604888160975763-1556226042085200439?l=blog.solidcraft.eu' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.solidcraft.eu/2010/10/video-from-my-presentation-at-agile.html</link><author>noreply@blogger.com (Jakub Nabrdalik)</author><thr:total>3</thr:total></item></channel></rss>
