<?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-386321015808580001</id><updated>2011-09-04T06:20:39.356-07:00</updated><category term='software-repositories data-mining cvs'/><category term='OSGi'/><category term='java'/><category term='groovy'/><category term='spring'/><category term='business rules'/><category term='software repositories archaeology visualization maintenance'/><category term='oopsla'/><category term='programming language'/><category term='testing'/><category term='jee'/><category term='architecture'/><category term='modularization'/><category term='conferences'/><title type='text'>I code so I don't have to ...</title><subtitle type='html'>I always write code.&lt;br&gt;
Sometimes I'll write about my code.&lt;br&gt;
Maybe someday I'll write about my writing on code writing.&lt;br&gt;
For now, I just look how to code less in order to do more.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-4546264122347971206</id><published>2010-12-07T01:46:00.001-08:00</published><updated>2010-12-07T03:14:03.622-08:00</updated><title type='text'>#shlcon2010 - Arquitecturas que crecen y arquitecturas que no</title><content type='html'>Me dió un enorme gusto dar esta plática, ya que es la primera vez que expongo ideas que llevan más de un año gestándose en mi mente. En particular:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Las analogías entre el desarrollo y crecimiento de organismos vivos con las condiciones que propician o inhiben el crecimiento de un sistema de software.&lt;/li&gt;&lt;li&gt;La relevancia de las ideas que Steele expuso en 1997 en su keynote "Growing a Language" al aplicarlas en el contexto de la arquitectura de sistemas.&lt;/li&gt;&lt;li&gt;La relevancia que tienen en el contexto de desarrollo de software las 15 propiedades que Christopher Alexander destiló e identificó como intrínsecas en los sistemas vivos (en un sentido muy amplio de la palabra).&lt;/li&gt;&lt;/ul&gt;Estas ideas pueden ser discutibles y finalmente erróneas, pero personalmente me han servido de diferentes maneras:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A entender de fondo los procesos y eventos que permiten a un sistema de software crecer adecuadamente.&lt;/li&gt;&lt;li&gt;A mejorar mis diseños, refinando el arte de no diseñar.&lt;/li&gt;&lt;li&gt;A diseñar explícitamente la manera en que un sistema puede y debe crecer. Entendemos que no es conveniente diseñar demasiado desde un inicio, sin embargo SÍ debemos ser explícitos en las maneras en que un sistema y su diseño puede crecer o de lo contrario el caos reinará. Debemos poner siempre atención en diseñar patrones de crecimiento.&lt;/li&gt;&lt;li&gt;A entender que el lugar 'natural' del software no es un repositorio, mucho menos el ambiente de desarrollo de un programador o el entorno creado por todo un equipo de desarrolladores. Aunque todos estos elementos son importantes, el lugar natural del software es en gran medida su entorno de operación, es decir, cuando se encuentra en interacción directa con el complejo entorno social, económico y tecnológico que lo rodea, lo define y al cual, &amp;nbsp;en el mejor de los casos, se integra de manera 'vital', catalizando otros procesos y fenómenos, habilitando la transformación y evolución del entorno en sí, de tal manera que el software es un órgano funcional y vivo dentro de un sistema más grande y complejo. Cuando esto sucede, se da una co-evolución de software-entorno. Cuando el software es exitoso, esta co-evolución se puede presentar de manera muy acelerada.&lt;/li&gt;&lt;li&gt;A razonar el concepto de robustez... y entender la gran ausencia de esta propiedad en los sistemas que desarrollamos de acuerdo a las prácticas más usadas hoy en día.&lt;/li&gt;&lt;li&gt;A identificar intuitivamente los llamados "atributos de calidad" con propiedades estéticas... &amp;nbsp;Solo algunos atributos de calidad por su puesto, y la interpretación puede ser muy cuestionable.&lt;/li&gt;&lt;/ul&gt;En fin, muy grato compartir algo de esto con los asistentes al #shlcon de hace ... ¡¡¡2 semanas!!!&lt;br /&gt;&lt;br /&gt;¡Qué rápido pasa el tiempo! =)&lt;br /&gt;&lt;div&gt;&lt;div id="__ss_5837961" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/zentimental.software/arquitecturas-que-crecen-y-arquitecturas-que-no-shlcon-2010" title="Arquitecturas que crecen y arquitecturas que no"&gt;Arquitecturas que crecen y arquitecturas que no&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse5837961" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=arquitecturasquecrecenyarquitecturasqueno-shlcon2010-101119140012-phpapp01&amp;stripped_title=arquitecturas-que-crecen-y-arquitecturas-que-no-shlcon-2010&amp;userName=zentimental.software" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse5837961" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=arquitecturasquecrecenyarquitecturasqueno-shlcon2010-101119140012-phpapp01&amp;stripped_title=arquitecturas-que-crecen-y-arquitecturas-que-no-shlcon-2010&amp;userName=zentimental.software" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/zentimental.software"&gt;Agustín Ramos&lt;/a&gt;.&lt;/div&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/386321015808580001-4546264122347971206?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/4546264122347971206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2010/12/shlcon2010-arquitecturas-que-crecen-y.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/4546264122347971206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/4546264122347971206'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2010/12/shlcon2010-arquitecturas-que-crecen-y.html' title='#shlcon2010 - Arquitecturas que crecen y arquitecturas que no'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-5971079649906409532</id><published>2010-06-22T22:34:00.000-07:00</published><updated>2010-06-22T22:47:20.606-07:00</updated><title type='text'>Spring IO 2010</title><content type='html'>I'd rather not talk about it, except for two things:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;We have a long way to go.&lt;/li&gt;&lt;li&gt;I'm available for giving FREE workshops at your university.&lt;/li&gt;&lt;/ul&gt;Here are the slides of the 2 talks I gave last Saturday.&lt;br /&gt;&lt;div id="__ss_4566197" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/zentimental.software/desarrollo-dirigido-por-comportamiento-con-cucumber-y-groovy" title="Desarrollo Dirigido por Comportamiento (con Cucumber y Groovy)"&gt;Desarrollo Dirigido por Comportamiento (con Cucumber y Groovy)&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse4566197" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=springio2010-desarrollodirigidoporcomportamientovonline-100621132512-phpapp01&amp;stripped_title=desarrollo-dirigido-por-comportamiento-con-cucumber-y-groovy" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse4566197" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=springio2010-desarrollodirigidoporcomportamientovonline-100621132512-phpapp01&amp;stripped_title=desarrollo-dirigido-por-comportamiento-con-cucumber-y-groovy" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/zentimental.software"&gt;Agustín Ramos&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div id="__ss_4566302" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/zentimental.software/hola-osgi" title="Hola OSGi"&gt;Hola OSGi&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse4566302" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=springio2010-holaosgi-100621133636-phpapp01&amp;stripped_title=hola-osgi" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse4566302" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=springio2010-holaosgi-100621133636-phpapp01&amp;stripped_title=hola-osgi" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/zentimental.software"&gt;Agustín Ramos&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/386321015808580001-5971079649906409532?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/5971079649906409532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2010/06/spring-io-2010.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/5971079649906409532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/5971079649906409532'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2010/06/spring-io-2010.html' title='Spring IO 2010'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-6906235353921638219</id><published>2010-05-18T12:36:00.000-07:00</published><updated>2010-05-18T12:41:06.974-07:00</updated><title type='text'>Software Craftsmanship, why it matters?</title><content type='html'>While reading Donald Norman's "&lt;a href="http://amzn.to/b90Ofd"&gt;The design of everyday things&lt;/a&gt;" unexpectedly I found a most useful idea for explaining the relevance of the Software Craftsmanship movement (strikethrough is mine):&lt;br /&gt;&lt;br /&gt;"Without a good &lt;span class="Apple-style-span" style="text-decoration: line-through;"&gt;model&lt;/span&gt; theory we operate by rote, blindly; we do operations as we were told to do them; we can't fully appreciate why, what effects to expect, or what to do if things go wrong. As long as things work properly, we can manage. When things go wrong, however, or when we come up with a novel situation, then we need a deeper understanding, a good &lt;span class="Apple-style-span" style="text-decoration: line-through;"&gt;model&lt;/span&gt; theory"&lt;br /&gt;&lt;br /&gt;That's it. I've seen so many software developers that are clueless when given a new project, team, environment, technology, etc. They have no idea what direction to follow when one is not given to them, or how to improve their careers and skills. In short: They don't have a good theory of what software development is all about.&lt;br /&gt;&lt;br /&gt;I think &lt;a href="http://manifesto.softwarecraftsmanship.org/"&gt;Software Craftsmanship&lt;/a&gt; is an attempt to create a good theory of what sound software development is all about.&amp;nbsp;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;&lt;b&gt;Now we know&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="text-decoration: underline;"&gt;&lt;b&gt;&amp;nbsp;our craft&lt;/b&gt;&lt;/span&gt;, and we must tell everybody who doesn't.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/386321015808580001-6906235353921638219?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/6906235353921638219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2010/05/software-craftsmanship-why-we-need-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/6906235353921638219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/6906235353921638219'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2010/05/software-craftsmanship-why-we-need-to.html' title='Software Craftsmanship, why it matters?'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-6802840297172645841</id><published>2010-04-29T23:35:00.000-07:00</published><updated>2010-04-30T00:36:45.976-07:00</updated><title type='text'>GULEV 2010 - Wrap up</title><content type='html'>I really enjoyed participating in&amp;nbsp;&lt;a href="http://gulev.org.mx/eventos/gulev2010/"&gt;GULEV 2010&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Although I had expected it to be a far greater event, It was a friendly and smooth place to meet some interesting people. &lt;br /&gt;&lt;br /&gt;In particular I had the chance to talk a while with some true great open source developers like &lt;a href="http://people.gnome.org/~federico/"&gt;Federico Mena&lt;/a&gt; (GNOME co-founder, now with Novell) and &lt;a href="http://www.alexandrocolorado.com/blog"&gt;Alexandro Colorado&lt;/a&gt; (OpenOffice.org). I also had the chance to meet the guys behind &lt;a href="http://www.springhispano.org/"&gt;springhispano.org&lt;/a&gt; and &lt;a href="http://www.javamexico.org/"&gt;javamexico.org&lt;/a&gt;. All of them are nice and interesting guys, everyone in his own way. &lt;br /&gt;&lt;br /&gt;Miguel Angel, the founder and organizer of this conference (which will celebrate it's 10th aniversary next year, prepare yourself for the party!), is a most gentle and passionate guy. He explained me all the struggle he had to go in order to keep the conference going on, because last year the AH1N1 virus and global economic factors forced him and his kind wife to cancel the conference. Fortunately this year was different and although small, the conference was very successful and it got many new friends (me included).&lt;br /&gt;&lt;br /&gt;The most interesting chat (and dinner) was with Alexandro, who through his opinions and recaps on some software history reminded me of the years when I was fully committed to promoting open source software, but most importantly, that open source is not much about convenience as it is about an idea: freedom. And freedom my friends, is undervalued nowadays. &lt;br /&gt;&lt;br /&gt;I also spent some time with my colleague and neighbor Chris, his wife and their newborn baby Natalia. They are such a trio! Congrats for being such good parents!&lt;br /&gt;&lt;br /&gt;I want to share with you the slides I used in my talks.&lt;br /&gt;&lt;br /&gt;The last one (BDD) was somehow improvised. It's a trimmed down version of a talk Chris and me gave a few days ago at Certum. Miguel made room for some unscheduled talks, and lately we've been having so much fun developing tests with &lt;a href="http://cukes.info/"&gt;cucumber&lt;/a&gt; and friends. So it seemed the perfect moment to introduce some real polyglot programming in the JVM applied to solve the annoyances of &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;Test Driven Development&lt;/a&gt;, although the real stars here are not so much the tools as the method.&lt;br /&gt;&lt;br /&gt;That's all for today.&lt;br /&gt;Take care.&lt;br /&gt;&lt;div id="__ss_3867362" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/zentimental.software/modularizacin-efectiva-domando-a-la-hidra" title="Modularización efectiva - domando a la hidra"&gt;Modularización efectiva - domando a la hidra&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse3867362" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=modularizacinefectiva-domandoalahidrav1-onlinr-100427013648-phpapp02&amp;stripped_title=modularizacin-efectiva-domando-a-la-hidra" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse3867362" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=modularizacinefectiva-domandoalahidrav1-onlinr-100427013648-phpapp02&amp;stripped_title=modularizacin-efectiva-domando-a-la-hidra" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;div id="__ss_3872550" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/zentimental.software/la-nueva-imagen-del-gur-el-maestro-artesano-dentro-del-ingeniero" title="La nueva imagen del gurú - El maestro artesano dentro del ingeniero"&gt;La nueva imagen del gurú - El maestro artesano dentro del ingeniero&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse3872550" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=lanuevaimagendelgurv1-100427114547-phpapp02&amp;stripped_title=la-nueva-imagen-del-gur-el-maestro-artesano-dentro-del-ingeniero" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse3872550" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=lanuevaimagendelgurv1-100427114547-phpapp02&amp;stripped_title=la-nueva-imagen-del-gur-el-maestro-artesano-dentro-del-ingeniero" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;div id="__ss_3910807" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/zentimental.software/bdd-desarrollo-dirigido-por-comportamiento" title="BDD - Desarrollo dirigido por comportamiento"&gt;BDD - Desarrollo dirigido por comportamiento&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse3910807" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=desarrollodirigidoporcomportamientov1-online-100430005936-phpapp02&amp;stripped_title=bdd-desarrollo-dirigido-por-comportamiento" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse3910807" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=desarrollodirigidoporcomportamientov1-online-100430005936-phpapp02&amp;stripped_title=bdd-desarrollo-dirigido-por-comportamiento" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/386321015808580001-6802840297172645841?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/6802840297172645841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2010/04/gulev-2010-wrap-up.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/6802840297172645841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/6802840297172645841'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2010/04/gulev-2010-wrap-up.html' title='GULEV 2010 - Wrap up'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-2835834738421750960</id><published>2010-02-07T06:24:00.000-08:00</published><updated>2010-03-09T09:06:00.112-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software repositories archaeology visualization maintenance'/><title type='text'>Source code evolution visualization: the moving picture metaphor</title><content type='html'>Just to share with you a visualization from the development history of my relatively recent &lt;a href="http://www.osgi.org"&gt;OSGi&lt;/a&gt; based project at Certum.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/yt9DH0QNtpo&amp;hl=en_US&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/yt9DH0QNtpo&amp;hl=en_US&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;It's not Star Wars! I'd rather call it "Code Wars" =) &lt;br /&gt;&lt;br /&gt;It was created with Andrew Caudwell's &lt;a href="http://code.google.com/p/gource/"&gt;gource&lt;/a&gt; and it's based on our project's 2nd repository (we moved from CVS without preserving full history), but you can quickly get a feeling of these points:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Developer participation was very intermittent (due to customer and management decisions).&lt;/li&gt;&lt;li&gt;We lacked (and it was impossible to set) a clear responsibility demarcation for each developer and module (a developer should touch only upon a restricted set of modules).&lt;/li&gt;&lt;li&gt;Developers had very different involvement and working patterns.&lt;/li&gt;&lt;/ol&gt;I think the most important thing about gource is that it enables and gives inspiration for a whole new family of &lt;a href="http://media.pragprog.com/articles/mar_02_archeology.pdf"&gt;software archeology&lt;/a&gt; tools and practices, with far reaching implications for software maintenance. Imagine this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Having a control panel for the replay of this kind of visualizations, with 1) filters for developers, modules and time frame. And 2) controls for playback, zooming and panning at will.&lt;/li&gt;&lt;li&gt;Being able to specify mapping rules from physical files to design modules (which could be much more useful) and with the option to choose between both.&lt;/li&gt;&lt;li&gt;Integrating this view with your project dashboards (e.g. JIRA)&lt;/li&gt;&lt;/ul&gt;You could use this setup to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Quickly get an objective idea of the source code evolution, in terms of work done.&lt;/li&gt;&lt;li&gt;If you are new to the project, get a feeling of the most recent project dynamics.&lt;/li&gt;&lt;li&gt;Identify time frames which produced the most unstable modules, and try to correlate this with the project's context and practices at the time.&lt;/li&gt;&lt;li&gt;Correlate with other charts and visualizations.&lt;/li&gt;&lt;li&gt;Identify project landmarks, and attach metadata and links to other sources providing more information of the events.&lt;/li&gt;&lt;/ul&gt;In a sense, this kind of view is an implementation of &lt;a href="http://www.oopsla.org/oopsla2009/program/onward/351-essays-1"&gt;"The Moving Picture Metaphor"&lt;/a&gt; as exposed by Mark Mahoney last OOPSLA conference. It's not an implementation of the whole metaphor, but It's a feasible one and it's certainly a great start.&lt;br /&gt;&lt;br /&gt;A complementary view to the one provided by gource is that of the source code metrics evolution, for example, as given by the &lt;a href="http://docs.codehaus.org/display/SONAR/Motion+Chart+plugin"&gt;Motion Chart&lt;/a&gt; plugin for &lt;a href="http://sonar.codehaus.org/"&gt;Sonar&lt;/a&gt;. I've found it really useful.&lt;br /&gt;&lt;br /&gt;You may think software archaeology is a useless subject which people like me do just for fun. If you are that kind of guy, let me tell you this, loud and clear: people who don't know and understand the past are condemned to repeat the same mistakes over and over again.&lt;br /&gt;&lt;br /&gt;If you are interested in the high definition video, let me know =)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/386321015808580001-2835834738421750960?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/2835834738421750960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2010/02/source-code-evolution-visualization.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/2835834738421750960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/2835834738421750960'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2010/02/source-code-evolution-visualization.html' title='Source code evolution visualization: the moving picture metaphor'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-7916461522105723798</id><published>2010-01-08T12:08:00.000-08:00</published><updated>2010-01-10T15:45:08.623-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software-repositories data-mining cvs'/><title type='text'>Mining your source code repository - Part 1</title><content type='html'>A new coincidence made me throw myself into another adventure: mining my dear old CVS repository.&lt;br /&gt;&lt;br /&gt;Why would you do that? From trivial to more advanced:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Detect stagnant and dead applications and modules.&lt;/li&gt;&lt;li&gt;Know your team commit habits.&lt;/li&gt;&lt;li&gt;Know "who is who" among your team.&lt;/li&gt;&lt;li&gt;Detect sources of instability within projects.&lt;/li&gt;&lt;li&gt;Detect unrecognized software assets.&lt;/li&gt;&lt;li&gt;Test hypothesis about the impact of certain practices and developmnent models.&lt;/li&gt;&lt;/ul&gt;In other words, you could make your repository talk to you: If you have built history, it certainly has a story to tell =)&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The commit history view&lt;/h3&gt;&lt;br /&gt;There are a lot of views of a source code repository, so I decided to start with something very basic: the commit history, and now I'll tell you how you can do the same.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Decide which modules are of your interest and do a clean checkout.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Once you've decided on your modules, you may do a batch checkout like this (&lt;a href="http://www.gnu.org/software/bash/bash.html"&gt;bash&lt;/a&gt;):&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;for m in module1 module2 module3 moduleN; do &lt;br /&gt;  cvs co $m; &lt;br /&gt;done&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;b&gt;2. Extract your change log&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;First, you need to install &lt;a href="http://www.red-bean.com/cvs2cl/"&gt;cvs2cl&lt;/a&gt;, a perl script which "does what you think it does: it produces a GNU-style &lt;a href="http://www.gnu.org/prep/standards/html_node/Change-Logs.html"&gt;ChangeLog&lt;/a&gt; for CVS-controlled source". Once in place, you should be able to execute this:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;for d in `ls`; do &lt;br /&gt;  cd $d &amp;amp;&amp;amp; echo -ne "Procesing $d ... " ;&lt;br /&gt;  cvs2cl.pl --revisions &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 ; &lt;br /&gt;  if [[ -f ChangeLog ]]; then  &lt;br /&gt;    awk  '/^[0-9]{4}.*/ {print $0}' ChangeLog | uniq &amp;gt; ChangeLog.tstamps &amp;amp;&amp;amp; echo "DONE" ; &lt;br /&gt;  else &lt;br /&gt;    echo "WARNING" ; &lt;br /&gt;  fi;&lt;br /&gt;  cd - ;&lt;br /&gt;done&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;This will produce 2 files for each project: your normal ChangeLog file and a second derived ChangeLog.tsamps with, well, the timestamp of every commit, besides the author of it. &lt;br /&gt;&lt;br /&gt;The if is necessary because it may be the case that some revision history files are corrupted, and by default, cvs2cl fails whenever a file causes problems. Nevertheless you can create a somewhat stripped down version of your ChangeLog by skipping that file, but that needs to be on a per case basis.&lt;br /&gt;&lt;br /&gt;You could further improve the awk part by, for example, extracting the commit comments (mostly useful if you have a commit comment template and the corresponding server side verification which, for example, distinguish between features and bug-fixes), including the list of files modified by each commit, the total number of lines modified, or calculating some other derived data. That's up to how you canalize &lt;i&gt;&lt;a href="http://en.wikipedia.org/wiki/Ch%27i"&gt;Ch'i&lt;/a&gt;&lt;/i&gt; through scripting in the language dearest to your heart.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. Summarize your data.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I find more useful to have a single data file for further analysis, so I aggregate all my single .tstamp files and take the opportunity to switch to .csv format&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;for d in `ls`; do &lt;br /&gt;  cd $d &amp;amp;&amp;amp; echo "Processing $d ... " ; &lt;br /&gt;  awk -v project=$d '{ printf "%s,%s,%s,%s\n",project,$1,$2,$3 }' ChangeLog.tstamps | sort -n -r &amp;gt;&amp;gt; &lt;b&gt;../cvs-activity-all.csv&lt;/b&gt; ;&lt;br /&gt;  cd - ; &lt;br /&gt;done&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;b&gt;4. Leverage your spreadsheet software.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;A &lt;a href="http://en.wikipedia.org/wiki/Pivot_table"&gt;pivot table&lt;/a&gt; is the most strightforward way to do some exploratory data analyisis. You can, for example, create some views for answering questions like:&lt;br /&gt;&lt;br /&gt;- What's the commit density history (for example, by month or quarter of the year) of every project?&lt;br /&gt;- Who are the top committers for this project?&lt;br /&gt;&lt;br /&gt;The following table is a color coded view for answering the former question on some sample projects, grouping commits by quarter&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/_kqenLhAyLfI/S0eHDoc0RmI/AAAAAAAAALw/HD1ClficUEc/s1600-h/commit-history-sample.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_kqenLhAyLfI/S0eHDoc0RmI/AAAAAAAAALw/HD1ClficUEc/s320/commit-history-sample.PNG" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Gaining knowledge&lt;/h3&gt;&lt;br /&gt;Knowledge only comes after reflection and further inquiry on your data. I found, for example, a very explicit causality relationship between the waterfall development followed by several projects (don't blame me yet!) and a fast growing commit density function approaching a peek just before the release date, followed by a long tail of, mostly, bug fixes. Those are clearly not great examples of sound software development, everyoune could tell, but I have data to prove it.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Final remarks&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;The approach presented here for commit history extraction is limited in the sense that it ignores files which are present in branches other than HEAD and haven't been merged yet. &lt;/li&gt;&lt;li&gt;If your interesting history is in a subversion repository, you can leverage the svn log command and svn2cl.&lt;/li&gt;&lt;/ul&gt;Further knowledge extraction will be the subject of a second part in this series. Im expecting to apply some &lt;a href="http://en.wikipedia.org/wiki/Machine_learning"&gt;machine learning&lt;/a&gt; techniques, particularly &lt;a href="http://en.wikipedia.org/wiki/Unsupervised_learning"&gt;unsupervised learning&lt;/a&gt; ones to make sense of the data. Time to clear the dust from my ML training! =)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/386321015808580001-7916461522105723798?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/7916461522105723798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2010/01/mining-your-source-code-repository-part.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/7916461522105723798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/7916461522105723798'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2010/01/mining-your-source-code-repository-part.html' title='Mining your source code repository - Part 1'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_kqenLhAyLfI/S0eHDoc0RmI/AAAAAAAAALw/HD1ClficUEc/s72-c/commit-history-sample.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-6883786971708827971</id><published>2009-10-27T10:14:00.000-07:00</published><updated>2009-10-27T18:44:34.828-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='modularization'/><category scheme='http://www.blogger.com/atom/ns#' term='oopsla'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='programming language'/><category scheme='http://www.blogger.com/atom/ns#' term='conferences'/><title type='text'>OOPSLA Day 1: Modularization</title><content type='html'>&lt;a href="http://www.blogger.com/"&gt;&lt;/a&gt;&lt;span id="goog_1256657389995"&gt;&lt;/span&gt;&lt;span id="goog_1256657389996"&gt;&lt;/span&gt;It´s an open problem. That's all.&lt;br /&gt;&lt;br /&gt;No wait, there´s a lot of work in progress, but at the end, as Aslam Khan wisely said at the afternoon panel backed by a very nice picture: "I feel like a kid".&lt;br /&gt;&lt;br /&gt;Why? The benefits of modularization are well understood. At least of modularization as a very general concept. But what techniques, language features or practices are the best for imposing modularity to existing and new systems? No one knows for sure.&lt;br /&gt;&lt;h2&gt;A tale of 3 language designers and one architect&lt;/h2&gt;First, the panel brought together 3 language designers and a software architect (Aslam).&amp;nbsp;He talked quickly about early indicators of relatively good modularization principles in an existing codebase:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Test cases: If there are enough of them, and they work, it means that your code base implements some design principles which allow to implement fixtures and mocks. Hence, it may be the case that your code is modularized.&lt;/li&gt;&lt;li&gt;&amp;nbsp;Pointcuts: Throwing pointcuts to an existing codebase and measuring how many hits they have is also an indicator of the homogeneity of the code base.&lt;/li&gt;&lt;/ul&gt;For new systems, he suggested:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Using a domain language throughout your project communication. This enables the natural identification of modules.&lt;/li&gt;&lt;li&gt;Using a domain specific language for system implementation. The next logical step. &amp;nbsp;&lt;/li&gt;&lt;/ul&gt;So he's a &lt;a href="http://domaindrivendesign.org/"&gt;Domain Driven Design&lt;/a&gt; (DDD) advocate, which got confirmed when we had a chat after the panel and I asked about the best modularization techniques and strategies he has found in the field. I don't know the relationship between DDD and modularization, so he suggested me to read the 2nd part of Evan's book. =$&lt;br /&gt;&lt;br /&gt;The language guys presented some AOP like stuff and took a position of 'language gene designers', but, why do you design a 'language gene' in the first place? Isn't it for building real software? I was amazed of the ignorance of these researches about the current practice of programming regarding the effects of language features in the current software industry, which has vast amounts of data to grasp what is really needed.&lt;br /&gt;&lt;br /&gt;Fortunately it turned out that these language designers were just guests at the workshop and they ran as soon as the panel ended, which leaved room to real talks about modularity.&lt;br /&gt;&lt;h2&gt;JDK modularizations says "I'm here! talk to me!"&lt;/h2&gt;At the corridor, there was this guy from Sun who showed some&amp;nbsp;&lt;a href="http://www.graphviz.org/"&gt;graphviz&lt;/a&gt; pics representing modularization efforts on the jdk (perhaps he's from&amp;nbsp;&lt;a href="http://openjdk.java.net/projects/jigsaw"&gt;jigsaw&lt;/a&gt;), and remarked that all was OK when managing modularity at the source code level, but at runtime you still have spaghetti. Then Aslam and the language guys made the observation that besides phenomenology and an impressive picture, what's the point of modularization at runtime within the jdk? No real answer.&lt;br /&gt;&lt;h2&gt;OSGi deemed not ready/suitable for enterprise development&lt;/h2&gt;At some point in that chat someone mentioned OSGi because he thought that I was talking about it when said something about my "embed-script-engine-add-spring-and-be-god" technique (which allows me to add/remove aspects at runtime ) and the sun guy got an upset face. "OSGi breaks Hibernate, not the other way around"was heard regarding it's class loader model. Nobody seemed to support OSGi as a &amp;nbsp;modularization technology ready for real world app development. Ouch!&lt;br /&gt;&lt;h2&gt;A nice talk and wrap-up&lt;/h2&gt;Then a few short presentations came, most of the things presented spinned around Aspects, until the agenda was fulfilled and a very interesting 1 hour chat took place. Topics we talked about:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The organizational and social aspects of development and how it impacts modularity.&lt;/li&gt;&lt;li&gt;Modularization evidence left behind by development patterns: branches in repository, average of affected artifacts by bug fix or requirement, etc.&lt;/li&gt;&lt;li&gt;The problem of making the business case for a refactoring towards better modularity, in the face of not having proper and convincing metrics to support it.&lt;/li&gt;&lt;li&gt;The convenience and inconvenience of current metrics relating to modularization.&lt;/li&gt;&lt;li&gt;The current practice of AOP, when some people introduce bugs for not being aware that an aspect or aspects existed, or when people use them like a commodity but they don't understand/manage them.&lt;/li&gt;&lt;li&gt;The nature of dependencies. Yo can't avoid them, but you can manage them.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;A nice talk overall.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Modularization is necessary, and it is a very complex problem.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We are beginning to understand it at large scale.&lt;br /&gt;&lt;/div&gt;&lt;div&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/386321015808580001-6883786971708827971?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/6883786971708827971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2009/10/oopsla-day-1-modularization.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/6883786971708827971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/6883786971708827971'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2009/10/oopsla-day-1-modularization.html' title='OOPSLA Day 1: Modularization'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-7566903683857516215</id><published>2009-10-27T07:52:00.000-07:00</published><updated>2010-01-14T19:48:08.925-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='oopsla'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>OOPSLA Day 1: Architecture meets testing</title><content type='html'>&lt;span style="font-family: inherit;"&gt;As an architect, do you...&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;involve yourself in the tasks of&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Devising a testing strategy?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Helping test managers build a test architecture?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Promoting test design methods?&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;consider testability as a quality attribute to be addressed just as you do with any other?&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;really practice test driven design (i. e. starting from the definition of the architecture)?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;care about the effectiveness and efficiency of the team who is gonna test your stuff?&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: inherit;"&gt;As far as I see, it´s unlikely that you answer "yes" to most of the questions above. But you should.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Why? Because your architecture is not something that abstract as the maya in hinduism. It's the very foundation on which &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: inherit;"&gt;working&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: inherit;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-family: inherit;"&gt;software&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;will be built. So your responsibility is not just delivering an architecture (not to say a Power Point), but a strategy for building working software based on that architecture.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="font-family: inherit;"&gt;Peter Zimmerer's &lt;/span&gt;&lt;a href="http://www.oopsla.org/oopsla2009/program/tutorials/177-what-every-software-architect-should-know-about-testing"&gt;&lt;span style="font-family: inherit;"&gt;tutorial&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: inherit;"&gt; gave me great insight. Lately I've discussed some ideas about testing strategies and testability with my team's new test manager, and raised questions such as:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;How do I design my systems and programs in order to be more testable?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;How should the testing teams apply their&amp;nbsp;effort in the most valuable way?&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: inherit;"&gt;Besides this we started using &lt;/span&gt;&lt;a href="http://sonar.codehaus.org/"&gt;&lt;span style="font-family: inherit;"&gt;sonar&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: inherit;"&gt; as a code quality management all-in-one-place tool. But Peter's talk just revealed that I had still a lot of work to do. Some of the lessons are:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Devise a risk based testing strategy.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Metrics about bugs, coverage and testing progress should be your drivers for test exit criteria.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Coverage has very different meanings: risks, quality attributes, features, requirements, use cases, user profiles, operations, data, platforms, etc.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Practice architecture testing. Don´t wait for functionality to be built.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;If you practice TDD, there´s no reason for not doing it from the very beginning: architecture.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Integration testing != integration.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Integration testing usually takes most of testing effort.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Design for testability. Testability = f ( Observability, &amp;nbsp;Controllability, Modularity, ... )&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Internal code quality affects directly external system quality.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: inherit;"&gt;This one last point may be better represented with a very recent story.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="font-family: inherit;"&gt;As I've said, I dropped a sonar instance a few weeks ago, and the very first project which got analyzed had respectable quality metrics (it's &lt;/span&gt;&lt;a href="http://www.osgi.org/"&gt;&lt;span style="font-family: inherit;"&gt;OSGi&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: inherit;"&gt; based and highly modularized), except for the web module. Then integration of the app began, and the oldest code in the web module (no need to say that the project had been asleep for a while due to organization priority changes) started giving problems: ugly code, specifically in 2 classes.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="font-family: inherit;"&gt;Then testing began, and although I had to stop making commits to the project, I saw that these 2 classes continued to give trouble to the rest of the team. I jumped to the sonar board and guess what I found: those 2 classes where the &amp;nbsp;ones with the most violations and the worst metrics. They urgently need a refactoring.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;So, this is not talking. Code quality metrics matter for very different purposes.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="font-family: inherit;"&gt;If you are not that bored enough by now, you may check out this tool: &lt;/span&gt;&lt;a href="http://code.google.com/p/testability-explorer/"&gt;&lt;span style="font-family: inherit;"&gt;Testability Explorer&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: inherit;"&gt;. It calculates a metric about the suitability of your code for unit testing. How it does what it does? According to the project site, it computes&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Non-Mockable Total Recursive Cyclomatic Complexity (What?!!! Fortunaley there's an explanation for it).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Global mutable state.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Law of Demeter violations.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family: inherit;"&gt;I have found it very useful. Although I've had not time to delve into the relation of the above metrics to compute the final result or&amp;nbsp;integrate the analyzer as part of sonar (a must!)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Next post will be about the workshop on assessment of contemporary modularization techniques =)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/386321015808580001-7566903683857516215?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/7566903683857516215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2009/10/oopsla-day-1-architecture-meets-testing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/7566903683857516215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/7566903683857516215'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2009/10/oopsla-day-1-architecture-meets-testing.html' title='OOPSLA Day 1: Architecture meets testing'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-269524595677303113</id><published>2009-09-30T15:40:00.000-07:00</published><updated>2010-01-08T12:40:53.252-08:00</updated><title type='text'>SG09 slides - OSGi as a foundation for platform and product lines development</title><content type='html'>Just to let you know I've uploaded the slides used at the Software Guru talk last Monday.&lt;br /&gt;&lt;br /&gt;En español :)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bit.ly/SG09-OSGi"&gt;http://bit.ly/SG09-OSGi&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/386321015808580001-269524595677303113?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/269524595677303113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2009/09/sg09-slides-osgi-as-foundation-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/269524595677303113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/269524595677303113'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2009/09/sg09-slides-osgi-as-foundation-for.html' title='SG09 slides - OSGi as a foundation for platform and product lines development'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-196070200978277200</id><published>2009-09-26T15:48:00.000-07:00</published><updated>2009-10-27T08:17:55.277-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jee'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='conferences'/><title type='text'>Upcoming events 2009</title><content type='html'>Well, I'm pretty excited about the upcoming events.&lt;br /&gt;&lt;br /&gt;First of all, I'm giving a talk next Monday at &lt;a href="http://www.sg.com.mx/sg09/"&gt;Software Guru 2009&lt;/a&gt; about &lt;a href="http://www.osgi.org/"&gt;OSGi&lt;/a&gt; as technological foundation for developing software platforms and &lt;a href="http://www.sei.cmu.edu/productlines/"&gt;product lines&lt;/a&gt;, based on our own experience at &lt;a href="http://www.certum.com/"&gt;certum&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Besides this, I'm going to&lt;a href="http://www.oopsla.org/oopsla2009/"&gt; OOPSLA 2009&lt;/a&gt; (Orlando) and &lt;a href="http://qconsf.com/"&gt;QCon 2009&lt;/a&gt; (San Francisco) for the very first time =). &lt;a href="http://bit.ly/oopsla2009Schedule"&gt;Here&lt;/a&gt; is a draft of my OOPSLA schedule.&lt;br /&gt;&lt;br /&gt;I'm specially interested in modularity, architecture and testing. So I've already signed for the following tutorials:&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.oopsla.org/oopsla2009/program/tutorials/159-agile-architecture-via-modularity-patterns"&gt;Agile Architecture via Modularity Patterns (&lt;/a&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://www.oopsla.org/oopsla2009/program/tutorials/159-agile-architecture-via-modularity-patterns"&gt;&lt;span style="font-family: arial;"&gt;Kirk Knoernschild&lt;/span&gt;)&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oopsla.org/oopsla2009/program/tutorials/177-what-every-software-architect-should-know-about-testing"&gt;What Every Software Architect Should Know About Testing (&lt;/a&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://www.oopsla.org/oopsla2009/program/tutorials/177-what-every-software-architect-should-know-about-testing"&gt;Peter Zimmerer)&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oopsla.org/oopsla2009/program/tutorials/149-using-aop-with-ddd-to-create-rich-clean-domain-models"&gt;Using AOP with DDD to Create Rich, Clean Domain Models (&lt;/a&gt;&lt;span style="font-family: Verdana, Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://www.oopsla.org/oopsla2009/program/tutorials/149-using-aop-with-ddd-to-create-rich-clean-domain-models"&gt;Aslam Khan)&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span class="Apple-style-span" style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;All of them are well known and respected professionals, but best of all is that I'll have the chance to meet and listen to great people like 2008 Turing Award Recipient: &lt;a href="http://www.oopsla.org/oopsla2009/program/invited-speakers/215-oopsla-keynote-speaker-turing-award-lecture-reprise"&gt;Barbara Liskov&lt;/a&gt;, C++ Father: &lt;a href="http://www.oopsla.org/oopsla2009/program/research-program/109-language-implementation"&gt;Bjarne Stroustrup&lt;/a&gt; and the like&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;If that's not enough, OOPSLA is colocated with &lt;a href="http://onward-conference.org/"&gt;Onward! conference&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;So, I'll be very busy =), not to mention that I'm enrolled in a rock climbing course with sights on climbing at &lt;a href="http://elpotrerochico.com/_wsn/page2.html"&gt;Potrero Chico&lt;/a&gt; on December and I'm having trouble imaging a compelling development strategy for a SOA/JEE project which just got approved.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;What's the trouble with this project? Let me explain: we estimated almost 60,000 development hours and must be delivered within 8 months (I've never worked on something like this from scratch). Best of all, for security reasons, we weren't given specs to make our estimate, just many clues about size and complexity and a list of deliverables. If I were a believer, I'd be praying for the specs not to come and make me regret not adding other 60k hours to cover my 'risk factor'.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;I'm very far from being a JEE fan, but this will really be a challenge for me. Why? Three reasons: size, complexity and people.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;So, don't be surprised if I start posting about JEE and development methodologies in the months to come.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Times, Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;&lt;span class="Apple-style-span" style="font-family: Times;"&gt;The one sure thing I can say for now is: test your ejb's using &lt;a href="http://openejb.apache.org/"&gt;OpenEjb&lt;/a&gt; and nothing else out there!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&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/386321015808580001-196070200978277200?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/196070200978277200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2009/09/upcoming-events-2009.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/196070200978277200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/196070200978277200'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2009/09/upcoming-events-2009.html' title='Upcoming events 2009'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-5109788214456656946</id><published>2009-08-16T19:45:00.000-07:00</published><updated>2009-08-17T19:27:19.640-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>Advancing OSGi tools, enterprise features and real world experience</title><content type='html'>I recently stumbled upon Craig Wall's (of "Spring in Action" and, lately, "Modular Java" fame) &lt;a href="http://www.jroller.com/habuma/"&gt;blog&lt;/a&gt;. I highly recommend his recipes for OSGi related stuff, particularly:&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold; "&gt;Integration testing of OSGi bundles with &lt;a href="http://www.jroller.com/habuma/entry/putting_osgi_to_the_test"&gt;PAX Exam&lt;/a&gt; and &lt;a href="http://www.jroller.com/habuma/entry/testing_osgi_spring_style"&gt;Spring-DM&lt;/a&gt; support.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Testing is important, so both options are welcomed. Nonetheless, I find PAX Exam more flexible and powerful. I prepared a feature matrix for you:&lt;/div&gt;&lt;center&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;table border="2" cellpadding="0" cellspacing="2"&gt; &lt;!--StartFragment--&gt;  &lt;col width="137"&gt;  &lt;col width="99"&gt;  &lt;col width="63" span="2"&gt;  &lt;tbody&gt;&lt;tr height="13"&gt;   &lt;td colspan="2" height="13" class="xl30" width="236" style="border-right:.5pt solid black"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Feature&lt;/span&gt;&lt;/td&gt;   &lt;td class="xl28" width="63"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;PAX Exam&lt;/span&gt;&lt;/td&gt;   &lt;td class="xl29" width="63"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Spring DM&lt;/span&gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td rowspan="3" height="39" class="xl32" style="text-align: left;"&gt;Provisioning&lt;/td&gt;   &lt;td class="xl33"&gt;Maven&lt;/td&gt;   &lt;td class="xl26"&gt;Yes&lt;/td&gt;   &lt;td class="xl24"&gt;Yes&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td height="13" class="xl33"&gt;HTTP&lt;/td&gt;   &lt;td class="xl26"&gt;Yes&lt;/td&gt;   &lt;td class="xl24"&gt;No&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td height="13" class="xl33"&gt;File&lt;/td&gt;   &lt;td class="xl26"&gt;Yes&lt;/td&gt;   &lt;td class="xl24"&gt;No&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td colspan="2" height="13" class="xl33" style="text-align: left;"&gt;Test Service Injection&lt;/td&gt;   &lt;td class="xl26"&gt;No&lt;/td&gt;   &lt;td class="xl24"&gt;Yes&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td rowspan="2" height="26" class="xl32" style="text-align: left;"&gt;Different Runtime Support&lt;/td&gt;   &lt;td class="xl33"&gt;Different Types&lt;/td&gt;   &lt;td class="xl26"&gt;Yes&lt;/td&gt;   &lt;td class="xl24"&gt;Yes&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td height="13" class="xl33"&gt;Different Versions&lt;/td&gt;   &lt;td class="xl26"&gt;Yes&lt;/td&gt;   &lt;td class="xl24"&gt;No&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td colspan="2" height="13" class="xl33" style="text-align: left;"&gt;Multiple Runtimes/same test&lt;/td&gt;   &lt;td class="xl26"&gt;Yes&lt;/td&gt;   &lt;td class="xl24"&gt;No&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td colspan="2" height="13" class="xl33" style="text-align: left;"&gt;Profiles Support&lt;/td&gt;   &lt;td class="xl26" style="text-align: center;"&gt;Yes&lt;/td&gt;   &lt;td class="xl24"&gt;No&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td colspan="2" height="13" class="xl33" style="text-align: left;"&gt;Junit 3&lt;/td&gt;   &lt;td class="xl26" style="text-align: center;"&gt;No&lt;/td&gt;   &lt;td class="xl24"&gt;Yes&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td colspan="2" height="13" class="xl33" style="text-align: left;"&gt;Juni 4&lt;/td&gt;   &lt;td class="xl26" style="text-align: center;"&gt;Yes&lt;/td&gt;   &lt;td class="xl24"&gt;No&lt;/td&gt;  &lt;/tr&gt;  &lt;tr height="13"&gt;   &lt;td colspan="2" height="13" class="xl33" style="text-align: left;"&gt;TestNG&lt;/td&gt;   &lt;td class="xl27" style="text-align: center;"&gt;Yes&lt;/td&gt;   &lt;td class="xl25"&gt;No&lt;/td&gt;  &lt;/tr&gt; &lt;!--EndFragment--&gt; &lt;/tbody&gt;&lt;/table&gt;    &lt;/div&gt;&lt;/center&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One great feature of PAX Exam is that of running the same test against a bunch of different OSGi runtimes. If you are a OSGi component developer, you probably want to be sure your bundles run on every possible platform.&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Two in a row: &lt;/span&gt;&lt;a href="http://www.jroller.com/habuma/entry/pax_runner_profiles_and_distributed"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;PAX Runner profiles and Distributed OSGi&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You don´t have to wait for the final &lt;a href="http://www.osgi.org/download/osgi-4.2-early-draft3.pdf"&gt;release of R4.2&lt;/a&gt; to be ready, neither your favorite OSGi distribution to implement it in order to use some nice &lt;a href="http://www.osgi.org/EEG/HomePage"&gt;Enterprise &lt;/a&gt;&lt;a href="http://www.osgi.org/EEG/HomePage"&gt;OSGi&lt;/a&gt; features.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Living in a service oriented world, I´m interested in Distributed OSGi and the reference implementation is already here from &lt;a href="http://cxf.apache.org/distributed-osgi.html"&gt;Apache CFX&lt;/a&gt;. With PAX Runner profiles it´s easier than ever to test drive this Enterprise OSGi goodie.  Before this, I had to rely on traditional spring remoting support.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;More to come&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My current team developed an OSGi based transactional platform (I'll give a talk about it at &lt;a href="http://www.sg.com.mx/sg09/"&gt;SG'09&lt;/a&gt;), my favorite IDE is OSGi based and I have an OSGi enabled phone (more about this on a later post). The question is: Do OSGi really pays off ? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, I know it can. But when introducing yourself to the world of  OSGi based apps, it´s not absolutely clear how to avoid getting into more trouble than you probably deserve. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Today you can get 1 published book in german, 3 in english and there are at least two more on the way (early access program), but there´s no much real world experience published on developing large scale OSGi based enterprise applications. We need to fix this ;-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This year I won´t make it into the &lt;a href="http://www.oopsla.org/oopsla2009/program/workshops/81-3rd-workshop-on-assessment-of-contemporary-modularization-techniques"&gt;3rd Workshop on Assessment of Contemporary Modularization Techniques&lt;/a&gt;. Nevertheless keep an eye on it. I'm sure great insight will come.&lt;br /&gt;&lt;/div&gt;&lt;div&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/386321015808580001-5109788214456656946?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/5109788214456656946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2009/08/advancing-osgi-tools-enterprise.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/5109788214456656946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/5109788214456656946'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2009/08/advancing-osgi-tools-enterprise.html' title='Advancing OSGi tools, enterprise features and real world experience'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-386321015808580001.post-3533851921892974235</id><published>2009-08-10T16:13:00.000-07:00</published><updated>2009-08-11T07:41:30.707-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='business rules'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Persistent Buiness Rules as Groovy Closures</title><content type='html'>I think groovy closures are an excellent choice for implementing and executing business rules, having them persistent on a database. What's the big deal of having business rule code on a database?&lt;br /&gt;&lt;br /&gt;- It makes the business rules implementations more managable.&lt;br /&gt;- You adhere to the&lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt; "Don't Repeat Yourself" principle&lt;/a&gt; (DRY)&lt;br /&gt;- A change in a rule can be immediately consumed by all the applications.&lt;br /&gt;- All of the above implies that your applications are less error prone.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Every business rule can be expressed as a formula, and some business rules are composites, which can be expresssed as composite formulas. In turn, each formula can be expressed as a groovy closure, and you can have composite groovy closures too. Finally, yo can easily store your closures as strings and evaluate them at runtime: groovy magic ! =)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Example&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Suppose we have a rule which sums the result of making some calculation on 2 properties (a and b) of every element in a collection, then applies a factor an returns the result. In groovy we can express this rule as the following closure:&lt;br /&gt;&lt;pre  style="padding: 5px; overflow: auto; line-height: 14px; color: rgb(0, 0, 0);font-size:12px;"&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;// &lt;span style="color: rgb(204, 0, 0);"&gt;Rule &lt;span style="color: rgb(204, 0, 0);"&gt;A&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;{ v, rule, factor -&gt; &lt;b&gt;&lt;span style="color: rgb(0, 153, 102);"&gt;def &lt;/span&gt;&lt;/b&gt;&lt;span style="color: rgb(0, 153, 102);"&gt;&lt;/span&gt;total = &lt;span style="color: rgb(255, 0, 0);"&gt;0&lt;/span&gt;; v.&lt;b&gt;&lt;span style="color: rgb(102, 204, 255);"&gt;each &lt;/span&gt;&lt;/b&gt;&lt;span style="color: rgb(102, 204, 255);"&gt;&lt;/span&gt;{ total += rule( it.a, it.b ) } ; total*factor }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Now, one variant of the nested rule (closure), which takes any two parameters, could be something like:&lt;br /&gt;&lt;pre  style="padding: 5px; overflow: auto; line-height: 14px; color: rgb(0, 0, 0);font-size:12px;"&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;// &lt;span style="color: rgb(204, 0, 0);"&gt;Rule &lt;span style="color: rgb(204, 0, 0);"&gt;B&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;{ x, y -&gt; Math.sqrt( x.&lt;b&gt;&lt;span style="color: rgb(102, 204, 255);"&gt;power&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;(y) ) }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Both rules can be stored as strings in a database, then you retrieve, assemble and execute them this way:&lt;br /&gt;&lt;pre  style="padding: 5px; overflow: auto; line-height: 14px; color: rgb(0, 0, 0);font-size:12px;"&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 102);"&gt;&lt;b&gt;def &lt;/b&gt;&lt;/span&gt;ruleACode = ruleDAO.findRule(&lt;span style="color: rgb(255, 0, 204);"&gt;'RULE_A'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: rgb(0, 153, 102);"&gt;&lt;b&gt;def &lt;/b&gt;&lt;/span&gt;ruleA = Eval.me(ruleACode)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 102);"&gt;&lt;b&gt;def &lt;/b&gt;&lt;/span&gt;ruleBCode = ruleDAO.findRule(&lt;span style="color: rgb(255, 0, 204);"&gt;'RULE_B'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: rgb(0, 153, 102);"&gt;&lt;b&gt;def &lt;/b&gt;&lt;/span&gt;ruleB = Eval.me(ruleBCode)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 102);"&gt;&lt;b&gt;def &lt;/b&gt;&lt;/span&gt;entities =&lt;br /&gt;[ &lt;b&gt;&lt;span style="color: rgb(0, 102, 153);"&gt;new &lt;/span&gt;&lt;/b&gt;MyBean(a:&lt;span style="color: rgb(255, 0, 0);"&gt;5&lt;/span&gt;, b:&lt;span style="color: rgb(255, 0, 0);"&gt;2&lt;/span&gt;), &lt;b&gt;&lt;span style="color: rgb(0, 102, 153);"&gt;new &lt;/span&gt;&lt;/b&gt;MyBean(a:&lt;span style="color: rgb(255, 0, 0);"&gt;2&lt;/span&gt;, b:&lt;span style="color: rgb(255, 0, 0);"&gt;4&lt;/span&gt;) ]&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 102);"&gt;&lt;b&gt;assert &lt;/b&gt;&lt;/span&gt;ruleA(entities, ruleB, &lt;span style="color: rgb(255, 0, 0);"&gt;0&lt;/span&gt;.&lt;span style="color: rgb(255, 0, 0);"&gt;5&lt;/span&gt;) == &lt;span style="color: rgb(255, 0, 0);"&gt;4&lt;/span&gt;.5&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;In the code above, first I get the string representation of both rules and convert them to individual closures, which is achieved with Eval.me(). Eval is a convenience class designed to easily execute groovy scripts from plain old java code. I recommend reading the &lt;a href="http://groovy.codehaus.org/api/groovy/util/Eval.html"&gt;javadoc&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The list 'entities' can be replaced with any collection of objects with properties of name 'a and 'b'.&lt;br /&gt;&lt;br /&gt;Finally I just call the closure (which implements Rule A) passing the list, the second closure (which implements Rule B) and the factor as parameters.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Discussion&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;You may argue that you can achieve business rules implementation management through proper component design, modularization and management. And, although I think it's the only way to go on some scenarios, I see various inconveniences in it when compared with the groovy+closure approach:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Code Bloating&lt;br /&gt;Did you notice how easy is to compose and execute closures? This is because a closure resembles a function, which is a vastly simpler concept than a class. Implementing rules with classes packaged in different jars can easily lead you to piles of complex boilerplate code to maintain and tons of related build and dependency management scripts and configuration files.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Incompatible components&lt;br /&gt;One drawback of highly modularized systems, where each module can have a life cycle of it's own, is how easy is to get into component impedance headaches (I believe most of you know what I am talking about)&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Separation of rule definition and implementation&lt;br /&gt;If you separate them, you need extra work (code, process, practice, people) to get them in sync.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;This may seem like nothing new if you have played with the &lt;a href="http://www.artima.com/lejava/articles/compiler_api.html"&gt;Java Compiler API&lt;/a&gt; (part of SE 1.6), but having groovy at hand enhances the whole approach.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Final Thoughts&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;You don't even need your whole team to learn groovy stuff. Here you have the execution of the same rules from pure Java code:&lt;br /&gt;&lt;pre  style="padding: 5px; overflow: auto; line-height: 14px; color: rgb(0, 0, 0);font-size:12px;"&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;public &lt;b&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;void &lt;/span&gt;&lt;/b&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;/span&gt;&lt;/span&gt;testComposedRules() &lt;b&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;throws &lt;/span&gt;&lt;/b&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;/span&gt;Exception {&lt;br /&gt;&lt;br /&gt;String ruleACode = ruleDAO.findRule(&lt;span style="color: rgb(42, 0, 255);"&gt;"RULE_A"&lt;/span&gt;);&lt;br /&gt;Closure ruleA = (Closure) Eval.&lt;i&gt;me&lt;/i&gt;(ruleACode);&lt;br /&gt;&lt;br /&gt;String ruleBCode = ruleDAO.findRule(&lt;span style="color: rgb(42, 0, 255);"&gt;"RULE_B"&lt;/span&gt;);&lt;br /&gt;Closure ruleB = (Closure) Eval.&lt;i&gt;me&lt;/i&gt;(ruleBCode) ;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-size:16;"&gt;  &lt;/span&gt;List&lt;mybean&gt; entities = &lt;b&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;new &lt;/span&gt;&lt;/b&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;/span&gt;ArrayList&lt;mybean&gt;() {{&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-size:16;"&gt;    &lt;/span&gt;add( &lt;b&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;new &lt;/span&gt;&lt;/b&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;/span&gt;MyBean() {{ setA(5); setB(2); }} );&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-size:16;"&gt;    &lt;/span&gt;add( &lt;b&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;new &lt;/span&gt;&lt;/b&gt;MyBean() {{ setA(2); setB(4); }} );&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-size:16;"&gt;  &lt;/span&gt;}};&lt;br /&gt;&lt;br /&gt;&lt;i&gt;  assertEquals&lt;/i&gt;(&lt;br /&gt;&lt;span class="Apple-style-span"  style="font-size:16;"&gt;  &lt;span class="Apple-style-span"  style="font-size:13;"&gt;  ruleA.call( &lt;b&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;new &lt;/span&gt;&lt;/b&gt;Object[] {entities, ruleB, 0.5 }), 4.5 );&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/mybean&gt;&lt;/mybean&gt;&lt;/code&gt;&lt;/pre&gt;You just need the groovy jar. Your class dependencies will limit to the Eval and Closure classes.&lt;br /&gt;&lt;br /&gt;Let me know how it works for you! =)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/386321015808580001-3533851921892974235?l=machinesareus.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://machinesareus.blogspot.com/feeds/3533851921892974235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://machinesareus.blogspot.com/2009/08/persistent-buiness-rules-as-groovy.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/3533851921892974235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/386321015808580001/posts/default/3533851921892974235'/><link rel='alternate' type='text/html' href='http://machinesareus.blogspot.com/2009/08/persistent-buiness-rules-as-groovy.html' title='Persistent Buiness Rules as Groovy Closures'/><author><name>Agustín Ramos</name><uri>http://www.blogger.com/profile/16864120031570441163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://3.bp.blogspot.com/_kqenLhAyLfI/Sr64FrKAKjI/AAAAAAAAALM/YyaCJHgdYyE/S220/Buena+pierna+para+llegar+ahi+arriba+en+bici.JPG'/></author><thr:total>2</thr:total></entry></feed>
