<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2657405825216370931</id><updated>2011-11-06T17:03:42.551-08:00</updated><category term='design patterns'/><category term='jdbc'/><category term='palettes'/><category term='git'/><category term='python'/><category term='development for Apple devices'/><category term='books'/><category term='security'/><category term='log'/><category term='people-ware'/><category term='database migrations'/><category term='cx_Oracle'/><category term='version control'/><category term='lessons learned'/><category term='networking'/><category term='oracle'/><category term='database'/><category term='humor(?)'/><title type='text'>Simone Bruno</title><subtitle type='html'>quod erat demonstrandum</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-6616751347028240263</id><published>2010-12-12T14:38:00.000-08:00</published><updated>2010-12-12T14:38:51.826-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='log'/><title type='text'>Dom_12_Dic_2010_18:07:53_CET.log</title><content type='html'>Playing around with python messaging, in particular RabbitMQ, celery and pika, yesterday night till 5pm! I should probably get a life.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-6616751347028240263?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/6616751347028240263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/12/dom12dic2010180753cetlog.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/6616751347028240263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/6616751347028240263'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/12/dom12dic2010180753cetlog.html' title='Dom_12_Dic_2010_18:07:53_CET.log'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-8549089592303888345</id><published>2010-11-27T18:18:00.000-08:00</published><updated>2010-11-27T18:18:29.284-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='palettes'/><title type='text'>Palettes</title><content type='html'>&lt;a href="http://www.degraeve.com/color-palette/index.php?q=http://images2.layoutsparks.com/1/119575/green-swirls-neon-color.jpg,040e03165d0c279a1451ce39c0f4b3,00190000ad0000ff0066ff45fff5ff"&gt;http://www.degraeve.com/color-palette/index.php?q=http://images2.layoutsparks.com/1/119575/green-swirls-neon-color.jpg,040e03165d0c279a1451ce39c0f4b3,00190000ad0000ff0066ff45fff5ff&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.degraeve.com/color-palette/index.php?q=http://fc08.deviantart.net/fs14/f/2007/012/9/b/Blue_Neon_King_Crown_by_Verde_Acido.jpg,070f161335501e4a6e28679a7bb3e0,00152700498f0066c2008fffbde6ff"&gt;http://www.degraeve.com/color-palette/index.php?q=http://fc08.deviantart.net/fs14/f/2007/012/9/b/Blue_Neon_King_Crown_by_Verde_Acido.jpg,070f161335501e4a6e28679a7bb3e0,00152700498f0066c2008fffbde6ff&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.degraeve.com/color-palette/index.php?q=http://wallpampers.com/pictures/2713/Blue%20Neon%20Nights.jpg,05061017285d1745792557ab19b0eb,00031d001da50056dd0060ff19e9ff"&gt;http://www.degraeve.com/color-palette/index.php?q=http://wallpampers.com/pictures/2713/Blue%20Neon%20Nights.jpg,05061017285d1745792557ab19b0eb,00031d001da50056dd0060ff19e9ff&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.degraeve.com/color-palette/index.php?q=http://www.dangerousminds.net/images/uploads/shanghai_dior_marion-1.jpg,07102a2a41654c698abcb9b57b8493,00094e0f4caa4788cff1f0eea0abc0"&gt;http://www.degraeve.com/color-palette/index.php?q=http://www.dangerousminds.net/images/uploads/shanghai_dior_marion-1.jpg,07102a2a41654c698abcb9b57b8493,00094e0f4caa4788cff1f0eea0abc0&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.degraeve.com/color-palette/index.php?q=http://www.loosetooth.com/Art/Gallery/Softies/0905/11blueboy.jpg,2634346598affdfdfd9cbbc62a6d90,294d4c83c6e3ffffffd9edf400a1fe"&gt;http://www.degraeve.com/color-palette/index.php?q=http://www.loosetooth.com/Art/Gallery/Softies/0905/11blueboy.jpg,2634346598affdfdfd9cbbc62a6d90,294d4c83c6e3ffffffd9edf400a1fe&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.degraeve.com/color-palette/index.php?q=http://reddogreport.com/wp-content/uploads/2010/07/news15-orange-neon-600x239.jpg,180209640b09e21701c43405f9b724,2e0007bc0000ff0000ff0a00ffec34"&gt;http://www.degraeve.com/color-palette/index.php?q=http://reddogreport.com/wp-content/uploads/2010/07/news15-orange-neon-600x239.jpg,180209640b09e21701c43405f9b724,2e0007bc0000ff0000ff0a00ffec34&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.degraeve.com/color-palette/index.php?q=http://www.crystalxp.net/galerie/img/img-wallpapers-digital-blue-smoke-redline-redapple-9199.jpg,080b0f31415c4e6c936d9dbf95d2e1,060c18244e934f89d595cbf1e7fbff"&gt;http://www.degraeve.com/color-palette/index.php?q=http://www.crystalxp.net/galerie/img/img-wallpapers-digital-blue-smoke-redline-redapple-9199.jpg,080b0f31415c4e6c936d9dbf95d2e1,060c18244e934f89d595cbf1e7fbff&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-8549089592303888345?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/8549089592303888345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/11/palettes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/8549089592303888345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/8549089592303888345'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/11/palettes.html' title='Palettes'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-7751722058740662297</id><published>2010-09-05T17:01:00.000-07:00</published><updated>2010-09-05T17:17:35.320-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='cx_Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Python and Oracle: you need to start somewhere!</title><content type='html'>If you need to access an Oracle database using python (actually, to access any database), the first thing you'll need to read is the &lt;a href="http://www.python.org/dev/peps/pep-0249/"&gt;Python Database API Specification 2.0&lt;/a&gt;, which proposes a standard interface to be used by database access libraries. This specification is database agnostic, and various libraries exist which implement it (more or less strictly) for different DBMS.&lt;br /&gt;The library I am using for Oracle access is&amp;nbsp;&lt;a href="http://cx-oracle.sourceforge.net/"&gt;cx-Oracle&lt;/a&gt;, which (almost!) conforms to this specification.&lt;br /&gt;If the Python Database API Specification is too abstract for you and you'd be happy if the official cx-Oracle docs contained more examples, what you need is a nice &lt;a href="http://oracleandpython.wordpress.com/2008/10/09/first-things-first/"&gt;tutorial&lt;/a&gt; to introduce yourself to this library. Then maybe&amp;nbsp;&lt;a href="http://oracleandpython.wordpress.com/2008/10/29/building-on-the-basics/"&gt;another tutorial&lt;/a&gt;&amp;nbsp;to go beyond the basics. Now probably the Specification and the cx-Oracle docs make more sense!&lt;br /&gt;Oh, if you want to work with cx-oracle, you will need to install it first :-). I found very useful this &lt;a href="http://catherinedevlin.blogspot.com/2008/06/cxoracle-and-oracle-xe-on-ubuntu.html"&gt;howto&lt;/a&gt;&amp;nbsp;&amp;nbsp;by &lt;a href="http://catherinedevlin.blogspot.com/"&gt;Catherine Devlin&lt;/a&gt;. If you work with Ubuntu, you will love it for sure.&lt;br /&gt;Hope this helps!&lt;br /&gt;&lt;br /&gt;PS&lt;br /&gt;I assume that yo have some familiarity with Python and Oracle.&lt;br /&gt;If not, I bet this post is not the most interesting you've ever read!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-7751722058740662297?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/7751722058740662297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/09/python-and-oracle.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/7751722058740662297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/7751722058740662297'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/09/python-and-oracle.html' title='Python and Oracle: you need to start somewhere!'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-1375481783995152091</id><published>2010-05-16T08:23:00.000-07:00</published><updated>2010-05-16T08:24:16.078-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design patterns'/><title type='text'>Model View Controller</title><content type='html'>Straight to the point: in a MVC architecture, do Model and View need to communicate directly, or all the communications should be mediated by the Controller? There are two schools of thought regarding this topic, and the question often generates little funny religion wars.&lt;br /&gt;The best answer to this question which I have ever found is in the &lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW6"&gt;Cocoa Design Patterns&lt;/a&gt;&amp;nbsp;document, available on the Apple dev center website (by the way, the document is a recommended reading regarding design patterns in general, whatever the language, platform or technology you use).&lt;br /&gt;&lt;br /&gt;To sum up, the document describes both models, named "traditional model" (in which there is direct communication between model and view) and the "Cocoa model", in which the Controller always mediates between View and Model.&lt;br /&gt;&lt;br /&gt;Here is the "Traditional" MVC model:&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/_Vf4fr-j7G8s/S_AJu9uXPwI/AAAAAAAABHQ/N8UJHPNgpNY/s1600/traditional_mvc.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="120" src="http://1.bp.blogspot.com/_Vf4fr-j7G8s/S_AJu9uXPwI/AAAAAAAABHQ/N8UJHPNgpNY/s320/traditional_mvc.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Here is the "Cocoa" MVC model:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_Vf4fr-j7G8s/S_AKMJXqNoI/AAAAAAAABHY/PbswfvOhtLo/s1600/cocoa_mvc.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="116" src="http://1.bp.blogspot.com/_Vf4fr-j7G8s/S_AKMJXqNoI/AAAAAAAABHY/PbswfvOhtLo/s320/cocoa_mvc.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;One of the main arguments in defence of the second architecture is that it theoretically improves the reusability of View and Model, because they are totally decoupled.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Read&amp;nbsp;&lt;a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW6"&gt;Cocoa Design Patterns&lt;/a&gt;&amp;nbsp;for a thorough discussion!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-1375481783995152091?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/1375481783995152091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/05/model-view-controller.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/1375481783995152091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/1375481783995152091'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/05/model-view-controller.html' title='Model View Controller'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Vf4fr-j7G8s/S_AJu9uXPwI/AAAAAAAABHQ/N8UJHPNgpNY/s72-c/traditional_mvc.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-3503277078244529594</id><published>2010-05-16T07:04:00.000-07:00</published><updated>2010-05-16T07:06:04.439-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development for Apple devices'/><title type='text'>Iphone Application startup: the complexity behind the scenes.</title><content type='html'>Let' write an IPhone application which displays a single "Helloworld" label at the center of the display.&lt;br /&gt;&lt;div&gt;&lt;div&gt;It's plenty of tutorials and books which explain how to do that: usually they explain how to use a View Based project template in X-Code, add a label with Interface Builder, and run the application.&lt;/div&gt;&lt;div&gt;Very easy.&lt;/div&gt;&lt;div&gt;But have a look to the set of files generated by Xcode while choosing the View based template: you will see a main method, an Application Delegate class, a ViewController class, a plist file, and two .xib files which define the main Window and the main View of the application.&lt;/div&gt;&lt;div&gt;Also, you will notice that the main .xib file is referenced in the plist file (as the "main nib" ..), and that it is made up of five objects: a UIApplication, a UI Responder, the Application Delegate, the View Controller and a Window Object. Also, some references between objects (or, more precisely "Outlets") are defined: the UIApplication contains a reference to the Delegate Object, which in turn contains references to both the ViewController and the Main window. Finally the ViewController is owner of the second .xib file, which defines the actual interface of our application and is connected to our ViewController class by the usual mechanism of Outlets and Actions.&lt;/div&gt;&lt;div&gt;Quite complicated for a simple HelloWorld application!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Fortunately, somebody (&lt;a href="http://www.oreillynet.com/pub/au/3332"&gt;Bill Dudney&lt;/a&gt;) already made an effort to put all the pieces together and explain very clearly how they all work together:&amp;nbsp;&lt;a href="http://bill.dudney.net/roller/objc/entry/demystifying_iphone_app_startup"&gt;Demystifying iPhone App Startup&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;&lt;div&gt;Really a great post, highly recommended!&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/2657405825216370931-3503277078244529594?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/3503277078244529594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/05/iphone-application-startup-complexity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/3503277078244529594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/3503277078244529594'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/05/iphone-application-startup-complexity.html' title='Iphone Application startup: the complexity behind the scenes.'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-2517879413984978802</id><published>2010-05-09T12:32:00.000-07:00</published><updated>2010-05-09T12:55:54.370-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lessons learned'/><category scheme='http://www.blogger.com/atom/ns#' term='people-ware'/><category scheme='http://www.blogger.com/atom/ns#' term='humor(?)'/><title type='text'>Did I write that code?!?</title><content type='html'>&lt;i&gt;&lt;b&gt;Preliminary warning: this post is not worth reading for you if you never make mistakes.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Illusory_superiority"&gt;Illusory superiority&lt;/a&gt; is, according to Wikipedia's definition, "a cognitive bias that causes people to overestimate their positive qualities and abilities and to underestimate their negative qualities, relative to others"&lt;br /&gt;&lt;div&gt;It is that well-known, well documented phenomenon (also known as the &lt;i&gt;above average effect&lt;/i&gt;) that makes so easy for us (T)IT professionals to judge and criticize other people's work. It's a fact of life.&lt;br /&gt;In other words, we tend naturally to have a distorted perception of reality when it comes to evaluate the quality/effectiveness of our work compared to the quality/effectiveness of the work of our colleagues.&lt;br /&gt;It is extremely therapeutic, in order to come back to reality, to periodically try to spot major flaws in your own work: poor design or shitty code, completely wrong approach to problems, wrong organizational choices. Try to be as cruel as possible (which means: as cruel as you would be if you were analyzing other people's work).&lt;br /&gt;The &lt;a href="http://en.wikipedia.org/wiki/Epiphany_(feeling)"&gt;epiphany&lt;/a&gt; will occur when you'll find yourself wondering, confused: "did I really write this code?" (or "did I really choose this process? did I really proposed this solution? did I really ignore this issue?", depending on what your actual work is).&lt;br /&gt;Everybody makes mistakes, experience allows us to improve ourselves recognizing them, but this virtuous path requires humility, as written in almost all books of self improvement written by spiritual gurus, genuinely illuminated guides or simply people which love making money selling books about this kind of stuff (And they actually sell them: smart guys, definitely above the average).&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-2517879413984978802?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/2517879413984978802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/05/did-i-write-that-code.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/2517879413984978802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/2517879413984978802'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/05/did-i-write-that-code.html' title='Did I write that code?!?'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-3723275004449633701</id><published>2010-04-13T15:22:00.000-07:00</published><updated>2010-04-13T15:43:18.050-07:00</updated><title type='text'>Iphone Apps vs Mobile Web vs Android vs... The winner is...</title><content type='html'>... Apple!&lt;br /&gt;&lt;br /&gt;Yesterday night I attended a &lt;a href="http://www.mobile-monday.de/events/event/listByDate?date=2010-04-12"&gt;Mobile Monday&lt;/a&gt;&amp;nbsp;meeting in&amp;nbsp;Düsseldorf&amp;nbsp;about current trends in mobile development, namely native apps (Iphone, Android, ...) vs browser-based web applications.&lt;br /&gt;The meeting did not make me change my mind about the best opportunities the market is offering these days to smart developers. I actually think there's a winner around, Apple, and its mobile eco-system (Iphone, Ipod, Ipad, ...).&lt;br /&gt;Why? A few reasons here:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Apple Iphone Apps and the App Store proofed to be effective, changing the mobile standards and defining a brand new profitable business model paradigm; the other main actors (including Google, I would say) are making their moves, of course, but they are all, still, behind&lt;/li&gt;&lt;li&gt;Objective C's popularity is quickly increasing, but still there are not as many good OC developers on the market as many web developers or java developers. Have a look to the job offers and you'll be quickly convinced that learning OC is not a waste of time on a career perspective.&lt;/li&gt;&lt;li&gt;The market requires Iphone developers: loads of major companies want a branded Iphone application because &lt;i&gt;it's cool&lt;/i&gt;, because it contributes positively to the brand, because the&amp;nbsp;Iphone is &lt;a href="http://en.wiktionary.org/wiki/de_facto"&gt;de facto&lt;/a&gt; &amp;nbsp;&lt;b&gt;&lt;i&gt;the&lt;/i&gt;&lt;/b&gt;&amp;nbsp;"smart phone" &lt;a href="http://en.wiktionary.org/wiki/par_excellence"&gt;par excellence&lt;/a&gt;. An example to make my point clear: &lt;a href="http://www.tecnisa.com.br/lp-iphone.html"&gt;http://www.tecnisa.com.br/lp-iphone.html&lt;/a&gt;. Tecnisa is one of the major brazilian construction firms, and they have a branded Iphone app, beautifully advertised in their website. No Android application, did you notice it?&lt;/li&gt;&lt;li&gt;Have you ever browsed your huge collection of porn pictures on an Ipad&amp;nbsp;(come on, I know you DO have a huge collection of porn pictures, and you DO know who Peter North, Davide Jannello and Jenna Jameson are...)? The truth is: Apple devices are the coolest around (but I'm looking forward to see &lt;a href="http://www.findfindfound.com/hk/DB31/db31-x.jpg"&gt;Casio&lt;/a&gt; mobile devices!!!).&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Prepare to buy my applications on the Apple Store!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;PS&lt;/div&gt;&lt;div&gt;Of course I know you still&amp;nbsp;can make loads of money developing "traditional" Web Apps, or Android Apps or.. whatever. Even developing python scripts or java command-line tools for DBA's or Sys-Admins. Probably even playing a &lt;a href="http://en.wikipedia.org/wiki/Kora_(instrument)"&gt;Calabash-made harp-lute&lt;/a&gt;.&amp;nbsp;It all depends on three factors:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;How smart you are&lt;/li&gt;&lt;li&gt;How business oriented you are&lt;/li&gt;&lt;li&gt;How lucky you are!&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-3723275004449633701?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/3723275004449633701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/04/iphone-apps-vs-mobile-web-vs-android-vs.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/3723275004449633701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/3723275004449633701'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/04/iphone-apps-vs-mobile-web-vs-android-vs.html' title='Iphone Apps vs Mobile Web vs Android vs... The winner is...'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-4656038496436502091</id><published>2010-03-08T15:57:00.000-08:00</published><updated>2010-09-20T02:24:12.353-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='people-ware'/><category scheme='http://www.blogger.com/atom/ns#' term='humor(?)'/><title type='text'>Psychology (psychiatry?) of the True IT Professional</title><content type='html'>It's easy to spot the True IT Professional (TITP, capital T is on purpose) among a bunch of fake ones.&lt;br /&gt;&lt;br /&gt;First of all, the TITP will &lt;i&gt;never&lt;/i&gt; lose an occasion to talk about technology: you mention a language? The TITP already knows it, and in one of his previous professional experiences he has successfully used it to solve almost impossible problems. Or has just written a book about it, or an article in a authoritative website, or there's a post in his blog about it. At least, he has attended a conference about it, or he has&amp;nbsp;&lt;i&gt;read something&lt;/i&gt; about it. The same applies for any frameworks, technologies, methods/methodologies of software development you can possibly imagine, even if you try with the most abstruse buzzwords: the TITP already knows it, not in a superficial way but with a deep and thorough understanding, and can probably show to you an entry in his Curriculum Vitae which documents his rock-solid expertise in the field.&lt;br /&gt;Furthermore, he will very often express an opinion about it, which is in 90% of cases extremely negative, in 10% of cases extremely positive and enthusiastic, but never neutral: "Technology X? It's a mess, and leads to messy code", "Framework Y? Mmh, no doubt: Z is much better, and I can tell you because I worked for many years with this kind of frameworks", "Method(ology) H? Brilliant, the best thing I've ever tried in my professional life. But unfortunately I know many IT guys that are not skilled enough to understand this and keep on using obsolete and ineffective ways to blablabla...".&lt;br /&gt;Expressing an opinion about a technology is a subtle, indirect way to convey to your audience the following message: "I know that!".&lt;br /&gt;&lt;br /&gt;The art of indirect messages is a technique that every TITP effortlessly masters, and it is the foundation of the second basic TITP behavioral pattern:&amp;nbsp;the "All other IT guys are professionally inferior to me" one. The TITP will never say "I am the best around". That would be arrogant. But, still, he would really like to say it, because he actually thinks so or, in some cases, simply likes to think so. Instead, he will adopt an &lt;i&gt;indirect strategy&lt;/i&gt; and start painting a world full of mistakes committed by &lt;i&gt;other&lt;/i&gt; developers and &lt;i&gt;other&lt;/i&gt; working teams; he will never run short of criticisms directed to other IT guys, primarily about their technical skills, but not neglecting their "political" skills, their ability to work in team, and even their lack of sense of humor. The subtle strategy behind this pattern is the following: if I can convey the idea that other people around are professionally less skilled and effective than me, &lt;i&gt;de facto&lt;/i&gt; I am successfully conveying the idea that &lt;i&gt;I am the best around (&lt;/i&gt;&lt;a href="http://en.wikipedia.org/wiki/Q.E.D."&gt;quod erat demonstrandum&lt;/a&gt;&lt;i&gt;).&lt;/i&gt;&amp;nbsp;Without looking arrogant. Clever.&lt;br /&gt;Ten TITP's out of ten talking with you will imply with their words the message "I am the best around".&lt;br /&gt;And you can bet they (we?) all are :-)!&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Post Scriptum&lt;/i&gt;&lt;br /&gt;A TITP has a blog, and he uses it to show technical proficiency, brilliant sense of humor and some knowledge of Latin&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-4656038496436502091?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/4656038496436502091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/03/psychology-psychiatry-of-true-it.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/4656038496436502091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/4656038496436502091'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/03/psychology-psychiatry-of-true-it.html' title='Psychology (psychiatry?) of the True IT Professional'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-4335080038358517088</id><published>2010-03-07T10:34:00.000-08:00</published><updated>2010-03-08T16:07:09.629-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='humor(?)'/><title type='text'>Simplicity is the ultimate form of sophistication..</title><content type='html'>After some years of CVS and SVN experience, it's good to have some relief from a painful world of branches and merges: GIT makes everything simpler. You can alter a repository history rebasing your commits, for example. With the "onto" option it is easy to transplant a line of development from one branch to a completely different one. You can reset your repository with the reset option in three different ways (--hard, --soft and.. mixed!), &amp;nbsp;depending whether you need to change your working tree, or only the git index (thus affecting the staged/cached content ready to be committed), or the reference to the HEAD of the current branch. The extra layer represented by the cached (or staged; two different words for the same concept, as - more generally - there are always multiple ways to the same truth) content of the index is beautifully managed by these three options (but be careful, do not make confusion between "reset" and "revert", the later being the dark side, so to speak, of the exotic "cherry-pick" command). Life is much easier now that a symmetrical diff is supported with the intuitive notation "git diff commit1...commit2" (did you notice the THREE dots?). &amp;nbsp;Merges are very easy to perform now: you just need to be careful that your working tree is in sync with your index before starting the job (it's not good to start a merge with a dirty working dir!), and run the merge command. Oh, be aware of &lt;a href="http://www.gelato.unsw.edu.au/archives/git/0504/2279.html"&gt;criss-cross merges&lt;/a&gt;, and choose carefully your merging strategy among the following: resolve, recursive, ours, subtree and the powerful &lt;a href="http://kerneltrap.org/mailarchive/git/2008/6/3/2010914"&gt;octopus merge&lt;/a&gt;. And now when working with remote repositories, there's no more room for useless complications since your local repository contains tracking branches which are mapped to remote branches in the original repository, and these tracking branches (in which you should &lt;i&gt;never&lt;/i&gt; run commit or push commands, don't forget it!) are mapped with local development branches using simple and intuitive&amp;nbsp;&lt;i&gt;refspecs&lt;/i&gt; configurations available in the .git/config file, which will be used by git whenever issueing a fetch, merge or push command. Anyway, the proliferating of branches and repositories will never add unnecessary complexity to the management of your git-version-controlled projects or your Continuous Integration environments, since it is a commonly adopted best practice in GIT projects to use a &lt;i&gt;depot&lt;/i&gt;&amp;nbsp;directory including an authoritative repository which all developers should clone/fetch/pull from and push to (don't call it master repository, or central repository: GIT is a DISTRIBUTED Version Control System!). GIT definitely recalls to me the beautiful declination of the &lt;a href="http://en.wikipedia.org/wiki/Occam's_razor"&gt;Okkam's Razor&lt;/a&gt; by Leonardo da Vinci: &lt;a href="http://en.wikipedia.org/wiki/Simplicity"&gt;simplicity&lt;/a&gt; is the ultimate form of sophistication :-).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-4335080038358517088?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/4335080038358517088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/03/simplicity-is-ultimate-form-of.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/4335080038358517088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/4335080038358517088'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/03/simplicity-is-ultimate-form-of.html' title='Simplicity is the ultimate form of sophistication..'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-2010763049205201056</id><published>2010-02-07T09:03:00.000-08:00</published><updated>2010-02-08T01:31:48.869-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>GIT security model</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;b&gt;Git, SHA1 and security&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Is the GIT security model dependent on the cryptographic security of the hashing algorithm (SHA1) used by git to generate id's for GIT objects?&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;After &lt;/span&gt;&lt;a href="http://www.schneier.com/blog/archives/2009/06/ever_better_cry.html"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;new progresses&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;last year in breaking the SHA1 algorithm, it is reasonable to try to find an answer to this question before deciding to adopt GIT for your software project(s). This was the subject of an interesting discussion I recently had with some colleagues.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;There's an interesting &lt;/span&gt;&lt;a href="http://www.mail-archive.com/cryptography@metzdowd.com/msg10800.html"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;post&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;by Linus Torvalds on the&amp;nbsp;&amp;nbsp;on the&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.mail-archive.com/cryptography@metzdowd.com/info.html"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Cryptography Mailing List&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt; &amp;nbsp;about this subject, dated 25 Apr. 2005.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Basically it would be very difficult for an an attacker, leveraging the possibility to generate a collision in order to corrupt a GIT object database, to produce huge harms because the GIT security model is NOT based on the cryptographic security of the SHA1 hash, but on the fact that (in Linus' words)"&lt;/span&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;git is distributed, which means that a developer should never actually use a public tree for his development&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;".&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;And, of course, the possibility of corrupting all the existing repositories of all users involved in a project, without anybody noticing it, is quite remote. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;b&gt;The adoption of SHA1: a design flaw?&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Even if we do not consider the adoption of SHA1 an issue by the point of view of security (i.e., we agree that that the weakness of the SHA1 algorithm does not make life easier for attackers who wants compromise the integrity of a GIT archive), still this could be considered a design flaw, since the id's for objects are not &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;deterministically&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt; unique, but only &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;probabilistically. &lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;My opinion? The probability of collisions of two files in a software project using SHA1 is so low that this will never be a concrete issue for GIT users (&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;thanks to Luca Milanesio, Peter Moore and Stefano Galarraga for your input&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;).&lt;/span&gt; &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-2010763049205201056?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/2010763049205201056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/02/git-security-model.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/2010763049205201056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/2010763049205201056'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/02/git-security-model.html' title='GIT security model'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-5881978008570648194</id><published>2010-02-04T11:26:00.000-08:00</published><updated>2010-02-07T12:00:39.269-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>Jdbc, TCP channels and other funny dudes...</title><content type='html'>&lt;div&gt;My most affectionate readers already know that&amp;nbsp;I recently worked on a java tool that automates the migration of database structure and content between different database versions (you know, changes in tables, fields, new indexes, and other database refactoring operations): the tool is called DMT, and I already spoke about it in the pages of this blog.&lt;/div&gt;&lt;div&gt;The tool is used by several development teams for all operations of database re-creation, migration and tests, and I was not receiving so many complaining emails these days, so I was pretty confident that it is now decently stable and the planned tests in production-like environment would run smoothly. Of course, this is not what happened: when DMT was used in a pre-production environment for testing purposes, the DBA's who run the tests experienced that it was not able to run the migration, hanging indefinitely without completing the execution of the migration task.&lt;/div&gt;&lt;div&gt;This was the right occasion for me to learn what happens when a TCP channel is closed while a jdbc connection is active over it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The problem&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;DMT connects to the Oracle host and sends through a jdbc connection the SQL statements to be executed&lt;/li&gt;&lt;li&gt;The Oracle server receives the SQL statements and begins the execution. While the SQL statements are running, there is no traffic between DMT and the Oracle server, because DMT keeps waiting from the Oracle Server a signal when the execution of the statement is completed (or when an Oracle exception occurs)&lt;/li&gt;&lt;li&gt;While the Oracle Server is running the SQL statements and DMT is waiting a signal that this process has been completed, a firewall detects that the TCP channel between DMT and the Oracle server is inactive and decides to close the connection because of a timeout configuration.&lt;/li&gt;&lt;li&gt;When Oracle completes the SQL execution, the TCP connection with DMT is no longer open, so it is not able to communicate to DMT that the job is done, and DMT keeps waiting a message forever, like an unlucky man which has an unrequited love for a woman&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;The solution&lt;/span&gt;&lt;/div&gt;&lt;div&gt;The TCP &lt;a href="http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/#overview"&gt;Keep-alive&lt;/a&gt;&amp;nbsp;mechanism!&lt;/div&gt;&lt;div&gt;It's possible to enable this mechanism in a jdbc connection simply adding the parameter ENABLE=BROKEN to the jdbc string used to activate the connection, and keep_alive "probes" will be &amp;nbsp;sent over the connection after a period of inactivity keeping the connection alive. The jdbc url will look like the following one:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="color: #333333;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;jdbc:oracle:thin:@(DESCRIPTION=(&lt;b&gt;ENABLE=broken&lt;/b&gt;)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=yourhost1)(PORT=1521))(ADDRESS= (PROTOCOL=TCP)(HOST=yourhost2)(PORT=1521))(LOAD_BALANCE=on)(FAILOVER=on))(CONNECT_DATA=(SERVER=dedicated)(SERVICE_NAME=service.yourcompany.com)(FAILOVER_MODE=(TYPE=session)(METHOD=basic)(RETRIES=10)(DELAY=3))))&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The TCP settings of the host OS will be used to determine when to start sending the keep-alive probes ("keep alive time" parameter), how many probes to send before detecting that the connection is closed ("keep alive probes" parameter) and the interval between two consecutive probes ("keep alive interval")(some further details &lt;a href="http://www.gnugk.org/keepalive.html"&gt;here&lt;/a&gt;).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Bonus: What does the classic "TCP/IP Illustrated" book say about keepalive?&lt;/b&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;i&gt;Many newcomers to TCP/IP are surprised to learn that no data whatsoever flows across an idle&amp;nbsp;TCP connection. That is, if neither process at the ends of a TCP connection is sending data to the&amp;nbsp;other, nothing is exchanged between the two TCP modules. There is no polling, for example, as&amp;nbsp;you might find with other networking protocols. This means we can start a client process that establishes a TCP connection with a server, and walk away for hours, days, weeks or months, and&amp;nbsp;the connection remains up. Intermediate routers can crash and reboot, phone lines may go down&amp;nbsp;and back up, but as long as neither host at the ends of the connection reboots, the connection&amp;nbsp;remains established . [...]&lt;/i&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;i&gt;There are times, however, when a server wants to know if the client's host has either crashed and&amp;nbsp;is down, or crashed and rebooted. The keepalive timer, a feature of many implementations, provides&amp;nbsp;this capability.&lt;/i&gt;&lt;/blockquote&gt;But be aware:&lt;span class="Apple-style-span" style="font-style: italic;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;i&gt;Keepalives are not part of the TCP specification. The Host Requirements RFC provides three reasons not to use&amp;nbsp;them: (1) they can cause perfectly good connections to be dropped during transient failures, (2) they consume&amp;nbsp;unnecessary bandwidth, and (3) they cost money on an internet that charges by the packet. Nevertheless, many&amp;nbsp;implementations provide the keepalive timer.&amp;nbsp;&lt;/i&gt;&lt;/blockquote&gt;Hope this helps!&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-5881978008570648194?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/5881978008570648194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/02/i-am-working-on-java-tool-that.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/5881978008570648194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/5881978008570648194'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/02/i-am-working-on-java-tool-that.html' title='Jdbc, TCP channels and other funny dudes...'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-6972459765333193919</id><published>2010-01-31T13:43:00.000-08:00</published><updated>2010-04-14T15:06:02.279-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Exploring GIT</title><content type='html'>I passed this Sunday afternoon reading&amp;nbsp;&lt;a href="http://www.oreilly.de/catalog/9780596520120/#"&gt;Version Control with GIT&lt;/a&gt;, by Jon Loeliger.&lt;br /&gt;Git is the distributed version control system currently used for Linux Kernel development, conceived and developed under the protective wing of Linus Torvalds himself. The key word here is &lt;i&gt;distributed&lt;/i&gt;: using GIT, there is no need of constant synchronization with a single, central repository, thus allowing a distributed model for software development. The book is quite interesting as it's different from most tutorials available in the web: the first chapters of the book describe the &amp;nbsp;internal data structures GIT is based on (commits, trees, blobs and tags stored in the GIT 'Object Store'), and the 'staging' mechanism implemented via the GIT 'index'; the main git commands are then explained referring&amp;nbsp;systematically&amp;nbsp;to these concepts, describing in detail what changes occur to the the git object store and git index as different git commands are executed. The advantage of this approach is that it forces the reader to a deeper understanding of what is behind the scenes while running each command. Of course, you'll have to spend some hours understanding these concepts before diving into git commands, but I think it's worth spending some more hours initially to properly learn a version control technology than spend a lot of hours after, running commands without a full understanding of all the implications and consequences. After all, Linus Torvalds himself stated in the GIT mailing list that you can't grasp and fully appreciate the power of GIT without understanding the purpose of the GIT index, which in turns refers to the objects in the GIT Object Store. If you are using GIT and you are not familiar with these concepts.. you should spend some time studying them, and&amp;nbsp;&lt;a href="http://www.oreilly.de/catalog/9780596520120/#"&gt;Version Control with GIT&lt;/a&gt;&amp;nbsp;is a good resource to have a look at.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-6972459765333193919?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/6972459765333193919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2010/01/exploring-git.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/6972459765333193919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/6972459765333193919'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2010/01/exploring-git.html' title='Exploring GIT'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-7011733572077900612</id><published>2009-12-07T18:30:00.000-08:00</published><updated>2010-06-23T11:21:31.801-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='database migrations'/><title type='text'>DMT rules</title><content type='html'>I'm proud to announce that the almighty Database Management Tool (DMT) I wrote has been successfully used to migrate data to the new version of &lt;a href="http://info.vodafone360.com/en/features#feature6"&gt;MyWeb&lt;/a&gt;, the mobile portal which is part of the &lt;a href="http://www.vodafone360.com/"&gt;360 platform&lt;/a&gt;. DMT rocks ;-)!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2657405825216370931-7011733572077900612?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/7011733572077900612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2009/12/it-worked.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/7011733572077900612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/7011733572077900612'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2009/12/it-worked.html' title='DMT rules'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2657405825216370931.post-4874411780310844608</id><published>2009-09-29T15:25:00.000-07:00</published><updated>2010-02-07T09:06:22.361-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='database migrations'/><title type='text'>Managing databases changes</title><content type='html'>&lt;span style="font-size: medium;"&gt;Software Development is one of the most entropic fields of human activity. "&lt;/span&gt;&lt;i&gt;&lt;span style="font-size: medium;"&gt;&lt;a href="http://www.merriam-webster.com/dictionary/errare%20humanum%20est"&gt;Errare humanum est&lt;/a&gt;&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size: medium;"&gt;, but if you want to screw up everything you need a computer", as I read somewhere. Without &lt;/span&gt;&lt;i&gt;&lt;span style="font-size: medium;"&gt;proper management&lt;/span&gt;&lt;/i&gt;&lt;span style="font-size: medium;"&gt; of all factors that come into play in the lifecycle of a software project, failure is the most probable epilogue of the story. Every experienced programmers know  very well that delivering a software product is not simply a matter of writing code. Coding is only a part (very important, of course) of the game, but it's not the whole game, and losing the overall picture is as easy as dangerous. I am currently working on a project to manage structural databases changes and data migrations between different database versions. It's a common mistake not to think about these issues since the very first phases of design and development of software products: usually architects and developers focus on good database design, on proper Object Relational Mapping, and on performance issues. Project managers and deployers begin to think about database migrations when a new software release is dropped, which requires database changes. Is the currently deployed database already compatible with the new release, or not? How can we determine this? If changes are needed, which scripts do need to be run? Which schemas need to be changed, all of the schemas used by the application or only a subset of them? The first time I had to think about these issues, it was for a pretty huge and complex project (the &lt;a href="http://en.wikipedia.org/wiki/Vodafone_live!"&gt;Vodafone Live! &lt;/a&gt;portal), in a quite complicated scenario: there were localized releases of software developed on different CVS branches (localizations were needed for functional adaptations of the software for the countries that would use it), and whenever a new release was dropped  deployers needed to know how to properly migrate the database and how to change the schemas so that it could work with the new version. Finally, after talking a bit about this with some colleagues (mainly Peter Moore, Mida Boghetich, and Alexis Konstantopoulos,  thank you guys) I came out with some basic principles to approach this issue.&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-size: medium;"&gt;The most important thing was to define a good &lt;/span&gt;&lt;b&gt;&lt;i&gt;&lt;span style="font-size: medium;"&gt;database &lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;b&gt;&lt;i&gt;&lt;span style="font-size: medium;"&gt;versioning&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;b&gt;&lt;i&gt;&lt;span style="font-size: medium;"&gt; mechanism&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;span style="font-size: medium;"&gt;. When I say "database version" I mean a unique identifier that describes the full set of Users and, for each User, Schema Objects (tables, constraints, indexes, stored procedures) that are required by given version(s) of the software. We choose to name database versions using the CVS labels used to tag the software modules responsible of the database creation. Then we started re-organizing the existing database migration scripts (mainly sql scripts) as &lt;/span&gt;&lt;i&gt;&lt;b&gt;&lt;span style="font-size: medium;"&gt;point to point migrations, &lt;/span&gt;&lt;/b&gt;&lt;span style="font-style: normal;"&gt;&lt;span style="font-size: medium;"&gt;that means migrations from a database version to another. (The &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;database version&lt;/span&gt;&lt;span style="font-style: normal;"&gt;&lt;span style="font-size: medium;"&gt; needs to be a separated, independent concept from the &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: medium;"&gt;software version&lt;/span&gt;&lt;span style="font-style: normal;"&gt;&lt;span style="font-size: medium;"&gt;, because different software versions can possibly require the same database version; consequently, not all releases do imply the need of a database migration). At this point we needed to solve the following problem: how can we check that a given database installation is compliant with a given database version? In other words, how can we run a &lt;/span&gt;&lt;b&gt;&lt;i&gt;&lt;span style="font-size: medium;"&gt;database compliance test&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;span style="font-size: medium;"&gt; on an existing database instance, to see if the database structure is compliant with a given db version or it has been corrupted, or not properly installed, or a past migration has not been run properly? For each database version, a textual description of all users was generated in a definite format, and to do that a dedicated tool was written which was able to connect to an existing database instance and generate the desired textual description of the database, so that comparing the actual database structure with the expected one was as simple as diffing two text files (The tool simply queries the database metadata tables to get all the required information, and formats the result according to a definite set of rules). The last ingredient of the recipe was a simple algorithm (let's call it the &lt;/span&gt;&lt;b&gt;&lt;i&gt;&lt;span style="font-size: medium;"&gt;pathfinder algorithm&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;span style="font-size: medium;"&gt;) to compose existing atomic migrations in order to run generic ones. For example, let's imagine that the following database migrations have been written: A to B, B to C, and C to D. If we need to  migrate from A to D, we will need to run these three migrations in the correct order; this is precisely the pathfinder's job: we tell the pathfinder which migration we need to run (Version Alfa to Version Omega), and it will tell us which existing migrations we need to run, and in which order (i.e., Alfa to X, X to Y, Y to F34, F34 to H67, H67 to Omega). Of course the provided examples are pretty simple, but you can easily imagine that if many database versions need to be supported, it's convenient to have a dedicated tool to compute which scripts need to be run and in which order.&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: medium;"&gt;To sum up, the solution that was successfully used to properly manage database changes was made up of the following "ingredients":&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size: medium;"&gt;A &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: medium;"&gt;Database versioning mechanism&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: medium;"&gt;: for each software release it must be clear what is the required database version, and this must be identified univocally with a string identifier&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-size: medium;"&gt;Point to Point migrations&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: medium;"&gt;: all sql scripts to manage schema changes and data migrations need to be written so that it's perfectly clear what the source database version and the target database version are.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: medium;"&gt;A &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: medium;"&gt;pathfinder&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: medium;"&gt; tool, able to compose the existing point to point migrations into generic ones&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span style="font-size: medium;"&gt;Compliance tests&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: medium;"&gt;, to automatically check if a database installation is compliant with a given database version&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span style="font-size: medium;"&gt;The previous description is just a short introduction to the approach I am currently using to manage database changes. Actually, I am working on a simple java tool to automate many of the processes implied by the adoption of the described key concepts. Furthermore, there are several existing tools and resources that can be very useful to handle database changes, or simply to provide inspiration regarding these topics: &lt;/span&gt;&lt;a href="http://www.liquibase.org/"&gt;&lt;span style="font-size: medium;"&gt;www.liquibase.org&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: 'Lucida Grande', Verdana, Lucida, Helvetica, Arial, sans-serif; line-height: 19px;"&gt;&lt;span style="font-family: Georgia, serif; line-height: normal;"&gt;&lt;span style="font-size: medium;"&gt;, &lt;/span&gt;&lt;a href="http://www.dbunit.org/"&gt;&lt;span style="font-size: medium;"&gt;www.dbunit.org&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: medium;"&gt;; I'd recommend also the "migrations" chapter in the Doctrine Manual (&lt;/span&gt;&lt;a href="http://www.doctrine-project.org/"&gt;&lt;span style="font-size: medium;"&gt;http://www.doctrine-project.org&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: medium;"&gt;).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&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/2657405825216370931-4874411780310844608?l=simone-bruno.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://simone-bruno.blogspot.com/feeds/4874411780310844608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://simone-bruno.blogspot.com/2009/09/managing-databases-changes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/4874411780310844608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2657405825216370931/posts/default/4874411780310844608'/><link rel='alternate' type='text/html' href='http://simone-bruno.blogspot.com/2009/09/managing-databases-changes.html' title='Managing databases changes'/><author><name>Simone Bruno</name><uri>http://www.blogger.com/profile/09537332932767375554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://4.bp.blogspot.com/_Vf4fr-j7G8s/TTb1Hgnh87I/AAAAAAAABOI/XczExCj60JA/S220/myself_grey.jpg'/></author><thr:total>0</thr:total></entry></feed>
