<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;AkIESX04fCp7ImA9WxBTFkU.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352</id><updated>2009-12-12T23:15:08.334-08:00</updated><title>Internna - Geared towards Open Source</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://internna.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://internna.blogspot.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>95</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/InternnaOSS" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;Ak8BRX8ycCp7ImA9WxBTFkw.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-7888575353592468170</id><published>2009-12-12T03:00:00.001-08:00</published><updated>2009-12-12T03:54:14.198-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-12T03:54:14.198-08:00</app:edited><title>My TODO list for 2010</title><content type="html">&lt;div style="text-align: justify;"&gt;It's that time of the year again! A lot of good wishes most of which won't ever see the light of day, of course :-) But no more introduction, here's my task list for next year:&lt;ul&gt;&lt;li&gt;&lt;b&gt;Spring 3.0&lt;/b&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/internna/" target="new"&gt;IWebMvc2&lt;/a&gt; is rapidly approaching a final release (I'm two bugs short). I'm already thinking in features for 3.0 and the new version of Spring tops the list. I'm specially interested in the new @REST/MVC support as I want to test an AJAX approach based on &lt;a href="http://jackson.codehaus.org/" target="new"&gt;Jackson&lt;/a&gt; views.&lt;/li&gt;&lt;li&gt;&lt;b&gt;JEE6&lt;/b&gt;&lt;br /&gt;Continuing the trend IWebMvc3 will be fully JEE6 compliant. The interesting parts of the specification are the new dependency injection JSR, the new validation model, web fragments, the web profile and (why not?) asynchronous servlets.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Maven 3 / Spring Roo&lt;/b&gt;&lt;br/&gt;What am I looking for actually? Scaffolding? No, not really. I'm more in the search for a project management tool that works at source level, integrates well with an IDE/third party tools (&lt;a href="https://hudson.dev.java.net/" target="new"&gt;Hudson&lt;/a&gt;, &lt;a href="http://sonar.codehaus.org/" target="new"&gt;Sonar&lt;/a&gt;) and saves me time applying all those things common to any web application like security, logging, testing, validation, you name it.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Open Source work&lt;/b&gt;&lt;br /&gt;I'm not going to abandon IWebMvc/&lt;a href="http://code.google.com/p/iwebjtracker/" target="new"&gt;IWebJTracker&lt;/a&gt; development, of course. But in addition I want to extend my commitment with &lt;a href="http://code.google.com/p/gmaps4jsf/" target="new"&gt;Gmaps4JSF&lt;/a&gt; (you like &lt;a href="http://gmaps-utility-library-dev.googlecode.com/svn/tags/mapsicle/1.0/examples/simple_demo.html" target="new"&gt;MapSicle&lt;/a&gt;?) I may even join Hazem in his &lt;a href="http://www.mashups4jsf.com/mashups4jsf-examples/pages/welcome.xhtml" target="new"&gt;new adventure&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Google projects&lt;/b&gt;&lt;br/&gt;Probably the source of most interesting news this year has been hands down, Google. I'm going to closely follow &lt;a href="http://code.google.com/p/guava-libraries/" target="new"&gt;Guava&lt;/a&gt;, &lt;a href="http://code.google.com/intl/es-ES/appengine/" target="new"&gt;GAE&lt;/a&gt;, &lt;a href="http://code.google.com/intl/es-ES/closure/" target="new"&gt;Closure&lt;/a&gt;, Chrome and may be, just may be, &lt;a href="http://code.google.com/intl/en/webtoolkit/" target="new"&gt;GWT&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;HTML 5&lt;/b&gt;&lt;br/&gt;I'm not sure if next year will complete the transition but obviously you can't miss this train.&lt;/li&gt;&lt;li&gt;&lt;b&gt;OSGi&lt;/b&gt;&lt;br/&gt;I want to test Glassfish v3 OSGi capacilities. And Spring products as well. A project that has always appealed to me has been &lt;a href="http://classworlds.codehaus.org/" target="new"&gt;classworlds&lt;/a&gt;...may this is the time?&lt;/li&gt;&lt;/ul&gt;So what is yours?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-7888575353592468170?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/wllMd3ExWZY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/7888575353592468170/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=7888575353592468170" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/7888575353592468170?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/7888575353592468170?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/wllMd3ExWZY/my-todo-list-for-2010.html" title="My TODO list for 2010" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/12/my-todo-list-for-2010.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMCSHo8fyp7ImA9WxBTEks.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-4460884081126567903</id><published>2009-12-08T01:27:00.000-08:00</published><updated>2009-12-08T02:17:49.477-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-08T02:17:49.477-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FishCAT" /><title>FishCAT testing for v3</title><content type="html">&lt;div style="text-align: justify;"&gt;Last week the latest installation of the &lt;a href="http://wiki.glassfish.java.net/Wiki.jsp?page=FishCAT" target="new"&gt;FishCAT&lt;/a&gt; program came to an end. FishCAT is the GlassFish Community Acceptance Testing program, that is, a community program run by Sun to QA GF (in this case v3) that gets participants from around the globe ().&lt;br /&gt;&lt;br /&gt;I like to join it each time for several selfish reasons. After all, Netbeans + Glassfish is my preferred development platform and if I'm going to use it extensively I want to ensure that it suits my needs. In addition, neither &lt;a href="http://code.google.com/p/internna/" target="new"&gt;IWebMvc&lt;/a&gt;/&lt;a href="http://code.google.com/p/iwebjtracker/" target="new"&gt;IWebJTracker&lt;/a&gt; nor &lt;a href="http://code.google.com/p/gmaps4jsf/" target="new"&gt;GMaps4JSF&lt;/a&gt; were working in GFv3 back at the start of the program. That, of course, forced me to use Tomcat as my main development server. Fortunately Glassfish shares code with Tomcat so having something working in the later means good news to solve the problem in the former. &lt;br /&gt;&lt;br /&gt;The process is really simple, when you find an issue you post a message in the mailing list and after a preliminary revision you're asked to post a bug report in the tracker. Just this initial check was enough to fix the Gmasp4JSF issue (a bug with the application code that traversed the folder structure below /, a subtle difference with Tomcat which wouldn't complain and just set the path to /) so it's a crucial step. There's an obvious commitment with the project and an internal dev is immediately assigned to the issue and you can see steady progress right form the start.&lt;br /&gt;&lt;br /&gt;Here's a brief list of pros:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;The people at Sun top the list without doubt. I haven't ever seem a team of such positive and passionate folks. Special thanks go to Judy Tang and Jan Luehe who were always helpful!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The importance given to the bugs. FishCAT is not a PR project. Sun really wants external devs to participate and puts resources to fix the issues reported. Kudos to the company here. They really understand how to run this kind of activity.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;They helped me as much as I helped them. Yes, I reported several nasty bugs in the deployment and web container components but in the process I got advices and could fix several hidden issues of my applications as well. It was a clear win-win situation for all of us.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;GFv3 will be the first EE 6 implementation available and that's a feat worth some testing.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Tens of developers from countries as different as Germany, China, South Africa, USA or Spain to mention some&lt;/li&gt;&lt;br /&gt;&lt;li&gt;GMaps4JSF and IWebMVc will fully work in the final release of GFv3!&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;I have one con though:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;For God's sake, please upgrade the network infrastructure! And that twentieth century issue tracker as well! Some days just posting a bug was such an exasperating task..&lt;/li&gt;&lt;/ul&gt;All in all, a very positive interaction indeed. I hope to see some of you next year!&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/1248732249041870352-4460884081126567903?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/OPld05hRjrE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/4460884081126567903/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=4460884081126567903" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/4460884081126567903?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/4460884081126567903?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/OPld05hRjrE/fishcat-testing-for-v3.html" title="FishCAT testing for v3" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/12/fishcat-testing-for-v3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQARnkyfip7ImA9WxNaE04.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-4798516718988665002</id><published>2009-11-27T04:26:00.000-08:00</published><updated>2009-11-27T08:12:27.796-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-27T08:12:27.796-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IWebJTracker" /><title>IWebJTracker progress update</title><content type="html">&lt;div style="text-align: justify;"&gt;It seems to me that as of lately I just post about IWebJTracker/IWebMvc2 progress. I guess that I don't have time for more...a pity. Nevertheless here goes another update.&lt;br /&gt;&lt;br /&gt;Next IWebJTracker milestone will be mainly based around integration. The project more or less handles issues already but it needs to communicate better.&lt;br /&gt;&lt;br /&gt;The first step in this path is providing friendly URLs. IWebJTracker has them now (for example, /project/IWEBJTRACKER will load the dashboard and automatically open the project). A bookmarking option has been also added (though I have to improve it...I'm not happy with the result yet)&lt;br /&gt;&lt;br /&gt;The second step is RSS, my preferred way to get updates on things I'm interested. I've added support to the framework and now every action should be pusblished to a feed.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/Sw_MXlzLbVI/AAAAAAAAAQ0/Y3Rkw2GY9O4/s1600/gmaps_rss.PNG"&gt;&lt;img style="display:block;margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 208px; height: 42px;" src="http://3.bp.blogspot.com/_TOuRkiuovcI/Sw_MXlzLbVI/AAAAAAAAAQ0/Y3Rkw2GY9O4/s400/gmaps_rss.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5408766383151082834" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_TOuRkiuovcI/Sw_MXbiqTUI/AAAAAAAAAQs/so2cSZXJTH4/s1600/all_rss.PNG"&gt;&lt;img style="display:block;margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 208px; height: 50px;" src="http://1.bp.blogspot.com/_TOuRkiuovcI/Sw_MXbiqTUI/AAAAAAAAAQs/so2cSZXJTH4/s400/all_rss.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5408766380397448514" /&gt;&lt;/a&gt;&lt;br /&gt;And the last step would be, something that can't be missed in an issue tracker, email support. I've added the Javamail connector but I haven't yet decided the interception points. Right now, IWebJTracker only emails the user to confirm the registration process. It's a matter of adding more templates.&lt;br /&gt;&lt;br /&gt;But the user is not the only target and continuing with the Java &amp; Open Source focus, the tracker can now get updates from the remote APIs of Hudson:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/Sw_Ii1qRkpI/AAAAAAAAAQU/vIyeZdSZH9g/s1600/hudson.PNG"&gt;&lt;img style="display:block;margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 205px; height: 145px;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/Sw_Ii1qRkpI/AAAAAAAAAQU/vIyeZdSZH9g/s400/hudson.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5408762178340754066" /&gt;&lt;/a&gt;&lt;br /&gt;And Sonar (data extracted from &lt;a href="http://nemo.sonarsource.org/components/index/176188" target="new"&gt;Nemo&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/Sw_IuBqkwZI/AAAAAAAAAQc/wYLvagXskYw/s1600/sonar.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 229px; height: 173px;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/Sw_IuBqkwZI/AAAAAAAAAQc/wYLvagXskYw/s400/sonar.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5408762370541797778" /&gt;&lt;/a&gt;&lt;br /&gt;Of course some other areas have received attention as well. For example, the My Projects tab now includes a timeline chart:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/Sw_LkQMsDoI/AAAAAAAAAQk/ilSGJfkOrrk/s1600/timeline.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 229px; height: 187px;" src="http://3.bp.blogspot.com/_TOuRkiuovcI/Sw_LkQMsDoI/AAAAAAAAAQk/ilSGJfkOrrk/s400/timeline.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5408765501179170434" /&gt;&lt;/a&gt;&lt;br /&gt;And..not really coding related...I've designed a logo for the project! I do not accept critics about this ;-)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/Sw_NBhoOMMI/AAAAAAAAAQ8/b3Sl5mHKlDA/s1600/iwebjtracker-logo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 333px; height: 72px;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/Sw_NBhoOMMI/AAAAAAAAAQ8/b3Sl5mHKlDA/s400/iwebjtracker-logo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5408767103585890498" /&gt;&lt;/a&gt;&lt;br /&gt;I hope you like the changes. As always, comments and help are welcome!&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/1248732249041870352-4798516718988665002?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/TJBY8pIkwmw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/4798516718988665002/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=4798516718988665002" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/4798516718988665002?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/4798516718988665002?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/TJBY8pIkwmw/iwebjtracker-progress-update.html" title="IWebJTracker progress update" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_TOuRkiuovcI/Sw_MXlzLbVI/AAAAAAAAAQ0/Y3Rkw2GY9O4/s72-c/gmaps_rss.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/11/iwebjtracker-progress-update.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8MSX0-eip7ImA9WxNUEUo.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-2395897790520551027</id><published>2009-11-02T00:00:00.000-08:00</published><updated>2009-11-02T08:21:28.352-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-02T08:21:28.352-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IWebJTracker" /><category scheme="http://www.blogger.com/atom/ns#" term="IWebMvc2" /><title>Yet another...issue tracker</title><content type="html">&lt;div style="text-align: justify;"&gt;I started the development of &lt;a href="http://code.google.com/p/iwebjtracker/" target="new"&gt;IWebJTracker&lt;/a&gt; because I needed to demonstrate the public and myself that &lt;a href="http://code.google.com/p/internna/" target="new"&gt;IWebMvc&lt;/a&gt; was a good enough framework that simplified development of 2.0 applications. &lt;a href="http://en.wikipedia.org/wiki/Application_lifecycle_management" target="new"&gt;Application Lifecycle management&lt;/a&gt; has always been an area of interest for me so an issue tracker seemed like a good candidate to code.&lt;br /&gt;&lt;br /&gt;The truth is that in the midtime some things have happened that affect the project (for example, &lt;a href="http://www.atlassian.com/software/jira/" target="new"&gt;Jira&lt;/a&gt; has a new version and price scheme and JetBrains has released a new product in this space, &lt;a href="http://www.jetbrains.com/youtrack/index.html" target="new"&gt;YouTrack&lt;/a&gt;). So the market situation is this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;There are very good commercial solutions (Jira, &lt;a href="http://www.fogcreek.com/FogBUGZ/" target="new"&gt;FogBuzz&lt;/a&gt;, YouTrack)&lt;/li&gt;&lt;li&gt;There are very good Open Source solutions (&lt;a href="http://trac.edgewall.org/" target="new"&gt;Trac&lt;/a&gt;, &lt;a href="http://www.bugzilla.org/" target="new"&gt;Bugzilla&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;But, IMHO all that doesn't change anything. I still miss an open source bug tracking system written in Java and that deploys to Tomcat out-of-the-box. So that's why IWebJTracker may still make some sense to someone down the road. Even more so if Subversion and Maven are also their target.&lt;br /&gt;&lt;br /&gt;But, make no mistake, all the above alternatives are better than IWebJTracker. Not only because they're more mature (remember this is a first milestone what I'm releasing today) but because they have a team of people (probably way better coders than I am) helping with the development. Remember that this is a one-man project coded during free hours. No more, no less.&lt;br /&gt;&lt;br /&gt;If you still want to try it out, bear with:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The fact that this is not production ready&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It has obvious flaws (no notification system yet, for example)&lt;/li&gt;&lt;/ul&gt;Last, I would like to publicly thank you the rest of the people that make  possible IWebMvc first and IWebJTracker later: the DWR team, the dojo team, SpringSource, &lt;a href="http://www.schillmania.com/" title="Scott Schiller's experimental design site"&gt;Scott Schiller&lt;/a&gt;, &lt;a href="http://alexgorbatchev.com/wiki/" target="new"&gt;Alex Gorbatchev&lt;/a&gt; or &lt;a href="https://jawr.dev.java.net/" target="new"&gt;Jordi Sellés&lt;/a&gt; among others.&lt;br /&gt;&lt;br /&gt;The download is available at &lt;a href="http://code.google.com/p/iwebjtracker/downloads/list" target="new"&gt;the project page&lt;/a&gt;. And more or less resembles like this:&lt;br /&gt;&lt;br /&gt;&lt;a rel="lightbox" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_TOuRkiuovcI/Su3Sh9v1FDI/AAAAAAAAAQM/TKdMKngzTlU/s1600/iwebjtracker_project_main.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 174px;" src="http://4.bp.blogspot.com/_TOuRkiuovcI/Su3Sh9v1FDI/AAAAAAAAAQM/TKdMKngzTlU/s400/iwebjtracker_project_main.png" alt="" id="BLOGGER_PHOTO_ID_5399203009239782450" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a rel="lightbox" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/Su3ShIlHdoI/AAAAAAAAAP8/GTiwHQvm8gk/s1600/iwebjtracker_dashboard.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 168px;" src="http://3.bp.blogspot.com/_TOuRkiuovcI/Su3ShIlHdoI/AAAAAAAAAP8/GTiwHQvm8gk/s400/iwebjtracker_dashboard.png" alt="" id="BLOGGER_PHOTO_ID_5399202994967770754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a rel="lightbox" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/Su3ShU8yQII/AAAAAAAAAQE/RsoqBlnPhVw/s1600/iwebjtracker_issue_main.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 164px;" src="http://3.bp.blogspot.com/_TOuRkiuovcI/Su3ShU8yQII/AAAAAAAAAQE/RsoqBlnPhVw/s400/iwebjtracker_issue_main.png" alt="" id="BLOGGER_PHOTO_ID_5399202998288269442" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;As always feedback, opinion or help is appreciated. Look for me on the &lt;a href="http://groups.google.com/group/internna" target="new"&gt;mailing list&lt;/a&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/1248732249041870352-2395897790520551027?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/ScGupRUJmvU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/2395897790520551027/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=2395897790520551027" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/2395897790520551027?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/2395897790520551027?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/ScGupRUJmvU/yet-anotherissue-tracker.html" title="Yet another...issue tracker" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_TOuRkiuovcI/Su3Sh9v1FDI/AAAAAAAAAQM/TKdMKngzTlU/s72-c/iwebjtracker_project_main.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/11/yet-anotherissue-tracker.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEMRnk4fyp7ImA9WxNXGU4.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-8609075438196439422</id><published>2009-10-07T05:27:00.000-07:00</published><updated>2009-10-07T10:48:07.737-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-07T10:48:07.737-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IWebJTracker" /><title>Jira 4 raises the bar...</title><content type="html">&lt;div style="text-align: justify;"&gt;In case you've missed it, &lt;a href="http://www.dzone.com/links/jira_4_the_centre_of_your_development_team.html?ref=ps" target="new"&gt;the announcement&lt;/a&gt;. Impressive, isn't it? Obviously I can't compete! A team of engineers and thirteen months of developement..starting with Jira 3. Admittedly, I'm a lonely developer, I've been working for three months during my free time and I started from scratch! Nonetheless, I won't despair...at least &lt;a href="http://code.google.com/p/iwebjtracker/" target="new"&gt;IWebJTracker&lt;/a&gt; will be fully Open Source and it doesn't look that bad actually (given that I'm not a designer, of course). Take a look at the main screen for an issue (as of now):&lt;br /&gt;&lt;br /&gt;&lt;a rel="lightbox" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/SsyKmOg7c3I/AAAAAAAAAPs/BOIiJjQutvo/s1600/issue.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 227px;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/SsyKmOg7c3I/AAAAAAAAAPs/BOIiJjQutvo/s400/issue.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5389835243391513458" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And somehow I've managed to keep things under control (which is always good if other developers decide to help):&lt;br /&gt;&lt;br /&gt;&lt;a rel="lightbox" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/SsyZZXB3WrI/AAAAAAAAAP0/-h4QjSbzBtI/s1600/sonar_1_11.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 165px;" src="http://3.bp.blogspot.com/_TOuRkiuovcI/SsyZZXB3WrI/AAAAAAAAAP0/-h4QjSbzBtI/s400/sonar_1_11.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5389851515013257906" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm really looking forward to releasing a first milestone and see the acceptance it gets from the community!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-8609075438196439422?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/h1hzNjiDHXk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/8609075438196439422/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=8609075438196439422" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/8609075438196439422?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/8609075438196439422?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/h1hzNjiDHXk/jira-4-raises-bar.html" title="Jira 4 raises the bar..." /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_TOuRkiuovcI/SsyKmOg7c3I/AAAAAAAAAPs/BOIiJjQutvo/s72-c/issue.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/10/jira-4-raises-bar.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08EQXs-cCp7ImA9WxNQFkk.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-5679739249531914902</id><published>2009-09-22T09:50:00.000-07:00</published><updated>2009-09-22T10:50:00.558-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-22T10:50:00.558-07:00</app:edited><title>The problem of Open Source</title><content type="html">&lt;div style="text-align: justify;"&gt;I've just had a meeting. The topic of today was finding a way to replace a software tool in use in some random area of a client. It's a testing tool but they have tweaked it to become a robot, like say &lt;a href="http://www.autoitscript.com/autoit3/" target="new"&gt;AutoIt&lt;/a&gt;. Not that I'm against of new uses for software but, really, using a testing application to create robots to manage windows created by your own code instead of using a batch process is a little bit over the top. But I digress as the problem, of course, is other.&lt;br /&gt;&lt;br /&gt;The problem is money. Licenses in fact. The issue is they're paying some royalties to another company (one that develops and sells software) and they're uncomfortable with the situation. Nobody says it like that and so the official excuse is the programming language of the scripts, VBA. But nonetheless, it's obvious to everybody.&lt;br /&gt;&lt;br /&gt;And so they've asked me if I knew of any Open Source library written in Java, free (as in beer) with a good community (support is crucial remember?) that could handle their use case. Right there I stopped paying attention. I have some &lt;a href="http://autodrum.com/img/media/wallpapers/porsche_911_turbo_2007_03.jpg" target="new"&gt;wishes&lt;/a&gt; myself.&lt;br /&gt;&lt;br /&gt;But, at least, I got something positive out of it. I got to think about why and/or how have we reached this situation? The outlook is indeed grim. Somehow nobody feels like paying for software anymore. Everybody expects to find some OSS project out there that resolves all kind of problems but, of course, just a minority of people (let alone enterprises!) consider donating code or contributing to any project. And worst, probably us (open source developers) have helped to create this kind of environment. Right now, Open Source and gratis are synonyms in the mind of many people. What was that about birds and beers? Heck, nobody really cares.&lt;br /&gt;&lt;br /&gt;Even worse is the disgrace that plagues the OSS world: whining users. Because too soon free is not enough and people demand more and more and more. Bandwith, documentation, examples, a forum, mailing lists, developers to answer promptly their question, enhancements, side projects...you name it. Sorry, I forgot to mention, free again.&lt;br /&gt;&lt;br /&gt;So our work and time is now expected to be altruist...and then cost us something in the process. But it never works the same the other way around. Sadly, it's sometimes becoming a burden. Too hefty.&lt;br /&gt;&lt;br /&gt;A rhetorical question, when will people awake and realize this is unsustainable? I've notice a trend, each year less and less people choose Computer Science as their studies. Can't help but think that they are not that wrong.&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/1248732249041870352-5679739249531914902?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/2zIZccNVlE4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/5679739249531914902/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=5679739249531914902" title="3 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/5679739249531914902?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/5679739249531914902?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/2zIZccNVlE4/problem-of-open-source.html" title="The problem of Open Source" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/09/problem-of-open-source.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04EQ3o9cCp7ImA9WxNRFUo.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-4942452116164906158</id><published>2009-09-10T01:07:00.000-07:00</published><updated>2009-09-10T01:38:22.468-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-10T01:38:22.468-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IWebJTracker" /><category scheme="http://www.blogger.com/atom/ns#" term="java" /><category scheme="http://www.blogger.com/atom/ns#" term="generics" /><title>They say generics are stupid...</title><content type="html">&lt;div style="text-align: justify;"&gt;Who am I to blame? This how my class declaration ended up being:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;&lt;b&gt;public abstract class&lt;/b&gt; AbstractProjectManager&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;C &lt;b&gt;extends&lt;/b&gt; ConnectionDetails, M &lt;b&gt;extends&lt;/b&gt; Module&amp;lt;P, M&gt; &amp; DomainEntity,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;P &lt;b&gt;extends&lt;/b&gt; Project&amp;lt;C, M&gt;&gt; &lt;b&gt;implements&lt;/b&gt; ProjectManager&amp;lt;C, P&gt; {&lt;br /&gt;...&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;With other niceties such as:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;&lt;b&gt;public interface&lt;/b&gt; Module&amp;lt;P &lt;b&gt;extends&lt;/b&gt; Project&amp;lt;?, C&gt;, C &lt;b&gt;extends&lt;/b&gt; Module&gt; {&lt;br /&gt;...&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now, I keep looking at them and thinking "if I have to do this there's something terribly wrong going with this design!" :-)&lt;br /&gt;&lt;br /&gt;On the other hand no one seems to complain about the overall quality of the code...&lt;br /&gt;&lt;br /&gt;&lt;a rel="lightbox" title="Sonar quality report for IWebJtracker" href="http://4.bp.blogspot.com/_TOuRkiuovcI/Sqi3dDhBNXI/AAAAAAAAAPc/kMyvjssyL2g/s1600/sonar_iwebjtracker_20090910.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 386px;" src="http://4.bp.blogspot.com/_TOuRkiuovcI/Sqi3dDhBNXI/AAAAAAAAAPc/kMyvjssyL2g/s400/sonar_iwebjtracker_20090910.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5379751464681944434" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So the development of IWebJtracker continues at a good pace&lt;br /&gt;&lt;br /&gt;&lt;a rel="lightbox" title="IWebJTracker Module creation component" href="http://2.bp.blogspot.com/_TOuRkiuovcI/Sqi5K8-ch3I/AAAAAAAAAPk/gt60yDtI2PM/s1600/iwebjtracker.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 237px;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/Sqi5K8-ch3I/AAAAAAAAAPk/gt60yDtI2PM/s400/iwebjtracker.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5379753352711931762" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-4942452116164906158?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/C4sqWgyLN5Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/4942452116164906158/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=4942452116164906158" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/4942452116164906158?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/4942452116164906158?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/C4sqWgyLN5Y/they-say-generics-are-stupid.html" title="They say generics are stupid..." /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_TOuRkiuovcI/Sqi3dDhBNXI/AAAAAAAAAPc/kMyvjssyL2g/s72-c/sonar_iwebjtracker_20090910.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/09/they-say-generics-are-stupid.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQAQnk-eCp7ImA9WxNREUk.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-236233703008747466</id><published>2009-09-05T01:46:00.000-07:00</published><updated>2009-09-05T02:35:43.750-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-05T02:35:43.750-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="plugins" /><category scheme="http://www.blogger.com/atom/ns#" term="gmaps4jsf" /><title>New Gmaps4JSF plug-in architecture</title><content type="html">&lt;div style="text-align: justify;"&gt;Chances are that if you have ever needed to add some kind of geolocation to a "enterprise" application you have met &lt;a href="http://code.google.com/p/gmaps4jsf/" target="new"&gt;GMaps4JSF&lt;/a&gt;. For those who haven't the name says it all really but, nonetheless, I will translate for the lazy, Google Maps for JSF, that is. There are other alternatives, and good ones, like say &lt;a href="http://liferay.exadel.com/web/guest" target="new"&gt;Richfaces&lt;/a&gt; but AFAIK this is the only one that works wirh JSF 1.1, 1.2 and 2.0, with or without AJAX, with or without Facelets and so on. Basically it works everywhere.&lt;br /&gt;&lt;br /&gt;The library is pretty complete as it already supports the map component and several children like markers, information windows, event listeners, street views et al. But it didn't span beyond what Google offers. Till now I should say. The thing is a client asked (some time ago) to provide some map functionality that unfortunately wasn't covered by Gmaps4JSF. I tried a pure Javascript approach first but, obviously, the results were not elegant in an otherwise pure server side application. Then I tried patching the library. In the end I did the job but this solution had also many drawbacks, the main one being that future releases would be incompatible with the changes and would leave the client stuck with an old version and without access to bug fixes. This was unacceptable. So I asked Hazem Saleh, the author, about a third way, creating a plugin system that could allow me and others to create new functionality without touching the core. We quickly agreed of course :-)&lt;br /&gt;&lt;br /&gt;Hands on with the task I devised a possible alternative. As Gmaps4JSF is Maven based it needed to be a new module. That was pretty clear from the start. I then tought about diving it even further and force the creation of new subprojects inside this module. Two problems remained, the first being the distribution (because I didn't want to require a new JAR download for each new plugin) and the second the integration with the core (because it should be seamless for the user).&lt;br /&gt;&lt;br /&gt;The former issue was solved by using the &lt;a href="http://maven.apache.org/plugins/maven-shade-plugin/" target="new"&gt;Shade plugin&lt;/a&gt;. I tried the &lt;a href="http://maven.apache.org/plugins/maven-assembly-plugin/" target="new"&gt;Assembly plugin&lt;/a&gt; before but felt short soon. Both Maven plugins allow the developer to group project artifacts and apply some rules in the process. The sahed plugin fitted better because it allow us to combine all JARs in a single one AND merge XML and text files to obtain a unique tag library as the result.&lt;br /&gt;&lt;br /&gt;The later was solved by designing a very simple (we want other people to contribute!) plugin architecture in the core. Just one interface (three methods) is enough to determine how a plugin interacts with the rest of the environment. So to build a new plugin you just need to follow these steps:&lt;ul&gt;&lt;li&gt;&lt;b&gt;Get the idea&lt;/b&gt;&lt;br/&gt;My first two plugins were ported from the &lt;a href="http://code.google.com/p/gmaps-utility-library-dev/" target="new"&gt;gmaps-utility-library&lt;/a&gt; project (drag zoom and tabbed max content). There are many other.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Create a Maven module&lt;/b&gt;&lt;br/&gt;Inside the Gmaps4JSF use the maven archetype to create a new module under the plugins folder. Add it to the parent POM if so you desire.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Declare the attributes of your component&lt;/b&gt;&lt;br/&gt;Just copy&amp;amp;paste one the available components and edit the attributes you need (for example, latitude and longitude).&lt;/li&gt;&lt;li&gt;&lt;b&gt;Implement the Plugin interface&lt;/b&gt;&lt;br/&gt;You have examples available so it should be pretty straightforward. You have access to the parent component (where your component is nested) and the map (both in JSF and Javascript).&lt;/li&gt;&lt;li&gt;&lt;b&gt;Register the plugin&lt;/b&gt;&lt;br/&gt;Just add one line (for each plugin) with the name of the implementation class to a plugins.txt file in your META-INF directory.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Create an example&lt;/b&gt;&lt;br/&gt;Nothing sells an idea better. It's just a simple JSP page.&lt;/li&gt;&lt;/ul&gt;And that's all really. If you decide to contribute an addition to the project drop a line in the mailing list. There are many interesting extensions to the map API so now you have the opportunity to colaborate without the fear of having to understand the entrails of JSF or the code of Gmaps4JSF. And for the rest, &lt;a href="http://mashups.s43.eatj.com/gmaps4jsf-examples/" target="new"&gt;enjoy the current work!&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-236233703008747466?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/ltzIrfR0LNE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/236233703008747466/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=236233703008747466" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/236233703008747466?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/236233703008747466?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/ltzIrfR0LNE/new-gmaps4jsf-plug-in-architecture.html" title="New Gmaps4JSF plug-in architecture" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/09/new-gmaps4jsf-plug-in-architecture.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQCR3Y4cSp7ImA9WxNSEko.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-755534731814881771</id><published>2009-08-26T01:33:00.000-07:00</published><updated>2009-08-26T01:46:06.839-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-26T01:46:06.839-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IWebMvc2" /><title>IWebMvc2 Final Release Candidate available</title><content type="html">&lt;div style="text-align: justify;"&gt;So, I've finally sit down to fix all the issues in IE and added some features required by &lt;a href="http://code.google.com/p/iwebjtracker/"&gt; IWebJTracker &lt;/a&gt; (like built-in grid filters and order by). I've uploaded a version with all the patches. Quite improved IMHO. And faster but beware that miracles in IE are beyond my capabilities. As a side effect it also works in Opera 10 Beta 3 in my tests and that's good as well.&lt;br /&gt;&lt;br /&gt;Not everything are good news though as I've introduced a (very visible) nasty bug that happens when the Locator tag file is compiled. It just happens once and it's resolved by hitting reload on the browser but the first impression (a Tomcat error page) is horrid, I know. Sigh..&lt;br /&gt;&lt;br /&gt;From now on I'll try to devote more time to the issue tracker and less to the framework. Let's see how it turns out.&lt;br /&gt;&lt;br /&gt;Enjoy!&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/1248732249041870352-755534731814881771?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/u8273aUNFVQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/755534731814881771/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=755534731814881771" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/755534731814881771?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/755534731814881771?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/u8273aUNFVQ/iwebmvc2-final-release-candidate.html" title="IWebMvc2 Final Release Candidate available" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/08/iwebmvc2-final-release-candidate.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8ESHk9eSp7ImA9WxNTFkQ.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-6816626890457922756</id><published>2009-08-18T12:04:00.000-07:00</published><updated>2009-08-19T08:46:49.761-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-19T08:46:49.761-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IWebJTracker" /><category scheme="http://www.blogger.com/atom/ns#" term="screenshots" /><title>IWebJTracker...a teaser</title><content type="html">&lt;div style="text-align: justify;"&gt;Just some screenshots so you get a taste of the current state of &lt;a href="http://code.google.com/p/iwebjtracker/" target="new"&gt;IWebJTracker&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/Sor8F2SmroI/AAAAAAAAAPE/wewnMnjjrqE/s1600-h/dashboard.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 201px;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/Sor8F2SmroI/AAAAAAAAAPE/wewnMnjjrqE/s400/dashboard.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5371382682995830402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_TOuRkiuovcI/Sor8OeszcSI/AAAAAAAAAPM/KiqIB4dnnLQ/s1600-h/newproject.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 56px;" src="http://1.bp.blogspot.com/_TOuRkiuovcI/Sor8OeszcSI/AAAAAAAAAPM/KiqIB4dnnLQ/s400/newproject.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5371382831282090274" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/Sor8VqPv_7I/AAAAAAAAAPU/Y74pYR4AVns/s1600-h/edit_profile.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 138px;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/Sor8VqPv_7I/AAAAAAAAAPU/Y74pYR4AVns/s400/edit_profile.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5371382954640539570" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;IWebJTracker is/will be the first application built using &lt;a href="http://code.google.com/p/internna/" target="new"&gt;IWebMvc2&lt;/a&gt;. I hope it will become a full &lt;a href="http://en.wikipedia.org/wiki/Application_lifecycle_management" target="new"&gt;ALM solution&lt;/a&gt; but at least it will be a Java oriented issue (bug) tracker. Open source, of course :-)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-6816626890457922756?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/ZbHu44FU0-c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/6816626890457922756/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=6816626890457922756" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/6816626890457922756?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/6816626890457922756?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/ZbHu44FU0-c/iwebjtrackera-teaser.html" title="IWebJTracker...a teaser" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_TOuRkiuovcI/Sor8F2SmroI/AAAAAAAAAPE/wewnMnjjrqE/s72-c/dashboard.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/08/iwebjtrackera-teaser.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IFQXw-fyp7ImA9WxJbF00.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-2887280384191343349</id><published>2009-07-25T09:52:00.000-07:00</published><updated>2009-07-27T06:31:50.257-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-27T06:31:50.257-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IWebJTracker" /><category scheme="http://www.blogger.com/atom/ns#" term="generics" /><title>Say it with me...GE-NE-RICS</title><content type="html">&lt;div style="text-align: justify;"&gt;Sorry, I'm in a bad mood today. It must be an uphill battle I guess. I've seen people confused with generics (I'm talking about Java here). They seem to get the concept and can use generic collections pretty well. Once teached they happily write:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;Set&amp;lt;Something&gt; somethings = new HashSet&amp;lt;Something&gt;();&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And for some unforeseeable reason they're happy with themselfs and proud of using generics. Some of them even attempt to understand advanced concepts like erasure (a concept that shouldn't even exist by the way). And, in fact, they do. Now, that's the end of the story. A dead end indeed.&lt;br /&gt;&lt;br /&gt;For the great majority generics are something, revolving collections (and comparators..or was that TOO advanced?), made by Sun so everybody can use them later in their applications. Nobody seems to go one step beyond and try to develop generic classes of their own. Go figure!&lt;br /&gt;&lt;br /&gt;So say we are designing a client application that needs to connect to several types of servers. A downright mediocre architect would write:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;public interface Server {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Object openConnection(Object connectionDetails);&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;He will argue that the specific types are unknown at the moment. Utter crap, of course. While an old school, barely capable, one would instead put something like:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;public interface Server {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Connection openConnection(ConnectionDetails connectionDetails);&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Better no doubt. But it suffers the same issue, namely &lt;a href="http://mindprod.com/jgloss/downcasting.html" target="new"&gt;downcasts&lt;/a&gt;. Downcasts are obviously not elegant but they also pinpoint problems and bad practices. Avoid like the plague.&lt;br /&gt;&lt;br /&gt;Generics to the rescue. Yes, you can do better! Believe me! That's what generics are really for. Not for collections but for you! For your designs! Let's refactor that interface of us a little. What would we need? Well, we know that a connection to the server is needed and that the server implementation and hence its connection are only known by the subclass in particular. So a FTP client has to return a different connection object that a Subversion client. Fine. Starting were our old good architect left the code we could try to modify it a bit. For example:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;public interface Server&amp;lt;T extens Connection&gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;T openConnection(ConnectionDetails connectionDetails);&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I know what your going to say...does that even compile? But looking at it more closely the changes are really minimum. We are just declaring a generic server that has one unknown parameter. But not completely unknown , at least we know it will be some kind of Connection object. But didn't we have that already covered with the old example? Yes..and now. Let's see an implementation. First we are going to use an abstract base class with some minor checkings:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;public abstract class AbstractServer&amp;lt;T extends Connection&gt; implements Server&amp;lt;T&gt; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;protected abstract T doOpenConnection(ConnectionDetails connectionDetails);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public final T openConnection(ConnectionDetails connectionDetails) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;..do some checks...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return doOpenConnection(connectionDetails);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The only interesting bit of the above code is the way we carry the generic parameter down the hierarchy. Till when? Until the final Server implementation:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;public final class SubversionServer extends AbstractServer&amp;lt;SubversionConnection&gt; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public SubversionConnection doOpenConnection(ConnectionDetails connDetails) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;See the difference now? The openConnection returns a specific class so the compiler checks the types for us! No more downcasts in the process! No class cast exceptions at runtime. And finally something to be proud of to show to your colleagues ;-)&lt;br /&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;PS.- In case you're wondering where that code actually comes from I'm happy to announce that I've started a new Open Source project at Google Code: &lt;a href="http://code.google.com/p/iwebjtracker/" target="new"&gt;IWebJTracker&lt;/a&gt;. It's in its infancy right now but with time it will become an issue (project?) tracker built completely in Java. Think of &lt;a href="http://trac.edgewall.org/" target="new"&gt;Trac&lt;/a&gt; or &lt;a href="http://projecttracker.riaforge.org/" target="new"&gt;Project Tracker&lt;/a&gt;. Why I'm doing it? For two reasons: first so &lt;a href="http://code.google.com/p/internna/" target="new"&gt;IWebMvc&lt;/a&gt; has a poster child application, second because there are no good OSS Java issue trackers. And by good here I mean with good &lt;a href="http://maven.apache.org/" target="new"&gt;Maven&lt;/a&gt; integration..&lt;a href="http://sonar.codehaus.org/" target="new"&gt;Sonar&lt;/a&gt;...&lt;a href="https://hudson.dev.java.net/" target="new"&gt;Hudson&lt;/a&gt;...see where I plan to go?&lt;br /&gt;&lt;br /&gt;PSS.- Any help is gladly welcome :-)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-2887280384191343349?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/bvFbWvrv95M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/2887280384191343349/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=2887280384191343349" title="4 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/2887280384191343349?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/2887280384191343349?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/bvFbWvrv95M/say-it-with-mege-ne-rics.html" title="Say it with me...GE-NE-RICS" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/07/say-it-with-mege-ne-rics.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkICQXs-eSp7ImA9WxJUGUQ.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-2003504685480102167</id><published>2009-07-19T02:22:00.001-07:00</published><updated>2009-07-19T03:16:00.551-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-19T03:16:00.551-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Multi File Upload" /><category scheme="http://www.blogger.com/atom/ns#" term="IWebMvc2" /><title>IWebMvc2 Release Candidate 10 available</title><content type="html">&lt;div style="text-align: justify;"&gt;For the last month or so I've been able to devote some time to &lt;a href="http://code.google.com/p/internna/" target="new"&gt;IWebMvc2&lt;/a&gt; and now it pays dividends. I've just uploaded a new Release Candidate and I'm well on track for a final release at the beginning of September.&lt;br /&gt;&lt;br /&gt;This new version has several interesting upgrades.&lt;br /&gt;&lt;br /&gt;Obviously the most notorious are the two new widgets: Multifile upload and Gallery. The former allows the user to upload a number of related documents and group them in the server as one entity. Documents can be added or removed as needed. It's been built from scratch as I wasn't happy with the matching widget in version one. Visually:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_TOuRkiuovcI/SmLnrZUa9CI/AAAAAAAAAOk/3VedXvzrlf8/s1600-h/multifileupload2.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 230px; height: 242px;" src="http://4.bp.blogspot.com/_TOuRkiuovcI/SmLnrZUa9CI/AAAAAAAAAOk/3VedXvzrlf8/s400/multifileupload2.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5360101239241241634" /&gt;&lt;/a&gt;&lt;br /&gt;Gallery is a direct consequence. It will show all the images from a MultiDocument in a slideshow manner. It's a direct port of the same widget in IWebMvc or a &lt;a href="http://www.dojotoolkit.org/book/dojo-book-0-9/part-5-dojox/dojox-image/thumbnailpicker" target="new"&gt;ThumbnailPicker&lt;/a&gt; from Dojo.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/SmLpa1mH-_I/AAAAAAAAAOs/PTImtdL8ATw/s1600-h/gallery.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 301px; height: 79px;" src="http://3.bp.blogspot.com/_TOuRkiuovcI/SmLpa1mH-_I/AAAAAAAAAOs/PTImtdL8ATw/s400/gallery.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5360103153797168114" /&gt;&lt;/a&gt;&lt;br /&gt;But the improvements do not end here. I've invested a lot of time to increase performance. The use of &lt;a href="http://docs.jboss.org/hibernate/stable/core/reference/en/html/performance.html" target="new"&gt;Hibernate batch&lt;/a&gt; has, at least, halved the boot time (DB populate has gone from over a minute to less than a few seconds) and offers a better response overall. The client has benefit from the new crop of browsers greatly and the demo application runs smoothly on FF 3.5 and Chrome 2 (IE continues to be my bane).&lt;br /&gt;&lt;br /&gt;Other minor issues include:&lt;ul&gt;&lt;li&gt;This release is based on Maven2 instead of Ant+Ivy&lt;/li&gt;&lt;li&gt;Dojo 1.3.2, SoundManager2 upgrade et al&lt;/li&gt;&lt;li&gt;&lt;a href="http://sonar.codehaus.org/" target="new"&gt;Sonar&lt;/a&gt; quality assurance (including core refactorings and new unit tests)&lt;/li&gt;&lt;li&gt;And add the usual bag of bug fixes..&lt;/li&gt;&lt;/ul&gt;Of course, this is the first publicized version in a while so you may have missed...&lt;br /&gt;&lt;br /&gt;The link widget:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/SmLtCgTz0YI/AAAAAAAAAO0/iXwvrHs0pVs/s1600-h/link.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/SmLtCgTz0YI/AAAAAAAAAO0/iXwvrHs0pVs/s400/link.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5360107133812855170" /&gt;&lt;/a&gt;&lt;br /&gt;Or the poll widget...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_TOuRkiuovcI/SmLtwN6fn6I/AAAAAAAAAO8/Xe_TbWR-ulQ/s1600-h/poll.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_TOuRkiuovcI/SmLtwN6fn6I/AAAAAAAAAO8/Xe_TbWR-ulQ/s400/poll.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5360107919148818338" /&gt;&lt;/a&gt;&lt;br /&gt;Or the many other...just &lt;a href="http://code.google.com/p/internna/downloads/list" target="new"&gt;check and enjoy&lt;/a&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/1248732249041870352-2003504685480102167?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/l_4k_Evzwu0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/2003504685480102167/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=2003504685480102167" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/2003504685480102167?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/2003504685480102167?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/l_4k_Evzwu0/iwebmvc2-release-candidate-10-available.html" title="IWebMvc2 Release Candidate 10 available" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_TOuRkiuovcI/SmLnrZUa9CI/AAAAAAAAAOk/3VedXvzrlf8/s72-c/multifileupload2.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/07/iwebmvc2-release-candidate-10-available.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUMRH88fyp7ImA9WxJUEk8.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-1408933954005764720</id><published>2009-07-10T02:56:00.000-07:00</published><updated>2009-07-10T04:44:45.177-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-10T04:44:45.177-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="quality" /><category scheme="http://www.blogger.com/atom/ns#" term="sonar" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><title>Quality assurance with Sonar</title><content type="html">&lt;div style="text-align: justify;"&gt;It's incredible how unknown a tool like &lt;a href="http://sonar.codehaus.org/" target="new"&gt;Sonar&lt;/a&gt; is yet. I guess &lt;a href="http://www.gradle.org/" target="new"&gt;Gradle&lt;/a&gt; suffers the same destiny. After all, they're both similar in their intent, improve the quality of your software. It seems lots of people know about unit testing (not so many about &lt;a href="http://en.wikipedia.org/wiki/Code_coverage" target="new"&gt;code coverage&lt;/a&gt;), less know about tools like &lt;a href="http://checkstyle.sourceforge.net/" target="new"&gt;Checkstyle&lt;/a&gt; or &lt;a href="http://findbugs.sourceforge.net/" target="new"&gt;FindBugs&lt;/a&gt; (static analysis of code) and just a minority are aware of other esoteric metrics like cyclomatic complexity. And even the few that use all of them do not extract all the value that a dashboard provides. That's what Sonar handles, it will take your project and stress it showing the results in a visually appealing site. With no extra work from you, the only requirement is to use Ant or, preferably, Maven.&lt;br /&gt;&lt;br /&gt;But seeing is believing so I'll try to convince you showing the whole process and what kind of enhancements you'll be getting. As the demo project I've chosen &lt;a href="http://code.google.com/p/internna/" target="new"&gt;IWebMvc2&lt;/a&gt;. I've nearly finished the development by now so it's a perfect timing to improve quality. In addition it's a complex web application made of three different sub-projects so something must arise. IMHO the quality of the code is pretty good, in theory I just want proofs...did I just say humble? ;-).&lt;br /&gt;&lt;br /&gt;The first task is downloading the project and installing it. It's trivial believe me (well as long as you know how to unpack an archive...). To run Sonar just go to the bin folder, select your OS and execute the provided script. Trivial again. Sonar show be accessible (although empty) at &lt;i&gt;http://localhost:9000&lt;/i&gt; by now. Go there and login with &lt;i&gt;admin/admin&lt;/i&gt;. Select configuration and under Quality Profiles click on &lt;i&gt;Sonar way with Findbugs&lt;/i&gt;: set as default.&lt;br /&gt;&lt;br /&gt;Next step is to build our project and include the Sonar phase. This is done typing:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;mvn clean compile sonar:sonar&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Pretty easy, wasn't it? If the project was built successfully the console was updated and shows something like:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/SlcbAwgWViI/AAAAAAAAAN4/owe8PBXwVgA/s1600-h/sonar_projects.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand; width:100%" src="http://3.bp.blogspot.com/_TOuRkiuovcI/SlcbAwgWViI/AAAAAAAAAN4/owe8PBXwVgA/s400/sonar_projects.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5356779981615027746" /&gt;&lt;/a&gt;A quick glance reveals a row per project analyzed indicating the number of rules violated and the coverage of the unit tests. There's a little bug with the latest JDK and Cobertura that reports 0% coverage always. As a workaround use JDK6_Update13 for example. The build time reflects how long ago was this information retrieved (not how long took the build itself, tricky). One click on the project shows the dashboard (this is a trimmed version):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/Slcewqfb2wI/AAAAAAAAAOA/PiFs4A5vep0/s1600-h/sonar_dashboard.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 100%" src="http://3.bp.blogspot.com/_TOuRkiuovcI/Slcewqfb2wI/AAAAAAAAAOA/PiFs4A5vep0/s400/sonar_dashboard.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5356784103169186562" /&gt;&lt;/a&gt;Here's the bread and butter! All kind of metrics! From the whole project. The graphic displays the number of modules (JARs) and the relative size of each one. It's used to drill down and get module specific statistics. In fact, every link allows to navigate to new pages with deeper details.&lt;br /&gt;&lt;br /&gt;Our task is to improve the quality of the project (bit by bit) so we can navigate to the &lt;i&gt;Violations&lt;/i&gt; section and get a detailed report of the problems:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_TOuRkiuovcI/SlchPJJejPI/AAAAAAAAAOI/-N9wMIINGHs/s1600-h/violations.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 100%" src="http://4.bp.blogspot.com/_TOuRkiuovcI/SlchPJJejPI/AAAAAAAAAOI/-N9wMIINGHs/s400/violations.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5356786825817918706" /&gt;&lt;/a&gt;The rules are divided in several areas, some are require while others are optional. Selecting one rule gives the complete list of locations where the code fails to comply. Selecting one of those locations highlights the code:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/SlcjytD-b_I/AAAAAAAAAOQ/qAGZnucG0_g/s1600-h/sonar_error.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 100%" src="http://2.bp.blogspot.com/_TOuRkiuovcI/SlcjytD-b_I/AAAAAAAAAOQ/qAGZnucG0_g/s400/sonar_error.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5356789635777196018" /&gt;&lt;/a&gt;In the above example Sonar has detected a private method that is never called. For performance and maintainability  it should be removed altogether. Now, this is not true at all because I KNOW this method is called using reflection. So I should just ignore this error (caution! static analysis tools are not perfect!). Otherwise I could simply open an IDE and correct the mistake.&lt;br /&gt;&lt;br /&gt;Of course Sonar remembers previous scenarios and can track the project life cycle (time machine they call it). Ideally you should be tying Sonar with a Continuous Integration server (out-of-the-box includes a &lt;a href="https://hudson.dev.java.net/" target="new"&gt;Hudson&lt;/a&gt; plug-in).&lt;br /&gt;&lt;br /&gt;I'm not gonna lie, quality requires effort. Even if you're an outstanding programmer. Sonar will just help (a lot actually) by providing visual and reporting tools but expect a slow (sometime tedious) climb to the top. Fortunately, in the end, it pays dividends.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-1408933954005764720?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/aYVsD-_LbMg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/1408933954005764720/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=1408933954005764720" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/1408933954005764720?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/1408933954005764720?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/aYVsD-_LbMg/quality-assurance-with-sonar.html" title="Quality assurance with Sonar" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_TOuRkiuovcI/SlcbAwgWViI/AAAAAAAAAN4/owe8PBXwVgA/s72-c/sonar_projects.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/07/quality-assurance-with-sonar.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYCQ3Y8fCp7ImA9WxJVGUQ.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-5792537378491309830</id><published>2009-07-07T10:13:00.000-07:00</published><updated>2009-07-07T11:09:22.874-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-07T11:09:22.874-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ant" /><category scheme="http://www.blogger.com/atom/ns#" term="Maven" /><category scheme="http://www.blogger.com/atom/ns#" term="Ivy" /><title>Finally...Maven</title><content type="html">&lt;div style="text-align: justify;"&gt;I've always been a happy Ant user. Even more so since &lt;a href="http://ant.apache.org/ivy/" target="new"&gt;Ivy&lt;/a&gt; has been available. Obviously that puts me in one side of the fence and I've been a very proactive supporter of that kind of project configuration. I must admit that included some rants about &lt;a href="http://maven.apache.org/" target="new"&gt;Maven&lt;/a&gt; here and there. In my biased opinion Maven lacked the flexibility that Ant provided and it was all about dependency management which was handled fine by Ivy. Probably my lack of confidence (knowledge) with the tool had some influence there too.&lt;br /&gt;&lt;br /&gt;Four things made me reconsider my position: &lt;a href="https://hudson.dev.java.net/" target="new"&gt;Hudson&lt;/a&gt;, &lt;a href="http://sonar.codehaus.org/" target="new"&gt;Sonar&lt;/a&gt;, &lt;a href="http://www.netbeans.org/" target="new"&gt;Netbeans 6.7&lt;/a&gt; and the amount of time I was spending writing scripts. At work I had to install a CI server a couple of weeks ago and I was not using &lt;a href="http://cruisecontrol.sourceforge.net/" target="new"&gt;CruiseControl&lt;/a&gt; if at all possible (bad bad memories, I guess). That left Hudson as the best option (well, for me). I spent some time through the documentation and quickly realized that Maven was quite more straightforward than Ant this time. I needed a quality tool as well and Sonar has always been on my radar. Sonar works (again) out-of-the-box with Maven and requires some extra configuration with Ant. Being the lazy developer that I am I decided to test Maven with one project and see the results.&lt;br /&gt;&lt;br /&gt;My first impression was pretty favorable. Migrating a simple Java project was a breeze and setting the job in Hudson trivial. I had the statistics online in less than half an hour. Finally I was understanding what was so good with Maven. It was not transitive dependency management, it was Convention over Configuration with the added benefit that other people where writing very interesting plugins for me. With absolutely no work on my side I had an automated build, quality control (testing plus quality assurance) and Jetty running. By now, I was in love with Maven. In more detail:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Zero configuration&lt;/b&gt;&lt;br/&gt;So much time lost with Ant refurbishing the same scripts time and again...&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Dependency management&lt;/b&gt;&lt;br/&gt;I found Maven quite easier to handle than Ivy. I really really missed the master configuration of Ivy though (it saves time when you don't want transitivity for any reason).&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;IDE support&lt;/b&gt;&lt;br/&gt;Today all major IDEs include seamless integration with Maven2. Latest Netbeans release, in particular, works wonders (the &lt;a href="http://maven.apache.org/plugins/maven-reactor-plugin/" target="new"&gt;reactor plugin&lt;/a&gt; is awesome). Ivy support is scarce by contrast.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Redistribution&lt;/b&gt;&lt;br/&gt;I've had to invest quite some work, many times, to offer Ant+Ivy scripts along with different project files (Eclipse, Netbeans, IDEA) to appease all kind of users. Not any longer. POMs are treated as first class citizens everywhere now. With the added benefit that I'll be able to upload the builds to the &lt;a href="http://mvnrepository.com/" target="new"&gt;central repository&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Future&lt;/b&gt;&lt;br/&gt;I'm under the impression that things like OSGi will be pretty much simpler with this approach.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;All in all, I'm leaving Ant. For good. I can't say anything but praises about Ant, it's been years of comradery. And yes, it's a somewhat sad situation but I can't help seeing it obsolete, overridden..&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-5792537378491309830?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/bNX0w4tD-Nk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/5792537378491309830/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=5792537378491309830" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/5792537378491309830?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/5792537378491309830?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/bNX0w4tD-Nk/finallymaven.html" title="Finally...Maven" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/07/finallymaven.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUHQXg9cCp7ImA9WxJQEUs.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-399693386709876223</id><published>2009-05-24T13:05:00.000-07:00</published><updated>2009-05-24T04:07:10.668-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-24T04:07:10.668-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Web Framework Smackdown" /><title>Web framework comparison - Prototyping</title><content type="html">&lt;div style="text-align: justify;"&gt;Some may say I have a biased opinion on the topic at hand. True. I hereby declare that I have a clear preference for &lt;a href="http://code.google.com/p/internna/" rel="external"&gt;dojo+DWR+Spring MVC&lt;/a&gt;. But I happen to have a cruel client as well and when they asked me to prepare a comparison between several modern web frameworks they purposely left Spring behind. The aim here was to build quick prototypes of enterprise applications to test new ideas proposed by the business people. Obviously they current architecture is a little bit outdated and not suitable for the task.&lt;br /&gt;&lt;br /&gt;They gave me a blank sheet to start although they did mention &lt;a href="http://rubyonrails.org/" rel="external"&gt;Ruby On Rails&lt;/a&gt; and &lt;a href="http://code.google.com/intl/en/webtoolkit/" rel="external"&gt;GWT&lt;/a&gt;. The first one was in the origin of everything, a new board member had recently joined the company and in his former position they were using RoR for the task. The second was probably due to the fact that several projects had spawned recently with Flex+BlazeDS as the client side technology but noone was really sure if it was the right path.&lt;br /&gt;&lt;br /&gt;Given this requirements I selected &lt;a href="http://seamframework.org/" target="new"&gt;Seam&lt;/a&gt;, &lt;a href="http://aribaweb.org/" target="new"&gt;AribaWeb&lt;/a&gt; and &lt;a href="http://www.grails.org/" target="new"&gt;Grails&lt;/a&gt; as well.&lt;br /&gt;&lt;br /&gt;Obviously this is not an apples-to-apples comparison. Ariba and Seam are both full Java stacks. RoR and Grails are server side backends very oriented to relational database repositories. While GWT is a RIA tool to layout views in pure Java with some communication middleware, like say, dojo+DWR or, as already mentioned, Flex+BlazeDS could be.&lt;br /&gt;&lt;br /&gt;But it makes for an interesting analysis anyway.&lt;br /&gt;&lt;br /&gt;The criteria to elect the champion contain the following points:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Learning curve&lt;/b&gt;&lt;br/&gt;We are talking about three hundred programmers that haven't ever coded in anything but JSF 1.1. Let's make the jump feasible.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Prototyping&lt;/b&gt;&lt;br/&gt;How suited for the task is the project? A scripting language seems better to throw something quickly even though it's not maintainable later. On the other hand, a good IDE with good component integration, a drag'n drop visual editor and a preview screen makes stupidly easy to churn pages.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Productivity&lt;/b&gt;&lt;br/&gt;How good are the APIs and third party libraries? How much code and configuration is needed to kick start a project? How easily is to connect client and server development?&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;CRUD&lt;/b&gt;&lt;br/&gt;Enterprise applications today always need to interact with a persistent backend.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Killer features&lt;/b&gt;&lt;br/&gt;Selling points for the upper management. What does this framework better? Where does it really shine? What unique characteristics does it put on the table?&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Weakness&lt;/b&gt;&lt;br/&gt;And what about these...?&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;b&gt;Maturity, popularity&lt;/b&gt;&lt;br/&gt;Is it a safe choice? Will it be around in the not so distant future?&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;There were others but neither as interesting (licensing, standardization) nor useful to you (migration, code reusability) so these make a good list. I'm not posting the tabular data for two reasons, first it depends heavily on the weights you assign to each column and second it's subjective and I don't want to start a flame war.&lt;br /&gt;&lt;br /&gt;But here are my personal conclussions.&lt;br /&gt;&lt;br /&gt;In the first round both RoR and GWT fell off the roaster but for very different reasons. In the case of RoR it scored very well in every technical category but, even if I could use it, the truth is a company like this is pretty commited to Java/JEE and such a rupture means time and money. And they're both scarce this days. Maybe for highly innovative teams in core areas but not as a general purpose tool. GWT didn't fare equally well. First for a RIA builder it lacks a decent widget library. Then I like DWR remoting better(biased again?). And finally it shuns standards like a plague. With this conditioning you're better served by Flex. Any day.&lt;br /&gt;&lt;br /&gt;The second round saw, and this was a suprise, Grails fail. Grails happens to have the same punch as Rails and then some more. A great ORM that simplifies greatly CRUD operations (nothing really can beat code generation and a &lt;i&gt;book.save()&lt;/i&gt;), scripting capabilities, joint compilation, Spring et al. Unfortunately it lacks a matching client plug-in. Flex is not there yet and dojo is too much work for a solution specifically looking for speed of development. The syntax is concise but many times awkward and in general Groovy/Grails still lack maturity (IDE support is minimum, plug-ins quality varies greatly, too many bugs yet). I guess you get used to Java's 24 months release cycle with bullet proof quality. Groovy is different in this aspect. I have good feelings about it (more with SpringSource behind the projects) but it takes time.&lt;br /&gt;&lt;br /&gt;The two final candidates provide the full stack, client and server. Seam is IMHO more powerful and a safer choice in general. The people behind Seam are the same that participate in several JSRs and other high profile projects like Hibernate. JBOSS has always been a very active OSS player and the quality of the components (EJB3, Richfaces, JBOSS Tools, Hibernate) is out of question. There's very little bad I can say about Ariba. It's new (very new) in the OSS space and the look&amp;amp;feel is not spectacular (subjective I know). That last bit was important because you want the wow factor when showing a innovative project to the final user. I have to admit that JSF weighed in favor of Seam here but in the end it was a worthy winner for us this time. Kudos to them!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-399693386709876223?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/OcFwQTRJ8Ic" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/399693386709876223/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=399693386709876223" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/399693386709876223?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/399693386709876223?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/OcFwQTRJ8Ic/web-framework-comparison-prototyping.html" title="Web framework comparison - Prototyping" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/04/web-framework-comparison-prototyping.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYNRnY-cSp7ImA9WxJRE04.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-1051076811941151197</id><published>2009-05-12T03:05:00.000-07:00</published><updated>2009-05-14T12:43:17.859-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-14T12:43:17.859-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Webflow" /><category scheme="http://www.blogger.com/atom/ns#" term="spring" /><category scheme="http://www.blogger.com/atom/ns#" term="review" /><category scheme="http://www.blogger.com/atom/ns#" term="book" /><title>Book review - Spring Web Flow Web Development</title><content type="html">&lt;div style="text-align: justify;"&gt;&lt;center&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;width:75%;text-align:center"&gt;This article was &lt;a href="http://java.dzone.com/articles/book-review-spring-web-flow" target="new"&gt;promoted to JavaLobby&lt;/a&gt; as well&lt;/div&gt;&lt;/center&gt;&lt;br /&gt;Right now there are two trends to develop web applications, either you choose the RIA model or a conversational approach.  In the former, say Flex with Cairgorm, both the model and the state is handled by the client. In the later, the server manages the scope sending a view to the browser which acts as a renderer. Of course, interactivity has improved over the years and nowadays partial requests are a must to improve user experience. &lt;a href="http://www.springsource.org/webflow" target="new"&gt;Spring WebFlow&lt;/a&gt; is the SpringSource approach to a server side (work/page) flow management for web applications and &lt;a href="http://www.packtpub.com/develop-powerful-web-applications-with-spring-web-flow-2/book" target="new"&gt;Spring Web Flow Web Development, the book,&lt;/a&gt; (I could think of better names!) tries to explain how to leverage it.&lt;br /&gt;&lt;br /&gt;The task is not minor because, let's face it, Java is a very complex platform and to start with WebFlow you should have a good understanding of JEE (at least JSF and the Servlet APIs), Spring and MVC in general. AJAX is welcome as well. The book, of course, can't help you there (you'd need a whole collection for that). This is not for novices! Fortunately a lot of people have learned JEE and Spring through the years and it's a matter of learning Webflow step by step but in depth.&lt;br /&gt;&lt;br /&gt;Now, here the book shines. I like the formating, very clear and clean, and the language, simple and direct. I would have changed the chapter structure a little though. I missed individual chapters for persistence (Security has one) and Spring MVC (Faces has one) and I would have reordered some things here and there (configuration is scattered) but that's subjective and overall the steps make sense. The concepts (flow, action, state, transition, continuation) are well defined and you get a grasp pretty soon but some times the book is too comprehensive like when enumerating the methods and fields of the available variables (messageContext, flowExecutionContext et al). This makes for a hard reading but it will be invaluable as a reference book to some. I prefer IDEs for that task though. In the same sense I missed more diagrams and graphs (I'm not referring to UML class diagrams here). In a book about flows it should be pretty easy to plot concepts using some circles here and there. In my mind, circles are not less valuable than XML snippets (the book has tons of these don't worry) and the reader will gladly accept some pictures to clarify concepts (and thank you for them). Nothing too fancy, this one (extracted from the book) is more than enough:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/SgvURrfOspI/AAAAAAAAAM0/NNHFcQSMRJM/s1600-h/webflow_scopes.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/SgvURrfOspI/AAAAAAAAAM0/NNHFcQSMRJM/s400/webflow_scopes.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5335591583747060370" /&gt;&lt;/a&gt;&lt;br /&gt;In summary, the book is extensive and a great tool to learn first, and as a reference guide later, to Spring Webflow. It's dense and it explains lots of concepts in depth. Be warned that to extract all value this book requires previous knowledge of complex notions, among them: Spring, JSF, AJAX, persistence/ORM, Security, unit testing and probably more. The authors have made the effort to introduce all these libraries/skills when they're first used but that just lessens the burden (a bit). All in all, an easy candidate to recommend to those who need to extract all the power that Webflow 2 has to offer or teams that are about to start a new project and need an initial push with the technology.&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/1248732249041870352-1051076811941151197?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/RVAqJBBRMiA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/1051076811941151197/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=1051076811941151197" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/1051076811941151197?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/1051076811941151197?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/RVAqJBBRMiA/book-review-spring-web-flow-web.html" title="Book review - Spring Web Flow Web Development" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_TOuRkiuovcI/SgvURrfOspI/AAAAAAAAAM0/NNHFcQSMRJM/s72-c/webflow_scopes.PNG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/05/book-review-spring-web-flow-web.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4MQX44fyp7ImA9WxJSF0o.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-8304870012465862061</id><published>2009-05-08T02:34:00.000-07:00</published><updated>2009-05-08T03:03:00.037-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-08T03:03:00.037-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PhoneGap" /><category scheme="http://www.blogger.com/atom/ns#" term="BlackBerry" /><title>PhoneGap, my new toy</title><content type="html">&lt;div style="text-align: justify;"&gt;The best thing about being a consultant is the fact that you have to work for different clients and different projects all the time. My last assignment included a lot of Flex and, now, mobile development.&lt;br /&gt;&lt;br /&gt;Being a lazy developer, as I am, I tried to find similarities with web development which, well, feels comfortable. &lt;a href="http://phonegap.com/" target="new"&gt;PhoneGap&lt;/a&gt; is a OSS project to build cross-mobile (native) applications using the familiar HTML/CSS/Javascript stack. It currently targets Android, iPhone and BlackBerry. This last one was the most important for me this time and, unfortunately, the one that was lagging behind, with a poor overall situation (the maintainer had abandoned development).&lt;br /&gt;&lt;br /&gt;No problem, that's the beauty of Open Source development! A quick look at the code (because that's actually the best available documentation) and I got a good idea of the intents both in iPhone, the core platform, and BlackBerry. It seemed that many lines were copied from the BlackBerry documentation and did not serve any obvious purpose. Given that the current code was failing to execute in the simulator I started to refactor...here and there, you know? By the afternoon I had a preview version with a Javascript Hello World and I was pretty happy. I sent the code to the PhoneGap team and got a warm welcome and some advice. Another day and I've been able to submit to the mailing list a working implementation of part of the API: telephony, vibration, location (GPS) and device information. Not bad for a couple of days! Even more so knowing it was my first mobile development ever (a fellow co-worker had to show me the use of the simulator...endless shame).&lt;br /&gt;&lt;br /&gt;And now for Windows Mobile...a much bigger job given that there's no code to start with. An implementation from scratch and with C#. Too daunting a task indeed! Let's see how it turns out.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-8304870012465862061?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/eOWadHBImg0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/8304870012465862061/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=8304870012465862061" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/8304870012465862061?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/8304870012465862061?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/eOWadHBImg0/phonegap-my-new-toy.html" title="PhoneGap, my new toy" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/05/phonegap-my-new-toy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAGR348cSp7ImA9WxVaEkw.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-5167451595429984831</id><published>2009-04-08T11:33:00.000-07:00</published><updated>2009-04-08T11:52:06.079-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-08T11:52:06.079-07:00</app:edited><title>Google App Engine account active</title><content type="html">&lt;div style="text-align: justify;"&gt;I've been lucky I guess. I've been looking for affordable Java hosting options for ages and now Google offers me a great alternative for free. I'm just installing the required SDKs and plug-ins. From there some changes to the core of IWebMvc2 to get security going and I hope to be able to create a home page with the demo application running! Thanks Google.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; It won't be that easy I guess. Missing Hibernate support (though JPA is available) means loosing all the related functionality (validator, search, extensions to the standard, ...). Some parts can be swapped with little effort but I'll have to devise something for the rest. Good times ahead&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/1248732249041870352-5167451595429984831?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/S-YPcj57WlI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/5167451595429984831/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=5167451595429984831" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/5167451595429984831?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/5167451595429984831?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/S-YPcj57WlI/google-app-engine-account-active.html" title="Google App Engine account active" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/04/google-app-engine-account-active.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UCRng_eCp7ImA9WxVUGUU.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-6961329276882414685</id><published>2009-03-25T05:04:00.000-07:00</published><updated>2009-03-25T05:47:47.640-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-25T05:47:47.640-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IWebMvc2" /><title>IWebMvc2 stable release available</title><content type="html">&lt;div style="text-align: justify;"&gt;A quick post just to mention I've compiled and uploaded a new &lt;a href="http://code.google.com/p/internna" target="new"&gt;IWebMvc2&lt;/a&gt; version. Although it includes a Beta version of &lt;a href="http://www.dojotoolkit.org/" target="new"&gt;dojo&lt;/a&gt; most things work (minor issues with image preview in IE remain). It packages two new widgets, Panel and Chart (though the later is considered preliminary and it's not enabled in the demo). The Panel widget allows a user to freely move content around the screen, collapse it or drag&amp;drop it to enabled zones.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_TOuRkiuovcI/ScogJLxPiWI/AAAAAAAAAMI/cUeac8OkUNQ/s1600-h/panel.bmp"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 211px; height: 87px;" src="http://4.bp.blogspot.com/_TOuRkiuovcI/ScogJLxPiWI/AAAAAAAAAMI/cUeac8OkUNQ/s400/panel.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5317097652214532450" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Apart from those this release includes loads of bug fixes and is nearly final. It's been tested under FF3+, IE 7/8, Chrome and Safari with good results (of course, report any issues you can find).&lt;br /&gt;&lt;br /&gt;The demo application is composed of several pages this time (instead of the CRUD widget alone) so the developer can see how widget composition does work. In addition this time I've chosen a full download (instead of Ivy) to achieve a better user experience when just evaluating the framework. It should be much faster this time, with a boot time under a minute (unfortunately HSQLDB still needs to be populated on startup).&lt;br /&gt;&lt;br /&gt;My next steps include a deep evaluation of other Java web frameworks including &lt;a href="http://www.grails.org/" target="new"&gt;Grails&lt;/a&gt;, &lt;a href="http://aribaweb.org/" target="new"&gt;Ariba Web&lt;/a&gt; and &lt;a href="http://www.oracle.com/technology/products/adf/adffaces/index.html" target="new"&gt;Oracle ADF Faces&lt;/a&gt;. Obviously each of those have unique characteristics difficult to replicate (and, well, more workforce) but that makes for an interesting goal, doesn't it?&lt;br /&gt;&lt;br /&gt;I hope you enjoy it!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-6961329276882414685?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/b0H5UOMmVpc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/6961329276882414685/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=6961329276882414685" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/6961329276882414685?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/6961329276882414685?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/b0H5UOMmVpc/iwebmvc2-stable-release-available.html" title="IWebMvc2 stable release available" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_TOuRkiuovcI/ScogJLxPiWI/AAAAAAAAAMI/cUeac8OkUNQ/s72-c/panel.bmp" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/03/iwebmvc2-stable-release-available.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAGRXk_fip7ImA9WxVUGEU.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-493932850739942915</id><published>2009-03-23T12:19:00.000-07:00</published><updated>2009-03-24T02:25:24.746-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-24T02:25:24.746-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><title>I'm no Javascript ninja..and you?</title><content type="html">&lt;div style="text-align: justify;"&gt;It's a sad confession to make but true nonetheless. Of course, I'm not a newbie either, I know the basics of the language, how to work with objects and functions and, of course, closures. I've even read (probably not that thoroughly) the &lt;a href="http://books.google.es/books?id=tKszhx-XkzYC&amp;dq=javascript+bible&amp;printsec=frontcover&amp;source=bn&amp;hl=es&amp;ei=zaPISdzxDZDRjAfp_N3TAw&amp;sa=X&amp;oi=book_result&amp;resnum=4&amp;ct=result#PPP1,M1" target="new"&gt;Javascript Bible&lt;/a&gt;.  But, for example, it was just last week that I met &lt;a href="http://trephine.org/t/index.php?title=JavaScript_loop_closures" target="new"&gt;loop closures&lt;/a&gt; for the first time. A loop closure is a language construct where a function can be applied to the traversed elements:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;for (i in [0, 1]) (function (i) {alert(i)}) (["a", "b"][i])&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I was amazed really. For me, the former solution to that problem (a scoping issue of the loop variable but read the whole article if in doubt) was usually along these lines:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;function loop(array, fn) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;for ( i in array) fn.call(array, array[i])&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;loop(["a", "b"], function(i){ alert(i) })&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Now, how much more elegant is the first snippet? It's like programming in Groovy, sometimes you are just surprised by the power offered by those one-liners. I have to admit that without the proper knowledge, the first time you face that kind of code is, well, daunting.&lt;br /&gt;&lt;br /&gt;But, to the topic, I was reading &lt;a href="http://ejohn.org/blog/eval-kerfuffle/" target="new"&gt;John Resig&lt;/a&gt; (highly recommended) and I stumbled upon:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;var obj = (function() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;var a = 21;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fn: function() {a;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;})();&lt;br /&gt;&lt;br /&gt;var foo;&lt;br /&gt;eval('foo=a', obj.fn);&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The above code was engineered to showcase a FF problem when handling &lt;i&gt;evals&lt;/i&gt;. I wasn't designed for anything meaningful don't worry. But in the process it happens to include interesting tidbits like private variables and the call of a function just after it's been defined. The really weird part are the two last lines where it assigns the &lt;i&gt;foo&lt;/i&gt; variable (using an &lt;i&gt;eval&lt;/i&gt;) in the scope of the function resultant of the anonymous function invocation. Well, it required me some time to understand that. What brings me to the current situation, I'm no JS ninja you see?&lt;br /&gt;&lt;br /&gt;JS has so many gotchas with inheritance and polymorphism that I'm not sure I will understand them all, ever. Then there are all the web issues like cross-browser, cross-domain, XSS, sandboxing et al. Even though I'm programming an OSS web framework (&lt;a href="http://code.google.com/p/internna/" target="new"&gt;IWebMvc&lt;/a&gt;) and it's quite capable, I hope, I still have issues with topics like namespaces! Not to mention if I should offer out-of-the-box support for things like &lt;a href="http://code.google.com/p/google-caja/" target="new"&gt;Google Caja&lt;/a&gt;. And that's after battling hard with other topics like cache, encapsulation, minification, gzipping, XHR, the many APIs AND the functionality itself. I don't wonder anymore why people find Javascript so fearful and find monstrosities like JSF palatable..&lt;br /&gt;&lt;br /&gt;So, what takes to be a ninja? Well, first of all this code should not pose any problem:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;Function.prototype.bind = function(){ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;var fn = this,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;args = Array.prototype.slice.call(arguments),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;object = args.shift(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return function() { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return fn.apply(object, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;args.concat(Array.prototype.slice.call(arguments))); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br /&gt;};&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;There you have an augmented native object (Function), private variables declarations, the "full" Array API and closures, of course. And, fortunately, a tutorial &lt;a href="http://ejohn.org/apps/learn/" target="new"&gt;here&lt;/a&gt;. Once there, you should be aware of browser native APIs, for example, querySelectorAll or the new native JSON parsing support. You have to be in touch with the &lt;a href="http://www.w3.org/2009/03/web-demo.xhtml" target="new"&gt;future of the web&lt;/a&gt; (worker threads, HTML5..). Canvas knowledge seems pretty useful as of today as well! Are you up to the task? My only advice, read the &lt;a href="http://svn.dojotoolkit.org/src/dojo/trunk/" target="new"&gt;dojo&lt;/a&gt; or &lt;a href="http://jqueryjs.googlecode.com/svn/trunk/jquery/src/" target="new"&gt;jQuery&lt;/a&gt; sources, there are no better tutorials out there. And then...&lt;a href="http://blog.nihilogic.dk/2008/04/super-mario-in-14kb-javascript.html" target="new"&gt;the challenge&lt;/a&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/1248732249041870352-493932850739942915?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/ixhl_gqziDc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/493932850739942915/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=493932850739942915" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/493932850739942915?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/493932850739942915?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/ixhl_gqziDc/im-no-javascript-ninjaand-you.html" title="I'm no Javascript ninja..and you?" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/03/im-no-javascript-ninjaand-you.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4CR3kycCp7ImA9WxVUFEs.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-5852074544249942535</id><published>2009-03-18T13:35:00.001-07:00</published><updated>2009-03-19T06:22:46.798-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-19T06:22:46.798-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="embedded" /><category scheme="http://www.blogger.com/atom/ns#" term="glassfish" /><title>Glassfish v3 embedded, are we there yet?</title><content type="html">&lt;div style="text-align: justify;"&gt;I've been preparing a new Release Candidate of IWebMvc2 (get it &lt;a href="http://code.google.com/p/internna/downloads" target="new"&gt;here&lt;/a&gt;). This time I wanted to part from Jetty as, although easy to setup, the results were not that amazing (a first access of around forty five seconds required to compile a complex JSP that relies on many tag files). And I've been following closely the development of Glassfish v3 (I really hope IBM does not buy Sun) so this seemed like a perfect opportunity to test the new embedded server feature.&lt;br /&gt;&lt;br /&gt;I started collecting some information from here and there and it seemed easy. I just needed a new repository location&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;&amp;lt;ibiblio name="glassfish" m2compatible="true"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;root="http://download.java.net/maven/glassfish" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And a couple of lines in my &lt;i&gt;ivy.xml&lt;/i&gt; file&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;&amp;lt;dependency org="org.glassfish.embedded" name="glassfish-embedded-api"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;rev="3.0-Prelude-Embedded-b14" conf="run-&gt;default" /&gt;&lt;br /&gt;&amp;lt;dependency org="org.glassfish.embedded" name="glassfish-embedded-web"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;rev="3.0-Prelude-Embedded-b14" conf="run-&gt;default" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Unfortunately GFv3Embedded does not offer any Ant tasks yet so you need a Java class. Something like:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;EmbeddedInfo ei = new EmbeddedInfo();&lt;br /&gt;Server server = new Server(ei);&lt;br /&gt;server.start();&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Tedious but hardly a showstopper. On the bright side the server instance is fully configurable and, for example, a pool/datasource can be added via code (mimicking the admin console commands)&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;CommandExecutor ce = server.getCommandExecutor();&lt;br /&gt;options.setProperty("datasourceclassname", "myDataSourceClass");&lt;br /&gt;options.setProperty("DEFAULT", "myConnPool");&lt;br /&gt;ce.execute("create-jdbc-connection-pool", options);&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Or a WAR deployed dynamically&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;options.setProperty("DEFAULT", "c:\\temp\\iwebmvc2.war");&lt;br /&gt;ce.execute("deploy", options);&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;So far so good. The surprise came later while executing the script. Just take a look of a trimmed version of the output&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;[ivy:retrieve]  found org.glassfish.embedded#glassfish-embedded-api;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.distributions#web;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.distributions#nucleus;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.osgi-platforms#felix;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found com.sun.enterprise#hk2;0.3.32-prelude-b28&lt;br /&gt;[ivy:retrieve]  found com.sun.enterprise#hk2-core;0.3.32-prelude-b28&lt;br /&gt;[ivy:retrieve]  found com.sun.enterprise#config;0.3.32-prelude-b28&lt;br /&gt;[ivy:retrieve]  found com.sun.enterprise#auto-depends;0.3.32-prelude-b28&lt;br /&gt;[ivy:retrieve]  found com.sun.enterprise#tiger-types-osgi;0.3.32-prelude-b28&lt;br /&gt;[ivy:retrieve]  found org.glassfish.core#api-exporter;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found com.sun.enterprise#osgi-adapter;0.3.32-prelude-b28&lt;br /&gt;[ivy:retrieve]  found woodstox#wstx-asl;3.2.3 in public&lt;br /&gt;[ivy:retrieve]  found org.glassfish#javax.xml.stream;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.core#glassfish;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.core#kernel;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.common#glassfish-api;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.common#internal-api;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.admin#config-api;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.common#common-util;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.external#grizzly-module;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.common#stats77;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.deployment#deployment-common;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.external#asm-all-repackaged;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found com.sun.pkg#pkg-client;1.0.7-15.1269&lt;br /&gt;[ivy:retrieve]  found org.glassfish.flashlight#flashlight-framework;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.flashlight#flashlight-agent;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.admin#monitoring-core;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.admin#admin-cli;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.admin#cli-framework;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.admin#launcher;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.branding#branding;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.distributions#nucleus-base;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.docs#basedocs;3.0-Prelude in javanet&lt;br /&gt;[ivy:retrieve]  found org.glassfish.deployment#deployment-admin;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.deployment#deployment-autodeploy;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.external#javadb;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found javadb#javadb;10.2.2.1-20070823&lt;br /&gt;[ivy:retrieve]  found org.glassfish.web#webtier-all;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.web#web-gui-plugin-common;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.web#web-glue;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.web#web-cli;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.common#container-common;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.common#glassfish-naming;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.transaction#transaction-internal-api;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish#javax.transaction;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish#javax.resource;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish#javax.persistence;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.connectors#connectors-internal-api;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish.deployment#dol;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish#javax.servlet;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish#javax.annotation;3.0-Prelude-Embedded-b14&lt;br /&gt;[ivy:retrieve]  found org.glassfish#javax.enterprise.deploy;3.0-Prelude-Embedded-b14&lt;br /&gt;...and so on...&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And worse....&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: #E0E0E0;"&gt;&lt;br /&gt;::::::::::::::::::::::::::::::::::::::::::::::&lt;br /&gt;::              FAILED DOWNLOADS            ::&lt;br /&gt;:: ^ see resolution messages for details  ^ ::&lt;br /&gt;::::::::::::::::::::::::::::::::::::::::::::::&lt;br /&gt;:: org.glassfish.osgi-platforms#felix;3.0-Prelude-Embedded-b14!felix.distribution-fragment&lt;br /&gt;:: com.sun.enterprise#hk2;0.3.32-prelude-b28!hk2.hk2-jar&lt;br /&gt;:: org.glassfish.core#glassfish;3.0-Prelude-Embedded-b14!glassfish.hk2-jar&lt;br /&gt;:: org.glassfish.core#kernel;3.0-Prelude-Embedded-b14!kernel.hk2-jar&lt;br /&gt;:: org.glassfish.common#glassfish-api;3.0-Prelude-Embedded-b14!glassfish-api.hk2-jar&lt;br /&gt;:: org.glassfish.common#internal-api;3.0-Prelude-Embedded-b14!internal-api.hk2-jar&lt;br /&gt;:: org.glassfish.admin#config-api;3.0-Prelude-Embedded-b14!config-api.hk2-jar&lt;br /&gt;:: org.glassfish.common#common-util;3.0-Prelude-Embedded-b14!common-util.hk2-jar&lt;br /&gt;:: org.glassfish.common#stats77;3.0-Prelude-Embedded-b14!stats77.hk2-jar&lt;br /&gt;:: org.glassfish.deployment#deployment-common;3.0-Prelude-Embedded-b14!deployment..&lt;br /&gt;....and many many more....&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;What was that? A horror movie? In the end I was able to find a JAR file that packaged every dependency (glassfish-embedded-all-10.0-SNAPSHOT.jar) but it looked like overkill (I don't want EJB, JMS, ...). At least I've learned something: Jetty works wonders for me, it's just I hadn't realized it fully :-)&lt;br /&gt;&lt;br /&gt;So kudos to the GFv3 team, a full blown embeddable Application Server is a nice feature to have. But there's work till it reaches (something that resembles) a mature option.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-5852074544249942535?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/F4bTvToAmKU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/5852074544249942535/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=5852074544249942535" title="4 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/5852074544249942535?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/5852074544249942535?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/F4bTvToAmKU/glassfish-v3-embedded-are-we-there-yet.html" title="Glassfish v3 embedded, are we there yet?" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/03/glassfish-v3-embedded-are-we-there-yet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UDRHY7cCp7ImA9WxVUFEs.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-7731753170262139964</id><published>2009-03-07T02:22:00.000-08:00</published><updated>2009-03-19T06:27:55.808-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-19T06:27:55.808-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="spring" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><title>Parallelism in Spring</title><content type="html">&lt;div style="background-color:#E0E0E0;text-align:center"&gt;&lt;b&gt;Update:&lt;/b&gt; This article has been promoted to &lt;a href="http://java.dzone.com/articles/parallelism-spring"&gt;Dzone&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I've been wanting to post about parallelism in Spring for ages by now. It's an interesting topic that doesn't get the attention it deserves(if any at all), probably because an IoC container and Spring in particular really shine managing dependencies, a task that intuitively promotes serial processing, and also because JEE APIs (say Servlet or EJB) hide the need of it. There's a specific area where no matter what you'll be looking for concurrency and that is data retrieval. As long as a couple of different resources are involved, or even one alone if the data requested is independent, there are efficiency gains processing the several connections in parallel. A common case in todays environments would be, for example, calling web services.&lt;br /&gt;&lt;br /&gt;Standard Java does not really offer any API to manage concurrency once inside a request (though the request itself is managed from a pool). In fact, it's open for discussion if the standard forbids opening new threads in a web context (it's specifically banned for EJBs). WebSphere and Weblogic proposed an alternative called CommonJ aka WorkManager API. It's a very good alternative when running under those application servers. Spring offers another, arguably even more powerful, option with the &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/scheduling.html#scheduling-task-executor" target="new"&gt;TaskExecutor&lt;/a&gt; abstraction. It's sometimes preferable, in a Spring environment, because it can use CommonJ as the underlying API but it can also use the Java5 Executor framework (among others) as well, making the switch just a matter of changing a couple of configuration lines.&lt;br /&gt;&lt;br /&gt;Let's review how to use the framework. Our only pre-requisite is to have at least two data retrieval services already configured as a dependency of a third bean. All the data retrieval services must share a common interface, I can recommend something like the &lt;a href="http://en.wikipedia.org/wiki/Command_pattern" target="new"&gt;Command pattern&lt;/a&gt; here (beware this approach is not fully followed bellow to better showcase inbound data processing). At this point we're going to change the individual dependencies and transform them into a collection, we'll add init and destroy methods and an executor (let's start with a JDK5 implementation):&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;public class ParallelService implements InitializingBean, DisposableBean {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private List&amp;lt;Command&amp;lt;T&gt;&gt; commands;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private ExecutorService executor;&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;With our current implementation based on Java 5 executors we need to start up the thread pool in the initialization method and conclude everything when Spring context is closed:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;public void afterPropertiesSet() throws Exception {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;executor = Executors.newFixedThreadPool(commands.size());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void destroy() throws Exception {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;executor.shutdownNow(); // Improve this as much as liked&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;We just need to handle the concurrent execution now. It's easy to do with the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Future.html"&gt;Future&lt;/a&gt; management of asynchronous tasks. Another alternative is to submit all tasks and await termination (see &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html" target="new"&gt;ExecutorService&lt;/a&gt;):&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;public void execute(Data data) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set&amp;lt;Future&amp;lt;?&gt;&gt; tasks = new HashSet&amp;lt;Future&amp;lt;?&gt;&gt;(commands.size());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (Command command : commands)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tasks.add(executor.submit(new RunCommand(command, data)));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (Future&lt;?&gt; future : tasks)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;future.get();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Other stuff to execute after all data has been retrieved&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The code above just creates a collection of Future objects to check when the jobs have finished. The tricky part is the creation of the concurrent job from a custom service and pass the required data (if needed). An inner class wrapper will suffice:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;private static class RunCommand implements Runnable {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private final Data data;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private final Command command;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public RunCommand(Command command, Data data) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.data = data;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.command = command;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void run() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;command.execute(data);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Well, that was pretty easy indeed. Right now we have a perfectly valid way to invoke beans in parallel. This approach has pros and cons. In the former list we have independence from Spring APIs (of course imagine that the Spring interfaces are substituted by their matching XML attributes) but we are also limited to a Java5 environment. If we don't mind introducing a dependency with Spring itself we can transform the source code to use the TaskExecutor framework:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;public class ParallelService {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private TaskExecutor taskExecutor;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private List&amp;lt;Command&amp;lt;T&gt;&gt; commands;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void setTaskExecutor(TaskExecutor taskExecutor) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.taskExecutor = taskExecutor;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;And now the init and destroy methods are substituted by some XML configuration:&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;&amp;lt;bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="corePoolSize" value="5" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="maxPoolSize" value="10" /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;property name="queueCapacity" value="25" /&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But notice that not all implementations of the TaskExecutor interface allow tracking the progress of a task once scheduled for execution!&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;public void execute)( {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (Command command : commands)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;taskExecutor.execute(new RunCommand(command));&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/1248732249041870352-7731753170262139964?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/cN1ftbs7ETY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/7731753170262139964/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=7731753170262139964" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/7731753170262139964?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/7731753170262139964?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/cN1ftbs7ETY/parallelism-in-spring.html" title="Parallelism in Spring" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/03/parallelism-in-spring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ICQXo6fip7ImA9WxVXF0U.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-7937909817859984050</id><published>2009-02-15T03:13:00.000-08:00</published><updated>2009-02-16T03:59:20.416-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-16T03:59:20.416-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Alfresco" /><category scheme="http://www.blogger.com/atom/ns#" term="how-to" /><category scheme="http://www.blogger.com/atom/ns#" term="WCM" /><title>Hands on with Alfresco WCM</title><content type="html">&lt;div style="text-align: justify;"&gt;Recently, during a pre-sales meeting, I was asked to prepare a demo of Alfresco's Web Content Manager solution. They were interested in a product that could ease the work with the static part of the web. Basically, they needed a tool to generate dynamic content that could then be exported to static HTML resources served by an Apache. In Alfresco this means filling templates based on web forms.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlOnprrHeI/AAAAAAAAALY/lupyErxwj5E/s1600-h/render_html.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 113px;" src="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlOnprrHeI/AAAAAAAAALY/lupyErxwj5E/s400/render_html.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5303356479316368866" /&gt;&lt;/a&gt;&lt;br /&gt;I hadn't touched Alfresco since version 2 so I was glad with the opportunity. As a matter of fact I hadn't ever even launched the WCM module as I've been always more interested in the Enterprise Content Manager (the document manager). But Alfresco is growing fast in this space and now has an important set of tools (in beta) like &lt;a href="http://wiki.alfresco.com/w/images/thumb/c/cc/Webstudio-3c-screen1.png/640px-Webstudio-3c-screen1.png" target="new"&gt;Studio&lt;/a&gt; or &lt;a href="http://www.alfresco.com/products/collaboration/" target="new"&gt;Share&lt;/a&gt; that handle this kind of environments.&lt;br /&gt;&lt;br /&gt;All in all, Alfresco WCM is pretty complete. In fact, it only has a weak point, the total lack of useful documentation (not commercial pamphlets). I guess this is a corollary of the OSS business model they've chosen. Sometimes community support just means exactly that, COMMUNITY SUPPORT.&lt;br /&gt;&lt;br /&gt;So, let's make the platform work in some quick steps!&lt;br /&gt;&lt;br /&gt;The first thing to do is to download the latest nightly build of Alfresco Labs 3 from http://dev.alfresco.com/downloads/nightly/dist/. The nightly build has been more stable than the promoted versions in my tests. Go figure. I'm assuming you have MySQL working already here (if you don't, install it first). Once downloaded just install it (keep the defaults except, may be, the OpenOffice integration tools).&lt;br /&gt;&lt;br /&gt;Unfortunately, this version is affected by a notorious bug that impedes rendering content from a XForm (and hence publishing anything useful). A custom build of the web-client JAR file is required. To do it check out the HEAD revision from their repository (svn://svn.alfresco.com/alfresco/HEAD) and modify two source files as explained in http://forums.alfresco.com/en/viewtopic.php?f=30&amp;t=7467&amp;st=0&amp;sk=t&amp;sd=a&amp;start=15. Build just by issuing an ant command. Keep the generated JAR.&lt;br /&gt;&lt;br /&gt;Download now the deployment module from http://sourceforge.net/project/showfiles.php?group_id=143373&amp;package_id=157460. This one is needed to publish generated content in a file system (even if local).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/SZlP_xMs4JI/AAAAAAAAALg/WFNf2s9HCh0/s1600-h/downloads.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 222px;" src="http://3.bp.blogspot.com/_TOuRkiuovcI/SZlP_xMs4JI/AAAAAAAAALg/WFNf2s9HCh0/s400/downloads.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5303357993162432658" /&gt;&lt;/a&gt;&lt;br /&gt;It should be installed inside &lt;alfresco_dir&gt;/deployment. Once installed modify the application context XML file and indicate the target directory.&lt;/div&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;&amp;lt;property name="targetData"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;map&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;entry key="default"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;map&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;entry key="root"&gt;&amp;lt;value&gt;C:/../Apache/htdocs&amp;lt;/value&gt;&amp;lt;/entry&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;entry key="user"&gt;&amp;lt;value&gt;admin&amp;lt;/value&gt;&amp;lt;/entry&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;entry key="password"&gt;&amp;lt;value&gt;admin&amp;lt;/value&gt;&amp;lt;/entry&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;entry key="autoFix"&gt;&amp;lt;value&gt;true&amp;lt;/value&gt;&amp;lt;/entry&gt;    &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/map&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/entry&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/map&gt;&lt;br /&gt;&amp;lt;/property&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Start Alfresco for the first time using the alf_start script. It will generate the database schema and explode the application(s). Stop it and replace the WCM JAR with the one built from Subversion (in WEB-INF/lib).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlSvEChLfI/AAAAAAAAALo/Bc2G159tuB0/s1600-h/replacing.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 234px;" src="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlSvEChLfI/AAAAAAAAALo/Bc2G159tuB0/s400/replacing.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5303361004697103858" /&gt;&lt;/a&gt;&lt;br /&gt;The installation is complete (for now). To start Alfresco follow this steps:&lt;ul&gt;&lt;li&gt;Start the Tomcat virtual server support executing virtual_start script&lt;/li&gt;&lt;li&gt;Start Alfresco using alf_start script&lt;/li&gt;&lt;li&gt;Go to the deployment folder and start the server with deployment_start&lt;/li&gt;&lt;/ul&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/SZlN43-cpcI/AAAAAAAAALI/H3ci7ocE6Vo/s1600-h/launch.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 213px;" src="http://3.bp.blogspot.com/_TOuRkiuovcI/SZlN43-cpcI/AAAAAAAAALI/H3ci7ocE6Vo/s400/launch.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5303355675699357122" /&gt;&lt;/a&gt;&lt;br /&gt;The login console is available now in at /alfresco. The Web Projects space should be available under the Company Home menu option.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlOS4ZykfI/AAAAAAAAALQ/kFnwG5cCBK0/s1600-h/web_projects_view.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 172px;" src="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlOS4ZykfI/AAAAAAAAALQ/kFnwG5cCBK0/s400/web_projects_view.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5303356122490638834" /&gt;&lt;/a&gt;&lt;br /&gt;A new web project can now be created. Everything should be working so you can add a test server,&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlUfT7k-FI/AAAAAAAAAL4/Mon7nFURF5o/s1600-h/deployment_server.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 136px;" src="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlUfT7k-FI/AAAAAAAAAL4/Mon7nFURF5o/s400/deployment_server.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5303362933108308050" /&gt;&lt;/a&gt;&lt;br /&gt;some web forms (the "extras" folder in the Alfresco installation includes several XSD and XSLT templates)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlUvcB8XpI/AAAAAAAAAMA/Z-IS6LC7dN8/s1600-h/web_form.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 211px;" src="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlUvcB8XpI/AAAAAAAAAMA/Z-IS6LC7dN8/s400/web_form.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5303363210160397970" /&gt;&lt;/a&gt;&lt;br /&gt;and/or the default workflow.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/SZlTcM1fq5I/AAAAAAAAALw/3eE4MR7T6eo/s1600-h/sandbox.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 91px;" src="http://3.bp.blogspot.com/_TOuRkiuovcI/SZlTcM1fq5I/AAAAAAAAALw/3eE4MR7T6eo/s400/sandbox.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5303361780152511378" /&gt;&lt;/a&gt;&lt;br /&gt;A nice addition to any installation today is &lt;a href="http://docasu.sourceforge.net/" target="new"&gt;docasu&lt;/a&gt;, a web/desktop (AIR based) UI to the Alfresco repository with a focus on easier document handling.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlNf5yaBzI/AAAAAAAAALA/hUKx0h5R434/s1600-h/docasu.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 90px;" src="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlNf5yaBzI/AAAAAAAAALA/hUKx0h5R434/s400/docasu.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5303355246688995122" /&gt;&lt;/a&gt;&lt;br /&gt;To install it, once again, checkout from SVN at http://code.optaros.com/svn/docasu/branches/docasu-on-air&lt;br /&gt; and follow the instructions at &lt;a href="http://code.optaros.com/trac/docasu/wiki/DoCASUonAirInstallation" target="new"&gt;their wiki&lt;/a&gt;. Basically you need to build the plugin, copy it to the amps folder in the Alfresco installation and execute the apply script (if the generated WAR does not include the modified web client JAR override it again). The desktop app requires an additional step (two if you don't have the air SDK already). I had to modify the exec task in the ant build file to include the complete path and manually download the mnt jar (from sourceforge) though. Once done, double click the icon in your installation directory and login to http://localhost:8080/alfresco. Just the same as with the web client!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-7937909817859984050?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/3EvWa8Qg-IU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/7937909817859984050/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=7937909817859984050" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/7937909817859984050?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/7937909817859984050?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/3EvWa8Qg-IU/hands-on-with-alfresco-wcm.html" title="Hands on with Alfresco WCM" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_TOuRkiuovcI/SZlOnprrHeI/AAAAAAAAALY/lupyErxwj5E/s72-c/render_html.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/02/hands-on-with-alfresco-wcm.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUBRX86fCp7ImA9WxVRGUU.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-7855396320297794799</id><published>2009-01-26T04:53:00.000-08:00</published><updated>2009-01-26T08:44:14.114-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-26T08:44:14.114-08:00</app:edited><title>Desarrollo de aplicaciones con IWebMvc2 - Parte I</title><content type="html">&lt;p style="text-align: justify;"&gt;Sin duda el espacio reservado a los frameworks web en Java está abarrotado. Los hay de todos los tipos, desde el tradicional Model2 (&lt;a href="http://www.springsource.org/documentation" target="new"&gt;Spring MVC&lt;/a&gt;) al basado en componentes (&lt;a href="http://wicket.apache.org/" target="new"&gt;Wicket&lt;/a&gt;). Tenemos alternativas que se ejecutan completamente en servidor (Seam) a algunas que trasladan gran parte de la lógica a Javascript procesándose en la máquina cliente (&lt;a href="http://directwebremoting.org/" target="new"&gt;DWR&lt;/a&gt;). Tenemos librerías especializadas en aplicaciones &lt;a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete" targte="new"&gt;CRUD&lt;/a&gt; (&lt;a href="http://www.blogger.com/www.openxava.org" target="new"&gt;OpenXava&lt;/a&gt;), con su propio lenguaje dinámico (&lt;a href="http://grails.org/" target="new"&gt;Grails&lt;/a&gt;), patrocinadas por fundaciones o empresas potentes, orientadas a entornos móviles y más. Todas ellos facilitan el desarrollo y en general están orientados al desarrollador. La pregunta es, ¿entonces por qué IWebMvc?&lt;/p&gt;&lt;p style="text-align: justify;"&gt;La respuesta es simple, una vez evaluadas todas las alternativas y decida la mejor para una aplicación concreta es muy posible que encontrar que lo ideal es un framework para la lógica de negocio, otro para la capa de web, componentes ricos para el cliente, integración de la comunicación cliente servidor, una capa de abstracción para el acceso a datos, seguridad y más.. Esto es lo que se denomina "full stack", es decir, un entorno. Seam, por ejemplo, provee uno basado en EJB3 y JSF. Pero ¿y si no interesa una aproximación basada completamente en servidor? Pues la lista se acorta a pasos agigantados. Ante esta situación existe una alternativa como &lt;a href="http://appfuse.org/display/APF/Home" target="new"&gt;Appfuse&lt;/a&gt; que integra muchos frameworks distintos pero ofrece muy poca funcionalidad añadida. O realizar la labor de integración individualmente, lo cual requiere un plus de esfuerzo. IWebMvc ofrece una plataforma completa perfectamente configurada basada en los, bajo una opinión personal, productos más interesantes y potentes en el entorno Open Source en Java que son:&lt;/p&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;&lt;b&gt;Spring&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Un contexto de inyección de dependencias específicamente diseñado para funcionar como middleware ofreciendo la misma capacidad que un servidor de aplicaciones pero de forma modular. Sus extensiones para web (MVC, Webflow) y seguridad son reconocidas como de lo mejor del mercado. Y es prácticamente ubicuo en el desarrollo de Java empresarial.&lt;/div&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;b&gt;JPA/Hibernate&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;El estándar para el acceso a base de datos con la capacidad de un ORM muy potente que además extiende la base con posibilidaddes como la cache de segundo nivel o la búsqueda por texto libre.&lt;/div&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;b&gt;DWR&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;La herramienta más sencilla para eliminar la barrera entre las diferentes metodologías a la hora de programar código cliente y código servidor.&lt;/div&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;b&gt;dojo&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;No existe una alternativa con una licencia OSS equivalente y que aporte tanto soporte al desarrollo en Javascript como una librería de componentes AJAX tan completa.&lt;/div&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;b&gt;Groovy&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;De manera que se pueda prototipar rápidamente código con un lenguaje dinámico.&lt;/div&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;b&gt;Y más...&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Como, por ejemplo, &lt;a href="https://jawr.dev.java.net/" target="new"&gt;JAWR&lt;/a&gt;, una librería dedicada a la distribución de JS/CSS de manera inteligente (¡que además esta desarrollada por otro español!), The Legion of Bouncy Castle para criptografía, Ant+Ivy para la gestión transitiva de dependencias o JasperReports para los informes.&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;Es posible partir de cero en la configuración de un proyecto con estos mismos pilares pero ¿que sentido tendría? Hoy por hoy, IWebMvc en su version 2.0 ofrece la mejor integración entre Spring/DWR existente. Y no es ésta una afirmación baldía ya que el propio desarrollo de IWebMvc ha impulsado el diseño y codificación de muchas de las mejoras que incluye la version 3.0 de DWR (en la particular de la parte relativa a la integración con Spring), como ha podido ser el escaneo de la vía de construcción, el mejorado soporte de anotaciones, los conversores integrados con el contexto, etc. Probablemente incluso no sería descabellado incluir dojo en este mismo apartado ya que no existen muchos proyectos que ofrezcan out-of-the-box este nivel de entrelazado.&lt;br /&gt;&lt;br /&gt;Pero IWebMvc va un paso más allá e incluye un soporte CRUD completo basado en AJAX (como todo en el resto del proyecto). Es decir, sin haber codificado una línea de código, el desarrollador obtiene un entorno configurado y la gestión de cualquier tipo de entidad persistida en una tabla de la base de datos. Y además todo esto construido mediante widgets reutilizables de manera que es posible gestionar la creación de nuevas pantallas en base a la paleta existente así como extender ésta mediante nuevos tags.&lt;br /&gt;&lt;br /&gt;Para terminar este primer artículo conviene repasar aunque sea de una manera somera parte de la lista de componentes de la plataforma. Las capturas son del tema por defecto e idioma inglés pero, por supuesto, esto cambia a voluntad del usuario.&lt;/div&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Básicos&lt;/b&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Los campos de texto, moneda, fecha, listas de valores, checkbox y otros del estilo estan perfectamente representados. Por ejemplo:&lt;br/&gt;&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/SX3OUHQaaVI/AAAAAAAAAKA/RDWCGT5El-4/s1600-h/textboxes.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 222px;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/SX3OUHQaaVI/AAAAAAAAAKA/RDWCGT5El-4/s400/textboxes.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5295615581798164818" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Avanzados&lt;/b&gt;&lt;div style="text-align: justify;"&gt;Existen widgets utilizables en formularios (con una correspondencia en servidor) que se alejan del típico campo de texto. Por ejemplo, la carga de ficheros, el de puntuación, la selección de color, el texto internacionalizado...&lt;br/&gt;&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_TOuRkiuovcI/SX3Z96zQbcI/AAAAAAAAAKI/2MvkBYqzkWc/s1600-h/advanced.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 191px;" src="http://3.bp.blogspot.com/_TOuRkiuovcI/SX3Z96zQbcI/AAAAAAAAAKI/2MvkBYqzkWc/s400/advanced.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5295628394637061570" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Tabla paginada&lt;/b&gt;&lt;div style="text-align: justify;"&gt;El componente de tabla paginada es la base sobre la que se desarrollan un número importante de los componentes más complejos. Entre sus funcionalidades destacan la carga vía AJAX, la paginación, la ordenación, la recolocación de columnas, la ocultación dinámica de columnas, el menu contextual o la selección múltiple. Una tabla paginada tiene una correspondencia uno a uno con una entidad de la base de datos. El desarrollador sólo necesita indicar cual.&lt;/div&gt;&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_TOuRkiuovcI/SX3boXzT6zI/AAAAAAAAAKQ/eT1nlNj_c3Q/s1600-h/paging.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 142px;" src="http://4.bp.blogspot.com/_TOuRkiuovcI/SX3boXzT6zI/AAAAAAAAAKQ/eT1nlNj_c3Q/s400/paging.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5295630223488052018" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Seguridad&lt;/b&gt;&lt;div style="text-align: justify;"&gt;CAPTCHA, identificación o desconexión son funcionalidades ofrecidas por defecto. Como siempre, todo por AJAX.&lt;/div&gt;&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/SX3i8j5ownI/AAAAAAAAAKw/zFnIdIPERdE/s1600-h/security.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 237px; height: 195px;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/SX3i8j5ownI/AAAAAAAAAKw/zFnIdIPERdE/s400/security.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5295638266914587250" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Localizador&lt;/b&gt;&lt;div style="text-align: justify;"&gt;Construido sobre la base de la tabla filtrada (una capacidad extra de la tabla base) permite referenciar el objeto actual con otras entidades de la base de datos. Estaríamos hablando del lado izquierdo en una relación 1-N (o una clave externa o foreign key).&lt;/div&gt;&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_TOuRkiuovcI/SX3c2hyLd4I/AAAAAAAAAKY/IXWBrdfMgIc/s1600-h/locator.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 141px;" src="http://1.bp.blogspot.com/_TOuRkiuovcI/SX3c2hyLd4I/AAAAAAAAAKY/IXWBrdfMgIc/s400/locator.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5295631566197454722" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Colección&lt;/b&gt;&lt;div style="text-align: justify;"&gt;Para tratar las relaciones 1-N desde el punto de vista contrario&lt;/div&gt;&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_TOuRkiuovcI/SX3ef_sBSuI/AAAAAAAAAKg/2XzXfDmYatA/s1600-h/collection.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 311px; height: 381px;" src="http://4.bp.blogspot.com/_TOuRkiuovcI/SX3ef_sBSuI/AAAAAAAAAKg/2XzXfDmYatA/s400/collection.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5295633378110950114" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;Direcciones&lt;/b&gt;&lt;div style="text-align: justify;"&gt;Algunas entidades comunes que acaban por incluirse en todas las aplicaciones como puede ser pais, provincia, direccion o sexo vienen predefinidas y con sus widgets particulares. ¡Integrados con las APIs AJAX de Google!&lt;/div&gt;&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_TOuRkiuovcI/SX3jsYCpN4I/AAAAAAAAAK4/wax9iYhdGc8/s1600-h/addresses.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 321px;" src="http://2.bp.blogspot.com/_TOuRkiuovcI/SX3jsYCpN4I/AAAAAAAAAK4/wax9iYhdGc8/s400/addresses.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5295639088364861314" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;CRUD&lt;/b&gt;&lt;div style="text-align: justify;"&gt;Finalmente, el widget mas complejo de la plataforma permite trabajar con una entidad listándola (con filtros o búsquedas estilo Google), creando informes, trabajando en modos de vista o edición, modificando los registros, generando nuevos objetos o eliminando filas existentes. ¡Incluyendo entidades anidadas!&lt;/div&gt;&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_TOuRkiuovcI/SX3gf0TJHGI/AAAAAAAAAKo/eI_DbmMTeHQ/s1600-h/crud_.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 187px;" src="http://4.bp.blogspot.com/_TOuRkiuovcI/SX3gf0TJHGI/AAAAAAAAAKo/eI_DbmMTeHQ/s400/crud_.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5295635574077070434" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Por supuesto, no todos los componentes tienen interfaz gráfica. Por ejemplo, IWebMvc ofrece hasta tres almacenes de datos (data stores) compatibles con dojo o incluye tags para encriptar datos en cliente, generar identificadores únicos, claves internacionalizadas acopladas con el Locale de Spring o la inclusión inteligente del Javascript en una página (cumpliendo con las normas de rendimiento de Yahoo!).&lt;br /&gt;&lt;br /&gt;En el próximo artículo explicaré como configurar una aplicación con IWebMvc 2.0 y como generar una página como la de &lt;a href="http://internna.googlecode.com/files/IWebMvc2%20Beta3.avi" target="new"&gt;este vídeo&lt;/a&gt; en cinco líneas de código. Para ir abriendo boca la aplicación de demonstración está disponible en &lt;a href="http://code.google.com/p/internna/downloads/list"&gt;el repositorio&lt;/a&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/1248732249041870352-7855396320297794799?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/ECsrDcfoK7Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/7855396320297794799/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=7855396320297794799" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/7855396320297794799?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/7855396320297794799?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/ECsrDcfoK7Q/desarrollo-de-aplicaciones-con-iwebmvc2.html" title="Desarrollo de aplicaciones con IWebMvc2 - Parte I" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_TOuRkiuovcI/SX3OUHQaaVI/AAAAAAAAAKA/RDWCGT5El-4/s72-c/textboxes.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://internna.blogspot.com/2009/01/desarrollo-de-aplicaciones-con-iwebmvc2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4GRHc4cCp7ImA9WxVTF0k.&quot;"><id>tag:blogger.com,1999:blog-1248732249041870352.post-2201505684117254671</id><published>2008-12-31T02:05:00.000-08:00</published><updated>2008-12-31T09:35:25.938-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-31T09:35:25.938-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mario" /><category scheme="http://www.blogger.com/atom/ns#" term="javafx" /><title>JavaFX, Mario and me</title><content type="html">&lt;div style="text-align: justify;"&gt;I guess I am a decent programmer. At least, I've been able to contribute some code to &lt;a target="new" href="http://directwebremoting.org/"&gt;DWR&lt;/a&gt; and/or &lt;a target="new" href="http://code.google.com/p/internna"&gt;IWebMvc&lt;/a&gt;. I could even say that I don't hate Javascript if that holds any value. But, anyway, I've always been bugged by a musing though...&lt;br/&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.hermann-uwe.de/files/images/programmer_hierarchy.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 449px; height: 649px;" src="http://www.hermann-uwe.de/files/images/programmer_hierarchy.png" alt="" border="0"&gt;&lt;/a&gt;The sad thing is I'm a proficient programmer of "enterprise" (read web) applications. I've always been afraid of not been a REAL coder. Say a Linux hacker or even better...a videogame programmer! You know the kind of people that deliver things like Call of Duty!&lt;br /&gt;&lt;br /&gt;I've always blamed my lack of imagination (I'm no game designer) or creative skills (probably a 6 year old kid draws better than me). But with time I've come to conclude that it's just fear. If the graphics are the problem there are multitude of game sprites around the net. And you don't need to invent something new really, a classical shooter or platform game fits the bill perfectly to start.&lt;br /&gt;&lt;br /&gt;So I decided that enough is enough and I had to try and make a video game (and become a Tier-1 developer). Well, as a matter of fact, I don't pretend to build a complete one (or some fancy 3d graphics...for now). Just a character that moves on screen and jumps to get coins will be enough to begin. Something like one of my all-time-favorites, &lt;a href="http://en.wikipedia.org/wiki/Super_Mario_World" target="new"&gt;Super Mario World&lt;/a&gt;. And I can even get the original sprites. Good!&lt;br&gt;&lt;center&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.gsarchives.net/snes/super_mario_world/sprites/animated/mario_walkleft.gif"&gt;&lt;img style="padding: 10px; cursor: pointer; margin-right:5px;" src="http://www.gsarchives.net/snes/super_mario_world/sprites/animated/mario_walkleft.gif" alt="" border="0"&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.gsarchives.net/snes/super_mario_world/sprites/animated/mario_spin.gif"&gt;&lt;img style="padding: 10px; cursor: pointer; margin-right:5px;" src="http://www.gsarchives.net/snes/super_mario_world/sprites/animated/mario_spin.gif" alt="" border="0"&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.gsarchives.net/snes/super_mario_world/sprites/animated/mario_walkright.gif"&gt;&lt;img style="padding: 10px; cursor: pointer; margin-right:5px;" src="http://www.gsarchives.net/snes/super_mario_world/sprites/animated/mario_walkright.gif" alt="" border="0"&gt;&lt;/a&gt;&lt;/center&gt;&lt;br&gt;Unfortunately, I'm proficient with Java, Groovy or Javascript but I'm not sure they're your best bet to code a Super Mario clone. I thought about Visual Studio Express C++ for a moment but, really, that was not feasible. C++ after Java seems like a trip to the past. What about something new and shiny? Something related to the Java world if possible? What about JavaFX? Said and done I was downloading the FX plugin for Netbeans and looking through some samples and tutorials.&lt;br /&gt;&lt;br /&gt;My first impression was...why the hell do they call this Java??? Yes, be warned, the syntax and the structure is all new. But it packs some interesting features! The &lt;b&gt;bind&lt;/b&gt; keyword was a nice surprise (it's like joining a pointer with its referenced value). How useful! The IDE support can improve though. It's still in it's infancy. I'm eagerly waiting for new versions. But watch for the preview mode, it detects changes on-the-fly without even saving the file and shows them on screen.&lt;br /&gt;&lt;br /&gt;Soon I realized I needed to use the ImageView (to show images) and the Timeline object to process animations. Using the bind keyword profusely let's you modify a variable and cascade changes in multiple places. By the way, you don't have to worry about concepts like &lt;a href="http://en.wikipedia.org/wiki/Double_buffering" target="new"&gt;Double Buffering&lt;/a&gt;, the platform handles them for you. That's pretty good for newbies. So how does a view look like in the end: a Stage object with a Scene inside that packs a group of components&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;Stage {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;title: "Mario sprites"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;width: 250&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;height: 120&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;scene: Scene {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content: [&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;Add some vars to control state:&lt;br&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;var x = 115.0;&lt;br /&gt;var state = 0;&lt;br /&gt;var currentAnimation : Timeline;&lt;br /&gt;def positions : Image[] = [&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Image {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;url: "{__DIR__}../resources/front.gif" },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Image {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;url: "{__DIR__}../resources/spin.gif" },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Image {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;url: "{__DIR__}../resources/left.gif" },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Image {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;url: "{__DIR__}../resources/right.gif" }&lt;br /&gt;];&lt;br /&gt;var activePosition = bind positions[state];&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;And a component:&lt;br&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;ImageView {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;translateX: bind x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;translateY: 10&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;image: bind activePosition&lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;The animation will be fired by a radio button as I yet haven't figured keyboard events. Notice that a change in state automatically changes the image and a change in the X axis magically repaints the image component:&lt;br&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; padding: 5px 2px 5px 3px; font-family: courier new; font-size: 12px; background-color: lightgray;"&gt;SwingRadioButton {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;onMouseClicked: function (event: MouseEvent) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (currentAnimation != null) currentAnimation.stop();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;state = 2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentAnimation = Timeline {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;keyFrames: [&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;KeyFrame {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;time: (x * 1s) / 50&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;values: [&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x =&amp;gt; 0.0 tween Interpolator.LINEAR,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;state =&amp;gt; 0 tween Interpolator.DISCRETE,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentAnimation =&amp;gt; null tween Interpolator.DISCRETE&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentAnimation.play();&lt;br /&gt;},&lt;/div&gt;&lt;br /&gt;And here's the result, 100 lines of code and three hours of work later:&lt;br/&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="320" height="166" class="BLOG_video_class" id="BLOG_video-49fd0e1c562f5dd6" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.blogger.com/img/videoplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DqAAAAPCZD0ddCGBZjZs6HcCGJYctCmZ2jHjVm7MNGpMLojvpWL1cgGJZ7lpQeMvhglfPW_Rgn02ISC-KDNHBXk9aDatLdN8IwwcFPIWwn-gz7-5zyizStY9xm3cfWSEFhzNuwW8eXC7Ir6Axf8O-ssSgwyUIbx9nu1MTBWyRODdO7HxHRpWiPvf7wN96D-T6HN7UNmdtNVjHALYAAkyjWvrSobMwlhJ8atYY399Yo7nHvJOT%26sigh%3D32aMityivD-4oGKu03VSb2FUI3I%26begin%3D0%26len%3D86400000%26docid%3D0&amp;amp;nogvlm=1&amp;amp;thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer2%3Fapp%3Dblogger%26contentid%3D49fd0e1c562f5dd6%26offsetms%3D5000%26itag%3Dw320%26sigh%3D0SLOL8zoP-7Z8Ds_EZRL8xkFtw4&amp;amp;messagesUrl=video.google.com%2FFlashUiStrings.xlb%3Fframe%3Dflashstrings%26hl%3Den"&gt;
&lt;param name="bgcolor" value="#FFFFFF"&gt;
&lt;embed width="320" height="166" src="http://www.blogger.com/img/videoplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DqAAAAPCZD0ddCGBZjZs6HcCGJYctCmZ2jHjVm7MNGpMLojvpWL1cgGJZ7lpQeMvhglfPW_Rgn02ISC-KDNHBXk9aDatLdN8IwwcFPIWwn-gz7-5zyizStY9xm3cfWSEFhzNuwW8eXC7Ir6Axf8O-ssSgwyUIbx9nu1MTBWyRODdO7HxHRpWiPvf7wN96D-T6HN7UNmdtNVjHALYAAkyjWvrSobMwlhJ8atYY399Yo7nHvJOT%26sigh%3D32aMityivD-4oGKu03VSb2FUI3I%26begin%3D0%26len%3D86400000%26docid%3D0&amp;amp;nogvlm=1&amp;amp;thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer2%3Fapp%3Dblogger%26contentid%3D49fd0e1c562f5dd6%26offsetms%3D5000%26itag%3Dw320%26sigh%3D0SLOL8zoP-7Z8Ds_EZRL8xkFtw4&amp;amp;messagesUrl=video.google.com%2FFlashUiStrings.xlb%3Fframe%3Dflashstrings%26hl%3Den" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/center&gt;&lt;br /&gt;All in all, much better than I expected to achieve given that this has been my first try managing any kind of graphics or animations and I had zero experience with JavaFX. The technology is really great though it needs maturing. I'm looking forward to seeing JavaFX views in Spring applications for example. And I have yet to read some tutorials about server side integration. But it has been a refreshing start. Follow my advice and give it a try!&lt;br/&gt;&lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1248732249041870352-2201505684117254671?l=internna.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/InternnaOSS/~4/uhIZiPf3LqQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://internna.blogspot.com/feeds/2201505684117254671/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1248732249041870352&amp;postID=2201505684117254671" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/2201505684117254671?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1248732249041870352/posts/default/2201505684117254671?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/InternnaOSS/~3/uhIZiPf3LqQ/javafx-mario-and-me.html" title="JavaFX, Mario and me" /><author><name>Jose Noheda</name><uri>http://www.blogger.com/profile/05894885162810151648</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="13034038878020481232" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://internna.blogspot.com/2008/12/javafx-mario-and-me.html</feedburner:origLink><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="enclosure" href="http://feedproxy.google.com/~r/InternnaOSS/~5/y2yybAf9hM4/video-play.mp4" length="0" type="video/mp4" /><feedburner:origEnclosureLink>http://www.blogger.com/video-play.mp4?contentId=49fd0e1c562f5dd6&amp;type=video%2Fmp4</feedburner:origEnclosureLink></entry></feed>
