<?xml version="1.0" encoding="iso-8859-1"?>



<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns:cc="http://web.resource.org/cc/"
  xmlns="http://purl.org/rss/1.0/">

<channel rdf:about="http://blogs.codehaus.org/people/vmassol/">
<title>Vincent Massol Think Tank</title>
<link>http://blogs.codehaus.org/people/vmassol/</link>
<description>On software quality, collaborative development and Open Source.</description>
<dc:language>en-us</dc:language>
<dc:creator></dc:creator>
<dc:date>2008-12-25T09:52:41+00:00</dc:date>
<admin:generatorAgent rdf:resource="http://www.movabletype.org/?v=2.661" />


<items>
<rdf:Seq><rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001740_moving_blog.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001647_great_new_searcharchiving_service_markmail.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001624_xwiki_presentation_valtech_days_2007.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001618_xwiki_maven_meetup.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001564_maven_support_just_got_better_with_sonatype.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001465_maven_conference_montreal.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001464_joining_xwiki.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001373_mavenday_2006_in_paris.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001371_checking_for_since.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001370_easy_unit_testing_of_file_operations.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001369_intellib.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001357_maven2_book_is_out.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001354_microsoft_technology_summit_2006_mts06.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001353_interview_on_maven_cargo_and_offshore.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001350_new_job_microsoft.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001338_wanted_wiki_features.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001325_how_can_i_improve_my_oss_project_managment_skills.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001324_ensuring_binary_compatibility.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001314_documentationdriven_development.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001307_cargo_v07_and_maven2_plugin_v01.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001275_javapolis_2005_slides_on_maven_2.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001218_welcome_to_the_matrix.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001209_database_manipulation_framework_wanted.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001188_farewell_to_nicolas_chalumeau.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001181_google_summer_of_code_results.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001170_javazone_2005.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001132_cds_vs_yds.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001114_white_paper_on_agile_offhore_french.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001097_manvebookorg_is_live.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001065_maven_using_the_cargo_plugin_for_testing.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001064_cargo_05_released.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001063_clirr_rocks.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001036_id_love_reusable_ant_tasks.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001007_increasing_open_source_project_contributions.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001006_distributed_build.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/001003_maven_book_and_maven_quiz.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000976_getting_svnsshprivate_key_to_work_in_intellij_ideaeclipse.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000963_javapolis_2004_maven_presentation.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000953_binary_dependency_builds.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000939_top_buildbreakers.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000931_javapolis_2004.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000905_6_jira_issuesmells.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000893_using_cargo_04_for_functional_testing.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000877_logifier.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000874_ossgtp_4th_meeting.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000869_omea_pro_review.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000842_writing_a_jira_3_plugin.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000789_cci_container_client_interface.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000783_maven_abbot_plugin_10_released.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000782_my_current_oss_todo_list.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000774_best_practice_source_code_communication.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000716_back_from_tsss_2004.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000688_what_is_pattern_testing.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000680_offshore_project_manager_interview.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000679_theserverside_symposium_2004.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000682_maven_statcvs_plugin_moved.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000675_common_source_parsing_storage_format_wanted.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000683_fisheye_for_cactus.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000670_faq_bots.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000652_rss_reader_should_diff_updates.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000684_maven_jetty_plugin_10_released.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000644_diffing_continuous_build_results.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000685_patterntesting_lead_changed.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000609_what_does_collaborative_offshore_and_ejbs_have_in_common_.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000605_database_testing_strategy_in_build.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000601_what_is_wrong_with_starteam.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000598_fighting_blog_spam_with_captchas.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000530_jini_ide_is_it_the_future.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000597_enlightening_build.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000520_cactus_v2_architecture_proposal.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000274_junit_in_action_book_signing_in_paris.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000273_cactus_new_vision.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000239_junit_in_action_news.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000250_mocking_classes_with_easymock.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000208_junit_in_action_off_to_press.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000170_using_rollbacks_for_unit_testing_database_code.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000681_maven_statcvs_plugin_20_released.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000138_aop_unit_testing_example.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000137_groovy_mock_objects_friendly.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000132_need_help_to_find_concept_map_software.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000098_evolving_javabased_apis_the_nightmare_of_binary_compatibility.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000080_back_from_tsss.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000066_theserverside_symposium.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000039_javaone_2003_blogs.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000036_eclipse_plugin_for_subversion.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000033_maven_checkstyle_plugin_now_supports_checkstyle_31.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000030_book_junit_in_action.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000028_maven_plugin_for_cactus_30_in_cvs.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000023_project_documentation_wiki_cvs_ml_html.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000022_mock_objects_releases.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000020_cactus_news_through_rss_feed.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000017_starteam_woes_followup.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000014_rss_feed_reader.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000008_subversion_pros_and_cons.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/vmassol/archives/000007_starteam_woes.html" />
</rdf:Seq>
</items>

</channel>

<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001740_moving_blog.html">
<title>Moving Blog</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001740_moving_blog.html</link>
<description><![CDATA[<p>After 2 years of non activity I'm starting to blog again. I've moved this blog to a <a href="http://massol.myxwiki.org">new location</a>. It's now created and hosted on the <a href="http://xwiki.org">XWiki</a> platform which is the project I've been working on for the past 2 years and I wanted to eat my own dog food. It's also much easier to contribute content and do fancy stuff thanks to the power of XWiki.</p>
<p>I hope to see you there!</p>
<p>Note: I'm keeping the old content here.</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2008-12-25T09:52:41+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001647_great_new_searcharchiving_service_markmail.html">
<title>Great new search/archiving service: Markmail</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001647_great_new_searcharchiving_service_markmail.html</link>
<description><![CDATA[<p>Jason Hunter was kind enough to set up a <a href="http://xwiki.markmail.org">Markmail site for XWiki</a>. <a href="http://markmail.org/">Markmail</a> is a mailing list archiving tool with a powerful search feature.</p>
<p>What sets it apart from other such tool IMO is the UI and speed/quality of search. I especially like the ability to see who's sending the most mails to a list and the nice syntax coloring display of emails (in addition to the thread view). Another nice feature is that emails are indexed a few seconds after they have been received by the list (compared to several hours with other tools). I love it :)
</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2007-12-19T10:25:25+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001624_xwiki_presentation_valtech_days_2007.html">
<title>XWiki presentation @ Valtech Days 2007</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001624_xwiki_presentation_valtech_days_2007.html</link>
<description><![CDATA[<p>I was invited to speak about the XWiki platform at the <a href="http://www.valtech.fr/fr/index/valtech_days.html">Valtech Days 2007</a>. It was a very interesting event, focused on Agility.  I presented XWiki a bit differently than what we are used to. Whereas XWiki was an Enterprise Wiki not long ago, it's really now a development platform for writing collaborative web applications (and more specifically applications focused on content). The presentation focused on the platform and what type of applications it's possible to build on top of it.</p>
<p>My slides are <a href="http://codehaus.org/~vmassol/blog/XWiki-ValtechDays-2007.ppt">available online</a>.</p>
]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2007-10-24T09:40:17+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001618_xwiki_maven_meetup.html">
<title>XWiki + Maven meetup</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001618_xwiki_maven_meetup.html</link>
<description><![CDATA[<p>
<a href="http://ludovic.org">Ludovic</a> and I are in the Silicon Valley between the 6th of October to the 12th of October 2007. We've been kindly invited by Google for the Google Summer of Code Mentor Summit (Thanks Google!) and we're taking that occasion to spend some time in the valley to meet the maximum number of people and talk about wikis and <a href="http://xwiki.org">XWiki</a>.
</p>
<p>If you're interested to meet up register on the <a href="http://www.facebook.com/event.php?eid=5630598061">Facebook event</a>.</p>
<p>We have also organized a joint XWiki and <a href="http://maven.apache.org">Maven</a> tech meetup on the 9th of October, at Terracotta. Indeed Terracotta has been extermely kind not only to lend us a room but also  to cater for some pizzas and snacks :) Thanks Terraccotta!</p>
<p>The address is:</p>
<pre>
Terracotta Inc.
650 Townsend St. Suite 325
San Francisco, CA 94103 USA
+1 415 738 4059
</pre>
<p><a href="http://blogs.sonatype.com/jvanzyl">Jason Van Zyl</a>, creator of Maven will be there too!</p>
<p>I hope to see a lot of you there!</p>

]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2007-10-06T00:19:45+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001564_maven_support_just_got_better_with_sonatype.html">
<title>Maven support just got better with Sonatype</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001564_maven_support_just_got_better_with_sonatype.html</link>
<description><![CDATA[<p>My friend <a href="http://blogs.maven.org/jvanzyl/">Jason Van Zyl</a> has started <a href="http://www.sonatype.com/">Sonatype</a>, a new company focused on Maven for the Enterprise and providing support, training and consulting for Maven. He's been joined by several talented Maven committers (<a href="http://www.ejlife.net/blogs/buildchimp">John Casey</a>, <a href="http://www.sonatype.com/about.html">Kenney Westerhof</a>, <a href="http://handyande.co.uk/Coding_News">Andrew Williams</a>, <a href="http://coderoshi.blogspot.com/">Eric Redmond</a> and <a href="http://www.sonatype.com/about.html">Eirik Bjørsnøs</a>) which make their team one of the most knowledgable team on the Maven topic on the planet. Knowing Jason's generosity and dedication to Maven you can be sure that this is the best possible move for the Maven project and it's great for the Maven ecosystem at large. As a proof, Sonatype has already delivered a <a href="http://www.sonatype.com/book/index.html">great (and free) Maven book</a>.</p>
<p>I'm also happy to report that <a href="http://xwiki.org">XWiki</a> (the company and open source project I work for) is a <a href="http://www.sonatype.com/partners/partners.html">Sonatype Partner</a>. I'd love to see Maven products built on top of XWiki. I think <a href="http://www.xwiki.org/xwiki/bin/view/Main/SecondGenerationWiki">XWiki's flexibility</a> makes it an ideal platform for building those products and at the same time empowering them with collaborative features. In the near future I'll work closely with Jason and his team to integrate XWiki and Maven and hopefully we'll see some cool things out of this.</p>
<p>Well done guys and long live Sonatype!</p>
]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2007-05-05T18:53:28+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001465_maven_conference_montreal.html">
<title>Maven Conference @ Montreal</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001465_maven_conference_montreal.html</link>
<description><![CDATA[<p>Mid December 2006 I was invited by the <a href="http://www.crim.ca/">CRIM</a> thanks to <a href="http://www.crim.ca/fr/siveton_vincent.html">Vincent Siveton</a> (Maven committer) to give a presentation on how to implement Quality on projects with Maven2. <a href="http://blogs.maven.org/jvanzyl">Jason Van Zyl</a> was also there and he talked and gave demonstrations of Maven2, Continuum and Archiva.</p>
<p>The conference was very well organized and the training room was superb. Thanks Vincent for setting this up.</p>
<p>I've made my slides available <a href="http://codehaus.org/~vmassol/blog/Quality-with-Maven2-20061201.ppt">here</a>.</p>
]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-12-17T17:10:54+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001464_joining_xwiki.html">
<title>Joining XWiki!</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001464_joining_xwiki.html</link>
<description><![CDATA[<p>I'm happy to announce that I'm joining <a href="http://www.xwiki.com">XPertNet</a> in the role of CTO. XPertNet is the company behind the open source <a href="http://www.xwiki.org">XWiki</a> product.</p>
<p>I'm extremely excited on several accounts:</p>
<ul>
<li>I'll be coming back to my first love which is software development. Even though I've continued doing development over all those years it was mostly during my free time, working on open source projects (mostly <a href="http://jakarta.apache.org/cactus">Cactus</a>, <a href="http://maven.apache.org">Maven</a> and <a href="http://cargo.codehaus.org">Cargo</a>). I'm glad to be able to bring software development in my day time job.</li>
<li>I've spent the last 9 years doing consulting (IT Architecture consulting and then Offshore software development consulting). I was keen to build a product and focus on that single job. I'll still do varied jobs of course but it'll be centered around a product.</li>
<li>I strongly believe wikis are only just entering the general market. They were niche tools so far but I have the feeling they're going to get more mainstream in the coming years. Of course XWiki is not just a simple wiki, it's actually a <a href="http://www.xwiki.org/xwiki/bin/view/Main/SecondGenerationWiki">second generation wiki</a>, on which collaborative web application can be developed (in short, take almost any "Web 2.0 application" - whatever it means! - and XWiki is a good candidate for building it).</li>
</ul>
<p>I'm now off to <a href="http://www.javapolis.com/">Javapolis 2006</a> where I'll be manning the XWiki booth with <a href="http://www.ludovic.org/">Ludovic</a> and <a href="http://wikibc.blogspot.com">Guillaume</a>. Come and say hello to us!</p>
]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-12-12T21:27:17+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001373_mavenday_2006_in_paris.html">
<title>MavenDay 2006 in Paris</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001373_mavenday_2006_in_paris.html</link>
<description><![CDATA[<p>I'm a bit late to report on this but we've have had a very nice <a href="http://www.application-servers.com/conf/2006/mavenday/index.html">Maven Day</a> in Paris in early July 2006, co-organized by <a href="http://www.application-servers.com/">Application-Servers.com</a> and the <a href="http://www.ossgtp.org">OSSGTP</a> (Parisian open sourcer group). Thanks to <a href="http://www.improve.fr">Improve</a> for sponsoring the event!</p>
<p>We were lucky to have Jason Van Zyl talk about new Maven2 stuff and especially the Repository Manager and the maven.org development platform. Emmanuel Venisse has done a presentation on Continuum, Fabrice Bellingard has presented a return of experience of implementing Maven in a large company and I have done a quick presentation of <a href="http://codehaus.org/~vmassol/blog/Panorama%20of%20Quality%20Features%20in%20Maven2%20-%2020060711.ppt">new quality features in Maven2</a>. See <a href="http://morlhon.net/blog/index.php/2006/07/19/94-meeting-with-jason-van-zyl">Jean-Laurent's blog entry</a> for more details.</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-07-27T21:30:20+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001371_checking_for_since.html">
<title>Checking for @since</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001371_checking_for_since.html</link>
<description><![CDATA[<p>It would be nice if there were a tool that could verify that you have correctly added <code>@since
</code>
 tags for methods added in the current version. It would do this by checking against the previous release.</p>
<p>This tool could be based on <a href="http://clirr.sourceforge.net/">Clirr</a> or <a href="http://www.jdiff.org/">JDiff</a> for example. It would also have an option to fail the build if there are new methods without a <code>@since
</code>
 tag.</p>
<p>Do you know if such a tool exists?</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-07-18T08:19:54+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001370_easy_unit_testing_of_file_operations.html">
<title>Easy unit testing of File operations</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001370_easy_unit_testing_of_file_operations.html</link>
<description><![CDATA[<p>The experience that I'm relating here is part of an exploratory refactoring that I'm currently doing on the <a href="http://cargo.codehaus.org">Cargo</a> code base. 
  Till now we were using Java File objects for representing J2EE archives or container installation and configuration directories. This is ok but it makes unit testing a little bit complex when it comes
to unit testing File operations. The reason is that you need to define a location on your local file system where you're going to read/write files to, clean up the files, etc.</p>

<p>Here's a method we had (it expands a JAR file):</p>

<div style="width:100%; overflow:auto; border-style: solid; border-width: 1px"><pre><div class="code"><pre>    <span class="category1">public</span> <span class="category1">void</span> expandToPath(<span class="category2">String</span> path) <span class="category1">throws</span> <span class="category2">IOException</span>
    {
         <span class="category2">File</span> workDir = <span class="category1">new</span> <span class="category2">File</span>(path);
         JarInputStream inputStream = getContentAsStream();
         
         <span class="category1">byte</span>[] buffer = <span class="category1">new</span> <span class="category1">byte</span>[40960];
         
         <span class="category2">ZipEntry</span> entry;
         <span class="category1">while</span> ((entry = inputStream.getNextEntry()) != <span class="category1">null</span>)
         {
              <span class="category2">String</span> entryName = entry.getName();
              entryName = entryName.replace('/', File.separatorChar);
              
              <span class="category2">String</span> outFileName = workDir.getPath() + File.separator + entryName;
              <span class="category2">File</span> outFile = <span class="category1">new</span> <span class="category2">File</span>(outFileName);
              
              <span class="category1">if</span> (outFileName.endsWith("<span class="quote">/</span>") || outFileName.endsWith("<span class="quote">\\</span>"))
              {
                   outFile.mkdirs();
               }
              <span class="category1">else</span>
              {
                   <span class="category1">if</span> (!outFile.getParentFile().exists())
                   {
                        outFile.getParentFile().mkdirs();
                    }
                   
                   <span class="category1">if</span> (!outFile.exists())
                   {
                        outFile.createNewFile();
                    }
                   
                   <span class="category2">FileOutputStream</span> out = <span class="category1">new</span> <span class="category2">FileOutputStream</span>(outFile);
                   <span class="category1">int</span> read;
                   <span class="category1">while</span> ((read = inputStream.read(buffer)) &gt; 0)
                   {
                        out.write(buffer, 0, read);
                    }
                   
                   out.close();
               }
          }
         inputStream.close();
     }</pre></div>
</pre></div>

<p>Here's how I've transformed the method by removing all <code>File
</code>
 operations and instead introducing a <code>FileHandler
</code>
 interface with the following methods, equivalent to the <code>File
</code>
 ones:</p>
<ul>
  <li>append(URI, String): appends a suffix to a URI</li>
  <li>mkdirs(URI): create directories for the URI</li>
  <li>exists(URI): return true if the URI exists</li>
  <li>createFile(URI): create a file</li>
  <li>getOutputStream(URI): get an output stream for the passed URI</li>
</ul>

<div style="width:100%; overflow:auto; border-style: solid; border-width: 1px"><pre><div class="code"><pre>    <span class="category1">public</span> <span class="category1">void</span> expandToPath(URI path) <span class="category1">throws</span> <span class="category2">IOException</span>
    {
         JarInputStream inputStream = getContentAsStream();
 
         <span class="category1">byte</span>[] buffer = <span class="category1">new</span> <span class="category1">byte</span>[40960];
 
         <span class="category2">ZipEntry</span> entry;
         <span class="category1">while</span> ((entry = inputStream.getNextEntry()) != <span class="category1">null</span>)
         {
              <span class="category2">String</span> entryName = entry.getName();
  
              URI outFile = getFileHandler().append(path, entryName);
  
              <span class="category1">if</span> (outFile.toString().endsWith("<span class="quote">/</span>"))
              {
                   getFileHandler().mkdirs(outFile);
               }
              <span class="category1">else</span>
              {
                   <span class="category1">if</span> (!getFileHandler().exists(getFileHandler().getParent(outFile)))
                   {
                        getFileHandler().mkdirs(getFileHandler().getParent(outFile));
                    }
   
                   <span class="category1">if</span> (!getFileHandler().exists(outFile))
                   {
                        getFileHandler().createFile(outFile);
                    }
   
                   <span class="category2">OutputStream</span> out = getFileHandler().getOutputStream(outFile);
                   <span class="category1">int</span> read;
                   <span class="category1">while</span> ((read = inputStream.read(buffer)) &gt; 0)
                   {
                        out.write(buffer, 0, read);
                    }
   
                   out.close();
               }
          }
         inputStream.close();
     }</pre></div>
</pre></div>
  
<p>The interesting part comes now. Because it was a bit hard to create a unit test for the original <code>expandToPath
</code>
 method nobody had done it. It would have involved passing a test JAR but more difficult it would
  have involved passing a target directory where the JAR would be expanded. This is not easy as the location of this target dir would depend from where the tests is executed and making it work seamlessly from both a build tool 
and from your IDE is not trivial. Here comes <a href="http://jakarta.apache.org/commons/vfs/">VFS</a> to help us. By implementing the <code>FileHandler
</code>
 interface using VFS, we can now write the following unit test:</p>
  
<div style="width:100%; overflow:auto; border-style: solid; border-width: 1px"><pre><div class="code"><pre>    <span class="category1">public</span> <span class="category1">void</span> testExpandToPath() <span class="category1">throws</span> <span class="category2">Exception</span>
    {
         URI jarURI = <span class="category1">new</span> URI("<span class="quote">ram:///test.jar</span>");
 
         FileObject testJar = VFS.getManager().resolveFile(jarURI.toString());
         <span class="category2">ZipOutputStream</span> zos = <span class="category1">new</span> <span class="category2">ZipOutputStream</span>(testJar.getContent().getOutputStream());
         <span class="category2">ZipEntry</span> zipEntry = <span class="category1">new</span> <span class="category2">ZipEntry</span>("<span class="quote">rootResource.txt</span>");
         zos.putNextEntry(zipEntry);
         zos.write("<span class="quote">Some content</span>".getBytes());
         zos.closeEntry();
         zos.close();
 
         DefaultJarArchive jarArchive = <span class="category1">new</span> DefaultJarArchive(jarURI);
         jarArchive.setFileHandler(<span class="category1">new</span> VFSFileHandler());
 
         jarArchive.expandToPath(<span class="category1">new</span> URI("<span class="quote">ram:///test</span>"));
 
         <span class="linecomment">// Verify that the rootResource.txt file has been correctly expanded</span>
         FileObject rootResource = VFS.getManager().resolveFile("<span class="quote">ram:///test/rootResource.txt</span>");
         assertTrue(rootResource.exists());
     }</pre></div>
</pre></div>

<p>Notice the use of the "ram:" URI scheme. This one of the <a href="http://jakarta.apache.org/commons/vfs/filesystems.html">many filesystems</a> supported by VFS and it means that all file operations will happen in a virtual file system in memory. 
  Also note that VFS doesn't currently support creating Zip files so we're using the JDK's <code>ZipOutputStream
</code>
 API.
The nice thing is that as this test operates in memory there's no need to define a target location on the file system.</p>

<p>The other nice thing is that by introducing VFS to this <code>expandToPath()
</code>
 method it's now possible to expand a JAR to any file system supported by VFS. We could thus expand to a FTP server, to a WebDAV repository, to an HTTP URL, to a remote machine using SSH, etc. All
this without changing a line to our code. Nice isn't it?</p>

  ]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-07-17T13:52:39+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001369_intellib.html">
<title>IntelliB</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001369_intellib.html</link>
<description><![CDATA[<p>(<b>Updated 2006-07-14</b>: Added section on discovering modules and added disclaimer at the end)</p>

<p>IntelliJ IDEA has revolutioned the IDE landscape by adding "intelligence" to IDEs. 
  A few days ago I did a thought experiment by asking myself the following question "how feasible would it be to build a project without knowing any meta-data about it?".
In other words, is it possible for a build tool to be intelligent enough to build a project without build files nor POMs. Said differently, is it possible to figure out a project's POM automatically?
Let's review some required typical meta-data information and see how they could be guessed.</p>

<h3>Source locations</h3>

<p>It is possible to guess where sources are by looking for <code>*.java
</code>
 files (for Java projects - The same applies for other project types). Now we still need to differentiate main sources from test sources 
but that's also relatively easy to do. We can check for classes extending JUnit's TestCase for example or the TestNG equivalent, or any other well-known testing framework.</p>

<p>Note: An interesting thing here is that to be intelligent we'd need the help of the community to add new rules to the discovery process. For example imagine that a new testing framework appears; we'd need to add 
it to the Test Discovery Rules. Thus, this type of intelligent build system would need to rely a lot on the community and thus would need to get its data from an online repository that could be edited by the community. </p>

<h3>Dependencies</h3>

<p>How do we detect project dependencies? One relatively way is to parse the sources that we have found above and find all external imports. Then query ibiblio to find matching package names (this information is present 
in Maven POMs on ibiblio). Now for guessing the version, there's no easy magic. A first approach would be to get the latest released version of the dependencies we've found.</p>

<h3>Project type</h3>

<p>Project types can easily be guessed by looking at some files. For example if a <code>web.xml
</code>
 file is present then it's a WAR project, if an <code>application.xml
</code>
 one is found then it's an EAR project, if a <code>jnlp
</code>
 file is found then it's a JNLP project, etc.</p>
  
<h3>SCM</h3>

<p>SCM can easily be guessed by looking for special files on the filesystem of the project. For example we would look for <code>.cvs
</code>
 directories for SCV and for <code>.svn
</code>
 files for Subversion, etc</p>
  
<h3>Developers</h3>

<p>Once we got the SCM URL we can then query the SCM to get the list of all developers.</p>

<h3>Project name</h3>

<p>The project name could be the name of the top level directory and the version could be set arbitrarily to 1.0. Actually we could even check ibiblio to see if the project is already on ibiblio, get the latest version there 
  and increase the minor number by one as a first order guess. Another strategy would be to query the SCM and look for tags and deduce existing versions by parsing those tags (there are some usual conventions for naming 
tags so it should be possible to make a good guess).</p>

<h3>Modules and artifacts</h3>

<p>Discovering the different modules of a project is probably one of the hardest thing to do. If you look at different projects in the wild I believe there are not that many directory structures out there. Maybe 10-15. Thus it 
  should be possible to register knowledge of these structures and let the tool discover which ones matches the closest with the project at hand. This would also allow to deduce the different artifacts that have to be generated.
  Of course it won't be perfect as there are projects which generate several artifacts and which may be in the same module. Again it's a question of doing 80% of the job and leaving 20% to be done manually.

<h3>Additional information</h3>

<p>Of course, the information found above are just guesses. In most cases they could be correct but of course we would need to offer a way for the user to edit them and to add any missing information.</p>

<h3>Conclusion</h3>

<p>I believe it should be possible to create such an intelligent meta-build project which could be used to generate files for one of the existing build system such as Maven, Ant, etc. For example it could create an internal POM file on 
which Maven could then be executed to produce the build results. At a minimum such a tool could be used to convert existing projects to Maven. I wonder how intelligent it could be but I guess it could go pretty far.</p>

<p>Disclaimer: Of course, such a tool would be bad from a conventions stand point. One of the great strength of Maven has been to standardize the directory structure of projects. I can go to any Maven project and I know exactly where 
stuff will, what will be generated, etc.</p>
  
<p>Are there other information which you think could be guessed automatically? Can you think of better algorithms to guess some of the information shown above?</p>


  ]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-07-13T09:54:49+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001357_maven2_book_is_out.html">
<title>Maven2 book is out</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001357_maven2_book_is_out.html</link>
<description><![CDATA[<p>Our Maven2 is book is officially out. Here's the marketing pitch:</p>
<blockquote>
<p>"Better Builds with Maven”"</p>
<ul>
  <li>is a comprehensive 'How-to' guide for use with Maven 2.0.4 and later</li>
  <li>is available free of charge and includes supporting sample code</li>
  <li>covers how to use Maven 2.0 to better manage the build, test and release cycles associated with software development</li>
  <li>is written for beginning and intermediate Maven users</li>
  <li>is authored by Maven experts</li>
  <li>Jason Van Zyl, Chief Architect and founder of Maven</li>
  <li>Vincent Massol, author of "Maven: a Developers Notebook"</li>
  <li>with chapters and key content and code contributions from leading Apache Software Foundation Maven Project members: Brett Porter, John Casey and Carlos Sanchez.</li>
  <li>is published by Mergere, Inc</li>
</ul>
<p>Content Includes:</p>
<ul>
  <li>An introduction to Maven 2.0</li>
  <li>Creating, compiling and packaging your first project</li>
  <li>Best practices and real-world examples</li>
  <li>Creating J2EE builds and using J2EE models</li>
  <li>Extending builds through plugins</li>
  <li>Monitoring source code, testing, dependencies and releases</li>
  <li>Leveraging repositories, Continuum for continuous integration and transitive dependencies</li>
  <li>Converting existing Ant builds to Maven</li>
</ul>
<p>Download a free copy at <a href="http://library.mergere.com">http://library.mergere.com</a>.</p>
</blockquote>
<p>I hope this book will help boost Maven2's adoption.</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-04-27T10:05:50+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001354_microsoft_technology_summit_2006_mts06.html">
<title>Microsoft Technology Summit 2006 (MTS06)</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001354_microsoft_technology_summit_2006_mts06.html</link>
<description><![CDATA[<p>I was invited to the Microsoft Technology Summit 2006 (MTS06). The conference happened in Seattle, in Microsoft campus at Redmond. This year there were 40 people all luminaries selected from communities 
competing with MS technologies (Open Source, PHP, Java, etc). MS offices in different countries proposed several candidates which were then reviewed. I heard there were several criteria (having written 2 books, having a web site with more than so many visits per day, working on so many open source projects within known communities, etc). 
In my case, I was proposed by Steve Sfartz from MS France, along with 3 other frenchmen: <a href="http://www.dgirard.eu/">Didier Girard</a> of <a href="http://www.application-servers.com">application-servers.com</a> fame, and 
<a href="http://blog.wampserver.com/index.php/2006/04/15/microsoft-technology-summit-conclusion/">Romain Bourdon</a> and <a href="http://www.cyruss.com/blog/index.php?2006/04/15/84-microsoft-technology-summit-conclusion">Cyril Pierre de Geyer</a> from PHP France, AFUP and contributors to PHP open source projects. All expenses were paid by MS.</p>
<p>There were 2 main goals for this conference:</p>
<ul>
  <li>Reduce "FUD" spread by influential non-MS technology users by showing them what MS is actually working on. It's harder to spread FUD when you know the details...</li>
  <li>Get feedback from competitive technology users to improve MS products/technologies</li>
</ul>
<p>I applaud MS for having the foresight (and the money) to do this. It takes some vision and courage to set this up and allow everyone to blog freely about it.</p>
<p>Here are the topics we were shown during these 3 days:</p>
<ul>
  <li>Scripting and dynamic languages by Jim Hugunin</li>
  <li>.NET CLR 2.0 Reliability by Allesandro Catorcini</li>
  <li>GotDotNet and Communities	by Korby Parnell</li>
  <li>Open Source at Microsoft by Bill Hilf</li>
  <li>Microsoft Research by Rick Rashid</li>
  <li>WCF & WS-* by Don Box</li>
  <li>Internet Explorer by Dean Hachamovitch</li>
  <li>LINQ/C#	by Luca Bolognese, Anders Hejlsberg</li>
  <li>Executive General Session by Sanjay Parthasarathy</li>
  <li>XBOX Extensibility by Brian Keller</li>
  <li>WPF – next generation UI by Chris Anderson</li>
  <li>Windows Server “Longhorn” as an App Server by Doug Purdy</li>
  <li>ASP.NET/IIS7/Atlas by Scott Guthrie</li>
  <li>InfoCard by Mike Jones</li>
  <li>Windows Mobile/Embedded	by Mike Hall and David Karle</li>
  <li>eScience – the Next Decade.  Lessons learned and the path forward from TerraServer, SkyServer and bio-informatics	by Jim Gray</li>
  <li>Software Factories by Jack Greenfield</li>
</ul>
<p>What was the outcome? Was it effective?</p>
<p>It was certainly good to be invited (many thanks to Steve for that). The presentations were of mixed quality and I felt that the topics were too broad. There were some that were of interest to me but lots of others were not in my area of expertise/interest.
I've also felt that there were not enough participation to meet the original goal defined by MS.</p>
<p>I'd like to believe Microsoft was serious about the feedback we gave them but I'm not sure how much I can believe this... The reason I have some doubt is because the sessions were not meant to gather feedback but rather to 
  explain how things are done at Microsoft. If the goal of this conference is to get feedback then I think the format of the presentations could be much improved. Here are some ideas for next year (in case there's a MTS07):</p>
<ul>
  <li>Mix formal presentations with round tables sessions. Get 10 persons per table with each table having a Microsoft coach to drive discussions. Have different topics per table and let attendees pick the topics that interest them.</li>
  <li>Use the <a href="http://www.spaconference.org/">SPA conference</a> session formats as exemples. This idea is to have more workhop sessions than formal presentations to get everyone's participation and to get deliverables as part of the session's outputs.</li>
  <li>Feedback from everyone was provided at different point in time and to different Microsoft employees. The feedback was received verbally and there's currently no guarantee that the feedback will be remembered and acted upon. I'd suggest to
  have a large white board that is used throught the conference to record all ideas for improvement. This will also stimulate feedbacks.</li>
  <li>Report on all feedback submitted during the previous conference at the begining on the conference to show what impact the feedback has had.</li>
</ul>
<p>Note that I have received an email from MS pointing to survey where MS is asking for feedback. I'd still prefer giving the feedback during the conference and directly to the concerned people but with a way of ensuring that this feedback will
be tracked (whether it is used or not doesn't matter that much, what's important to me is that it is considered and that I know of the outcome).</p>
<p>All in all a very good week and in addition were had some nice treats: a welcome basket of eatable goodies and ... a one-year MSDN subscription! Now that's very nice and I'm pretty sure last year's participant must be jealous by now ;-). 
  BTW, on this topic of presents, there were some real disapointments when MS announced that we would have a 120$ voucher to buy stuff at the MS company store ... and when we later learned that this voucher was only the right to
spend up to 120$ at the store! I'd suggest to remove this next year as most around me (including me) have found this more negative than positive. Of course the announcement of the MSDN subscription the day after helped a lot overcome
this negative feeling ;-). We're too spoiled for sure...</p>
<p>Once more, thanks Steve and Microsoft for this very nice week!</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-04-23T15:52:47+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001353_interview_on_maven_cargo_and_offshore.html">
<title>Interview on Maven, Cargo and Offshore</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001353_interview_on_maven_cargo_and_offshore.html</link>
<description><![CDATA[<p><a href="http://www.almaer.com/blog/">Dion Almaer</a> has interviewed me during <a href="http://www.javapolis.com/confluence/display/JP05/Home">JavaPolis 2005</a>:</p>
<p>
<blockquote cite="http://www.javapolis.com/confluence/display/JP05/Home">
"During this Vincent Massol interview you'll receive more information on the status, philosophy and strenghts of Maven 2.0. "What were the shortcomings in Maven 1 and how do we now write maven 2 plugins ?" are just a few questions Dion Almaer asked. Other topics discussed are Continuum, Cargo and Agile outsourcing and offshoring... check it out."
</blockquote >
</p>
<p>The video is available <a href="http://www.javapolis.com/confluence/display/JP05/Vincent+Massol+Interview">here</a>.</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-04-21T14:20:34+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001350_new_job_microsoft.html">
<title>New job @ Microsoft</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001350_new_job_microsoft.html</link>
<description><![CDATA[<p>I'm changing job and leaving Pivolis for Microsoft! I would never have believed this possible a month ago...</p>
<p>It appears that Microsoft is serious about Java and Open Source after all. They contacted me for my work on <a href="http://maven.apache.org">Maven</a>. 
As a matter of fact, their own MSBuild system is not working as well as they would have liked and they are interested in reusing Maven as a build scaffolding and develop numerous Java and .Net plugins on top of it 
and integrate it all in the next version of Visual Studio (which will sport lots of new features for Java development too).
This is all part of their new 2007 plans for implementing <a href="http://blogs.msdn.com/askburton/articles/232021.aspx">Software Factories</a>. I can't tell you much more at this stage.</p>
<p>The best news is that I won't be working alone on this as they are setting up a full scale Java Team. Yeah that rocks! Some friends from our <a href="http://ossgtp.xwiki.com/">Open source group in Paris</a> have also been recruited
(check <a href="http://www.ludovic.org/xwiki/bin/view/Main/NouvelleAventure">Ludovic</a>'s , <a href="http://www.jeremi.info/index.php/2006/04/01/91-changement-de-direction">Jeremi</a>'s , <a href="http://www.application-servers.com/comments.do?reqCode=readComments&sid=2006-04-01-11:39:41">Didier</a>'s and <a href="http://jroller.com/page/francoisledroff/?anchor=nouveau_job">Francois</a>'s blogs).</p>
<p>I'll be blogging more about it, stay tuned...</p>
<p><b>Update (3rd April 2006)</b>: Of course this was an April's fool. However there's some truth in it. I'm indeed going to Redmond the week of the 10th of April. Microsoft is inviting 70 people using competing technologies from all over the world. The
idea seems to be twofolds: Microsoft will present what they are working on and we are expected to critique/provide feedback on what they're doing compared to what we are doing using our technologies. Sounds pretty fun. It seems
this is something similar to the event that <a href="http://raibledesigns.com/page/rd?entry=microsoft_conference_for_developer_community">Matt Raible attended</a> (more
<a href="http://raibledesigns.com/page/rd?entry=microsoft_s_agenda_at_the">here</a>, <a href="http://raibledesigns.com/page/rd?entry=this_is_gonna_be_good">here</a> and <a href="http://raibledesigns.com/page/rd?entry=so_who_s_at_microsoft">here</a>). I'll blog more on this when I know more.
</p>  
  ]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-04-01T07:20:42+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001338_wanted_wiki_features.html">
<title>Wanted wiki features</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001338_wanted_wiki_features.html</link>
<description><![CDATA[<p>Current wikis are great. However when used as development wikis I have found some limitations which are hampering their use. Please note that my experience is based on using <a href="http://atlassian.com/software/confluence/">Confluence</a> and <a href="http://www.xwiki.org/">XWiki</a> and other wikis may support some of the features mentioned below. Here's my top wishlist for development wikis and for Confluence and XWiki in particular:
<ul>
  <li><b>Moderated wikis</b>. Right now there are only two choices for a wiki: either they are open and anyone can edit a page or they are closed wikis and you need to register and get the rights to make modifications. For example most spaces on the <a href="http://docs.codehaus.org/">Codehaus wiki</a> are closed. 
    They were initially open but vandalism was too high and we had to close them. This is hampering documentation contributions. A moderated wiki would alleviate this: when the page is saved, an email would be sent to a list of moderators for the space for
    approval of rejection (either by responding to a certain email address as for mailing list moderation or by clicking on a link in the email). Ideally, clicking on the validation link in the email would open the page in a browser with the modifications 
  highlighted so that the moderator could make some changes before clicking on the save button.</li>
  <li><b>Anonymous edits</b>. Although this feature already exists, I'd like wikis to add 2 fields when anonymously editing a topic: a user name and an email address. The idea is make it even easier to contrinute to a wiki. If the wiki is moderated as
    explained above, moderators would receive an email. The idea of the username and email is to allow the moderator/community to discuss with the contributor if need be and to give him credits. These 2 fields would obviously be optional and there
  should be a text on the page explaining that the email will not get displayed on the wiki and that filling the fields will allow credits/acknowledgment to be given.</li>
  <li><b>Diff notifications</b>. Most wikis allow some form of space watch but the wikis I have used still do not offer the possibility to send notifications in a text diff format (wiki markup diff is good enough). For a development wiki, the idea is to send
  diff notifications to the development mailing list so that all developers are aware of wiki page modifications.</li>
  <li><b>Daily notifications</b>. This is also supported in some wikis but what I would like is the ability to watch a single space and to aggregate changes in that space (using the diff notification format mentioned above). Please note that
    Confluence does not support this as it requires you to modify all other spaces permissions so that the user doing the watch has no view rights on the other spaces, which is not usable for example on wikis such as the one on Codehaus which have hundreds of spaces.
  <li><b>In place comments</b>. The idea is again to lower contribution by allowing wiki users to highlight a portion of text in their browser and to associate a comment with it (like a post-it). There would be an option to turn on/off these comments. It's easier
  for a user to highlight a line and put a comment like "I don't understand this sentence" or fix a typo rather than have to use current the type of comments at the bottom of a page. Note that this is similar to how word processors such as Word allow adding comments to a document.</li>
  <li><b>Patch handling</b>. I'd like the ability to make modifications to a page and then instead of saving, have the ability to click on a "Generate patch" button which would generate a text file in wiki markup diff format. Then there would need to be a "Apply patch" action
  that can be done on a page. This would allow using wikis for project development web sites and allow contributors to provide documentation patches along with code patches. This is currently a big pain when using a wiki as a project development web site.</li>
</ul>
<p>I have quite a few other suggestions for improvements but I feel those are the major ones when it comes to using a wiki as a project development wiki. Let's hope wiki vendors are listening... :-). Are these also on your wish list?</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-03-17T10:07:41+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001325_how_can_i_improve_my_oss_project_managment_skills.html">
<title>How can I improve my OSS project managment skills?</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001325_how_can_i_improve_my_oss_project_managment_skills.html</link>
<description><![CDATA[<p>I've been asking myself the following 2 questions for about 5 years now: am I good at managing an open source project and making it successful? How can I improve?</p>
<p>I guess it depends on the definiton of "successful". My definition of a successful OSS project is:</p>
<ol>
  <li>A project that has a big user community and mindshare</li>
  <li>A project that has a big development community (i.e. committers and contributors). That is the development mailing list should be quite active with lots of contributions, improvements, ideas being discussed. All those submitted by a large number of different persons</li>
  <li>A project that lives on if the initial or main contributor leaves the project</li>
</ol>
<p>If we go by point 1, I think that the main 2 projects I have started (<a href="http://jakarta.apache.org/cactus">Cactus</a> and <a href="http://cargo.codehaus.org">Cargo</a>) are not doing too bad. Cargo is still new but it seems
to be on track and its user base is growing very quickly.</p>
<p>However on points 2 and 3, I'm not so sure I'm doing well. Mind you, Cargo has quite a lot of committers (growing every week!) and they're all doing a great job.
I'm just thinking about the level beyond (look at the activity on the Maven project, Spring or other projects as an example of what I mean). Cactus is a bit different as it's now a mature project, so let's focus on Cargo.
Of course it could be that these project domains are narrow and thus do not interest lots of developers. This is probably true but I don't think this is the only issue.
I have the feeling that some of the reasons could be:</p>
<ul>
<li>Unconsciously I may be "driving" the project too much. For example if someone proposes something, I'm probably going to argue with this person in order that it fits Cargo's quality crtieria and direction.
It's possible that by doing this, I'm cutting some creativity from this person and
thus even if he implements the thing, maybe he'll feel it has not completely come from him and won't identify with it enough to maintain and improve it in the future. Or maybe by arguing I'm just making the life of that person harder
and as this person is doing this in the little free time he has, he may not pursue it...</li>
<li>Maybe I'm answering emails asked on the list too fast, thus preventing any other contributor to answer. This is setting the tone and maybe as a consequence people are expecting me to answer all emails. Everyone "knows" that I'll answer them anyway...</li>
<li>The same could be said for applying patches and implementing things. I think this is less true though as I also have a day job and there are lots of JIRA issues accumulating in the Cargo project for example, so there's room for takers</li>
<li>Documentation of Cargo seems good at first glance (although I know there are lots of holes). I wonder if, as a consequence Cargo users who look at the web site think that Cargo is stable, mature, etc and thus may feel less inclined to participate. Who 
wants to participate to a project that is mostly "done"! (Note: For those reading this and interested in Cargo, it is far from true and there are tons of things to design and implement!)</li>
</ul>
<p>On the other hand, I feel that not doing any one of these points will hamper Cargo's user adoption...</p>
<p>Or maybe I'm completely wrong on all points above and this is just me fantasizing!</p>
<p>I'm really interested to know what you think and if this is something other OSS committers/contributors have noticed too. I've given the example of Cargo but really this is a general discussion on how to best manage an OSS project.</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-02-16T12:09:43+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001324_ensuring_binary_compatibility.html">
<title>Ensuring binary compatibility</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001324_ensuring_binary_compatibility.html</link>
<description><![CDATA[<p>I see 2 use cases where ensuring <a href="http://blogs.codehaus.org/people/vmassol/archives/000098_evolving_javabased_apis_the_nightmare_of_binary_compatibility.html">binary compatibility</a> is a must:</p>
<ul>
<li>When you're developing a framework, i.e. a piece of software meant to be used at an API level by other developers. In that case, breaking binary compatibility is not something to do lightly.</li>
<li>When working in a large team it's common to define "interface" projects that represent the contracts to be followed by the different teams. In that case breaking the binary compatibility in an "interface" project is something that has to be planned and organized.</li>
</ul>
<h3>Enforcing binary compatibility in the build</h3>
<p>The automated build is a nice place to enforce binary compatibility as the build is something executed by the indiviudal developers before checking-in and it's also executed by the continuous integration build. 
Thus any binary incompatibility can be quickly discovered. Or course this doesn't replace tests which can also help discover breakages. However the problem is that with all the nice refactoring IDEs we have now, it's easy
to refactor the tests at the same time as the code and thus introducing a binary incompatibility is not always noticed.</p>
<p>A good strategy to discover an incompatibility is to compare the current code with the latest released code. This is what <a href="http://blogs.codehaus.org/people/vmassol/archives/001063_clirr_rocks.html">Clirr</a> is doing. 
Clirr currently sports an Ant and Maven1 integration. The good news is that there's a Maven2 plugin in the work (more on that when it's released). However using a tool is only good if there's a strategy behind it.</p>
<h3>Strategy for using Clirr</h3>
<p>Here is what I believe can be done to automate binary compatibility checks in the build:</p>
<ul>
<li>Start by organizing your packages so that you <a href="http://jakarta.apache.org/cactus/participating/apis.html">clearly demarcate the user-public API from the SPI from the internal implementations</a>. You'll probably want to fail the build only on the user-public API (and possibly on the SPI too but that's
probably a lower severity).</li>
<li>Use Clirr to make your build fail upon violation on the user-public API.</li>
<li>After discussing with the team and possibly with users, decide whether you wish to allow the binary incompatibility. Always consider going for a deprecation cycle. If you choose to allow the incompatibility, register it in an exception file that you
pass to Clirr so that it builds without choking on those errors (Note: I believe Clirr needs to be improved to better support exceptions not only at the file level but at the violation level).</li>
<li>When the release time comes, you'll have a nice file listing all the binary incompatibilities. Include it in the release notes so that your users know what to expect and even better, for each incompatibility add a description that explains
how to modify the user code to use the new version of the API.</li>
</ul>
<p>Note: On the <a href="http://cargo.codehaus.org">Cargo</a> project we've <a href="http://cargo.codehaus.org/Release+notes+for+Cargo+0.5">tried to do this</a>, even though there's still room for lots of improvement. Actually our main issue on Cargo is
not detecting binary incompatibilites but rather deciding to release a 1.0 version which would mean that from then forward we would aways look for a deprecation solution rather than break binary compatibility. We've always pushed back this 1.0 release 
because our API has been changing quite frequently but we're now nearing a 1.0 version. When that comes we'll turn Clirr on to fail the build upon breakage. I'll let you know how it goes...</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-02-12T13:48:56+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001314_documentationdriven_development.html">
<title>Documentation-Driven Development</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001314_documentationdriven_development.html</link>
<description><![CDATA[<p>I'm currently writing my third book and I'm starting to notice a pattern. Whenever I write a book about a tool/framework to which I have access to the sources, the code ends up being better.</p>
<p>The way I work goes like this: I start writing about a topic. If it's taking too long to explain it, I consider that something is wrong about the code. I modify the source code so that the 
document I'm writing has the minimal required size to explain the topic.</p>
<p>The good thing with a book is that what you're explaining has to be simple and not convulted which leads to this nice
effect of improving usability of your code. I get a bit of the same result when I write project documentation but not to the same level. This is probably simply because writing a book is a more
involved process, you dedicate more time to it and thus you want it to be as perfect as possible (and thus as readable as possible).</p>
<p>I guess nothing here is new. This is all about having a user of your code. Tests are "users" of your code and thus leads to better design. I guess documentation can also be a "user" of the code
and thus help improving it.</p>
<p>If you're writing some framework/tool, consider writing a book for it and if you're diligent in your writing your code will end up being better! As an added benefit your users will love you... :-)</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-01-21T08:55:37+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001307_cargo_v07_and_maven2_plugin_v01.html">
<title>Cargo v0.7 and Maven2 plugin v0.1</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001307_cargo_v07_and_maven2_plugin_v01.html</link>
<description><![CDATA[<p><a href="http://cargo.codehaus.org">Cargo</a> is a container-manipulation library that allows configuring, starting and stopping containers. It also deploys modules to those containers. Version 0.7 has been
<a href="http://cargo.codehaus.org/Release+notes+for+Cargo+0.7">released</a> last week along with version 0.1 of a <a href="http://cargo.codehaus.org/Maven2+plugin">Maven2 plugin</a>. The nice thing about Cargo is that it provides a uniform API across all containers and it has 
<a href="http://cargo.codehaus.org/Extensions">several end user APIs</a>: a Java API, Ant tasks, a Maven 1 plugin, a Maven 2 plugin, a Netbeans plugin, an IntelliJ IDEA plugin, etc. You can use any of those extensions with all the <a href="http://cargo.codehaus.org/Containers">supported containers</a>.</p>
<p><note><i>Note: Adding a new container is very easy and you only have to implement a small interface and your container will be made available automatically through all the existing end user APIs - Make sure to contact us if you're interested in adding a new
container support.</i></note></p>
<p>I'd like to quickly demonstrate how to use the new Maven 2 plugin on 2 use cases (more samples can be found <a href="http://tinyurl.com/b57dl">here</a>):</p>
<ul>
<li>Use case 1: Deploying a WAR to Tomcat 5.x and starting the container</li>
<li>Use case 2: In-place webapp deployment with Jetty 4.x</li>
</ul>
<h3>Deploying a WAR and starting Tomcat 5.x</h3>
<p>Create a Maven 2 project and put the following configuration in your <code>pom.xml
</code>
 file:</p>
<code><xmp>
[...]
  <packaging>war</packaging>
[...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.cargo</groupId>
        <artifactId>cargo-maven2-plugin</artifactId>
        <configuration>
          <container>
            <containerId>tomcat5x</containerId>
            <home>c:/apps/jakarta-tomcat-5.0.30</home>
          </container>
          <configuration>
            <dir>${project.build.directory}/tomcat</dir>
          </configuration>
        </configuration>
      </plugin>
    </plugins>
  </build>
</xmp>
</code>

<p>To generate your WAR, start Tomcat and deploy the WAR in it, simply type: <code>mvn package cargo:start
</code>
. That's all! Do you want to do the same in, say, Orion 2.0.5? Simply change <code>tomcat5x
</code>
 with <code>orion2x
</code>
 and the <code>home
</code>

element to point to where you have installed Orion 2.0.5. You don't have Orion on the machine running the build? No issue, simply replace <code>&lt;home&gt;
</code>
 with:</p>
<code><xmp>
<zipUrlInstaller>
  <url>http://www.orionserver.com/distributions/orion2.0.5.zip</url>
</zipUrlInstaller>
</xmp>
</code>

<p>Orion 2.0.5 will then be automatically downloaded and installed the first time you run your build.</p>
<h3>Inplace webapp development with Jetty</h3>
<p>Let's imagine you're using the same project as above but this time you'd like to start Jetty and make it point to your webapp directory (i.e. <code>src/webapp
</code>
) so that whenever you make a change to your webapp's sources Jetty 
automatically picks it up and serves it. See <a href="http://blogs.codehaus.org/people/brett/archives/001306_developing_with_jetty_where_have_you_been_all_my_life.html">Brett's nice blog post</a> on this. Simply modify your <code>pom.xml
</code>
 as follows:</p>
<code><xmp>
[...]
  <packaging>war</packaging>
[...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.cargo</groupId>
        <artifactId>cargo-maven2-plugin</artifactId>
        <configuration>
          <!-- No container specified thus it'll default to Jetty -->
          <configuration>
            <dir>${project.build.directory}/jetty</dir>            
            <deployables>
              <deployable>
                <!-- Override location to point to the exploded webapp. 
                     Otherwise it'll deploy the generated WAR. We want 
                     to ensure that jetty reloads any change made to the
                     webapp source tree... -->
                <location>${basedir}/src/main/webapp</location>
              </deployable>
            </deployables>
          </configuration>
        </configuration>
      </plugin>
    </plugins>
  </build>
</xmp>
</code>

<p>Then open a shell prompt and type <code>mvn cargo:start
</code>
. Jetty will start and monitor your webapp's dir for any change (Note that the same can be achieved using other containers too).</p>
<p>If you're interesting in learning more, check the <a href="http://cargo.codehaus.org">documentation</a> and join us on the <a href="http://archive.codehaus.org/cargo/">Cargo mailing lists</a>.</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2006-01-10T21:05:22+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001275_javapolis_2005_slides_on_maven_2.html">
<title>Javapolis 2005 slides on Maven 2</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001275_javapolis_2005_slides_on_maven_2.html</link>
<description><![CDATA[<p>I'm just back from <a href="http://www.javapolis.com/confluence/display/JP05">Javapolis 2005</a>. I had the pleasure to present <a href="http://codehaus.org/~vmassol/blog/javapolis2005-Maven 2.0-massol.ppt">Maven 2.0</a>.</p>
<p>I was lucky to be presenting in Room 1 (the big one) and it was well packed. Here are the questions I asked the audience last year:</p>
<p><quote><i>
"The room was packed (I'd say around 400 to 600 people). Before starting with my session I've asked how many people are already using Maven and I've counted about 20 (but at that time the room was only half-packed), so I'd say it was about 3-5%. My second was "How many are planning to use Maven" and I got a resounding 3/4th of the people raising their hand. That shows that Maven is still in it's early adoption phase and that it has some great potential."
</i></quote></p>
<p>This year when I asked  the audience who is using Maven 1, I got about 30%-35% hands raised. Wow! This is a huge boost from the 3%-5% of last year! There were also about 5% people already using Maven 2 so that's great too. It seems Maven's adoption is well on its way</p>
<p>Thanks everyone for the warm welcome during the presentation.</p>
<p>Enjoy the slides while waiting for Javapolis to broadcast the videos.</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-12-16T19:09:31+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001218_welcome_to_the_matrix.html">
<title>Welcome to the Matrix!</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001218_welcome_to_the_matrix.html</link>
<description><![CDATA[<p>Amazon has released a beta of the <a href="http://www.mturk.com/mturk/welcome">Mechanical Turk</a>. It allows a program to programatically ask a question to a human and wait for the answer. Here's an example (copied from <a href="http://blog.outer-court.com/archive/2005-11-04-n69.html">Google Blogoscoped</a>):</p>
<pre><div class="code"><pre>read (photo);
photoContainsHuman = callMechanicalTurk(photo);
<span class="category1">if</span> (photoContainsHuman == TRUE) {
   acceptPhoto;
}
<span class="category1">else</span> {
   rejectPhoto;
}</pre></div>
</pre>
<p>This is really like the Matrix except that the humans get paid a little bit of money (but in the end that's close to getting fed) and it's other humans that controlling the programs... until we have web services using other web services using the Mechanical Turk. Then who's controlling who is going to be hard to decide :-)</p>
<p>Source: <a href="http://blog.outer-court.com/archive/2005-11-04-n69.html">Google Blogoscoped</a>.</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-11-04T18:30:50+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001209_database_manipulation_framework_wanted.html">
<title>Database manipulation framework wanted</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001209_database_manipulation_framework_wanted.html</link>
<description><![CDATA[<p>I'm working on automating a J2EE build using Maven 2 and I'm in need of a Maven 2 plugin to do the following:</p>
<ol>
<li>load a database schema in the instance</li>
<li>load data in the instance</li>
<li>start/stop a database instance</li>
<li>ability to create an instance from scratch</li>
</ol>
<p>The ideal situation would be to find an existing Java framework that would already perform all or some of those steps. Then I could easily create a Maven 2 plugin wrapping it.
So far I haven't been able to find such a tool. If you know any please suggest them!</p>
<p>Here's what I have found so far below. Please note that I have probably made mistakes while filling this table and I'd be happy to be corrected...</p>
<table border="1">
  <th>
    <td>Load schema</td>
    <td>Load data</td>
    <td>Start/stop instance</td>
    <td>Create instance</td>
    <td>Comments</td>
  </th>
  <tr>
    <td><a href="http://dbunit.sourceforge.net">DBunit</a></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/forbidden.gif"/></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/add.gif"/></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/forbidden.gif"/></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/forbidden.gif"/></td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td><a href="http://db.apache.org/ddlutils/">DDLUtils</a></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/add.gif"/></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/forbidden.gif"/></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/forbidden.gif"/></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/forbidden.gif"/></td>
    <td>I think DDLUtils is the old commons-sql project.</td>
  </tr>
  <tr>
    <td><a href="http://db.apache.org/derby/integrate/plugin_help/ij_toc.html">Derby ij</a></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/add.gif"/></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/add.gif"/></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/forbidden.gif"/></td>
    <td><img src="http://docs.codehaus.org/images/icons/emoticons/forbidden.gif"/></td>
    <td>ij 10.1.1.0 requires the db2jcc.jar which is not on Ibiblio. I need to check the license to see if it could be uploaded.</td>
  </tr>
</table>
<p>Again, let me know if you know some tools that are not listed here.</p>
<p>If no such tool exist, an idea I have would be to add support for databases in <a href="http://cargo.codehaus.org">Cargo</a>. Indeed Cargo is meant for manipulating any kind of containers.
It happens that the first type of container we've implemented are J2EE containers but it should work for any other type and the interfaces should remain the same.</p>
<p>WDYT?</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-10-26T18:49:41+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001188_farewell_to_nicolas_chalumeau.html">
<title>Farewell to Nicolas Chalumeau</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001188_farewell_to_nicolas_chalumeau.html</link>
<description><![CDATA[<p>Dear friends,</p>

<p>This is a sad moment. Our friend and colleague Nicolas Chalumeau has departed this world on the 4th of October at the age of 27.</p>

<p>The Apache Software Foundation would like to express its condolences to Nicolas' family and friends.</p>

<p>Nicolas had been developing open source software at Apache for several years. He was participating in several projects including Jakarta Cactus and Apache Maven. But even more importantly than helping those projects, what made Nicolas stand apart was his kindness and his generosity. He was always open to discussion and was constantly helping others. On the Cactus project he was regularly the first to answer questions from newcomers trying to use Cactus.</p>

<p>Recently he had taken up the important task of helping migrate Cactus to use Cargo and he had been working diligently towards that task. Actually Nicolas had been doing such a great job on the Cactus project that the Cactus committers had unanimously voted him in to become a committer. Nicolas was voted an Apache committer on the 1st of August 2005. I had several discussions with Nicolas about this new role and he was extremely happy to be part of the Apache Foundation.</p>

<p>Nicolas, we'll miss you, but the work you have done for the community will be remembered forever and will live on. All our thoughts and good wishes are with you and your loved ones.</p>

<p>-Vincent on behalf of the Apache community</p>

<p>(we have also created a special <a href="http://jakarta.apache.org/cactus/participating/nicolas.html">farewell page for Nicolas</a> on the Cactus website).</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-10-06T15:55:29+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001181_google_summer_of_code_results.html">
<title>Google Summer Of Code results</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001181_google_summer_of_code_results.html</link>
<description><![CDATA[<h3>Results</h3>
<p>
  The <a href="">Google Summer of Code</a> is now over. I've had the pleasure of being a mentor for 
  <a href="http://www.codehaus.org">Codehaus</a>. More specifically I've mentored the following
  projects:
</p>
<ul>
  <li>
    <b>JBoss 3.x and 4.x support in <a href="http://cargo.codehaus.org">Cargo</a></b>. 
    This project was successfully implemented by Nyoman Winardi (a.k.a. Win). Win started sending 
    patches and over the course of the programme Win became a committer proper. The full support
    of JBoss 3.x and 4.x will be available in the next release of Cargo (version 0.7).
  </li>
  <li>
    <b><a href="http://www.jcp.org/en/jsr/detail?id=88">JSR-88</a> support for Cargo</b>. This project was successfully implemented by
    Lev Olkhovich who also became a Cargo committer. Lev implemented deployment of J2EE archives
    using JSR-88. In the process he started a conversation to refactor Cargo to support the
    notion of remote containers. There's still some refactoring going on and we need to add some
    more tests but we should be able to have support for remote containers and JSR-88
    in Cargo 0.7. 
  </li>
  <li>
    <b>Refactor <a href="http://jakarta.apache.org/cactus">Cactus</a> to use Cargo</b>. One more 
    project revolving around Cargo! This one was implemented by Xuan Thang Nguyen. Xuan sent 
    several patches and thanks to Felipe we've applied
    some of those. However, I have to admit I have personally not been available enough to 
    fully help Xuan apply his patches. We still have some patches in JIRA that haven't been
    applied yet. Actually the plan was to have Nicolas Chalumeau to help Xuan and apply Xuan's
    patches. Nicolas has been working and helping on Cactus for a long time now and was voted
    a committer on Cactus at the beginning of the SOC programme. However, the Apache Software 
    Foundation (ASF) is extremely slow when it comes to adding a committer to a project (it can take
    more than 2 months) and we've not been able to give right access to Nicolas. Thus he's not
    been able to apply his own patches nor Xuan's... This is really an issue that the ASF has to
    solve quickly lest it'll see people leaving to create their project somewhere else.
  </li>
  <li>
    <b><a href="http://faqbot.codehaus.org">Faqbot</a> project</b>. There were 2 students on this
    project: Jie Tang and Harsh Puri. Harsh has had to resign from the programme because of the
    tragic flooding that happened in the region of Mumbai. Jie has continued alone and has done
    some good work. Unfortunately he's not been able to fully complete the project (which was
    probably the most ambitious of all the SOC projects I've mentored). The hardest part was
    probably starting a project from scratch. Everything had to be done. Hopefully Jie and others
    will continue the project and make it release-ready. <a href="http://blogs.codehaus.org/people/vmassol/archives/think_tank.html#000670_faq_bots">I was very excited by this 
    project</a> and I still am. 
  </li>
  <li>
    <b>Real-time collaboration editing (<a href="oxyd.codehaus.org">Oxyd</a>)</b>. This one
    was implemented by Jeremi Joslin of <a href="http://xwiki.org">XWiki</a> fame. Even though it
    was a project started from scratch Jeremi was able to complete it and have a first usable 
    release ready. Well done Jeremi!
  </li>
</ul>
<h3>Learnings</h3>
<ul>
  <li>
    Open source is about collaboration with others. I don't think the SOC emphasis was enough on
    this point. For example it was "fordbidden" for students to work together and the main focus 
    was to produce a working piece of software.
  </li>
  <li>
    Open source is not bound by time. People do it in their free time (at least most people) and as 
    such they can't be expected to be bothered by strong release pressure. The SOC students had
    to work on a given date which caused some friction as the students were not always aligned with 
    the project's timeline. Let me give you one example; 
    It happened that some student needed to do a refactoring to the existing code to progress. 
    This needs to be reviewed and possibly voted by project committer. There could easily be a 
    delay of 1 week before we get everyone's agreement/ideas, etc. In the meantime the student 
    is under pressure to quickly progress.
  </li>
  <li>
    I have taken too many students. I felt I did not do the best possible job when it came to 
    mentoring them. Some were not autonomous enough and would have required more mentoring. I'll
    take fewer students next time. The hardest is really to mentor students on a new open source project started from scratch.
    As I'm already involved with several open source project, I did not have enough 
    bandwidth to help on all aspects required to set up a new project.
  </li>
  <li>
    Several students had not enough time to participate. Some were still passing exams, others
    had some other summer job. This, combined with the deadline and the nature of open source did not
    mix well together. I think students should have an open source project to complete on a much 
    longer timescale (possibly with milestones to monitor progress). This would also help in
    having them really integrated into an open source team. In addition it'll show their real
    commitment over time which is really what "professional" open source is about. There's 
    nothing worse that someone who contributes big portion of code and then leaves some time
    after. Then, all the bug fixing and maintenance falls on the shoulders of the committers who
    were not the ones with the itch in the first place...
  </li>
</ul>
<h3>Parting words</h3>
<p>
  The SOC was good. It has boosted the open source community quite remarkably (even though it has
  also probably put some strain on it...). Out of all the students I've mentored I think 2 or 3
  of them (out of 6 initially) will continue to work on the open source project they've 
  participated to. That's a 30%-50% ratio and I'm very happy about it. Thanks Google for making this happen!
</p>
  ]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-09-28T16:25:41+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001170_javazone_2005.html">
<title>Javazone 2005</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001170_javazone_2005.html</link>
<description><![CDATA[<p>Javazone 2005 was good. It's getting more international every year but there's still a lot of Norwegian speaking there, which was a bit difficult to understand from time to time... Oh well, I had <a href="http://www.coffeebreaks.org/blogs/">Jerome Lacoste</a> translating for me whenever needed. Thanks Jerome. It also gave me the opportunity to learn "Hey alle semmon" ("hi everybody") and <a href="http://www.savoirtech.com/roller/page/jgenender">Jeff Genenger</a> woke up his audience on thursday morning with a "I'm a loud-mouthed american, don't listen to me I don't know anything" in Norwegian! :-)</p>
<p>I have presented <a href="http://www.codehaus.org/~vmassol/blog/Javazone2005%20-%20From%20m1%20to%20m2%20-%2020050914.ppt">From Maven 1 to Maven 2</a> which went well. There were about 60-70 people in the room, all Maven 1 users (to be expected for such a talk) and a few (about 5) Maven 2 users.</p>
<p><b>Update 2005-09-28</b>: Kito has <a href="http://weblogs.java.net/blog/kito75/archive/2005/09/javazone_2005_o_1.html">blogged about JavaZone 2005</a> and has uploaded some nice <a href="http://www.flickr.com/photos/97271958@N00/sets/1023006/">pictures</a>.</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-09-15T08:56:27+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001132_cds_vs_yds.html">
<title>CDS vs YDS</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001132_cds_vs_yds.html</link>
<description><![CDATA[<p>I've just tried today <a href="http://www.copernic.com/en/products/desktop-search/index.html">Copernic Desktop Search</a> (CDS). I've been 
using <a href="">Yahoo Desktop Search</a> (YDS) for several months now and I'm very happy with it. It has some issues though like it's putting 
my laptop on its knees when it performs indexing, it has no Windows taskbar integration, etc. I wanted to see how CDS fared against YDS.</p>
<p>Here are my findings after one day of using CDS. Please note that this is definitely not long enough to have a definitive opinion on the 
topic but I thought I'd still share what I've learnt today.</p>
<h3>General opinion</h3>
<p>CDS is a very good desktop search. I was very impressed. It seemed perfect at first and then slowly I started finding some little
flaws compared to YDS. Still it is extremely good. It has all the features you'll find in YDS and Google Desktop Search (GDS).</p>
<h3>Pros of CDS vs YDS</h3>
<ul>
<li>Integration with Windows taskbar</li>
<li>Low resource for indexing. It is not slowing my laptop when indexing. That's very good!</li>
<li>Immediate scanning of new resources. If you receive an email for example, it is immediatly available for searching. No need to 
wait for the next indexing.</li>
</ul>
<h3>Cons of CDS vs YDS</h3>
<ul>
<li>No vertical layout for views (as there is in YDS). This means that you cannot fully the message being previewed</li>
<li>No "All" categories search. You have to choose the category you wish to search (emails, files, contacts, etc)</li>
<li>No as-you-type results</li>
<li>No possibility to choose the columns to display (for exemple email folders or email size). There are only a few basic columns</li>
<li>Slower to search and display items than YDS. It was very fast initially and it quickly became slow and very slow as indexed items increased</li>
<li>XML preview is using IE engine on Windows and thus there are lots of XML files that don't display correctly</li>
</ul>
<p>Some minor details:</p>
<ul>
<li>Delete key does not work to suppress an email</li>
<li>Cannot select different emails (to suppress them for example)</li>
</ul>
<h3>Conclusion</h3>
<p>If only it could have a better view layout and be faster to display results it would be perfect. Its killer features are really its CPU-friendly 
indexing for me and the immediate availability of new resources in searches.</p>
<p>I've just noticed that YDS has released verson 1.2beta yesterday and I'm installing it. For now, I'll still keep using YDS which is still my favorite. YMMV.</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-07-13T18:19:19+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001114_white_paper_on_agile_offhore_french.html">
<title>White Paper on Agile Offhore (French)</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001114_white_paper_on_agile_offhore_french.html</link>
<description><![CDATA[<p>I've just finished writing a White Paper for <a href="http://www.pivolis.com">Pivolis</a>, my company. It's on the topic of <a href="http://www.pivolis.com/fr/formulaire/formulaire.php3">Agile Offshore Software Development</a> and it explains how to perform collaborative software development when teams are distributed. It's a return of experience from the two main offshore development projects I have been on for the past 3.5 years.</p>
<p>It addresses different types of concern: from culture to communications to technical infrastructure to development practices.</p>
<p>Now just before you rush to it, you should know that it's written in French. I'm really sorry about that. I would have much preferred to write it in English but Pivolis' first market is currently France.</p>
<p>I hope you'll enjoy it.</p>
<p>Note: On the Pivolis web site, don't click on the English flag. The English version of the site is not yet up to date and you won't find the White Paper there.</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-06-19T11:02:23+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001097_manvebookorg_is_live.html">
<title>Manvebook.org is live</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001097_manvebookorg_is_live.html</link>
<description><![CDATA[<table>
  <tr><td>
<p>
In preparation for the launch of <a href="http://mavenbook.xwiki.com/xwiki/bin/view/Main/Book">Maven: A Developer's Notebook</a>, Tim and I have created the <a href="http://www.mavenbook.org">Mavenbook.org</a> web site. By using it you'll be able to track the progress of the book but more importantly it'll allow you to download the book's source code, get additional samples, read tips and tricks on using Maven, etc. All of this through a blog interface.
</p>
<p>BTW, we're not web designers so we've used a <a href="http://oswd.org/viewdesign.phtml?id=2070&referer=%2Fsearch.php%3Fsearchstring%3Dsimplexed%26tab%3Ddescription">skin</a> found on <a href="http://oswd.org/">OSWD</a>. I really like this web site which has both free skins and premium ones.</p>
<p>Last, the icing on the cake, the web site has been done using <a href="http://www.xwiki.com">XWiki</a>. Yeah, you heard it right, there is a wiki under the hood, which allow us to easily edit any page online. Each news item is actually a wiki page to which we have associated an Article object. The home page has a simple macro that does a search for all pages with articles and matching some criteria. Cool, no?</p>
</td>
<td><img alt="Maven: A Developer's Notebook" src="http://codehaus.org/~vmassol/blog/mdn.jpg"/></td>
</tr>
</table>
<p>Enjoy!</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-05-23T15:26:15+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001065_maven_using_the_cargo_plugin_for_testing.html">
<title>[Maven] Using the Cargo plugin for testing</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001065_maven_using_the_cargo_plugin_for_testing.html</link>
<description><![CDATA[<p><a href="http://cargo.codehaus.org">Cargo</a> 0.5 has been <a href="http://cargo.codehaus.org/Downloads">released yesterday</a>. One novelty
is the <a href="http://cargo.codehaus.org/Maven+Support">Maven plugin</a>. You can now start and stop a variety of containers using this plugin. This should come very handy for all of you
wishing to perform integration or functional testing with Maven. The containers that are currently supported are: Resin 2.x, Resin 3.x, Tomcat 3.x, Tomcat 4.x, Tomcat 5.x, Orion 1.x, Orion 2.x, Jetty 4.x, jo! 1.x, OC4J 9.x and WebLogic 8.x.</p>
<p>For example, imagine that you have some integration tests in your project's test directory and that you need, say, Tomcat 5.0.30 to run
them. You'll need to start the Tomcat container before the <code>test:test
</code>
 goal kicks in. Do this by writing a preGoal in your <code>maven.xml
</code>
:</p>
<div style="width:100%; overflow:auto; border-style: solid; border-width: 1px"><code><xmp>
<preGoal name="test:test">
  <ant:mkdir dir="${maven.build.dir}/tomcat"/>
  <attainGoal name="cargo:start"/>
</preGoal>
</xmp>
</code>
</div>
<p>You'll need to provide Cargo configuration data in your <code>project.properties
</code>
 or <code>build.properties
</code>
 file. For example a minimal configuration would be:</p>
<div style="width:100%; overflow:auto; border-style: solid; border-width: 1px"><code><pre>
cargo.containers = tomcat
cargo.container.tomcat.containerKey = tomcat5x
cargo.container.tomcat.homeDir = C:/apps/tomcat-5.0.30
cargo.container.tomcat.config.hint = standalone
cargo.container.tomcat.config.dir = ${maven.build.dir}/tomcat
cargo.container.tomcat.config.standalone.servlet.port = 8180
</pre>
</code>
</div>
<p>Alternatively you can ask the plugin to automatically download and install Tomcat for you (it'll download it only once), by specifying:</p>
<div style="width:100%; overflow:auto; border-style: solid; border-width: 1px"><code><pre>
cargo.containers = tomcat
cargo.container.tomcat.containerKey = tomcat5x

cargo.zipUrlInstaller.tomcatinstaller.installUrl = http://www.apache.org/dist/jakarta/tomcat-5/v5.0.30/bin/jakarta-tomcat-5.0.30.zip
cargo.zipUrlInstaller.tomcatinstaller.installDir = ${maven.build.dir}/installs
cargo.container.tomcat.zipUrlInstaller = tomcatinstaller

cargo.container.tomcat.config.hint = standalone
cargo.container.tomcat.config.dir = ${maven.build.dir}/tomcat
cargo.container.tomcat.config.standalone.servlet.port = 8180
</pre>
</code>
</div>
<p>As you may have noticed, in our example above we've reused the existing Maven Test plugin which looks for test sources in <code>${pom.build.unitTestSourceDirectory}
</code>
. With this strategy
you'll need to create a separate subproject for running your integration/functional tests in order not to interfere with pure unit tests that you may already have in <code>${pom.build.unitTestSourceDirectory}
</code>
.
<p>If there's a strong demand, we may consider adding a <code>cargo:test
</code>
 goal in the future that you look for tests in, say, <code>src/test/cargo
</code>
 by default (leaving <code>src/test/java
</code>
 for unit tests).</p>
<p>Please note that there's also an alternative which is to <a href="http://blogs.codehaus.org/people/vmassol/archives/000893_using_cargo_for_functional_testing.html">start the Container directly from your unit tests</a>.</p>
<p>If you find Cargo interesting, please come and help us on the <a href="http://archive.codehaus.org/cargo/">Cargo mailing lists</a>. There are lots of different ways you can help: trying Cargo on containers, implementing
new containers (for example, JBoss, JOnas, WebSphere, etc), discussing new ideas, letting us know what new features you'd love to see, etc.</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-05-01T10:48:50+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001064_cargo_05_released.html">
<title>Cargo 0.5 released</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001064_cargo_05_released.html</link>
<description><![CDATA[<p>The <a href="http://cargo.codehaus.org">Cargo</a> team is pleased to announce the <a href="http://cargo.codehaus.org/Downloads">release of Cargo 0.5</a>.</p>
<p>The major changes from Cargo 0.4 to 0.5 are:</p>
<ul>
  <li>New Maven plugin</li>
  <li>Added support for hot deployments</li>
  <li>Added support for the <a href="http://www.tagtraum.com/">jo!</a> container</li>
</ul>
<p>Detailed release notes are available on the <a href="http://cargo.codehaus.org/Downloads">download</a> page.
<p>Here's an example of how to use Cargo from Java:</p>
<div style="width:100%; overflow:auto; border-style: solid; border-width: 1px"><pre><div class="code"><pre><span class="category2">Container</span> container = <span class="category1">new</span> Resin3xContainer();
container.setHomeDir("<span class="quote">c:/apps/resin-3.0.8</span>");

Deployable war = container.getDeployableFactory().createWAR("<span class="quote">path/to/simple.war</span>");
container.getConfiguration().addDeployable(war);

container.start();
<span class="linecomment">// Here you are assured the container is started.</span>

container.stop();
<span class="linecomment">// Here you are assured the container is stopped.</span></span></pre></div>
</pre></div>
<p>Here's an example using the provided Ant tasks:</p>
<div style="width:100%; overflow:auto; border-style: solid; border-width: 1px"><code><xmp>
<cargo-orion2x homeDir="c:/apps/orion-2.0.3" output="target/output.log" 
    log="target/cargo.log" action="start">
  <configuration>
    <property name="cargo.servlet.port" value="8180"/>
    <war warfile="path/to/my/simple.war"/>
    <ear earfile="path/to/my/simple.ear"/>
  </configuration>
</cargo-orion2x>
</xmp>
</code>
</div>
<p>And here's an example using the Maven plugin:</p>
<div style="width:100%; overflow:auto; border-style: solid; border-width: 1px"><code><pre>
// To run it:
maven cargo:start

// To configure it, add the following in a Maven properties file:
cargo.containers = myTomcat
cargo.container.myTomcat.containerKey = tomcat5x
cargo.container.myTomcat.homeDir = c:/apps/jakarta-tomcat-5.0.30
cargo.container.myTomcat.config.hint = standalone
cargo.container.myTomcat.config.dir = ${maven.build.dir}/myTomcat/config
cargo.container.myTomcat.config.standalone.servlet.port = 8180
</pre>
</code>
</div>
<p>Enjoy!</p>
]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-05-01T10:36:23+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001063_clirr_rocks.html">
<title>Clirr rocks!</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001063_clirr_rocks.html</link>
<description><![CDATA[<p><a href="http://clirr.sourceforge.net">Clirr</a> is one of these tools that would deserve to be known better. I have mentioned it several times in other posts but it's really the first
time I get to use it in real. It rocks! I'm about to release <a href="http://cargo.codehaus.org">Cargo</a> 0.5 and I wanted to get an exact list 
of the API modifications we have done compared to version 0.4.</p>
<p>Here's the kind of output Clirr gives (the full output is available <a href="http://cargo.codehaus.org/Downloads#clirr">here</a>):</p>
<div style="width:100%; overflow:auto; border-style: solid; border-width: 1px"><code><pre>
ERROR: 8001: org.codehaus.cargo.deployment.DefaultJarArchive: Class org.codehaus.cargo.deployment.DefaultJarArchive removed
INFO: 8000: org.codehaus.cargo.module.DefaultJarArchive: Class org.codehaus.cargo.module.DefaultJarArchive added
ERROR: 7002: org.codehaus.cargo.container.Container: Method 'public void addDeployable(org.codehaus.cargo.container.deployable.Deployable)' has been removed
INFO: 7011: org.codehaus.cargo.ant.ConfigurationElement: Method 'public void addConfiguredEar(org.codehaus.cargo.ant.EARElement)' has been added
INFO: 4000: org.codehaus.cargo.container.jetty.JettyStandaloneConfiguration: Added org.codehaus.cargo.container.configuration.StandaloneConfiguration to the set of implemented interfaces
ERROR: 7005: org.codehaus.cargo.container.Container: Parameter 1 of 'public void setConfiguration(org.codehaus.cargo.container.Configuration)' has changed its type to org.codehaus.cargo.container.configuration.Configuration
ERROR: 7006: org.codehaus.cargo.ant.ConfigurationElement: Return type of method 'public org.codehaus.cargo.container.Configuration createConfiguration(org.codehaus.cargo.container.Container)' has been changed to org.codehaus.cargo.container.configuration.Configuration
ERROR: 4001: org.codehaus.cargo.container.jetty.JettyStandaloneConfiguration: Removed org.codehaus.cargo.container.Configuration from the set of implemented interfaces
INFO: 7003: org.codehaus.cargo.container.spi.AbstractConfiguration: Method 'public void configure()' has been removed, but an inherited definition exists.
ERROR: 5001: org.codehaus.cargo.container.deployable.EAR: Removed org.codehaus.cargo.util.MonitoredObject from the list of superclasses
INFO: 5000: org.codehaus.cargo.container.deployable.EAR: Added org.codehaus.cargo.util.monitor.MonitoredObject to the list of superclasses
ERROR: 7012: org.codehaus.cargo.container.Container: Method 'public java.io.File getOutput()' has been added to an interface
INFO: 7010: org.codehaus.cargo.container.spi.AbstractContainer: Accessibility of method 'protected java.io.File getOutput()' has been increased from protected to public
INFO: 6000: org.codehaus.cargo.container.property.GeneralPropertySet: Added public field JVMARGS
</pre>
</code>
</div>
<p>Even though we're using JIRA with an Iteration-Driven Development strategy (IDD) it was still a very interesting exercise to verify that we had not missed any issue by running Clirr on the source code. 
In addition, it provides a more detailed view of what exactly has changed in term of API which our JIRA report does not provide.</p>
<p>The next step would be to use it to fail our build whenever someone introduces a public API break. It would be quite easy for us because we've cleanly separated non-public API from public APIs by using internal
packages (see the <a href="http://jakarta.apache.org/cactus/participating/apis.html">Cactus API design rule</a> to see what it means). Of course sometimes, you want to voluntariy add a breaking change. That's legitimate
 but it has to be controlled. The strategy would be to have the build fail and then if the change is voluntary to exclude it from Clirr.</p>
<p>Well done Lars!</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-04-30T15:22:11+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001036_id_love_reusable_ant_tasks.html">
<title>I&apos;d love reusable Ant tasks</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001036_id_love_reusable_ant_tasks.html</link>
<description><![CDATA[<p>Where is Ant heading in the future? I would be very interested to learn more about this. I've been using Ant for several years now and I've always been a happy user. However these days, I'm no longer using much the XML scripting side of Ant but I'm using heavily the Ant Java API; what I'm interested in are the Java Ant tasks.</p>
<p>I think this is really where the value of Ant is. All those years of implementing the base building block for a portable OS Java API have created a very useful Task set. I think every Java application that needs to do copying, deleting a directory, spawning a Java application, etc should use these tasks. There's no point in reinventing the wheel!</p>
<p>For example, you may think that deleting a directory is simple. But it's not so easy. Have a look at the Delete Ant task source code. You'll find portion of code like this one:</p>
<pre><div class="code"><pre><span class="blockcomment">/**
 * Accommodate Windows bug encountered in both Sun and IBM JDKs.
 * Others possible. If the delete does not work, call System.gc(),
 * wait a little and try again.
 */</span>
<span class="category1">private</span> <span class="category1">boolean</span> delete(<span class="category2">File</span> f) {
     <span class="category1">if</span> (!f.delete()) {
          <span class="category1">if</span> (Os.isFamily("<span class="quote">windows</span>")) {
               System.gc();
           }
          <span class="category1">try</span> {
               Thread.sleep(DELETE_RETRY_SLEEP_MILLIS);
           } <span class="category1">catch</span> (<span class="category2">InterruptedException</span> ex) {
               <span class="linecomment">// Ignore Exception</span>
           }
          <span class="category1">if</span> (!f.delete()) {
               <span class="category1">if</span> (deleteOnExit) {
                    <span class="category1">int</span> level = quiet ? Project.MSG_VERBOSE : Project.MSG_INFO;
                    log("<span class="quote">Failed to delete </span>" + f + "<span class="quote">, calling deleteOnExit.</span>"
                        + "<span class="quote"> This attempts to delete the file when the ant jvm</span>"
                        + "<span class="quote"> has exited and might not succeed.</span>"
                        , level);
                    f.deleteOnExit();
                    <span class="category1">return</span> <span class="category1">true</span>;
                }
               <span class="category1">return</span> <span class="category1">false</span>;
           }
      }
     <span class="category1">return</span> <span class="category1">true</span>;
}</pre></div>
</pre>
<p>Would you have thought about this? Probably not and you would have been right not to as this only happens in some rare occasions. But when one of your users reports it, it's going to be darn difficult to identify and fix. Personally I'd rather depend on a stable and well tested library rather than recode it myself.</p>
<p>The problem is that the Ant tasks are a bit too much linked to the execution engine (the XML scripting engine). For example reusing an Ant tasks requires you to create a Project object. This in turn drags loggers, the Ant classloader (in some cases) and possibly other objects. I know it's possible to use Ant from Java (I've been doing it for a long time now) but I'd love it be even easier to do so.</p>
<p>Instead of writing:</p>
<pre><div class="code"><pre>Project project = <span class="category1">new</span> Project();
Expander expander = project.createTask("<span class="quote">unzip</span>"); 
expander.setSrc(<span class="category1">new</span> <span class="category2">File</span>(zipfile)); 
expander.setDest(<span class="category1">new</span> <span class="category2">File</span>(destdir)); 
expander.execute();</pre></div>
</pre>
<p>I'd like to be able to write:</p>
<pre><div class="code"><pre>Expand expand = <span class="category1">new</span> Expand();
expand.setSrc(<span class="category1">new</span> <span class="category2">File</span>(zipfile));
expand.setDest(<span class="category1">new</span> <span class="category2">File</span>(destdir));
expand.setLogger(myLogger);
expand.execute();</pre></div>
</pre>
<p>I don't want to see the get/setLocation, get/setTaskName(), get/setDescription() and in general all methods from Task.java.</p>
<p>What I'd love to see is Ant moving in the direction of providing completely reusable Tasks that have 0% dependencies on the Ant engine. This means that loggers, classloaders would be passed to the Ant task by the program who uses it.</p>
<p>I'd like to see Ant provide 2 distributable jars: one containing the XML scripting engine only and one containing all the pure java beans Ant tasks that can be reused in any Java application.</p>
<p>I'd like to see Ant separate into 2 subprojects: one for the XML scripting engine (let's call it engine) and one for the Ant tasks (let's call it tasks). The reason for the 2 projects is to ensure there's no dependency in the direction tasks->engine.</p>
<p>I'd like to see Maven2 use those completely reusable Ant tasks instead of recreating them (this is a wish I'm addressing to both projects, not just Ant! :-)).</p>
<p>I'd like to see those Ant tasks being a JSR and incorporated in a future version of the JDK, thus providing a higher level API that the best classes from the JDK.</p>
<p>Is that where Ant is heading today?</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-04-07T16:29:11+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001007_increasing_open_source_project_contributions.html">
<title>Increasing open source project contributions</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001007_increasing_open_source_project_contributions.html</link>
<description><![CDATA[<p>I may be dense but I've just realized today that there is a potentially simple way to increase participation to an open source project. That's always been one of the questions on my mind: how do I make my open source projects more successful? For me 
a successful open source project is one which has a rich developer community. How do I make this possible? There are of course several ideas to make this happen but the one that dawned on me this morning is that
the project has to reduce its complexity (by making it more modular for example).</p>
<p>Indeed, the barrier to participation is often due to the fact that a user who wants to participate will need to understand the whole design, how the different classes are entangled, what effect a change here will have on the rest of the project, etc.
Thus, if we make the project more modular a contributor who wants to participate will only need to understand the design of a given 'module'.</p>
<p>A 'module' would need to have some good-to-have characteristics:<p>
<ul>
<li>Very loose coupling with other modules</li>
<li>Clearly defined and *published* interfaces. There should be some documentation on the project's web site explaining them and a tutorial showing how to implement new modules (or swapping a module implementation by another one) for example.</li>
<li>Separate builds so that it's easy to build only the module (this can be alleviated if the master build is easy to use (i.e. no property tweaking necessary, it just builds - As it's the case with good Maven builds... ;-))</li>
<li>Separate documentation on the web site, so that the website itself is modular and the complexity of each module is hidden in that module's web site. Thus the top level web site would be quite simple only listing what the project does as a whole and listing the different modules</li>
</ul>
<p>Interestingly one way to implement the 'very loose coupling with other modules' characteristic is by using a Service Architecture. This can be done for example by using the Dependency Injection pattern and/or using a lightweight container - PicoContainer, Spring, etc).</p>
<p>This is probably obvious stuff but I've just realized that it's not only good design practices but that it'll also help open source projects attract more contributions. Of course that leads to another topic which is when to accept contributions and how to maintain them in the long run but that would be another discussion...</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-03-11T11:21:57+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001006_distributed_build.html">
<title>Distributed build</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001006_distributed_build.html</link>
<description><![CDATA[<p>Continuing with my current build-mania, I'd like to propose the idea of a distributed build architecture. I'd love to
see my favorite continuous integration tools (CruiseControl, DamageControl and Continuum in the future) support this notion in the future (I know they're thinking about it already!).</p>
<h3>So what is the need for a distributed build?</h3>
<p>I can see several use cases:</p>
<ul>
<li>building on several JDKs</li>
<li>building on different OS platforms</li>
<li>building with different environment setups (for example building with different application servers, different browsers, different databases, etc) to validate that a product integrates well with various environment setups</li>
<li>delegating the build load on several machines when the build starts to take too long (of course, the first solution should be to try to lighten your build as much as possible)</li>
</ul>
<h3>A proposed architecture</h3>
<p><b>Disclaimer</b>: this only ONE potential solution. There are lots of other solution probably even more valid than this one. Please feel free to add your ideas as comments to this post.</p>
<a href="http://www.codehaus.org/~vmassol/blog/distributed_build_archi.jpg"><img src="http://www.codehaus.org/~vmassol/blog/distributed_build_archi_small.jpg"/></a>
<p>It could work as follows:</p>
<ol>
<li>The central build machine (aka the build orchestrator) decides to start a build. The orchestrator can be one existing continuous integration tool like CruiseControl, DamageControl, etc.
They can trigger a build on anything they want: time-based, change-based, manual, continuously, etc. The orchestrator sends a build request to the space. The request contains all the information 
about the requested build (e.g. JDK to run on, OS to run on, App.Sever/DB/etc to run on)</li>
<li>The space holds all requests. It chould be a good idea to provide a browser to see pending requests (preferably using a simple HTTP browser so that people who wish to contribute can see what type of builds are required). 
In any case it's important that the space be transactional (Note: I'm not sure about the word "transactional". What I mean is that a request cannot be read by several build agents at the same time)</li>
<li>Build agents listen on space build requests objects that match their capabilities. Using Jini/Javaspace would be nice here because (among other things) agents would be able to easily listen to requests with Jini attributes (OS, JDK, etc). Once they read a request they start a local build and publish the result to the space as a Result object</li>
<li>The build orchestrator listens to Results object, and generate result reports, aggregating all results. Build results could contain anything required: result of the build, logs, generated artifacts, etc. The orchestrator gets the data from the Result object and perform usual build operations (publishing, build result notification).</li>
</ol>
<p>Of course there would be several details to sort out, like should we send 2 Requests object for each build need so that we can compare the results and only accept the result if they match, etc.</p>
<h3>Conclusion</h3>
<p>I think this type of distributed build could be especially interesting for open source projects in order to build an active community around a project. This would be yet another way in which people can contribute 
to an open source project: by lending some of their machine CPU to perform continuous integration builds of this project. This usually makes sense as open source projects may be low on hardware resources and lending 
some would help. Of course it also bring its challenge of security issues that would also need to be implemented...</p>
<p>Would you like such a distributed build system? I personally prefer this architecture over one where the orchestrator directly sends build requests to build agents as I find it more scalable and more flexible.</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-03-11T09:28:42+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/001003_maven_book_and_maven_quiz.html">
<title>Maven book and Maven Quiz</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/001003_maven_book_and_maven_quiz.html</link>
<description><![CDATA[<p>Here it is, it's now official! I'm currently writing a Maven book for O'Reilly with <a href="http://www.oreillynet.com/pub/au/1738">Tim O'Brien</a>. I can't say much more at this point in time except that it'll be available sometime this summer.</p>
<p>I've also written <a href="http://www.javablackbelt.com/jbb/WikiPage.do?action=view&page=Maven">2 Maven quizzes</a> for <a href="http://www.javablackbelt.com/">JavaBlackBelt.com</a>. If you want to see if your Maven knowledge is up to the par, go and take them! And let me know your comments. If you register on the site you can even propose new questions!</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-03-10T09:21:54+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000976_getting_svnsshprivate_key_to_work_in_intellij_ideaeclipse.html">
<title>Getting svn+ssh/private key to work in IntelliJ IDEA/Eclipse</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000976_getting_svnsshprivate_key_to_work_in_intellij_ideaeclipse.html</link>
<description><![CDATA[<p>At last, I was able to get the svn+ssh protocol to work from both IntelliJ IDEA (Irida #3200) and Eclipse (3.1M4), using a private key! Here's how to do it:<p>
<h3>For IntelliJ IDEA</h3>
<ul>
<li>Start by downloading the latest <code>javasvn.jar
</code>
 from the <a href="http://www.tmate.org/svn/">TMate JavaSVN web site</a>. You need version 0.8.0 or later (I've used 0.8.0). The reason is that there is a new property named <code>javasvn.ssh2.key
</code>
 that has been added as a hack for getting the Subclipse plugin for Eclipse to work with svn+ssh... Drop the jar in <code>[IDEAHOME]/plugins/svn4idea/lib
</code>
, replacing the existing jar of the same name there.</li>
<li>Modify the <code>[IDEAHOME]/bin/idea.bat
</code>
 file to add the <code>javasvn.ssh2.key
</code>
 system property: <code>IF "%IDEA_JVM_ARGS%" == "" set IDEA_JVM_ARGS= [...] -Djavasvn.ssh2.key=/path/to/your/private/key
</code>
.</li>
<li>Make sure you use  an openSSH-compatible private key. The Putty format is NOT supported by JSch. If you have a Putty private key, use Puttygen to export it as an OpenSSH key.</li>
<li>Make you sure you specify a valid username in the IDEA subversion setting, leaving the password field blank.</li>
</ul>
<h3>For Eclipse</h3>
<ul>
<li>Install <a href="http://subclipse.tigris.org/">Subclipse</a> using the provided Eclipse update site</li>
<li>Install the <a href="http://www.tmate.org/svn/subclipse.html">JavaSVN Subclipse Extension</a>, also using the provided Eclipse update site</li>
<li>Modify the way you start Eclipse as mentioned on the <a href="http://www.tmate.org/svn/subclipse.html">JavaSVN Subclipse Extension</a> web page</li>
<li>Go the SVN Repository Exploring perspective, right-click on your SVN Repository, click on "properties" and make sure you enter a valid username (leave the password blank).
</ul>
<p>Enjoy! That should please all the Codehaus hausmates... :-)</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-02-06T14:23:56+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000963_javapolis_2004_maven_presentation.html">
<title>Javapolis 2004 Maven presentation</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000963_javapolis_2004_maven_presentation.html</link>
<description><![CDATA[<p>Javapolis/Javalobby have just made by <a href="http://blogs.codehaus.org/people/vmassol/archives/000931_javapolis_2004.html">Maven presentation</a> available in <a href="http://www.javalobby.org/av/javapolis/27/massol-maven">audio+slides</a> format.</p>
<p>Enjoy! (I hope...;-))</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-01-26T07:59:56+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000953_binary_dependency_builds.html">
<title>Binary Dependency Builds</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000953_binary_dependency_builds.html</link>
<description><![CDATA[<h3>The concept</h3>
<p>The typical local builds that developers run on their machines work by building the subproject they're working on but also all the dependent subprojects it requires. Usually, as building all dependent subprojects takes
a lot of time, the developer infrequently checks-out other project sources and build them on demand. His focus is on his subproject that he's making modifications to (and rightly so!). This strategy has the following 
drawbacks:</p>
<ul>
<li>Setting up the build on a new fresh machine is complex and takes time. Indeed you have to check out all the top level project sources and build all projecets one by one until you reach the subproject you're concerned with.</li>
<li>It doesn't scale too well. Your local build starts taking tens of minutes which does not encourage running it that often. And if you do, you don't rebuild all the subprojects even though there are probably lots of changes 
that have been made by other coworkers. Thus, you're increasing the possibility of an integration break (breaking your other coworkers when they integrate your changes).</li>
<li>When someone from another team inadverently breaks your project's build, you'll have to switch context (i.e. stop what you're doing) and help out to restore the master build. If this happens unfrequently, it's probably fine 
and even positive (as it increases team collaboration ;-)). However when it happens frequently (which is bound to happen as the team grows), you'll start suffering from it...</li>
</ul>
<p>Because of all these problems, I have been using a different approach on my current project for the past 2 years. This was mostly motivated by the fact that the project is a big project (close to 100 developers) and we were hitting the issues 
mentioned above. I have called this strategy "Binary Dependencies Build". If you're interested this is an approach I have presented both at <a href="http://www.pivolis.com/pdf/Enterprise_Builds_V1.0.pdf">TSSS2004</a> and 
at <a href="http://www.codehaus.org/~vmassol/blog/Maven%201.0%20-%2020041216.ppt">Javapolis 2004</a>.</p>
<p>Here is how it works (click on image for a larger picture):</p>
<a href="http://www.codehaus.org/~vmassol/blog/binary-dependencies-build.jpg"><img src="http://www.codehaus.org/~vmassol/blog/binary-dependencies-build-small.jpg"/></a>
<p>Imagine that you have a "trading" subproject that depends on 2 other subprojects ("partners" and "referenceData"). The idea is that your local build will NOT build them from sources but instead will download their <b>latest
version that work</b> from a remote artifact repository (a location where the result of the subproject build is located). In order to accelerate even further the build, the versions downloaded are stored locally. In our example, 
the latest "partners" jar is already available locally and is thus not downloaded but the "referenceData" one is not. It is downloaded and then stored locally. The "trading" subproject is built using these binary dependencies.</p>
<p>This is all fine but there is a burning question: How do I do continuous integration with such a system? Won't the binary dependencies be old versions when I get them? The solution to this is to have a continuous build
server that continuously build subprojects and puts their artifacts in the remote repository. Note that there are put in the repository <b>only</b> if their build passes with no errors. This ensure that there are always fresh
versions available and that they are as "good" as they can get.</p>
<h3>Doing it with Maven</h3>
<p>The good news is that this feature is built in Maven. Maven implements this support of artifact repositories (local and remote) and it supports the process of automatic download of artifacts not available in the local repository. 
Usually Maven will verify first in the local repository if the artifact's version exists and if so will use it. However, if an artifact's version contains the "SNAPSHOT" keyword, Maven will always check if there's is a more uptodate
artifact in the remote repository. This allows implementing easily the strategy defined above.</p>
<h3>Conclusion</h3>
<p>We've been very happy with this solution so far. I think there are 2 key points in making this work:</p>
<ul>
<li>A good build that provides assurance that the binary artifacts are working. Indeed we've experienced that our subproject build was not always good enough to qualify how "good" was a jar artifact. This was usually caused by the 
non-existence of automated functional tests which meant that even though the build was passing the jar was not working when executed on the developer's machine. The solution is of course to include integration/functional tests in
the build (at least the master CI build). </li>
<li>A quick master build. It's important that it generates fresh jar artifacts as quickly as possible so that CI can happen as often as possible.</li>
</ul>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2005-01-12T10:44:45+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000939_top_buildbreakers.html">
<title>Top build-breakers</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000939_top_buildbreakers.html</link>
<description><![CDATA[<p>Here's a non-ordered list of the main problems causing build-breaks that we had found on the current project I'm working on (Note that this list is now a year old and that we have fixed some of them - Unfortunately the majority still remains...). I've added some possible ideas on how to fix them.</p>

<ol>

<li><b>Build takes too long to execute (and thus it is executed less often)</b></li>
  <ul>
    <li>Fix the build by having more subprojects with binary dependencies and/or streamline the build to
        ensure that only important build steps are run. Optimize it (f.e. offer different goals/targets: one
        for a clean build and another one that does not perform a clean).</li>
  </ul>

<li><b>Local build not executed</b></li>
  <ul>
    <li>Build coaches to increase build awareness. Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>.</li>
  </ul>

<li><b>Public API breakage in dependent project without warning</b></li>
  <ul>
    <li>Better team communication. Set up a deprecation policy. Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>.</li>
  </ul>

<li><b>Not enough continuous commits (all packed up at end of iteration)</b></li>
  <ul>
    <li>Team meetings to explain more the importance of continuous integration. Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>. The idea is that if you keep your changes to yourself and accumulate them, whenever you'll want to commit them, 
        the unbreakable build will likely reject your changes as they will break some other part of the code. Thus you'll need to spend several days to talk to other developers to not only fix your code but also fix theirs. Normally
        after doing this several times, you should understand that it is in your best interest to commit frequently.</li>
  </ul>

<li><b>No functional/integration automated tests (f.e. no local verification of ejb-jar deployments)</b></li>
  <ul>
    <li>Automated functional tests! Build a suite slowly over time, improving it at each iteration. And maintain it! Decide on a good data handling strategy (this is usually the main issue). Ensure that your data strategy keeps everyone in sync WRT DB data.</li>
  </ul>

<li><b>Commit problems (Forget to commit some files, Pb due to SCM tool - Starteam: new directory do not appear in Starteam view!)</b></li>
  <ul>
    <li>Coaching + change the SCM tool! Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>.</li>
  </ul>

<li><b>Devs “building” with IDE but forgetting to use the automated build</b></li>
  <ul>
    <li>Coaching. Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>.</li>
  </ul>

<li><b>Checkstyle errors failing the build</b></li>
  <ul>
    <li>Coaching. More team meeting to decide what checkstyle errors we want to fail the build or not. Get a strong team buy-in. Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>.</li>
  </ul>

<li><b>Failing unit tests</b></li>
  <ul>
    <li>It probably means that the unit tests are actually integration tests depending on database data. Ensure that unit tests are quick and fast and independent of the environment. Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>.</li>
  </ul>

<li><b>[Maven] project.xml not up to date and missing dependency</b></li>
  <ul>
    <li>SCM diff emails on check-ins (team by team) in order for everyone to have the knowledge of what's happening. Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>.</li>
  </ul>

<li><b>Database data modifications (voluntarily or involuntarily) leading to test breakage</b></li>
  <ul>
    <li>Better data strategy. See for example the <a href="http://blogs.codehaus.org/people/vmassol/archives/think_tank.html#000605_database_testing_strategy_in_build">databse testing strategy in build</a> post.</li>
  </ul>

<li><b>Continuous build not cleaned between different runs</b></li>
  <ul>
    <li>Fix it. Perform a clean build from time to time.</li>
  </ul>

<li><b>Local SCM update not done before local build (in order to get the latest files)</b></li>
  <ul>
    <li>SCM diff emails on check-ins (team by team) in order for everyone to have the knowledge of what's happening. So you'll know better when to update our local workspace. Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>.</li>
  </ul>

<li><b>Environment differences in local build vs central build</b></li>
  <ul>
    <li>Work continuously towards making the developer's environment as close as possible as the integration environment. Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>. This allows executing the build on the server and thus it runs in the same environment as the continuous build.</li>
  </ul>

<li><b>No local deployments done before commits (f.e. no EJB deployments)</b></li>
  <ul>
    <li>Coaching (in order to ensure that developers do perform deployments on their machines before check-in) + add some checks in the build to automate the verification (they can be f.e. some hand-picked functional tests).</li>
  </ul>

<li><b>Checkstyle errors hidden in tons of warnings</b></li>
  <ul>
    <li>Fix it. Newest versions of Checkstyle allow filtering on severity.</li>
  </ul>

<li><b>Non-atomic commits and central build starting with in-flight commits</b></li>
  <ul>
    <li>Use a scheme a la CruiseControl (wait for some inactivity time on the SCM before trigging a build). Or change the SCM (for subversion for example). Note: We have tried to use CC with StarTeam but even though the infrastructure team increased CPU + RAM, StarTeam falls when it is polled by 3 or 4 CC builds in parallel... (Solution: Dump ST or ask Borland to come and tune the parameters). Complementary idea: <a href="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">"unbreakable builds"</a>. This forces "atomic" commits.</li>
  </ul>

<li><b>[Distributed development] rsync issues: sometimes jars are corrupted or lost</b></li>
  <ul>
    <li>Fix the rsync process (Note: this is now no longer happening I believe)</li>
  </ul>

<li><b>[Distributed development] VPN instability making it difficult to SCM-update</b></li>
  <ul>
    <li>Fixed mostly. However usage of Starteam is still extremely slow making hard to SCM-update from remote. Solutions: Use a less bandwidth/responsetime consuming SCM (f.e. Subversion), increase bandwidth (but the issue is mostly with response time which cannot be changed), or use a replication mechanism (I don't like this as I believe it introduces its own issues - I really much prefer everyone working directly on the same repository, especially as I know it works (I've done it in the past using CVS with a team of 30 developers and it was working fine).</li>
  </ul>

<li><b>Errors when executing the application</b></li>
  <ul>
    <li>This is because there are no automated functional tests. Automate them!</li>
  </ul>

</ol>

]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-12-31T12:28:21+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html">
<title>Unbreakable builds</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000937_unbreakable_builds.html</link>
<description><![CDATA[<h3>Let's create Unbreakable Builds</h3>
<p>Out of my last two development projects, one had a strong sense of quality and excellence in general and continuous build failures were the exceptions (about 3-4 per week for a 30 developers team) 
and the other one was quite the opposite and everyone was surprised when the continuous build was passing (there were about 5 build breaks a day as an average for a 40 developers team). 
I'm sure this is also pretty common to other projects. Obviously the best is to build (pun intended) 
a build awareness in the team. However, you'll need strong evangelists for this to happen who may not always be available and other circumstances may make this difficult.</p>
<p>A thought struck me about a year back: what if we were able to prevent the continuous build from failing <b>by design</b>. There's a French saying that goes something like 
"it's better to cure than to heal". I think this is definitely a good idea to apply to continuous build failures. Why not make a continuous build system that cannot fail. At that time
I thought it was a nice idea (I had meant to blog about it but I forgot) but I could not see very well how it could work. Now a year after, I really think it's a nice idea and I'd like
to explore it.</p>
<h3>The architecture</h3>
<p>A potential basic architecture is shown in figure 1 (click to get a larger picture).</p>
<a href="http://www.codehaus.org/~vmassol/blog/unbreakable builds - architecture.jpg"><img src="http://www.codehaus.org/~vmassol/blog/unbreakable builds - architecture - small.jpg"/></a>
<p>The general principle is to catch the commit data before they get committed to the SCM, to perform a build and to perform the actual commit only if the build is successful.
Here are the detailed steps:</p>
<ol>
<li>The developer performs a commit using his favorite SCM client tool. Note that it is best if the tool is able to perform the commit asynchronously so that the developer
can continue working on something else.</li>
<li>The committed data are intercepted using a pre-commit hook script (all modern SCM support this). This script is in charge of doing 2 things:
  <ul>
    <li>Finding out the list of projects to be built. Indeed, say that the commit contains 5 files belonging to 2 different projects. We need to rebuild these 2 projects. The algorithm
        for finding out the projects to which belong the changes sources can be as simple as a mapping between the file paths (which contains the project name) and the project name.</li>
    <li>Creating a build job and pushing it on a queue. The reason for the queue is that building all the projects on the machine that hosts the SCM is not going to be scalable. We want the
    SCM to be as responsive as before. Hence the queue.</li>
  </ul>
</li>
<li>We need build machines to perform the actual build. They could be dedicated build machines that build continuously the build jobs. There could also be developer workstation. The concept is
to have one or several build kicker applications installed on those machines. The "continuous build kicker" will continuously get a job from the build job queue and build it, whereas the 
"idle build kicker" will only pick a job to build when the machine is idle (hey, look around you and see how many machines are unused because the people are either on holiday, sick, in a meeting, etc. That's a lot of power).
</li>
<li>The build kickers start by updating their workspace to have the latest files for the projects associated with the changes files. Then they try to "merge" the changes files in their workspace (note:
this may be the tricky part to implement unless the SCM offers a way in the pre-commit hook to get the full file - I need to explore this). If they cannot succeed they stop with an error message that flows back to the user. This 
can happen if someone else has been working on the same source and their change has made it to the SCM before ours has. If the merge succeeds, the build kicker starts the build. The build hasa to be
relatively quick so you should not build all the projects. I suggest building the modified projects and the ones that directly depend on them so that an API break can be detected (more on that
below)</li>
<li>When the build is finished (or if an error occurs), the build kicker sends the result back to the pre-commit hook (using a RPC mechanism for example).</li>
<li>If the result if positive, the pre-commit script either performs the real commit to the SCM</li>
<li>The resulting message is returned to the user. In case of error the user would see for example the build console log</li>
</ol>
<h3>Advantages</h3>
<p>Here are the following advantages of such a system:</p>
<ul>
<li>Does not break other developers upon a build failure. All developers can work uninterrupted even though they can still work on HEAD in a continuous integration fashion</li>
<li>Lowers the effort required to get a CI system working thus it helps teams adopt CI</li>
<li>Prevents breakage of APIs. Indeed in step 4 above, we've mentioned that a good strategy is for the build to build not only the projects that have changes but also all projects that directly uses those 
projects (one level). This will allow detecting unwanted API breakages.</li>
<li>Increase self-confidence when committing which (I hope) will make it easier to get developers to commit continuously<li>
<li>Allows continuing working on one's own machine (instead of having to wait for the current build to free the CPU which is being used at 100%!). You know get your own PBS (Personal Build Server)</li>
<li>Forces atomic commits!</li>
</ul>
<h3>Questions/Issues</h3>
<p>I'm sure you're now burning with tons of remarks/questions showing why it wouldn't work :-) Here's what I've currently thought about. If you have any opinion or other questions, I'd love to hear them.</p>
<h5>Q: What happens if someone else also commits a change to the same file?</h5>
<p>It works in the same way as usual. The build kicker will try to "merge" the changes after having done a workspace update and if it cannot, the user will get an error explaining that the merge failed. The 
user will then need to perform an update on his local machine and resolve the conflict.</p>
<h5>Q: Imagine I perform a commit and I start working on a new feature. Then my commit is rejected because of a failure. How do I fix this without loosing my current changes?</h5>
<p>Answer 1: This is actually relatively similar to what you're currently doing. Imagine you're committing something. Then you start working on something new and the continuous build tells you 2 hours later
that your change has broken something. The difference is that your changes have been committed so you can easily create a new workspace and fix it there. We could do the same here by having the
pre-commit hook actually make your changes available through a URL (sent in the commit answer) as a patch so that it is easy for you to apply it to a fresh new checkout.</p>
<p>Answer 2: You wait till the build is finished on the server. You can perform other activities like documenting, reading, thinking, designing, writing new classes, new tests, etc. Basically you work on
stuff that do not conflict with the past changes. Actually this is probably what you're currently doing when your build is running as it is eating all your CPU...</p>
<h5>Q: Doesn't it take too long to build?</h5>
<p>You need to ensure your build is taking as little time as possible. I think 5-10 minutes should be ok. The best way to achieve this is probably to use binary dependencies instead of rebuilding dependent
projects (a la Maven), except maybe direct dependencies. You'll still need a continuous build running continuously to produce fresh binary dependencies. I guess it's also best to use an SCM client that
can do asynchronous commits in order to let you continue working while the commit is in progress.</p>
<h5>Q: What if I want to modify an API but I wish that each projects modifies its own files?</h5>
<p>Several options:</p>
<ul>
<li>You could go through a deprecation cycle.</li>
<li>You could be doing the refactoring on one machine only (not always possible)</li>
<li>You could also plan it. Anyway an API breakage has to be planned with communications. Thus you could say: on that day, at such hour
we're going to be committing this break and we have 1 day to fix all our dependent projects. When this happens you can turn off this "unbreakable build" feature for the day.</li>
</ul>
<p>The interesting point here is that you *want* the API breakage to be detected as the default instead of the opposite.</p>
<h3>Conclusion</h3>
<p>It seems to me this would be particularly useful on big projects with lots of developers. It should also be useful to introduce continuous integration on an existing project as it lowers the
discipline required by everyone. Obviously this is just an idea that I haven't tested yet. I'm very keen to see this in action. If any of you has any experience please share it. I'm planning to spend some
time trying to implement it. If you're interested to help out, let me know too.</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-12-29T15:18:02+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000931_javapolis_2004.html">
<title>Javapolis 2004</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000931_javapolis_2004.html</link>
<description><![CDATA[<p><a href="http://www.javapolis.com">Javapolis 2004</a> was a real success. In the past, I've attended 
TheServerSide symposiums and Javapolis was very similar: packed with technical sessions and full of well-known speakers.
The setup was excellent (kudos to Stephan and his team) and the rooms were amazing. Look at the size of this screen!</p>
<a href="http://www.codehaus.org/~vmassol/blog/vincent@javapolis2004.jpg"><img src="http://www.codehaus.org/~vmassol/blog/vincent@javapolis2004.jpg" width="400" height="265"/></a><br/><small>Picture shot by (c) Philippe Kernevez</small>

<p>There were the usual suspects (Mike Cannon-Brookes, Rod Johnson, Cedric Beust, Gavin King, etc) but as it was happening close to France, it was
cool to see that almost all my <a href="http://ossgtp.xwiki.com/">OSSGTP</a> fellows were also there (Ludovic Dubost, Henry Story, Benjamin Mestrallet, Francois Le Droff, Didier Girard).
In addition it was good to see Jerome Lacoste and Philippe Kernevez there.</p>
<p>I've had the pleasure of giving 2 sessions:</p>
<ul>
<li><a href="http://www.codehaus.org/~vmassol/blog/Maven 1.0 - 20041216.ppt">Maven</a>: A session explaining why you would use Maven and trying to show Maven from all its different angles. 
I hope I have been successful in sharing my enthousiasm for Maven. The room was packed (I'd say around 400 to 600 people). Before starting with my session I've asked how many people are already
using Maven and I've counted about 20 (but at that time the room was only half-packed), so I'd say it was about 3-5%. My second was "How many are planning to use Maven" and I got a resounding
3/4th of the people raising their hand. That shows that Maven is still in it's early adoption phase and that it has some great potential.</li>
<li><a href="http://www.codehaus.org/~vmassol/blog/AOSD - Agile Offshore - 20041217.ppt">AOSD: Agile Offshore</a>: The last day was for the business track presentations and I gave one which is my return of experience
of 3 years of doing offshore development using an agile methodology.</li>
</ul>
<p>It seems the tracks were all recorded and you should be able to see them live very soon (I'm really excited to see that for myself as I've missed a few sessions during the first days of the conference
and looking at oneself in Video is a good way to improve one's presentation skills... ;-)).</p>
<p>See you next year at Javapolis 2005!</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-12-18T15:55:06+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000905_6_jira_issuesmells.html">
<title>6 JIRA issue-smells</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000905_6_jira_issuesmells.html</link>
<description><![CDATA[<p>When working using a Time-boxing approach with JIRA there are some typical 
issue-smells that I have noticed appear frequently. In order to perform good 
deliveries it is important to fight them.</p>
<ul>
<li><b>Issue smell 1: Too many unscheduled issues</b>. This means 
that new issues are not assigned to iterations, i.e. that they are not planned 
to be fixed.
</li>
<li><b>Issue smell 2: Open issue from past iterations</b>. Any 
issue that is left from a previous iteration has to be rescheduled so that 
everyone knows when it is planned to be fixed. If some portion of the issue has 
been done, I've found that it is usually best to split the task into 2,
so that the work done in the iteration it was scheduled is clearly shown in the
release notes for that iteration and the unfinished part can be scheduled in
a future iteration.
</li>
<li><b>Issue smell 3: No iterations in changelog view</b>. This means that
past iterations that are finished have not been JIRA-released. The good
thing about releasing an iteration is that it forces to solve the unfinished
issues (see Issue smell 2). In addition it allows cleaning the roadmap view
that becomes less cluttered by all past issues and which gives a clear view
of what's left to be done. Last it provides an important feeling of achievement.
</li>
<li><b>Issue smell 4: Issue types in issue description</b>. I have often
noticed that some JIRA projects were using some description conventions for
some issue types. For example, using <code>XXX - Code review
</code>
 for a code review
issue on the XXX feature. In that case, a real JIRA issue type should be 
created. The reason is that by defining a proper JIRA issue type, it is now
possible to perform operations on this new issue type: it will appear
properly in the release notes under its own category, it can be searched for,
etc.
</li>
<li><b>Issue smell 5: Issue status are not in sync with the reality</b>. This
is often a big problem (especially with distributed teams) as people usually
rely on JIRA to provide an exact view of the progress. If issues are found
not in sync, there's a tendency to not "trust" JIRA anymore, which in turn
leads to less using it and loosing visibility. One good strategy is to 
do <b>Issue Driven Development (IDD)</b>. It goes like this: When a task is done and
just before the code is checked in, ensure that the corresponding JIRA issue
is marked as Resolved/Closed. If there's no issue, create one (unless the
modification is a really minor one that the user should really not be
concerned with). Then check in the code mentioning the issue number in the
checkin comment (that allows for example using the <a href="http://confluence.atlassian.com/display/JIRAEXT/JIRA+Subversion+plugin">JIRA CVS/Subversion plugins</a>).
Note: If you're using CVS/Subversion you could write a quick pre-commit hook that verifies
that each comment has a reference to a JIRA issue.
</li>
<li><b>Issue smell 6: Lots of resolved (but not closed) issues</b>. Most projects
I have seen do not use a Resolved state. However, people often mark the issue
as resolved but not closed and the issue stays in this state for ages without
anyone doing anything about it. So either remember to directly close issues
or if you're using JIRA 3 create a custom workflow that do not have a Resolved 
state (if you're not using the resolved state of course!).
</li>
</ul>
<p>Let me know if you have found other important issue-smells when using JIRA!</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-12-04T11:11:18+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000893_using_cargo_04_for_functional_testing.html">
<title>Using Cargo 0.4 for functional testing</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000893_using_cargo_04_for_functional_testing.html</link>
<description><![CDATA[<h3>Introduction</h3>
<p>
Automated tests are good. Automated Functional tests are even better as they are the proof that your application is working. In addition, with automated functional tests you can also automate your delivery process. However, writing automated functional tests is hard. The main reason it is hard is because you need to control your execution environment (database, application server, etc).
</p>
<p><a href="http://cargo.codehaus.org">Cargo</a> is a framework that you can use to automatically install, configure and execute J2EE containers. Thus it allows you to control your execution environment (for the J2EE container at least) and permits completely automated functional tests for J2EE applications.</p>
<h3>Example</h3>
<p>Let's walk through an example. Imagine we wish to start up Tomcat 4.1.31 before such test runs. Here's what we could write:</p>
<pre><div class="code"><pre><span class="category1">public</span> <span class="category1">class</span> MyTest <span class="category1">extends</span> TestCase
{
     <span class="category1">private</span> <span class="category2">Container</span> container;
 
     <span class="category1">protected</span> <span class="category1">void</span> setUp()
     {
          <span class="linecomment">// (1) Optional step to install the container from a URL pointing to its distribution</span>
          Installer installer = <span class="category1">new</span> ZipURLInstaller(
              "<span class="quote">http://www.apache.org/dist/jakarta/tomcat-4/v4.1.31/bin/jakarta-tomcat-4.1.31.zip</span>");
          installer.install();
  
          <span class="linecomment">// (2) Create the Cargo Container instance wrapping our physical container</span>
          container = <span class="category1">new</span> Tomcat4xContainer();
          container.setHomeDir(installer.getHomeDir());
      }
 
     <span class="category1">public</span> <span class="category1">void</span> testSomething()
     {
          <span class="linecomment">// (3) Statically deploy some WAR</span>
          Deployable war = container.getDeployableFactory().createWAR("<span class="quote">src/testinput/my.war</span>");
          container.addDeployable(war);
  
          <span class="linecomment">// (4) Start the container</span>
          container.start();
  
          <span class="linecomment">// (5) Perform any test you wish here</span>
          [...]
      }
 
     <span class="category1">protected</span> <span class="category1">void</span> tearDown()
     {
          <span class="linecomment">// (6) Stop the container</span>
          container.stop();
      }
}</pre></div>
</pre>
<p>Step 1 is optional. You can also rely on the container being already installed on the test machine if you wish. However, it's nice to completely automated the testing and assume nothing (or very little - We still need an OS and a JDK on the machine). In this example we're fetching the Tomcat 4.1.31 installation from the web. We could fetch it from our intranet or from a location on the machine or from our SCM.</p>
<p>In Step 2, we have not told Cargo what container Configuration to use. Thus Cargo will use a default Configuration and it will configure it so that your container will execute in a temporary directory that it will create in your OS system tmp dir. If you wish to control this you can use:</p>
<pre><div class="code"><pre>Configuration configuration = <span class="category1">new</span> CatalinaStandaloneConfiguration(container, "<span class="quote">target/tomcat4x</span>");
configuration.setProperty(ServletPropertySet.PORT, "<span class="quote">8080</span>");
container.setConfiguration(configuration);</pre></div>
</pre>
<p>in step 3, we create a Cargo wrapper around a physical WAR and we add it to our container so that it is deployed when the container starts.</p>
<p>We then start the container (step 4), perform any testing we wish (step 5) and ensure the container is always stopped at the end of our test (step 6).</p>
<p>If we wish to start and stop the container only once during our whole test suite we can use a standard JUnit TestSetup.</p>
<h3>Conclusion</h3>
<p>This is just a short introduction to Cargo to demonstrate how easy it is to start/stop a container. The API is of course richer. Also, we're showing here how to use Cargo for functional testing of J2EE application but Cargo is also meant to be used by any application that requires a container to be up and running. It could also be used by IDE plugin writers, etc.</p>
<p>For more information on Cargo, please see the <a href="http://cargo.codehaus.org">Cargo website</a> and join us on the <a href="http://cargo.codehaus.org/mail-lists.html">Cargo mailing lists</a>. You'll be warmyl welcomed! :-)</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-11-17T19:43:41+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000877_logifier.html">
<title>Logifier</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000877_logifier.html</link>
<description><![CDATA[<p>How often are you trying to debug some Java application to find that you can't continue your debugging easily because the code is entering into some third-party library?</p>
<p>At that point, either the library is open sourced and you can rush to download the source, modify the code to add some <code>System.out.println
</code>
 and spend 3-4 hours to find out how to rebuild  the project.... or it's not open source and then there's much that you can do except trying to find out the reason with your sheer brain power!</p>
<p>How good would it be if there was an application (let's call it a Logifier) at which you could throw a jar and it would return a new aspectified jar  on which it would have weaved some Logging aspect that you could configure!</p>
<p>This would allow us to realize the full power of aspects: an external Java application that was not built with logging can now be converted to log things for us...</p>
<p>So who wants to be the first to build such a handy application? :-) Does it  already exist?</p>
<p><b>Update 7/11/04</b>: I've just remembered reading about  <a href="http://www.theserverside.com/news/thread.tss?thread_id=29757">AntFlow</a> on TSS. That would be an excellent way of implement this. Imagine a hot folder called "logifier" and any jar you drop in there is automatically logified using an AspectJ/AspectWerkz/etc Ant task and a common logging aspect such as <a href="http://tinyurl.com/6byw8">this one</a>! Now that would be cool. It could be a good coding exercise for the next <a href=http://blogs.codehaus.org/people/vmassol/archives/000874_ossgtp_4th_meeting.html"">OSSGTP</a>.]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-11-05T15:50:50+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000874_ossgtp_4th_meeting.html">
<title>OSSGTP - 4th meeting</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000874_ossgtp_4th_meeting.html</link>
<description><![CDATA[<p><a href="http://ossgtp.xwiki.com">OSSGTP</a> stands for Open Source Software Get-Together Paris. It's a montly meeting set up in Paris gathering Open Source actors (mostly Java OSS ATM). We've had our 4th meeting on the  21st of October 2004.</p>
<p>This time we had several newcomers: Henry Story, Patrick Chanezon and Luis  Arias. Patrick did a presentation on <a href="https://rome.dev.java.net/">Rome</a>, his pet project and Henry tried to explain to us <a href="http://bblfish.net/work/atom-owl/2004-08-12/blogexample.html">how to combine ATOM and FOAF</a> and what <a href="http://semtext.org/atom/atom.html">ATOM/OWL</a> was...  Not a simple task is you're not versed in ontologies... ;-)</p>
<p>Here are Henry and Luis:</p>
<img src="http://ossgtp.xwiki.com/xwiki/bin/download/Main/PhotosDeVincent/49KI0021.jpg"/>
<p>Here's Patrick:</p>
<img src="http://ossgtp.xwiki.com/xwiki/bin/download/Main/PhotosDeVincent/49KH0019.jpg"/>
<p>And some of us trying to figure out what OWL, FOAF and ontologies are:</p>
<img src="http://ossgtp.xwiki.com/xwiki/bin/download/Main/PhotosDeVincent/49KI0022.jpg"/>
<p>Then, as usual we went for dinner together and had a very nice evening disucssing a bit about everything...</p>
<p>A few other pictures are available <a href="http://ossgtp.xwiki.com/xwiki/bin/view/Main/PhotosDeVincent">here</a>.</p>
<p>Next time we'll try some coding or review session as <a href="http://ossgtp.xwiki.com/xwiki/bin/view/Main/21Octobre2004PropositionsSujets">suggested on our Wiki</a>. If you're in Paris, feel free to join us.</p>.]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-11-04T11:07:50+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000869_omea_pro_review.html">
<title>Omea Pro review</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000869_omea_pro_review.html</link>
<description><![CDATA[<h3>Analysis</h3>
<p>I've just tried <a href="http://www.jetbrains.com/omea/">Omea Pro</a> (build 353) and I've got to say it's very promising! It's hard to explain what Omea is... I think it can be viewed as two things:</p>
<ol>
<li>A search tool that aggregates all data from your computer (all files types including PDF, Word, Excel but excluding PPT, Outlook emails, ICQ/Miranda conversations, Outlook Tasks, Outlook contacts, RSS/Atom feeds, Newsgroups, etc)</li>
<li>A productivity tool that you can use instead of all your different tools for managing all your incoming data (mails, files, feeds, newsgroups)</li>
</ol>
<p>After using it for 2 days, here are the pros I have found:</p>
<ul>
<li>The searching feature is excellent. I find it much better than Google Desktop or Lookout in term of relevance, breadth of search and organizing the results</li>
</ul>
<p>Here are the thing to improve I have noticed (please remember that it is beta software):</p>
<ul>
<li>It's resource hungry: after a few hours of using it, it easily reaches 300MB and more. It's also a little bit slow.</li>
<li>It has not reached a level where it is at least as good as the tools it gets its data sources from. For example, it's not as good as Outlook, it's not as good as a dedicated RSS feed reader, etc. I believe it will never be able to be as good as those specialized tools. JetBrains has recognized this by trying to make it bi-directional data-wise (your changes from Omea are reflected in Outlook and vice-versa). However this doesn't work for Newsgroups and RSS feeds for example.</li></ul>
<p>Now the real questions is how should I use it? As a search tool? But then it's a bit heavy to be left sitting idle on my desktop. And it's too heavy to start it on demand (it currently takes 30 seconds to 1 minute to start - I'm sure it'll be improved in the future). As a productivity tool? Possibly, although it's missing some of the features I use in my specialized tools. For example:</p>
<ul>
<li>I use the "Reading pane - Right" view of Outlook which gives me 3 vertical panes next to each other. Once you get used to this, it's hard to go back. I'm told this will be in the next version of Omea Pro.</li>
<li>I use NewzCrawler which let me see only feeds which have unread items in them, feed by feed (I don't read all blogs at the same speed).</li>
</ul>
<h3>Conclusion</h3>
<p>I currently don't think I'll be able to keep Omea open all the time as it's too heavy to have both Outlook and Omea open at the same time. 
Also, I don't like the fact that I have to stop using my favorite Feed reader (NewzCrawler). I really do not want to manage 2 feed tools and tell each one which feeds I have already read. 
Of course, I could simply not use the feed feature of Omea. However I feel that using Omea just for searching makes it loose a lot of its attraction.
If I just want a search tool, I can use Goodle Desktop or Lookout (even if they are less powerful they are probably good enough for my daily needs).</p>
<p>I think the real challenge for JetBrains is to make the tool <b>good enough</b> in each domain (mail handling, feed reading, etc) so that it can be used instead of the dedicated tool. That means that you would use Omea for day to day
activities and the specialized tool from time to time only when you need one of the power feature. Of course, this is a huge challenge for JetBrains and honestly I am not sure if it is achievable.</p>
<p>Anyway, the tools is promising and intriguing enough so that I'll follow the different builds to see how it evolves.</p>
<p>If you're using it, please drop me a note on how you use it and how you handle it vs the specialized tools. Thanks</p>
<p><b>Update 04/11/2004</b>: I've just tried build 358 and I am extremely pleased to report that the memory consumption has decreased a lot: whereas it wasa before 300MB for me, it's now 140MB. Good job!</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-11-01T10:34:10+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000842_writing_a_jira_3_plugin.html">
<title>Writing a JIRA 3 plugin</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000842_writing_a_jira_3_plugin.html</link>
<description><![CDATA[<p>On one of my projects at work we have moved to JIRA 3 (beta). We moved to benefit from the new custom 
workflow feature. Unfortunately it was missing one key feature we wanted: the ability to send notification
emails on custom workflow transitions (I've just been told by Atlassian that this is a feature they're
currently working on). To remedy this and thanks to Atlassian's support, I've decided to delve
in the JIRA Java API and develop a workflow function plugin to implement email sending.</p>
<p>I have to say that JIRA 3's extensibility is great! JIRA can almost be seen as a full fledge foundation 
for developing project tracking applications, in the same spirit as Eclipse is a full fledge
foundation for developing java applications (RCP). Both Eclipse and JIRA come with a default 
application using this API to demonstrate their power (the IDE for Eclipse, the issue tracker for JIRA).
Note that the 
new plugin system in JIRA has several similiarities with the Eclipse plugin architecture. Of course, I'm sure
JIRA still has a lot of ground to cover to expose a plugin API covering all domains of issue tracking (i.e.
allowing to replace all parts of the JIRA issue tracker) but it's going in the right direction.</p>

<p>Here is a short tutorial on how to develop a workflow function plugin. Note that you should
also check the <a href="http://confluence.atlassian.com/display/JIRA/A+Brief+Guide+To+JIRA+Plugins">Atlassian tutorial on how to develop plugins</a>.</p>

<p>The source code is available <a href="http://www.codehaus.org/~vmassol/blog/jira-sendmail/jira-sendmail-function-src-1.2.zip">here</a> and
the plugin jar is available <a href="http://www.codehaus.org/~vmassol/blog/jira-sendmail/sendmail-jira-function-plugin-1.2.jar">here</a>.</p>

<h3>Setting up the project</h3>
<p>Here's the directory structure I have chosen for my plugin. Please also note that I have used Maven to
perform the build (extremely easy to setup as Atlassian is also using Maven and they have all their jars
in a Maven remote repository on <a href="http://repository.atlassian.com">http://repository.atlassian.com</a>).</p>
<img src="http://www.codehaus.org/~vmassol/blog/jira-sendmail/sendmail-jira-directories.jpg"/>
<p>A plugin is composed of several files (it is packaged as a JAR at runtime):</p>
<ul>
<li>A plugin descriptor (<code>atlassian-plugin.xml
</code>
)</li>
<li>Java source files</li>
<li>Velocity templates for the plugin UI (the <code>*.vm
</code>
 files)</li>
</ul>
<p>The <code>project.properties
</code>
 file simply adds the Atlassian Maven remote repo to the list of repos
searched by Maven to download dependencies:
<div class="code"><pre>maven.repo.remote=http:<span class="linecomment">//repository.atlassian.com,http://www.ibiblio.org/maven</span></span></pre></div>

<p>The <code>project.xml
</code>
 contains the required JIRA dependencies and the definition of resources to 
include in the generated jar. Here's an extract:</p>
<xmp><code>[...]
  <dependencies>
    <dependency>
      <groupId>atlassian-jira</groupId>
      <artifactId>atlassian-jira</artifactId>
      <version>3.0-beta</version>
    </dependency>
    <dependency>
      <groupId>osworkflow</groupId>
      <artifactId>osworkflow</artifactId>
      <version>17Aug2004</version>
    </dependency>
    <dependency>
      <groupId>propertyset</groupId>
      <artifactId>propertyset</artifactId>
      <version>1.3</version>
    </dependency>
[...]
  <build>
    <sourceDirectory>src/main</sourceDirectory>

    <resources>
      <resource>
        <directory>src/etc</directory>
        <includes>
          <include>atlassian-plugin.xml</include>
        </includes>
      </resource>
      <resource>
        <directory>src/etc/templates</directory>
        <includes>
          <include>**/*.vm</include>
        </includes>
      </resource>
    </resources>

  </build>

</code>
</xmp>
<p>Generating the plugin jar is as simple as typing <code>maven jar
</code>
.</p>

<h3>The Worflow Function plugin extension point</h3>

<p>Here's what the <code>atlassian-plugin.xml
</code>
 plugin descriptor contains:</p>
<xmp><code><atlassian-plugin key="sendmail.jira.plugin.workflow.sendmail" name="SendMail Plugin">
  <plugin-info>
    <description>Plugin for sending emails on custom workflow transitions.</description>
    <version>1.0</version>
    <application-version min="3.0" max="3.0"/>
    <vendor name="Vincent Massol" url="http://blogs.codehaus.org/people/vmassol/"/>
  </plugin-info>

  <workflow-function key="sendmail-function" name="Send Notification Mail" class="sendmail.jira.plugin.workflow.SendMailFunctionPluginFactory">
    <description>Sends a notification email.</description>
    <function-class>sendmail.jira.plugin.workflow.SendMailFunction</function-class>
    <orderable>false</orderable>
    <unique>true</unique>
    <deletable>true</deletable>
    <weight>900</weight>
    <default>false</default>
    <resource type="velocity" name="view" location="sendmail-function-view.vm"/>
    <resource type="velocity" name="input-parameters" location="sendmail-function-input-params.vm"/>
  </workflow-function>

</atlassian-plugin>

</code>
</xmp>

<p>What you have to understand:</p>
<ul>
<li>A plugin is made of 2 java classes: a plugin factory class (<code>SendMailFunctionPluginFactory
</code>
) which is in charge of setting up all
that is necessary for the execution of the plugin feature, and the plugin execution class (<code>SendMailFunction
</code>
).</li>
<li>A workflow plugin is expected to bundle 2 velocity template files: one for asking the user to input some data required by the plugin execution (this is
the <code>input-parametes
</code>
 velocity template, and one for displaying what the function will do. The later is visible if you click on a workflow
transition in JIRA and then on the post-functions tab.</li>
</ul>

<h3>The Java API</h3>
<h4>The Plugin Factory class</h4>
<p>Without further ado, here's the skeleton for the <code>SendMailFunctionPluginFactory
</code>
 class:</p>
<pre><div class="code"><pre><span class="category1">public</span> <span class="category1">class</span> SendMailFunctionPluginFactory <span class="category1">extends</span> AbstractWorkflowPluginFactory
    <span class="category1">implements</span> WorkflowPluginFunctionFactory
{
     <span class="category1">public</span> SendMailFunctionPluginFactory(FieldManager fieldManager)
     {
      }
 
     <span class="category1">protected</span> <span class="category1">void</span> getVelocityParamsForInput(Map velocityParams)
     {
      }
 
     <span class="category1">protected</span> <span class="category1">void</span> getVelocityParamsForView(Map velocityParams, 
          AbstractDescriptor descriptor)
     {
      }
 
     <span class="category1">public</span> Map getDescriptorParams(Map conditionParams)
     {
      }
}</pre></div>
</pre>
<p>Those 4 methods are called by JIRA itself:</p>
<ul>
<li>The constructor is called when you click on the "add" button to add the function to your list of post-functions. The <code>FieldManager
</code>
 instance can be 
used to get issue fields meta-data (it does not contain any issue data as there's no issue associated with the function yet - This will only happen when the function is
triggered by an issue transition).</li>
<li>The <code>getVelocityParamsForInput()
</code>
 method can be used to store some properties in the <code>velocityParams
</code>
 map. These properties will then be
accessible from the <code>"input-parameters"
</code>
 Velocity template.</li>
<li>The <code>getVelocityParamsForView()
</code>
 method can be used to store some properties in the <code>velocityParams
</code>
 map. These properties will then be
accessible from the <code>"view"
</code>
 Velocity template. In addition the <code>descriptor
</code>
 parameter provides access to the data entered by the user in the input phase (these data are stored in the workflow data structure itself).</li>
<li>The <code>getDescriptorParams()
</code>
 method is the bridge between the data contained in the Velocity context and the data in the Workflow context. More precisely
you put in there the code to extract the data that have been entered by the user in the Velocity context and you put the data in the workflow descriptor context. This descriptor
context is the second parameter that is available in your <code>getVelocityParamsForView()
</code>
 method.</li>
</ul>
<p>Here's a look at the <code>input-parameters
</code>
 velocity template:</p>
<xmp><code><tr bgcolor=ffffff>
    <td align="right" valign="top" bgcolor="fffff0">
        <span class="label">Group emails:</span>
    </td>
    <td bgcolor="ffffff" nowrap>
        <input type="text" name="groupEmails" value=""/>
        <br><font size="1">Comma-separated list of JIRA groups to send emails to.</font>
    </td>
</tr>
<tr bgcolor=ffffff>
    <td align="right" valign="top" bgcolor="fffff0">
        <span class="label">Individual emails:</span>
    </td>
    <td bgcolor="ffffff" nowrap>
        <input type="text" name="individualEmails" value=""/>
        <br><font size="1">Comma-separated list of JIRA users to send emails to.</font>
    </td>
</tr>

</code>
</xmp>
<p>As you can see, the variables <code>groupEmails
</code>
 and <code>individualEmails
</code>
 will hold the data entered by the user.</p>


<h4>The Plugin Function class</h4>
<p>Here's the code that implements the plugin feature (in our case the sending of the notification email):</p>

<pre><div class="code"><pre><span class="category1">public</span> <span class="category1">class</span> SendMailFunction <span class="category1">implements</span> FunctionProvider
{
     <span class="category1">public</span> <span class="category1">void</span> execute(Map transientVars, Map args, PropertySet ps)
     {
      }
}</pre></div>
</pre>
<p>The <code>execute()
</code>
 method is called by JIRA when an issue transition happens.</p>
<p>The parameters have the following meanings:</p>
<ul>
<li>The <code>transientVars
</code>
 parameter holds useful data such as the issue that was modified. You get a referernce to the issue by calling <code>transientVars.get("issue");
</code>
. It contains
also other piece of data such as the <code>comment
</code>
 entered by the user, etc.</li>
<li>The <code>args
</code>
 parameter holds all the data stored in the workflow context (aka the workflow descriptor). This is the data you have stored yourself in the <code>getDescriptorParams()
</code>

method explained above.</li>
<li>I'm not too sure what the <code>ps
</code>
 parameter is used for. I think it holds data related to the workflow steps but this needs to be confirmed. Anyway, you shouldn't need it in most cases.</li>
</ul>

<h3>Deploying and executing the plugin</h3>

<p>Deployment is a simple as dropping the plugin jar in <code>[jira install dir]/atlassian-jira/WEB-INF/lib
</code>
 for example (it may be possible to drop it in other classloaders but I haven't tried).</p>
<p>In the following image we can see how JIRA has automatically discovered our plugin and extracted information from the plugin descriptor to make them available at the right extension point in JIRA:</p>
<img src="http://www.codehaus.org/~vmassol/blog/jira-sendmail/sendmail-jira-newfunction.jpg"/>
<p>Here is the page (using the <code>input-parameters
</code>
 Velocity template) to let the user enter data for our function:</p>
<img src="http://www.codehaus.org/~vmassol/blog/jira-sendmail/sendmail-jira-inputparams.jpg"/>
<p>Here is how our function is displayed (using the <code>view
</code>
 Velocity template):</p>
<img src="http://www.codehaus.org/~vmassol/blog/jira-sendmail/sendmail-jira-view.jpg"/>

<p>I hope you got a good feel of what's possible to do with the JIRA API.</p>

<p>Note: For those wondering, I am not affiliated with Atlassian at all. I simply happen to like their tools (JIRA, Confluence) and I like the spirit of their team.</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-09-30T10:22:48+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000789_cci_container_client_interface.html">
<title>CCI: Container Client Interface</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000789_cci_container_client_interface.html</link>
<description><![CDATA[<p><b>11/08/2004 update</b>: The project is about to start on Codehaus and is now named Cargo.</p>
<p><b>Note</b>: There is also an <a href="http://www.theserverside.com/blogs/showblog.tss?id=CCI">article</a> and a <a href="http://www.theserverside.com/discussions/thread.tss?thread_id=27404">discussion thread</a> on TheServerSide about this inititative</p>
<p>Here's a new idea for an open source project I'd like to start. It could be called CCI (Container Client Interface). It would aim 
at providing a simple Java API to start/stop/configure/deploy Java containers (In the first version the goal would be to support J2EE containers).
This Java API could then be used by lots of other projects (Ant tasks, Maven plugins, IDE plugins, Cactus, etc).</p>
<p>The inspiration comes from the <a href="http://jakarta.apache.org/cactus">Cactus</a> project, which already provides an extensive
API to perform such tasks. The goal is to refactor the Cactus Ant API, remove anything related to Cactus and make it a standalone
project called CCI</p>
<p>Here's an integraton test showing what the API could look like:</p>
<pre><div class="code"><pre>    <span class="category1">public</span> <span class="category1">void</span> testStartWithOneWarDeployed()
    {
         <span class="category2">Container</span> container = <span class="category1">new</span> Resin3xContainer();
         container.setHomeDir("<span class="quote">/apps/resin-3.0.8</span>");
         container.setPort(8080);
         container.setInstallDir(<span class="category1">new</span> <span class="category2">File</span>("<span class="quote">target/resin3x</span>"));
 
         WAR war = <span class="category1">new</span> WAR("<span class="quote">src/testinput/simple.war</span>");
         <span class="category2">URL</span> pingURL = <span class="category1">new</span> <span class="category2">URL</span>("<span class="quote">http://localhost:</span>" + PORT + "<span class="quote">/simple/index.html</span>"); 
         war.setPingURL(pingURL);
 
         container.addDeployable(war);
 
         ContainerRunner runner = <span class="category1">new</span> DefaultContainerRunner(container);
 
         runner.start();
         assertTrue("<span class="quote">Container not started yet!</span>", <span class="category1">new</span> HttpUtils().ping(pingURL));
         
         runner.stop();        
         assertFalse("<span class="quote">Container not stopped yet!</span>", <span class="category1">new</span> HttpUtils().ping(pingURL));
     }</pre></div>
</pre>
<p>As you can see there are several main Objects/Interfaces:</p>
<ul>
<li><b>Container</b>: This the main object that provides the API to start/stop the container.</li>
<li><b>WAR</b>: A WAR archive to be deployed in the container. Inherits from <b>Deployable</b>. There will be other types later on (WAR, EAR, RAR)</li>
<li><b>ContainerRunner</b>: Athough a container can be <code>start
</code>
ed without a container runner, the container runner provides advanced
feature like starting the container in a different thread, verifying if the container is already started, waiting till the container is started,
waiting till the container is stopped, etc.</li>
</ul>
<p>Note that the ping URLs are the URLs that will be pinged by the ContainerRunner object to ensure the container has finished
starting. Thus, after <code>container.start()
</code>
 has finished executing you can be sure the container is started
and the archives have been deployed and are ready for servicing requests. A better solution in the future will be to use
JMX to ensure the container has finished starting. However, all containers do not yet support this feature.</p>
<p>A shorthand code version to start Resin 3.0.8 could look like:</p>
<pre><div class="code"><pre>        <span class="category2">Container</span> container = <span class="category1">new</span> Resin3xContainer("<span class="quote">/apps/resin-3.0.8</span>");
        container.setInstallDir("<span class="quote">target/resin3x</span>");
        container.addDeployable(<span class="category1">new</span> WAR("<span class="quote">src/testinput/simple.war</span>"));
        container.start();</pre></div>
</pre>
<p>This is just a taste of what he CCI API could look like. Let me know what you think!</p>
]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-07-24T20:56:34+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000783_maven_abbot_plugin_10_released.html">
<title>[Maven] Abbot plugin 1.0 released</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000783_maven_abbot_plugin_10_released.html</link>
<description><![CDATA[<p>I've just released a Maven plugin for <a href="http://abbot.sourceforge.net/">Abbot</a>. Abbot is a Swing unit testing framework. The <a href="http://maven.apache.org/reference/plugins/abbot/">Maven Abbot plugin</a> supports the following:</p>
<ul>
<li>Ability to start the Abbot Costello editor using either jars defined in the POM or the jars from an already installed WebStart application.</li>
<li>Ability to execute Abbot XML scripts through the Ant &lt;junit&gt; task</li>
<li>Ability to execute Abbot XML scripts on an already installed WebStart application (end-to-end functional testing)</li>
</ul>
<p>You can download the Maven Abbot plugin <a href="http://maven.apache.org/reference/plugins/abbot/downloads.html">here</a>.</p>
<p>Please note that this plugin was written jointly with Christian Blavier whom I thank very much for his help!</p>
]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-07-11T20:10:25+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000782_my_current_oss_todo_list.html">
<title>My current OSS todo list...</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000782_my_current_oss_todo_list.html</link>
<description><![CDATA[<p>Here is a list of OSS stuff I'm considering doing in some short future (note that I'm not planning to do all of them ;-))</p>
<ul>
<li><a href="http://blogs.codehaus.org/people/vmassol/archives/000520_cactus_v2_architecture_proposal.html">Cactus v2</a></li>
<li>Create a container OSS project that offers a Java API to configure containers, start/stop them and deploy archives. The idea is to extract the existing API from the Cactus project (which already supports these tasks for several containers: Tomcat, Orion, Resin, JBoss, WebLogic, etc). Cactus would be refactored to use this new project. This API would be nice for any other project that requires a container.</li>
<li>Implement a Maven plugin for <a href="http://clirr.sourceforge.net">Clirr</a>. Note: I have almost finished a first version.</li>
<li>Implement suppor for history reports in Maven. For example it would be nice to get Clover reports over time, Checkstyle reports over time, Dashboard reports over time, etc. I'm currently thinking to consider reports as project artifacts and store them in the Maven repository. A history plugin could provide support to save/load them. Another solution (probably better) involves using a lightweight database (e.g. Hypersonic SQL) and considering this database file as the artifact.</li>
<li>Continue adding support for RSS feeds to the existing Maven plugins, wherever it makes sense. The final idea is to offer RSS feeds to all project information so that project members can have their own Personal Project Information Portal (PPIP). Among the tools I like/use, RSS feeds are already available for: JIRA, Confluence/TWiki, FishEye, Maven Checkstyle plugin, Maven Changes plugin. Next in my list are: Maven Clover report, Maven Dashboard plugin, Maven PMD plugin, Maven XDoc plugin (for downloads).</li>
</ul>
<p>In addition to this, I plan to continue fixing Cactus v1 bugs (albeit slowly...) and continue fixing bugs and adding enhancements to the Maven plugins I have started (changes, clover, abbot, etc).</p>
<p>If you're working on the same topics or if you're interested in contributing, please let me know!</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-07-11T19:46:26+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000774_best_practice_source_code_communication.html">
<title>Best practice: Source code communication</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000774_best_practice_source_code_communication.html</link>
<description><![CDATA[<h3>The need for source code communication</h3>

<p>When you're working in a team one of the most important aspect of development is to know what others are working on, what they are modifying. 
Indeed, in development everything is tied one way or another:
<ul>
<li>if someone changes the database schema, I need to know</li>
<li>if someone updates a build dependency to a newer version of a framework I need to know</li>
<li>if someone changes a public API, I need to know</li>
<li>if someone starts working on the same set of source files as mine, I need to know</li>
<li>if someone modifies a best practice document, I need to know so that I can have a look at what's new</li>
</ul>
<p>Basically, I need to know whenever some source file on which my work depend on is modified.</p>
<p>Of course, I could rely on verbal communications: "Hey Joe, I'm gonna work on this files for the coming 4 hours". Sure, that'll work too. However
it's not a scalable solution (Imagine a project divided in 5 teams of 10 persons each) and it works only if the participants are acutely aware
of what each developer is depending upon which is near impossible. In addition, if the team is distributed it becomes virtually impossible to
communicate such small events in any efficient manner. There has to be a better solution.</p>
<p>And there is! There are actually 2 solutions I know of, one better than the other.</p>

<h3>Solution 1: Diff emails on SCM commit</h3>

<p>This first solution involves setting up a server-side hook in your SCM. Most SCMs supports executing a script upon source check-in/commit.
Just write a script that sends an email containing the diffs between what the user is committing and what already exists in the repository. The 
reason for the diff is that we're interested by what's different and not by the full content. This is what is done in most open source projects.
Here's an example:</p>

<img src="http://www.codehaus.org/~vmassol/blog/fisheye/commit-diff-email.jpg"/>

<p>The problems with this solution are:</p>
<ul>
<li>It's not very easy to let the developer choose finely what files/directories they want to monitor</li>
<li>The diff information is received in your email, among all you other emails. It's good to reserve emails for actions that you have to perform.
Here we're not talking about actions but about information. I believe a better channel for information is for example a RSS feed. It still comes
to you but it does not clutter your other emails.</li>
</ul>

<h3>Solution 2: RSS feeds</h3>

<p>This solution involves setting up some kind of server that will generate RSS feeds for the developers. Implementing this could be quite involved.
Fortunately there's a tool called <a href="http://www.cenqua.com/fisheye/">FishEye</a> from Cenqua that does exactly this. It's an improved viewcvs. Most importantly it allows developers
to generate RSS feeds on any resource (any directories and any files). Here's what the HTML view looks like:</p>

<img src="http://www.codehaus.org/~vmassol/blog/fisheye/fisheye-dashboard.jpg"/>

<p>Then here's what you get in your favorite feed reader (I'm using Newz Crawler here):</p>

<img src="http://www.codehaus.org/~vmassol/blog/fisheye/fisheye-rssfeed.jpg"/>

<p>Clicking on the diff link generates the following view:</p>

<img src="http://www.codehaus.org/~vmassol/blog/fisheye/fisheye-rssdiff.jpg"/>

<p>Note: Please note that FishEye currently only supports CVS. Other SCMs like Subversion are planned in the future.</p>

<h3>Conclusion</h3>

<p>It is relatively simple and very effective to set up a way to notify developers about changes happening in the repository. I would even
suggest that not doing so is a "communication anti-pattern". In order for it to be the most effective possible, developers should not be "spammed"
by tons and tons of diff information. Thus to prevent this spamming you should consider 2 options: using RSS feeds instead of emails and allowing
developers to choose their feeds. There are obviously some feeds that should be more "mandatory" than others. For example, the one notifiying of 
database schema change, the one notifying of build changes and the one notifying of public API changes. It's important, as always, that there is
a champion in the team, explaining to others the benefit of these feeds and how they should be best used. Otherwise the power of them may exist
but it won't be harnessed.</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-07-03T12:06:57+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000716_back_from_tsss_2004.html">
<title>Back from TSSS 2004</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000716_back_from_tsss_2004.html</link>
<description><![CDATA[<p>TheServerSide Symposium 2004 was a great event. With about 500 people, most of them being actors of the enterprise java world. All the usual suspects were there and it was cool to meet again people I had seen last year in Boston.</p>
<p>Here are the slides of my 2 presentations:</p>
<ul>
<li><a href="http://www.pivolis.com/pdf/Enterprise_Builds_V1.0.pdf">Enterprise builds</a> (<a href="http://www.theserverside.com/symposium/sessionAbstracts.html#abstractsMassol1">description</a>).
</li>
<li><a href="http://www.pivolis.com/pdf/Distributed_Agile_V1.0.pdf">Case study: Distributed Agile Development</a> (<a href="http://www.theserverside.com/symposium/sessionAbstracts.html#abstractsMassol2">description</a>).
</li>
</ul>
<p><b>Update</b>: All TSSS slides are available <a href="http://wiki.theserverside.com/symposium/display/SLIDES/Home">here</a> (registered attendees only).</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-05-13T20:04:03+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000688_what_is_pattern_testing.html">
<title>What is Pattern Testing?</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000688_what_is_pattern_testing.html</link>
<description><![CDATA[<p>Pattern Testing is the concept of automatically verifying the good application of architectural/design patterns in code. It uses AOP to perform this feat.</p>
<p>Pattern Testing is a concept I started researching in 2002 on a big project at work. At that time, I was already using Checkstyle and PMD to
perform verification of rules. However, I was finding them limited in several ways:</p>
<ul>
<li>They were mostly focusing on syntactic rules, whereas I was mostly interested in semantic rule checking. Checkstyle has improved a lot in this
area over the past 2 years. However, even though there are some semantic rules , they are usually simple and not very "business"-oriented. Note that 
this is not to diminish Checkstyle which I find great and use on all projects.</li>
<li>They were focusing on applying rules on a single file (using AST trees), whereas I was interested in applying rules that span several files (this
is necessary for architectural/design checks). As a consequence writing pattern tests using Checkstyle is difficult.</li>
<li>They were limited to static checks. I wanted to be able to say "ensure that no method call is passed a null parameter", "ensure that there are no more than 10 calls to the database per user case", etc</li>
</ul>
<p>The result was the <a href="http://patterntesting.sf.net">Pattern Testing</a> project on SourceForge. It's implemented using AspectJ.
It contains some pre-made Pattern Tests but more importantly it lets you write your own. There is Maven plugin that makes it easy to
run any Pattern Test on any mavenized project.</p>
<p>The possibilities of Pattern Testing are <a href="http://patterntesting.sourceforge.net/whatis.html">endless</a>.

<p>Here's an example of a rule that says that we do not want to instantiate business classes (i.e. a class that extends BasicBC). That's because
they are instantiated by factories/service managers:</p>

<pre><div class="code"><pre><span class="category1">public</span> aspect NoNewOnFrmwkClassesPatternTest
{
     declare error: 
       call(com.some.package.BasicBC+.new(..)) : 
         "<span class="quote">Do not instantiate a business class directly</span>";
}      </pre></div>
</pre>

<p>I used Pattern Tests for some time on that project at work and then I changed job. I was still interested in the concept but with my other open source involvements I didn't take the
time to work on it as much as I wanted. Thus it became a bit abandoned. However, these past weeks, I have found renewed interest in the concept
for several reasons:</p>
<ul>
<li>I was contacted by Matt Smith who was interested in taking the lead of the Pattern Testing project. I gladly handed this over to him and he's now the one driving the project</li>
<li>I have started working on <a href="http://blogs.codehaus.org/people/vmassol/archives/000520_cactus_v2_architecture_proposal.html">Cactus2</a> and as the Cactus 2
architecture is based on AOP, the concepts are very close.</li>
<li>On the new project I am on, we're starting to want to automate our architectural/design checks and some teams have initiated using Pattern Tests.</li>
</ul>
<p>Are any of you using Pattern Testing too?</p>

]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-04-21T08:50:53+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000680_offshore_project_manager_interview.html">
<title>Offshore Project Manager interview</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000680_offshore_project_manager_interview.html</link>
<description><![CDATA[<p>I've given an <a href="http://www.apec.fr/recruteurs/actualites/semaine_metier/jsp/RecrutDeliaSemaineMetier.jsp?APECHTML_TEXT_NAME_22222222222222222_attribute=1_ARTICLE_13764">interview</a> (in French) for the French magazine Courrier-Cadre about the new job of "Offshore Project Manager" that I am currently doing for <a href="http://www.pivolis.com">Pivolis</a> on the BNP Paribas project.</p>
<p>It explains what are the day to day activities of an offshore coach (I prefer the word "coach" to "project manager") on a collaborative development project.</p>
<p>Here are some tasks that we (we are 2 from Pivolis working on this project) are performing on this project:</p>
<ul>
<li>Administrative tasks:</li>
  <ul>
  <li>Arrival/Departure administration (Secure id card, Star Team account, Test Director account, Wiki account, JIRA account, mailing lists accounts, etc)</li>
  <li>Organisation of visits (identification of requirement, dates, agendas, people) in both directions Paris -> India and India -> Paris</li>
  <li>Visa handling</li>
  </ul>
<li>Infrastructure for offshore:</li>
  <ul>
  <li>Infrastructure coordination + improvements (monitor performances, tune tools) - with help from BNPP infrastructure team</li>
  </ul>
<li>Organisational:</li>
  <ul> 
  <li>Weekly technical and management conf calls with all the teams (dev team + integration team + tech team) + follow up from these calls</li>
  <li>Management meetings</li>
  <li>Technical meetings</li>
  <li>Weekly management level meetings</li>
  <li>Communication facilitators + related communication improvements</li>
  <li>Offshore team selection (senior members mostly)</li>
  <li>Offshore training programme improvements</li>
  <li>Crisis escalation investigation + handling</li>
  <li>Accompany Paris members during offshore visits, ensuring success of agenda/visit.</li>
  </ul>
<li>Methodology/Expertise:</li>
  <ul>
  <li>Definition of Project Development Process with “offshore in mind” and continous improvements (short iterations introduction, usage of JIRA for detailed plannings, acceptance criteria for code delivery, wiki setup, etc).</li>
  <li>Work inside the teams to implement the collaborative development process.</li>
  <li>Quality suggestions + improvements (testing strategy / build improvements for quality + measurements)</li>
  <li>Expertise on build (Maven) + continuous build + testing + collaborative development processes</li>
  <li>Architecture + implementation of regression platform</li>
  </ul>
</ul>

]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-04-17T13:28:13+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000679_theserverside_symposium_2004.html">
<title>TheServerSide Symposium 2004</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000679_theserverside_symposium_2004.html</link>
<description><![CDATA[<p>I'll be going to the <a href="http://www.theserverside.com/symposium/">TheServerSide Symposium 2004</a> again this year. I have the privilege to present the following 2 sessions:</p>
<ul>
<li><a href="http://www.theserverside.com/symposium/sessionAbstracts.html#abstractsMassol1">Enterprise builds</a>: This session covers the different architectural concepts required for continuous builds of large projects. We show several strategies and explain how to implement these concepts with different continuous integration tools like Ant, Maven, CruiseControl, etc. The goal is to show what it takes to succeed in implementing an enterprise build. We cover concepts such as environment-dependent builds, binaries dependencies vs source dependencies, snapshot vs reference versions, continuous build strategies, where do tests fit in the build cycle, database strategies for continuous build, team organization related to build, etc. 
</li>
<li><a href="http://www.theserverside.com/symposium/sessionAbstracts.html#abstractsMassol2">Distributed Agile Development</a> (case study): This session will present Pivolis return of experience on a large scale J2EE banking project (approx. 100 persons in development team) developed collaboratively from 2 locations (France and India). We will discuss how we addressed the challenge of migrating from a collocated development setup to a collaborative distributed one. We will also detail how the project was made more agile in the process. We will cover the pitfalls that happened and see how they were resolved. </li>
</ul>
<p>There's also a nice <a href="http://wiki.theserverside.com/symposium/dashboard.action">wiki available</a> for the event.</p>
<p>Once the event is finished, I'll post my slides on this blog.</p>
]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-04-17T13:16:30+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000682_maven_statcvs_plugin_moved.html">
<title>[Maven] StatCvs plugin moved</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000682_maven_statcvs_plugin_moved.html</link>
<description><![CDATA[<p>After discussing with the <a href="http://statcvs-xml.berlios.de/">StatCvs-XML</a> team, we have decided that it would be best that they host the Maven StatCvs plugin on their <a href="http://statcvs-xml.berlios.de/maven-plugin/">own site</a>.</p>
<p>This will make it easier for them to improve it and keep it in sync with StatCvs-XML. This is possible thanks to the <code>plugin:download
</code>
 feature of Maven 1.0 rc1/rc2 which allows users to easily install some external plugins. It is also possible to reference a plugin in your own <code>project.xml
</code>
 as a dependency of type <code>plugin
</code>
.</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-04-09T10:55:00+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000675_common_source_parsing_storage_format_wanted.html">
<title>Common source parsing storage format wanted</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000675_common_source_parsing_storage_format_wanted.html</link>
<description><![CDATA[<p>As part of my day work, I've met <a href="http://www.castsoftware.com/">CAST Software</a> 
in France. They are really nice guys. And they have a very good product suite that analyzes
application source code and produces different kinds of reports (quality and reverse-engineering/browsing).
</p>
<p>The really nice part is their open architecture:</p>
<img src="http://www.codehaus.org/~vmassol/blog/cast.jpg"/>

<p>It's nice for the following reasons:</p>
<ul>
<li>There can be as many parsers as there are languages, script languages, etc. All data goes to the same 
database and this data is available to all analyzers. This means that it's possible to define analyzers
that act at the level of the full application. For example, you can define some architecture pattern
validation. This is the same idea I had some time ago with the 
<a href="patterntesting.sourceforge.net">PatternTesting</a> project, using AOP to write these rules (I
was relying on the Javac parser to perform the source code parsing for me).</li>
<li>It allows to write browsing tools that show the full flow of the application, from configuration
files to database tables</li>
</ul>

<p>Compare this to existing open source tools (or not open source for some) like 
<a href="http://checkstyle.sourceforge.net">Checkstyle</a>, <a href="http://clirr.sourceforge.net/">Clirr</a>,
<a href="http://pmd.sourceforge.net/">PMD</a>, <a href="http://findbugs.sourceforge.net/">Findbugs</a>, 
<a href="http://www.jcoverage.com/">jcoverage</a>, <a href="http://www.redhillconsulting.com.au/products/simian/">Simian</a>, 
<a href="http://www.thecortex.net/clover/index.html">Clover</a>, etc. They all use their own parsers and more 
important their own persistence format for storing the parsed data. Even though they almost all offer an XML report format,
it's already processed data (as opposed to raw parsing data). Thus it is very hard to reuse the information
from these tools to offer a higher level integrated view. It's also a lot of work for these tools to develop all the
necessary parsers.</p>

<p>What would be really nice is the creation of an open source project that does the following:</p>
<ul>
<li>Define a common storage model (database schema, XML schema, other). It should allow to store historical data too.</li>
<li>Define a common API to store parsing data</li>
<li>Define a common API to query parsing data</li>
</ul>
</p>
<p>If such open source project existed, we could have parser projects which could parse Java code, .Net code, Hibernate configuration
+ code, Struts configs + code, AspectJ Aspects, etc. These parsers would user the common API to store parsed data in the common storage format,
thus making the data available to other projects, such as the one mentionned above (Checkstyle, PMD, etc). These projects
woud be analyzers and would use the common API to query parsed data and generate reports for their domain of work.</p>

<p>With this, we could build nice analyzers that could completely check for full architecture best practices, across technologies and 
across frameworks.</p>

<p>Do you think such a project would work?</p>

<p>Note: Maybe CAST should open source this part (storage model) and keep as closed source their added value Parsers and Analyzers? :-)</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-04-08T11:32:36+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000683_fisheye_for_cactus.html">
<title>Fisheye for Cactus</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000683_fisheye_for_cactus.html</link>
<description><![CDATA[<p>TheCortex (creator of Clover) has announced a new product called <a href="http://fisheye.thecortex.net/">FishEye</a>. It's an SCM mining tool.</p>
<p>They have accepted to <a href="http://fisheye.thecortex.net/viewrep/jakarta-cactus">run it on Cactus</a>. It's very nice. The things I like particularly:</p>
<ul>
<li>RSS feeds on commits, at all directory levels. For example you can subscribe to the feed that monitors changes to the xdocs files if you're interested in documentation updates.</li>
<li>Annotations (for e.g.: http://fisheye.thecortex.net/viewrep/jakarta-cactus/build.xml?r=1.69)</li>
</ul>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-04-05T08:56:00+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000670_faq_bots.html">
<title>FAQ bots</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000670_faq_bots.html</link>
<description><![CDATA[<table>
<tr>
<td><p>A year ago, I spent some time looking at <a href="http://alicebot.org/">Alice Bot</a>. It's a bot that allows discussing with human beings. It has won several times the <a href="http://www.loebner.net/">Loebner prize</a>, which means it gets as close as possible to imitating a human person. The bot is controlled by XML files written in <a href="http://www.alicebot.org/aiml.html">AIML</a>.</p>
<p>The idea that I had at that time was to use it as a live FAQ answerer for the Cactus project. I never came to do it though... need more time...</p>
</td>
<td>
<OBJECT id="VHSS" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" WIDTH=180 HEIGHT=135><PARAM NAME=movie VALUE="http://vhost.alicebot.org/vhsssecure.php?doc=http%3A%2F%2Fvhost.alicebot.org%2Fgetshow.php%3Facc%3D1138%26ss%3D38629%26sl%3D0%26embedid%3D17bcfa247b4dfca92e650f4a7adfe243&edit=0&acc=1138&firstslide=1&loading=1&minimal=1&bgcolor=0xFFFFFF"><PARAM NAME=quality VALUE=high><PARAM NAME=scale VALUE=noborder><PARAM NAME=bgcolor VALUE=#FFFFFF><EMBED src="http://vhost.alicebot.org/vhsssecure.php?doc=http%3A%2F%2Fvhost.alicebot.org%2Fgetshow.php%3Facc%3D1138%26ss%3D38629%26sl%3D0%26embedid%3D17bcfa247b4dfca92e650f4a7adfe243&edit=0&acc=1138&firstslide=1&loading=1&minimal=1&bgcolor=0xFFFFFF" swLiveConnect=true NAME="VHSS" quality=high scale=noborder bgcolor=#FFFFFF WIDTH=180 HEIGHT=135 TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"></EMBED></OBJECT>
</td>
</table>

<p>I've been reminded of this idea by some posts on the Cactus mailing list. I'd venture that at least 50-70% of the the questions asked have already been answered in some form in the past, are available in the Cactus documentation or are easy to answer by some generic rule. I think it could be fun to train a bot to answer these questions. For those that the bot couldn't answer, the user would be redirected to the mailing list where Cactus experts would find the answer and train the bot so that it gets better next time.</p>
<p>It should be possible to have rules that would generate the following kind of dialogue:</p>
<ul>
<li>[user] I'm getting an error when running Cactus tests</li>
<li>[bot] Is the error happening on the client side or the server side?</li>
<li>[user] I don't know</li>
<li>[bot] Could you turn logging on and see if the error appears in the client side log or the server side log?</li>
<li>[user] how do I turn logging on?</li>
<li>[bot] See the Cactus <a href="http://jakarta.apache.org/cactus/integration/manual/howto_config.html#logging">logging configuration page</a></li>
<li>[user] It's happening on the client side</li>
<li>[bot] Is the error hapenning during the HTTP connection?</li>
<li>[user] yes</li>
<li>etc...</li>
</ul>
<p>It would be cool! My only worry is that it would take too long to create the AIML files. But maybe not. Any experience?</p>
<p>What would be even better would be that the bot would learn from the mailing list posts itself. However, that's probably science fiction at this point in time...</p>
<p><i>Note: The image was borrowed from Alicebot.org</i></p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-04-01T19:36:09+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000652_rss_reader_should_diff_updates.html">
<title>RSS reader should diff updates</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000652_rss_reader_should_diff_updates.html</link>
<description><![CDATA[<p>I'm using <a href="http://www.sharpreader.net/">SharpReader</a> and I don't whether the following is true for other readers.</p>
<p>Whenever a blog entry is updated by its author it appears in bold (indicating a change) and in italic (indicating that it's an update). However I have no clue what modifications were done to the entry and most of the time I don't have enough energy to read again the full entry trying to figure out by myself what has changed.</p>
<p>What would be really nice would be that the RSS reader shows a diff, highlighting the changes (as it's done for CVS commit diffs).</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-03-19T08:58:04+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000684_maven_jetty_plugin_10_released.html">
<title>[Maven] Jetty plugin 1.0 released</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000684_maven_jetty_plugin_10_released.html</link>
<description><![CDATA[<p>I've just released a <a href="http://maven.apache.org/reference/plugins/jetty">Maven plugin for Jetty</a>. The Maven Jetty plugin allows easy deployment and execution of Jetty.</p>
<p>
Features in this version includes:
<ul>
<li>Ability to automatically generate the Jetty XML configuration file</li>
<li>Ability to start Jetty</li>
<li>Deployment of WAR defined as dependencies and tagged with the <code>jetty.bundle
</code>
 property</li>
<li>Deployment of the current project if it's a WAR project</li>
</ul>
<p>Note that this plugin has been tested with Maven 1.0-rc2. Using it with another version of Maven is at your own risks! :-)</p>
<p>You can download the Jetty Maven plugin <a href="http://www.ibiblio.org/maven/maven/plugins/maven-jetty-plugin-1.0.jar">here</a>.</p>
]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-03-17T18:39:00+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000644_diffing_continuous_build_results.html">
<title>Diffing continuous build results</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000644_diffing_continuous_build_results.html</link>
<description><![CDATA[<p>All continuous builds have a common point: when a project fails we have to find out why. There can be several reasons:</p>
<ul>
  <li>Reason 1: a change in the project itself is causing the failure</li>
  <li>Reason 2: a change in one of the project's dependencies is causing the failure</li>
</ul>
<p>Solving case 1 is relatively easy. However, solving case 2 is usually quite difficult. How could we make it easier?</p>
<p>Here's a proposal for improving continuous build tools:</p>
<p><i>When a project goes from a "success" build state to a "failure" build state, perform a source diff (using CVS or whatever SCM used) between the 2 dates on both the project itself + all its dependencies. Then generate a report showing all the changes.</i></p>
<p>This should allow to get a clear view of all the things that changed and that led to the build failure. This strategy seems especially well suited to continuous build systems as these builds are executed often and thus the differences between 2 builds should be small enough to get a clear picture.</p>
<p>Has anyone done this already? Does it work?</p>
<p>Note: I have <a href="http://www.mail-archive.com/general%40gump.apache.org/msg00567.html">suggested</a> this idea to the <a href="http://gump.apache.org">Gump</a> project. I would be very eager to see how it works out.</p>
<p>Implementation details:</p>
<ul>
<li>If your SCM is too slow to perform large diffs over several revisions there is still hope! Save the last build checkout and perform a file diff against the current checkout and the last saved one. If you're using CVS or an SCM that supports putting metainformation in source file (like $Id:$) then you'll also get to know who made the change. Otherwise, for each file change you'll need to query your SCM to know who made the change.</li>
<li>I think it might be interesting to target the build failure emails to the list of people who have made changes since the last build + at least one person from the failed project's team.</li>
</ul>
<p>Limitations:</p>
<ul>
<li>Say we have project A which depends on project B which depends on project C. If project A fails because of a change in project C, then we won't know it unless we're doing diff on transitive dependencies. But that might be too long. I think a good strategy would be to only generate diff on the first level dependencies. Then possibly provide a feature to generate transitive dependencies on demand (but not at at every build failure - it'll be too costly I think).</li>
</ul>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-03-15T22:30:47+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000685_patterntesting_lead_changed.html">
<title>PatternTesting lead changed</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000685_patterntesting_lead_changed.html</link>
<description><![CDATA[<p>After several months of no activity, the <a href="http://patterntesting.sourceforge.net/">PatternTesting</a> project is getting alive again! Matt Smith is now taking the lead. On my side, I have not forgotten the idea of doing Pattern Tests using AOP. I am actually continuing this exploration with <a href="http://blogs.codehaus.org/people/vmassol/archives/000520_cactus_v2_architecture_proposal.html">Cactus2</a>, in a slightly different way.</p>
<p>In the meantime, please welcome Matt and let's wish him the best of success with the PatternTesting project!</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-03-01T22:30:00+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000609_what_does_collaborative_offshore_and_ejbs_have_in_common_.html">
<title>What does collaborative offshore and EJBs have in common? :-)</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000609_what_does_collaborative_offshore_and_ejbs_have_in_common_.html</link>
<description><![CDATA[<p><i>Warning: Don't take this comparison too seriously... ;-) It's a bit like comparing apples and oranges
and I'm sure the analogy breaks quite quickly if you pursue it too far. However, I do believe that the 
contained message is true.</i></p>

<p>I've just realized that collaborative offshore and EJB have a common point: they are both using 
a distributed model. By collaborative offshore, I mean teams developing on both sides (onsite and offhsore) 
and interacting continuously to build a system.</p>
<p>I've been working on 2 big offshore projects so far for the past 2.5 years (working with an Indian partner) and 
I've found that there is an organizational model that does not work well: onsite people directly managing 
developers (<a href="#figure1">Figure 1</a>). In the same way, calling directly Entity Beans from the client side is a bad practice because 
1) it involves a lot of network round-trips and thus is inefficient and 2) it 
does not allow changing the implementation without affecting the client (<a href="#figure2">Figure 2</a>).</p>

  <table border="0">
    <caption><a name="figure1"/><b>Figure 1: Onsite Project lead managing directly offshore developers</b></caption>
    <tr><td>
      <img alt="Figure 1: Onsite Project lead managing directly offshore developers" 
        src="http://blogs.codehaus.org/people/vmassol/archives/offshore_developer_direct.jpg" width="339" height="231" border="0" />
    </td></tr>
  </table>

  <table border="0">
    <caption><a name="figure2"/><b>Figure 2: Client calling Entity beans directly</b></caption>
    <tr><td>
      <img alt="Figure 2: Client calling Entity beans directly" 
        src="http://blogs.codehaus.org/people/vmassol/archives/ejb_direct.jpg" width="333" height="226" border="0" />
    </td></tr>
  </table>

<p>What is the solution we have used for EJBs? Answer: introduce a facade (Session Bean) which "manages" the 
underlying components (<a href="#figure3">Figure 3</a>). I've found that it is the same with collaborative offshore: there 
is a strong need to always introduce a local Project Lead (<a href="#figure4">Figure 4</a>).</p>

  <table border="0">
    <caption><a name="figure3"/><b>Figure 3: EJB client calling a facade</b></caption>
    <tr><td>
      <img alt="Figure 3: EJB client calling a facade" 
        src="http://blogs.codehaus.org/people/vmassol/archives/ejb_indirect.jpg" width="424" height="229" border="0" />
    </td></tr>
  </table>

  <table border="0">
    <caption><a name="figure4"/><b>Figure 4: Onsite Project Lead interacting with a local Project Lead</b></caption>
    <tr><td>
      <img alt="Figure 4: Onsite Project Lead interacting with a local Project Lead" 
        src="http://blogs.codehaus.org/people/vmassol/archives/offshore_developer_indirect.jpg" width="423" height="231" border="0" />
    </td></tr>
  </table>

<p>It probably sounds very obvious but very often there is an initial tendency by onsite managers new to offshore to directly manage
offshore "resources" (in order to reduce support costs). So far, whenever they've tried, it has failed (although we told them it wasn't 
a good idea but it seems some people need to see it by themselves to believe... ;-)).</p>

<p>I wonder if there'll be a time in the future where our communications skills will be so great that it will
allow direct managment across the wire. Probably... but this is still in the future...</p>
<p>Has this also been your experience?</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-02-18T09:06:48+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000605_database_testing_strategy_in_build.html">
<title>Database testing strategy in build</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000605_database_testing_strategy_in_build.html</link>
<description><![CDATA[<p>Applying a working build strategy for testing against a database is not easy. It depends on the complexity of the database model, it depends on the size of the teams. However, I've found that the strategy described below is the one that has worked the best for the projects I have been involved in:</p>
<ul>
<li>Do not mix unit tests independent of the environment (i.e. where interactions with the environments are stubbed/mocked) with integration unit tests (IUT). They have to be separated and put in different different in the SCM. The reason is that the 2 kinds of tests do not support the same execution workflow. More below.</li>
<li>Have a database build project (in the sense of an Ant or Maven project) in your SCM. This is extremely important. The goal of this project is to provide the following build targets/goals:
  <ul>
    <li><i>create-schema</i>: create the database schema from the ground up (in the database specified as properties)</li>
    <li><i>load-static-data</i>: loads static data (i.e. read only data)</li>
    <li><i>load-minimal-data</i>: loads a functionally minimal set of data. It should contain all data required functionally but only 1 or a few entries of each type. It's not supposed to reflect the state of the database when in production.</li>
    <li><i>load-full-data</i>: loads a full set of data as expected in production.</li>
  </ul>
</li>
<li>Put the database data (minimal + full sets) in your SCM as flat files (by opposition as keeping the data live in the database). The reason for this is because:
  <ul>
    <li>you get automatic notification of data changes by using your SCM send-email-on-commit feature that all good SCM have</li>
    <li>it is build-friendly and allows automated and controlled builds</li>
    <li>it is controlled, i.e. you know what you're doing with your data, who is modifying them, you can revert if need be, etc</li>
  </ul>
</li>
<li>Here's the workflow for executing IUT or functional tests. For each project and before the test suite runs:
  <ul>
    <li>execute <code>database:create-schema
</code>
</li>
    <li>execute <code>database:load-static-data
</code>
</li>
    <li>execute <code>database:load-minimal-data
</code>
</li>
  </ul>
<p>Then, each test should also have the opportunity to load data in its setup (using DBUnit or similar). This is required for example to test special cases where the database is missing some required data and we wish to verify the exception handling part of the code. It is also required if the test requires more than the minimal data set (although that should be relatively infrequent).</p>
<p>Note that the tests can also be ordered to save some database load time. Although not the best strategy I've found that this was sometimes required on some projects with complex database models.</p>
</li>
</ul>
<p>On the other hand, here are strategies that have not been working so well for me in the past:</p>
<ul>
  <li>Have a live database where developers can directly update data. The problems encountered were:
    <ul>
      <li>it is not controlled. You do no know who's putting data and what is being modified. You cannot easily revert a change</li>
      <li>it's difficult with distributed teams as you need to set up a replication mechanism. The problem is that often developers update their local database and forget to update the master database which leads to lots of build failures. The solution exposed above does not suffer from this problem.</li>
      <li>It's hard to sync everyone on the exact same set of data. Some minimal data + variations works best.</li>
     </ul>
</li>
<li>Do not provide minimal data and let developers write from scratch the data they require for their tests and load these data before each test. This does work for small projects with simple database models but not for complex ones.  There's really the need for a minimal data set.</li>
</ul>

<p>Is that also your experience?</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-02-16T09:18:46+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000601_what_is_wrong_with_starteam.html">
<title>What is wrong with Starteam...</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000601_what_is_wrong_with_starteam.html</link>
<description><![CDATA[<p>I'm revisiting an <a href="http://blogs.codehaus.org/people/vmassol/archives/2003_05.html#000007_starteam_woes">old entry</a> I posted about a year ago about Starteam woes. The reason is that the project I'm working on is delivering a first release soon and we'll be attacking the second leg of the journey... and it maye be time to lobby for a source repository change... :-). Thus I need to prepare my ammunitions again. By running it through you guys I hope to flesh out the inaccuracies of my points and possibly find new arguments in favor of... CVS. Yeah, I am biased!</p>
<p>Here's what I feel is wrong with Starteam:</p>
<ul>
<li>No "clean checkout" option. That is, if a file is deleted from the StarTeam repository, even if you perform a checkout all, the deleted files will not be removed from your local working copy.  Actually it is possible but only through the command line interface.</li>
<li>No ability to send email diffs on commits (using tools like <a href="http://www.badgers-in-foil.co.uk/projects/cvsspam/example-simple.html">CVSSpam</a>)</li>
<li>No nice IDE integration such as the CVS integrations we can see in IntelliJ, Eclipse, NetBeans, JBuilder, etc. More specifically the ability to see exactly what files are not in sync with the repository.</li>
<li>Limited integration with the majority of development tools: limited integration in Maven (BTW that's because it's been developed on this project itself by Emmanuel Venisse that there is limited integration in Maven!), no JIRA integration, etc</li>
<li>No JIRA integration. It seems there's a nice CVS integration which allows to link source code to issues resolved by entering the issue number in CVS commits. As we're using JIRA we could use this!</li>
<li>No possibility to run an Ant or Maven build every time there's a commit (a la Damage Control). That would allow our build to be in a better shape.</li>
<li>Starteam is very slow on WAN links. It may be due to our project policy to use locking on files. In any case if we had CVS we wouldn't have used this locking which is hampering productivity.</li>
<li>No windows explorer integration. To use Starteam you need to open yet another GUI application and perform operations from there (unless you use the command line but nobody is using it here). CVS has a nice TortoiseCVS client.</li>
<li>With Starteam a major problem for our build is that people forget to check in directories. No wonder as the Starteam GUI client does not show at all new directories!</li>
<li>Starteam is quite expensive and as a result we have only a limited number of fixed licenses. Anyone using floating licenses gets disconnected every few minutes. Very annoying.</li>
<li>Starteam admin seems more complex than CVS's. We have often had problems of database in the past year.</li>
</ul>
<p>Any more? Any inaccuracy in there (I'm sure there are as I am biased!)?</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-02-11T08:23:28+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000598_fighting_blog_spam_with_captchas.html">
<title>Fighting blog spam with captchas</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000598_fighting_blog_spam_with_captchas.html</link>
<description><![CDATA[<p>I've just learnt that there was a name for "a computer-generated test that humans can pass but computer programs cannot". It's
called a <a href="http://www.wordspy.com/words/captcha.asp"><i>captcha</i></a>.
You can see those on some web sites during registration. Here's an example:</p>

<img alt="captcha.jpg" src="http://blogs.codehaus.org/people/vmassol/archives/captcha.jpg" width="450" height="250" border="0" />

<p>Some of my Octo workmates are developing a java framework for generating captchas called <a href="http://jcaptcha.sourceforge.net/">JCaptcha</a>. What I find 
interesting is one possible use of captchas: <b>preventing spam</b>. More specifically the idea would be to use captchas to prevent 
blog spam. It means that people who enter blog comments would need to be humans. What I don't know is whether blog spam is being
done manually by individuals or if it's automated. In any case this solution will prevent automated blog spam which is a good 
first step!</p>
<p>The JCaptcha project has just released a <a href="http://sourceforge.net/project/showfiles.php?group_id=97877">beta</a> version.
I guess one next step could be the creation of a MoveableType plugin. Then I would hope to convince Bob to let us try it on 
Codehaus blogs :-)</p>

<p><b>Update 18/04/04</b>: It seems that James Seng beat me with <a href="http://james.seng.cc/archives/000145.html">this captcha idea</a>. Not only the idea but also an MT implementation. In addition, he's created yet another MT plugin for preventing comment spam by implemeting an <a href="http://james.seng.cc/archives/000152.html">MT Bayesian filter</a>.</p>


]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-02-10T20:22:42+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000530_jini_ide_is_it_the_future.html">
<title>Jini IDE. Is it the future?</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000530_jini_ide_is_it_the_future.html</link>
<description><![CDATA[<p>I've started thinking about what would be the best possible IDE back in 2001. At that time, I had tried Sun's Jini and liked it quite a lot. I linked the 2 concepts (IDE and Jini) and came up with the idea of a Jini-based IDE. At that time I started writing down some ideas (<a href="http://jtop.jini.org/jtop-0.2.doc">here</a> and <a href="http://jjtop.sourceforge.net/">here</a>). However I did not pursue this idea as creating a full fledged IDE is a master achievement and I did not have the time nor the wish to do so!</p>
<p>However, even today in 2003, I still think it had some nice ideas that I would like to see in existing and future IDEs. Here are some ideas about this Jini IDE:</p>
<ul>
<li>Each module would be a Jini service. Examples of modules are: javac compiler module, RMI compiler module, java editor module, source repository module, java execution module, junit execution module, etc.</li>
<li>It would be lightweight. It would be able to bootstrap with a minimal jar containing only the "microkernel" (+ possibly a module cache manager). Thus you could move from one machine to another easily. To install it, simply click on a browser link and download this minimal core. The rest will be downloaded as need be when you need the modules.</li>
<li>As each module is a Jini module, there would be 3 possibilities to implement a module:
  <ul><li>The Proxy contains only local methods and there are no communication between the proxy and the back-end service,</li>
<li>The Proxy is a “smart proxy”, i.e. there are both local and remote methods which communicate with the back-end service,</li>
<li>The Proxy is only a client stub, all the methods are remote</li>
</ul>
</li>
<li>It would be completely distributed. For example, the compile menu of the IDE would list all compiler module implementations the IDE has been able to discover when contacting the different Jini lookup services.</li>
<li>It would be self-healing: if a module is no longer available on a given server, another replacement will be automatically discovered (by the magic of Jini leases).</li>
<li>By using Jini leases, the IDE would support hot-patching/uninterrupted services</li>
<li>It would be secure using Jini security for modules. This will allow to support both open source modules and commercial modules.</li>
<li>What would be nice would be to have a repository service which would automatically save edited code on the server side (in a user-private zone). This would enable remote building. Developers on the move would be able to get their environment set up rapidly on any machine. Same if you wish to share environment with someone else, etc.</li>
<li>It would be completely modular with caching done on the client side to improve performances. The modularity should allow the creation of module repositories on the web. It would also allow creating IDE "a la carte".</li>
</ul>

<p>Of course, this is a bit utopic as we would need to overcome several difficulties:</p>
<ul>
<li>definition of standard module interfaces. However lots of work has been done there already by Netbeans and Eclipse and that could be reused.</li>
<li>there would need to be some module certification tests to ensure a module is properly coded, does not hog the IDE, plays well with others, etc</li>
</ul>
<p>Of course, this IDE of the future could be implemented in a technology other than Jini (P2P, Web services, etc). I still believe Jini is way ahead of web services but they are catching up slowly on security, transactions. To my knowledge there's still no notion of "leases" in web services, nor of code that moves around the network and can execute locally.</p>

<p>What do you think? Is that Jini-like IDE something you would also like to see in the future?</p>

<p><b>Update</b>: This blog entry has been <a href="http://www.theserverside.com/news/thread.tss?thread_id=23873">reposted on TSS</a> (several interesting comments).</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-02-10T15:28:00+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000597_enlightening_build.html">
<title>Enlightening build</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000597_enlightening_build.html</link>
<description><![CDATA[<p>Imagine you have a continuous build system in place and that it builds automatically your projects every few hours. When the team is large it can be quite challenging to coach all team members in being careful about the build and that before committing code, people need to run the build locally on their machine first. There are also other problems, like the build works locally but not on the continuous build machine.</p>
<p>Anyway, I've found that there are different kinds of projects. Some where the build is taken very seriously and a build-aware mentality quickly spreads and others where people do see the value of the build but have more difficulties taking it very seriously (leading to lots of build failures).</p>
<p>One idea that I've had is to use a physical artifact to represent a build success or a build failure. People like to see and touch things. Doing some research I've found the <a href="http://www.ambientdevices.com/cat/orb/orborder.html">Ambient Orb</a> which seems close enough to what I have in mind:</p>

<img alt="ambient-orb-alt1.jpg" src="http://blogs.codehaus.org/people/vmassol/archives/ambient-orb-alt1.jpg" width="400" height="313" border="0" />
<p>(Image stolen from ThinkGeek)</p>

<p>The idea is that the orb will turn more and more red depending on the number of projects that failed to build during the past cycle.</p>

<p>I have yet to buy one and try it but I like the idea. Has anyone done this already? Can it be done easily with the Ambient Orb? Are there devices other than the Ambient Orb on the market (for example, I don't need the wireless radio network connection at all especially as I live in France)?</p>

<p><b>Update</b>: This blog entry has been <a href="http://www.theserverside.com/news/thread.tss?thread_id=23844">reposted on TSS</a>.</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2004-02-09T10:34:06+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000520_cactus_v2_architecture_proposal.html">
<title>Cactus v2 architecture proposal</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000520_cactus_v2_architecture_proposal.html</link>
<description><![CDATA[  <h3>Cactus v2 architecture</h3>
  <ul>
    <li><a href="#rationale">Rationale</a></li>
    <li><a href="#architecture_choices">Architecture choices</a></li>
    <li><a href="#hla">High level architecture</a></li>
    <li><a href="#cactus_test_case">Cactus test case example</a></li>
    <li><a href="#design">Detailed design</a></li>
    <li><a href="#challenges">Challenges</a></li>
  </ul>
  
  <a name="rationale"></a>
  <h3>Rationale</h3>
  <p>
    Why a new architecture? Several reasons:
  </p>
  <ul>
    <li>
      The existing architecture is restricted to testing Servlet components
      (and its variations: Taglibs, Filters, JSP). We've tried to create an 
      SPI so that implementations for other containers can be written but
      it is not possible with the current architecture.
    </li>
    <li>
      We'd like to make Cactus the de facto tool for performing integration
      unit testing (aka in-container testing) for <b>any</b> type of 
      component in <b>any</b> type of container. See <a href="#figure1">figure
      1</a>.
    </li>
    <li>
      We'd like to make it easy for others to create Cactus extensions. This
      is not currently possible with the existing architecture.      
    </li>
    <li>
      We'd like to maximize the reusability of other testing tools. For example,
      instead of implementing in Cactus the HTTP layer that calls the server
      side, we'd like the user to use his favorite tool (e.g. HttpUnit). For
      unit testing Message-Driven Beans, the user will be able to use his 
      favorite JMS injector (e.g. Commons Messenger), etc. This will allow 
      leveraging all the features in those tools (for example, support for HTTPS
      in HttpUnit, support for Cookie handling, etc).
    </li>
    <li>
      We'd like to standardize on a server side interception mechanism instead of
      inventing our own.
    </li>
  </ul>
  <table border="0">
    <caption><a name="figure1"/><b>Figure 1: Scope of Cactus v2</b></caption>
    <tr><td>
      <img alt="Figure 1: Scope of Cactus v2"
        src="http://blogs.codehaus.org/people/vmassol/archives/cactusv2_scope.jpg" 
        width="569" height="413" border="0" />
    </td></tr>
  </table>

  <a name="architecture_choices"></a>
  <h3>Architecture choices</h3>
  <p>
    These are the high-level architecture choices on which Cactus v2 will be built:
  </p>
  <ul>
    <li>
      An AOP framework for server-side interception. There are 2 possible 
      contenders: AspectJ or AspectWerkz. We are currently favorizing AspectWerkz
      because it allows to write test cases in Java. AspectJ extends the Java
      language and requires strong tool support. It will change with the advent of
      JDK 1.5 as the JDK will become meta-data compatible and Aspect will probably
      take advantage of this. However, it will take several years before everyone
      is on JDK 1.5 and we need a solution before this.
    </li>
    <li>
      Cactus v2 will continue to be a JUnit extension. A Cactus v2 test case will be
      a JUnit test case and thus any JUnit test runner will work (provided the server
      has been started and the components and tests deployed).
    </li>
  </ul>

  <a name="hla"></a>
  <h3>High level architecture</h3>
  <p>
    The Cactus system is composed of 3 parts (see <a href="#figure2">figure 2</a>):
  </p>
  <ul>
    <li>
      A Cactus test case, which is a combination of a JUnit test case (with 
      <code>testXXX()
</code>
 methods executed on the client side) and aspects
      used on the server side to perform interception and/or validation on the 
      server side (see <a href="#figure3">figure 3</a>). More specifically, 3 
      typical uses cases for these aspects are:
      <ul>
        <li>
          Intercept the call to the component under test and redirect the flow of
          execution to a specific method to unit test it,
        </li>
        <li>
          Prevent the flow of execution to call some subsystem. For example, stop the
          flow of execution before it goes to the database and instead return canned
          values.
        </li>
        <li>
          Perform asserts to verify server-side expectations. For example, verify that
          the Servlet HTTP Session contains such and such values after executing such
          method, verify that the Database connection is closed as many times as it is
          open for such and such use case, verify that the number of SQL queries is 
          below such number (e.g. less than 10 SQL queries per use case), etc. These 
          are server-side expectations.
        </li>
      </ul>
    </li>
    <li>
      A Cactus runner to execute Cactus tests automatically. This involves starting the
      container, deploying the application and tests in the container, starting the 
      tests and stopping the container.
    </li>
    <li>
      A Cactus framework to support starting a test case on the client side and 
      continuing it on the server side, and also to support transferring test results
      from the server side to the client side so that results can be displayed in the
      executing JUnit test runner. This framework also contains helper aspects and 
      classes to help write test cases.
    </li>          
  </ul>          
  <table border="0">
    <caption><a name="figure2"/><b>Figure 2: High-level architecture</b></caption>
    <tr><td>
      <img alt="Figure 2: High-level architecture" 
        src="http://blogs.codehaus.org/people/vmassol/archives/cactusv2_archi.jpg" 
        width="616" height="115" border="0" />
    </td></tr>
  </table>

  <a name="cactus_test_case"></a>
  <h3>Cactus test case example</h3>
  <p>
    Here is an example of a typical Cactus test case using AspectWerkz 0.9. Please 
    note that this example is a work in progress and is non-functional at this stage. 
    We're also working towards simplifying the syntax for test case writers:
  </p>
  <table border="0">
    <caption><a name="figure3"/><b>Figure 3: Cactus test case sample</b></caption>
    <tr><td>
<pre><div class="code"><pre><span class="category1">package</span> org.apache.cactus.sample.servlet;

<span class="category1">import</span> java.util.Hashtable;

<span class="category1">import</span> javax.servlet.http.HttpServletRequest;

<span class="category1">import</span> org.codehaus.aspectwerkz.attribdef.Pointcut;
<span class="category1">import</span> org.codehaus.aspectwerkz.attribdef.aspect.Aspect;
<span class="category1">import</span> org.codehaus.aspectwerkz.joinpoint.JoinPoint;
<span class="category1">import</span> org.codehaus.aspectwerkz.joinpoint.MethodJoinPoint;

<span class="category1">import</span> com.meterware.httpunit.GetMethodWebRequest;
<span class="category1">import</span> com.meterware.httpunit.WebConversation;
<span class="category1">import</span> com.meterware.httpunit.WebRequest;
<span class="category1">import</span> com.meterware.httpunit.WebResponse;

<span class="category1">import</span> junit.framework.TestCase;

<span class="category1">public</span> <span class="category1">class</span> TestSampleServletAspectWerkz <span class="category1">extends</span> TestCase
{
     <span class="blockcomment">/**
      * Intercepts Servlet's doXXX calls and instead redirect the flow of
      * execution to the {@link SampleServlet#getRequestParameters} method to
      * unit test.
      * 
      * @Aspect
      */</span>
     <span class="category1">public</span> <span class="category1">static</span> <span class="category1">class</span> GetRequestParametersTestAdvice <span class="category1">extends</span> Aspect
     {
          <span class="blockcomment">/**
           * @Execution * *..SampleServlet.do*(..)
           */</span>
          Pointcut interceptServlet;
          
          <span class="blockcomment">/**
           * @Around interceptServlet
           */</span>
          <span class="category1">public</span> <span class="category2">Object</span> catchGetRequestParameters(JoinPoint joinPoint) 
              <span class="category1">throws</span> <span class="category2">Throwable</span>
          {
               MethodJoinPoint jp = (MethodJoinPoint) joinPoint;
               SampleServlet servlet = (SampleServlet) jp.getTargetInstance();
               <span class="category2">Hashtable</span> params = servlet.getRequestParameters(
                   (HttpServletRequest) jp.getParameters()[0]);
               assertNotNull(params.get("<span class="quote">param1</span>"));
               assertNotNull(params.get("<span class="quote">param2</span>"));
               assertEquals("<span class="quote">value1</span>", params.get("<span class="quote">param1</span>"));
               assertEquals("<span class="quote">value2</span>", params.get("<span class="quote">param2</span>"));
               <span class="category1">return</span> <span class="category1">null</span>;
           }
      }
 
     <span class="blockcomment">/**
      * Test {@link SampleServlet#getRequestParameters} by calling the server 
      * side using HttpUnit. On the server side, our aspect will kick in and
      * the {@link GetRequestParametersTestAdvice#catchGetRequestParameters} 
      * test method will be called to unit test our method.    
      */</span>
     <span class="category1">public</span> <span class="category1">void</span> testGetRequestParameters() <span class="category1">throws</span> <span class="category2">Exception</span>
     {
          WebConversation conversation = <span class="category1">new</span> WebConversation();
          WebRequest request = <span class="category1">new</span> GetMethodWebRequest(
              "<span class="quote">http://localhost:8080/test/SampleServlet?param1=value1&amp;param2=value2</span>");
          WebResponse response = conversation.getResponse(request);
      }    
}</pre></div>
</pre>
    </td></tr>
  </table>
  <p>
    We would like to be able to write the following (not yet supported by AspectWerkz but we've had commitment from the AW team that they will
    make modifications to support it! :-)). The difference with the previous sample is the removal of the inner aspect class + the
    typed poincut interception.
  </p>
  <table border="0">
    <caption><a name="figure4"/><b>Figure 4: Ideal Cactus test case sample</b></caption>
    <tr><td>
<pre><div class="code"><pre><span class="category1">package</span> org.apache.cactus.sample.servlet;

<span class="category1">import</span> java.util.Hashtable;

<span class="category1">import</span> javax.servlet.http.HttpServletRequest;

<span class="category1">import</span> org.codehaus.aspectwerkz.attribdef.Pointcut;
<span class="category1">import</span> org.codehaus.aspectwerkz.joinpoint.JoinPoint;
<span class="category1">import</span> org.codehaus.aspectwerkz.joinpoint.MethodJoinPoint;

<span class="category1">import</span> com.meterware.httpunit.GetMethodWebRequest;
<span class="category1">import</span> com.meterware.httpunit.WebConversation;
<span class="category1">import</span> com.meterware.httpunit.WebRequest;
<span class="category1">import</span> com.meterware.httpunit.WebResponse;

<span class="category1">import</span> junit.framework.TestCase;

<span class="category1">public</span> <span class="category1">class</span> TestSampleServletAspectWerkz <span class="category1">extends</span> TestCase
{
     <span class="blockcomment">/**
      * @Execution * *..SampleServlet.do*(..)
      * @And @Target(SampleServlet)
      * @And @Args(HttpServletRequest)
      */</span>
     Pointcut interceptServlet;
         
     <span class="blockcomment">/**
      * @Around interceptServlet
      */</span>
     <span class="category1">public</span> <span class="category1">void</span> catchGetRequestParameters(SampleServlet servlet,
         HttpServletRequest request) <span class="category1">throws</span> <span class="category2">Throwable</span>
     {
          <span class="category2">Hashtable</span> params = servlet.getRequestParameters(request);
          assertNotNull(params.get("<span class="quote">param1</span>"));
          assertNotNull(params.get("<span class="quote">param2</span>"));
          assertEquals("<span class="quote">value1</span>", params.get("<span class="quote">param1</span>"));
          assertEquals("<span class="quote">value2</span>", params.get("<span class="quote">param2</span>"));
      }
 
     <span class="blockcomment">/**
      * Test {@link SampleServlet#getRequestParameters} by calling the server 
      * side using HttpUnit. On the server side, our aspect will kick in and
      * the {@link #catchGetRequestParameters} test method will be called 
      * to unit test our method.    
      */</span>
     <span class="category1">public</span> <span class="category1">void</span> testGetRequestParameters() <span class="category1">throws</span> <span class="category2">Exception</span>
     {
          WebConversation conversation = <span class="category1">new</span> WebConversation();
          WebRequest request = <span class="category1">new</span> GetMethodWebRequest(
              "<span class="quote">http://localhost:8080/test/SampleServlet?param1=value1&amp;param2=value2</span>");
          WebResponse response = conversation.getResponse(request);
      }    
}</pre></div>
</pre>
    </td></tr>
  </table>

  <a name="design"></a>
  <h3>Detailed design</h3>
  <p>
    The detailed design of Cactus v2 is shown in <a href="#figure5">figure 5</a> below.
  </p>
  <table border="0">
    <caption><a name="figure5"/><b>Figure 5: Detailed design</b></caption>
    <tr><td>
      <img alt="Figure 5: Detailed design" 
        src="http://blogs.codehaus.org/people/vmassol/archives/cactusv2_design.jpg" 
        width="618" height="254" border="0" />
    </td></tr>
  </table>
  <p>
    It works as follows:
  </p>
  <ol>
    <li>
      The Cactus tests are started by a JUnit Test Runner (any JUnit Test Runner).
    </li>
    <li>
      The Cactus framework intercepts the JUnit call to the test case <code>runBare()
</code>

      method. It checks if a listener socket has been set up. If not it sets up one. It passes
      the test name to it (so that the server side can later on find out what test is 
      currently being executed),
    </li>
    <li>
      It calls the test case <code>testXXX()
</code>
 method. In this method the test case writer
      has written the logic to call the server side (using any existing framework; for
      example HttpUnit for calling an HTTP service),
    </li>
    <li>
      The flow of execution reaches the application to test on the server side, 
    </li>
    <li>
      Somewhere during the execution of the application, the test aspect defined by the test
      case writer kicks in. Before that aspect is executed, the Cactus framework intercepts
      it,
    </li>
    <li>
      The Cactus server side interceptor then calls the listener socket set up in step 2 to 
      get the name of the test being executed (the test that was started on the client side). 
      It checks if the aspect matches the current test,
    </li>
    <li>
      If the aspect matches, its advice is executed, performing whatever logic the test case 
      writer has put in it,
    </li>
    <li>
      Before the call returns to the client side, the Cactus server side interceptor calls
      the socket listener to pass to it the server side test result (it passes to it any
      exception raised on the server side; for example <code>AssertionFailedError
</code>

      exceptions),
    </li>
    <li>
      After the <code>testXXX()
</code>
 method finishes its execution and before the test 
      result is communicated to the JUnit Test Runner, the Cactus client side interceptor
      verifies if any error has been reported by the server side execution. If so, it 
      rethrows the server side exception to the JUnit Test Runner. Otherwise it lets the
      result of <code>testXXX()
</code>
 bubble up to the JUnit Test Runner.
    </li>   
  </ol>
  <p>
    Some additional comments/ideas:
  </p>
  <ul>
    <li>
      If one of the <code>catchXXX()
</code>
 methods is not called, it should result in an
      <code>AssertionFailedError
</code>
 being raised. This is to prevent not executing
      server-side test code without knowing it. As we are using interception, I guess it's
      easy to make a mistake when defining the join point and thus we need this safeguard.
    </li>
  </ul>

  <a name="challenges"></a>
  <h3>Challenges</h3>
  <p>
    The following challenges await us:
  </p>
  <ul>
    <li>
      Being able to make the Cactus test case easy to write for test case writers,
    </li>
    <li>
      Make the execution of Cactus test case easily executable. Runtime code weaving
      would be nice but is not supported by old JVMs. We will probably have a mixed
      model as is being supported by AspectWerkz.
    </li>
    <li>
      Find out if integration with Chad's <a href="http://www.virtualmock.org/">VirtualMock</a> is possible/desirable.
    </li>
  </ul>
  <p>
    Please challenge us to improve our design! :-)
  </p>
  <p>
    Disclaimer: Please also note that, at this point in time, this architecture and 
    ideas are only mine and do not represent (yet!) the official view of the Cactus 
    project. I am proposing it to the Cactus project members.
  </p>
]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-12-21T16:11:47+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000274_junit_in_action_book_signing_in_paris.html">
<title>JUnit in Action - book signing in Paris</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000274_junit_in_action_book_signing_in_paris.html</link>
<description><![CDATA[<p>For French people or anyone visiting Paris at that time, I'll be doing some book signing for JUnit in Action on the 20th of December 2003, at the <a href="http://www.lmet.fr">Le Monde en "Tique"</a> bookshop. From 15:00 to 18:00.</p>
<p>If you're interested to discuss a bit about unit testing, JUnit, TDD, Cactus, Maven, Ant, open source, Apache/Jakarta, etc come and join me!</p>
<p>For those in other countries, sorry! I don't think Manning will pay for the trip. That's unless JUnit in Action becomes a bestseller of course! You know what you have to do! :-)</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-12-01T12:46:11+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000273_cactus_new_vision.html">
<title>Cactus new vision</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000273_cactus_new_vision.html</link>
<description><![CDATA[<p>Currently the Cactus project is a framework to help unit test J2EE components (and mostly Servlet/JSP/Taglib).</p>
<p>I'd like to expand its goal and make it a <b>framework for building in-container testing solutions</b>. Cactus would still offer an implementation for J2EE component testing but it will also open up an API for plugging other implementations. Some ideas are shown on the diagram below.</p>

<img alt="cactus_new_vision.jpg" src="http://blogs.codehaus.org/people/vmassol/archives/cactus_new_vision.jpg" width="569" height="413" border="0" />

<p>
For this to happen, the core helper classes will have to be separated from the HTTP protocol implementation and the existing Cactus TestCases. 2 SPIs will appear:
<ul>
<li>one for plugging in different protocol implementations (RMI, JMS, etc). Currently Cactus provides the HTTP implementation.</li>
<li>one for plugging in custom test case implementations (still looking for a good name for these). Currently Cactus provides the ServletTestCase, FilterTestCase and JspTestCase.</li>
</ul>
<p>Moreover, the Cactus integration modules (aka front-ends) will also need to provide clearly-defined extension points to help automate the whole process of starting the container, deploying components, running the tests and shutting down the container.</p>
<p>I'm currently working on the Cactus code to make the 2 SPIs surface. The first test drive of these new SPIs will be to implement support for EJB TestCases.</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-12-01T12:29:55+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000239_junit_in_action_news.html">
<title>JUnit in Action news</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000239_junit_in_action_news.html</link>
<description><![CDATA[<p><a href="http://www.manning.com/massol">Junit in Action</a> is now available in both ebook and printed format on <a href="http://www.manning.com/massol">Manning web site</a>, <a href="http://www.amazon.com/exec/obidos/tg/detail/-/1930110995/qid=1069663492/sr=8-1/ref=sr_8_1/102-0714618-6488150?v=glance&n=507846">Amazon</a> and all good libraries.</p>
<p>Here are some resources about JIA:</p>
<ul>
<li><a href="http://www.manning.com/massol">JIA web site</a>.</li>
<li><a href="http://www.manning.com/massol/junit-in-action-massol-toc.pdf">Table of contents</a>.</li>
<li><a href="http://www.manning.com/getpage.html?project=massol&filename=chapters.html">Sample chapters</a>.</li>
<li><a href="http://junitbook.sourceforge.net/">Source code</a>. JIA source code has been donated to open source under an Apache license.</li>
</ul>
<p>Reviews:</p>
<li>Full review on <a href="http://www.theserverside.com/resources/article.jsp?l=JUnitBookReview">TheServerSide</a>.</li>
<li>Comments on <a href="http://www.theserverside.com/resources/article.jsp?l=JUnitInAction">TheServerSide</a> following the post of 2 sample chapters.</li>
<li>Review on <a href="http://www.javaranch.com/bunkhouse/Miscellaneous.jsp#1930110995">JavaRanch</a>. The JavaRanch <a href="http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=forum&f=68">Testing forum</a> is also currently discussing it. Additional comments by <a href="http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=68&t=000233">Jason Menard</a>.</li>
<li>Review on <a href="http://www.amazon.com/exec/obidos/tg/detail/-/1930110995/ref=cm_rev_all_1/102-0714618-6488150?v=glance&s=books&n=507846&vi=customer-reviews">Amazon</a>.</li>
</ul>
]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-11-24T10:00:09+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000250_mocking_classes_with_easymock.html">
<title>Mocking classes with Easymock</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000250_mocking_classes_with_easymock.html</link>
<description><![CDATA[<p>Joel Shellman has coded an <a href="http://groups.yahoo.com/group/easymock/files/">extension (easymock-patch-1.0.jar)</a> of EasyMock which allows to mock class (and not only interfaces).</p>
<p>To use it:</p>
<ul>
<li>put the extension jar <b>in front</b> of the easymock jar in your classpath (it works with Easymock 1.0 only, not with the new 1.0.1b which has modifications for extending Easymock). It overrides the <code>MockControl
</code>
 class by a new one accepting a class as parameter as shown below.</li>
<li>add cglib to your classpath (I've tried it with version <a href="http://www.ibiblio.org/maven/cglib/jars/cglib-rc2-1.0.jar">rc2-1.0</a>).</li>
<li> add bcel to your classpath (I've tried it with version <a href="http://www.ibiblio.org/maven/bcel/jars/bcel-5.1.jar">5.1</a>).</li>
</ul>
<p>Here's an example. First let's start by the class we wish to mock:</p>
<pre><div class="code"><pre><span class="category1">package</span> test;

<span class="category1">public</span> <span class="category1">class</span> Calculator
{
     <span class="category1">private</span> <span class="category1">int</span> amount;
     
     <span class="category1">public</span> Calculator(<span class="category2">Integer</span> amount)
     {
          this.amount = amount.intValue();
      }
     
     <span class="category1">public</span> <span class="category1">int</span> compute()
     {
          <span class="category1">return</span> this.amount;
      }
}</pre></div>
</pre>
<p>Here's now the class we wish to test (it uses the Calculator class):</p>
<pre><div class="code"><pre><span class="category1">package</span> test;

<span class="category1">public</span> <span class="category1">class</span> Account
{
     <span class="category1">public</span> <span class="category1">int</span> computeBalance(Calculator calculator)
     {
          <span class="category1">return</span> calculator.compute();
      }
}</pre></div>
</pre>
<p>Now, here's our test of <code>computeBalance
</code>
. Notice that we are mocking the <code>Caculator
</code>
 <b>class</b>:</p>
<pre><div class="code"><pre><span class="category1">package</span> test;

<span class="category1">import</span> org.easymock.MockControl;

<span class="category1">import</span> junit.framework.TestCase;

<span class="category1">public</span> <span class="category1">class</span> AccountTest <span class="category1">extends</span> TestCase
{
     <span class="category1">public</span> <span class="category1">void</span> testComputeBalance()
     {
          Account test = <span class="category1">new</span> Account();
          
          MockControl control = MockControl.createControl(Calculator.class,
              <span class="category1">new</span> <span class="category2">Class</span>[]{Integer.class}, <span class="category1">new</span> <span class="category2">Object</span>[]{<span class="category1">new</span> <span class="category2">Integer</span>(5)});
          Calculator mock = (Calculator) control.getMock();
          
          mock.compute();
          control.setDefaultReturnValue(10);
          control.replay();
          
          <span class="category1">int</span> result = test.computeBalance(mock);
          assertEquals(10, result);
      }
}</pre></div>
</pre>
<p><i>Note: I don't know how to instantiate a constructor taking primitive types. Don't know if it is supported.</i></p>
<p>That's nice. However, there are a few drawbacks I can see:</p>
<ul>
<li>It doesn't encourage refactoring and creating interfaces (which is the right way to go in most cases). However, it can still be useful in some cases like when mocking third party classes which do not have interfaces (and there are quite a lot of them, especially in the JDK...)</li>
<li>It doesn't work with final classes. Thus not possible to mock the JDK's URL class for example. It also won't work with private constructors of course</li>
<li>It forces to know the constructor values when creating the mock</li>
<li>It still doesn't help in cases where it is no easy to introduce the mock in the class under test. In that regards, it's less powerful than interception (a la AOP).</li>
</ul>
<p>So it's not a silver bullet but it will certainly help in cases where you have no control over the sources (like when using third-party libraries.</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-11-09T12:10:56+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000208_junit_in_action_off_to_press.html">
<title>JUnit in Action - off to press</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000208_junit_in_action_off_to_press.html</link>
<description><![CDATA[<p>At long last! After 18 months of hard work, JUnit in Action has gone to press. It will be available in printed edition in about 3 weeks at <a href="http://www.manning.com/massol">Manning's web site</a> and I guess 2 weeks later at other bookstores.</p>
<p>The e-book edition will be available sometime this week.</p>
<p><b>22/10/2003 update</b>: the ebook is now <a href="http://www.manning.com/massol">available</a>.]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-10-19T20:27:33+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000170_using_rollbacks_for_unit_testing_database_code.html">
<title>Using rollbacks for unit testing database code?</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000170_using_rollbacks_for_unit_testing_database_code.html</link>
<description><![CDATA[<p>Let's imagine you wish to perform unit test for code that calls the database. Let's also imagine that you want to test in integration, i.e. verify that the SQL query does actually goes to the database and returns database data.</p>
<p>The traditional approach is to:</p>
<ol>
<li>Preload static data before the test suite runs</li>
<li>Load specific test related data in the database before each test. A variation is to restore the modified data at the end of the test</li>
</ol>
<p>There are several disadvantages to point 2:</p>
<ul>
<li>Finding out the specific data that needs to be set up for the test is time-consuming and you often need to know the full database schema (and not only the domain you're working on). This is especially true for big projects</li>
<li>There are referential integrity concerns that forces you to set up again data for a lot of other tables that the ones you are concerned with as they are linked through keys</li>
</ul>
<p>One solution that our project team discussed yesterday is about <b>using transaction rollbacks</b>. It would work as follows:</p>
<ul>
<li>Before the test suite starts, load the database with full data (this is done only once and usually takes a good 5 minutes for complex projets)</li>
<li>Before the test starts, start a transaction (in JUnit's setUp() method for example)</li>
<li>run the test</li>
<li>rollback the transaction to restore the database data in a pristine state</li>
</ul>
<p>I was suprised to see no mention of this on the articles mentioning database unit testing (http://www.dallaway.com/acad/dbunit.html, http://www.dbunit.org/bestpractices.html). The reason may be that there are some glitches with this technique that make it impossible to use in practice... I'd like to know what you think? Have you done this before?</p>
<p>Notes:</p>
<ul>
<li>The code under tests should not create a new transaction as nested transactions are usually not supported</li>
</ul>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-09-27T08:32:09+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000681_maven_statcvs_plugin_20_released.html">
<title>[Maven] StatCvs plugin 2.0 released</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000681_maven_statcvs_plugin_20_released.html</link>
<description><![CDATA[<p>I have just released version 2.0 of the <a href="http://maven.apache.org/reference/plugins/statcvs">StatCvs plugin</a> for Maven.</p>
<p>The Maven StatCvs plugin is a plugin for <a href="http://statcvs-xml.berlios.de/">StatCvs-XML</a> that generates CVS statistic reports.</p>
<p>
Changes in this version:
<ul>
<li>Migrated the plugin to use the new statcvs-xml jar (which generates XML xdoc output instead of HTML).</li>
</ul>
<p>
You can download the StatCvs Maven 2.0 plugin <a href="http://www.ibiblio.org/maven/maven/plugins/maven-statcvs-plugin-2.0.jar">here</a>.
</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-09-21T19:05:00+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000138_aop_unit_testing_example.html">
<title>AOP Unit Testing example</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000138_aop_unit_testing_example.html</link>
<description><![CDATA[<p>The mock object strategy is nice but how do you apply it when you have some existing code that uses
tons of static calls, does not have setters prepared so that you can introduce your mocks, etc?</p>
<p>One solution is to use AUT: AOP Unit Testing! (hehe... yet another acronym :-)).
<p>Let's try that by writing a unit test using AspectJ for an EJB. Let's imagine we want to unit test
the following <code>createOrder()
</code>
 method:</p>
<pre><div class="code"><pre><span class="category1">package</span> junitbook.ejb.service;

<span class="category1">import</span> java.rmi.RemoteException;
<span class="category1">import</span> java.util.Date;

<span class="category1">import</span> javax.ejb.EJBException;
<span class="category1">import</span> javax.ejb.SessionBean;
<span class="category1">import</span> javax.ejb.SessionContext;

<span class="category1">import</span> junitbook.ejb.domain.OrderLocal;
<span class="category1">import</span> junitbook.ejb.domain.OrderUtil;
<span class="category1">import</span> junitbook.ejb.util.JMSUtil;
<span class="category1">import</span> junitbook.ejb.util.JNDINames;

<span class="category1">public</span> <span class="category1">abstract</span> <span class="category1">class</span> PetstoreEJB <span class="category1">implements</span> SessionBean
{
     <span class="category1">public</span> <span class="category1">int</span> createOrder(<span class="category2">Date</span> orderDate, <span class="category2">String</span> orderItem)
     {
          OrderLocal order = OrderUtil.createOrder(orderDate, 
              orderItem);
  
          <span class="category1">try</span>
          {
               JMSUtil.sendToJMSQueue(JNDINames.QUEUE_ORDER, 
                   order.getOrderId(), <span class="category1">false</span>);
           }
          <span class="category1">catch</span> (<span class="category2">Exception</span> e)
          {
               <span class="category1">throw</span> <span class="category1">new</span> EJBException(e);
           }
          <span class="category1">return</span> order.getOrderId().intValue();
      }
 
     <span class="category1">public</span> <span class="category1">void</span> setSessionContext(SessionContext sessionContext) 
         <span class="category1">throws</span> EJBException, <span class="category2">RemoteException</span> {}
     <span class="category1">public</span> <span class="category1">void</span> ejbRemove() 
         <span class="category1">throws</span> EJBException, <span class="category2">RemoteException</span> {}
     <span class="category1">public</span> <span class="category1">void</span> ejbActivate() 
         <span class="category1">throws</span> EJBException, <span class="category2">RemoteException</span> {}
     <span class="category1">public</span> <span class="category1">void</span> ejbPassivate() 
         <span class="category1">throws</span> EJBException, <span class="category2">RemoteException</span> {}
}</pre></div>
</pre>

<p><i>Note that the nasty calls to <code>OrderUtil.createOrder()
</code>
 and
<code>JMSUtil.sendToJMSQueue
</code>
 are static!</i></p>

<p>Our challenge here is to unit test this method in isolation from the rest. Here are the corresponding unit tests: 
one to verify it works when there is no exception (<code>testCreateOrderOk
</code>
) and one to verify it also
works when there is a JMS exception raised, for example (<code>testCreateOrderWhenJMSException
</code>
):</p>

<pre><div class="code"><pre><span class="category1">package</span> junitbook.ejb.service;

<span class="category1">import</span> java.util.Date;

<span class="category1">import</span> javax.ejb.EJBException;
<span class="category1">import</span> javax.jms.JMSException;

<span class="category1">import</span> com.mockobjects.dynamic.Mock;

<span class="category1">import</span> junit.framework.TestCase;
<span class="category1">import</span> junitbook.ejb.domain.OrderLocal;
<span class="category1">import</span> junitbook.ejb.domain.OrderUtil;
<span class="category1">import</span> junitbook.ejb.util.JMSUtil;

<span class="category1">public</span> <span class="category1">class</span> TestPetstoreEJB <span class="category1">extends</span> TestCase
{
     <span class="category1">private</span> PetstoreEJB ejb;
     
     <span class="category1">protected</span> <span class="category1">void</span> setUp()
     {
          this.ejb = <span class="category1">new</span> PetstoreEJB() {};
      } 
 
     <span class="category1">public</span> <span class="category1">void</span> testCreateOrderOk()
     {
          <span class="category1">int</span> result = this.ejb.createOrder(<span class="category1">new</span> <span class="category2">Date</span>(), "<span class="quote">1234</span>");
          assertEquals(1234, result);
      }
 
     <span class="category1">public</span> <span class="category1">void</span> testCreateOrderWhenJMSException()
     {
          <span class="category1">try</span>
          {
               this.ejb.createOrder(<span class="category1">new</span> <span class="category2">Date</span>(), "<span class="quote">1234</span>");
               fail("<span class="quote">Should have thrown an EJBException</span>");
           }
          <span class="category1">catch</span> (EJBException expected)
          {
               assertEquals("<span class="quote">some jms error</span>", 
                   expected.getCausedByException().getMessage());
           }
      }
}    

aspect TestPetstoreEJBAspect
{
     OrderLocal around():
         call(* OrderUtil.createOrder(..)) &amp;&amp;
         cflow(execution(* testCreateOrder*()))
     {
          Mock mockOrderLocal = <span class="category1">new</span> Mock(OrderLocal.class);
          OrderLocal orderLocal = (OrderLocal) mockOrderLocal.proxy();
          mockOrderLocal.matchAndReturn("<span class="quote">getOrderId</span>", <span class="category1">new</span> <span class="category2">Integer</span>(1234));
          <span class="category1">return</span> orderLocal;
      }
 
     <span class="category1">void</span> around():
         call(* JMSUtil.sendToJMSQueue(..)) &amp;&amp;
         cflow(execution(* testCreateOrderOk()))
     {
          <span class="category1">return</span>;
      }
 
     <span class="category1">void</span> around() <span class="category1">throws</span> JMSException:
         call(* JMSUtil.sendToJMSQueue(..)) &amp;&amp;
         cflow(execution(* testCreateOrderWhenJMSException()))
     {
          <span class="category1">throw</span> <span class="category1">new</span> JMSException("<span class="quote">some jms error</span>");
      }
}</pre></div>
</pre>
<p><i>Note: I highly recommend using Eclipse 3.0M3 and the latest AJDT plugin if you wish to run this code. The AJDT works great
for writing AspectJ projects.</i></p>
<p>That's quite nice and it works nicely but as you have noticed the test code is neither very easy to write nor to read. What 
I would love is a dynamic language geared towards writing these kinds of unit tests! Could Groovy provide that? That would be
soooooo nice!</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-08-30T19:54:29+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000137_groovy_mock_objects_friendly.html">
<title>Groovy, mock objects friendly?</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000137_groovy_mock_objects_friendly.html</link>
<description><![CDATA[<p>James Strachan has posted a news about <a href="http://radio.weblogs.com/0112098/2003/08/29.html#a399">starting a new dynamic language for the java platform called Groovy</a>. 
He mentions using it for writing unit tests a la JUnit.</p>

<p>I think that's an excellent idea! On most projects I've been on, writing good unit tests often comes late in the development. Usually people
write functional or integration tests but rarely unit tests which test code in isolation from the rest. And once the design best practices have
been decided and lots of code has been already written, writing unit tests is hard because it requires severe refactoring and design changes. The hard part is the introduce mock objects in the code under test. Some code uses statics, other instanciate domain objects instead
of them being passed to it, etc.<p>

<p>Of course, extreme TDD practictioners would say that it is much better to refactor the code under test so that it become more flexible and
better able to support change. That's true but that's difficult to practice for the majority of projects and difficult to apply if the project
has not been started the TDD way.</p>

<p>What would be nice is to have a dynamic language geared towards introducing easily changes to the code so that it can support the mock objects
approach. There is a unit testing framework out there that does almost this; it's called <a href="http://www.polygenix.net/">AgileTest</a> from Polygenix.</p>
<p>Maybe Groovy could extend the ideas from AgileTest and become a generic dynamic language to easily insert mock objects (among other things)? Sprinkle this with an
AspectJ-like syntax and you've got something quite nice!</p>
<p>I know I'm probably changing the original idea but what I'd love to have is a language purely geared towards unit testing</p>
<p>What do you think?</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-08-30T14:49:41+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000132_need_help_to_find_concept_map_software.html">
<title>Need help to find concept map software</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000132_need_help_to_find_concept_map_software.html</link>
<description><![CDATA[<p>About 2 years ago, I discovered the <a href="http://cmap.coginst.uwf.edu/">Concept Map</a> idea and I began to do a simple proof of concept as shown by the following diagram.</p>

<img alt="simple unit testing map" src="http://blogs.codehaus.org/people/vmassol/archives/unittesting.gif" width="733" height="377" border="0" />

<p>Note that more thorough examples are available from the <a href="http://cmex.coginst.uwf.edu/CMEX/Mars%20Spacecraft%20Mis.html">NASA web site</a>.</p>

<p>I would like to revive this idea and start drawing some concept maps about the JUnit ecosystem. I would like to have some of these
maps in my JUnit in Action book but I would also like to set up a collaborative web site gathering all knowledge around JUnit using 
these concept maps.</p>

<p>This is all nice but the software I used then (IHMC Concept Map Software) is now very old (2001), the GUI is flaky and the software
does not lend too well to distributed updating of the maps on the web (it uses a custom server which opens a specific TCP/IP port and 
thus does not easily allow updates behind a firewall, etc).</p>

<p>I need your help! My questions to you are:</p>
<ol>
<li>Do you know how this concept has evolved? Is it still a hot topics nowadays?</li>
<li>Do you know of any software (preferable free) that would allow me to easily draw maps such as the one above and allows collaborative editing over the web?</li>
</ol>

<p>Thanks!</p>

]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-08-26T17:53:00+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000098_evolving_javabased_apis_the_nightmare_of_binary_compatibility.html">
<title>Evolving Java-based APIs ... The nightmare of binary compatibility!</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000098_evolving_javabased_apis_the_nightmare_of_binary_compatibility.html</link>
<description><![CDATA[<p>I have been coding in java for the past 6 years and I thought I knew the language and platform 
quite well. Well, two days ago I was proved wrong as I discovered a new facet of it
that I wasn't aware of: binary compatibility...</p>

<p>There is a good article called <a href="http://eclipse.org/eclipse/development/java-api-evolution.html">Evolving Java-based APIs</a> by Jim des Rivieres.</p>

<p>It's a complex subject that not a lot of persons are aware of and which is extremely 
important if you're a framework writer. Let me give one example.</p>

<p>Imagine you have a <code>ServletTestCase
</code>
 public API class (i.e. users can use it)
and it inherits from an <code>AbstractTestCase
</code>
 class. This latter class is not
supposed to be used by end users. However, it has some public API methods accessed
through the <code>ServletTestCase
</code>
 by the users.</p>

<p>Now, if you think you can safely refactor the <code>AbstractTestCase
</code>
 class 
you're wrong! For example, if you wish to split the <code>AbstractTestCase
</code>
 class
in 2: <code>AbstractClientTestCase
</code>
 and <code>AbstractWebTestCase
</code>
, the
second one inheriting from the first, you're in for trouble...</p>

<p>Indeed, code that has been compiled with the first version of the framework will
have a reference to <code>AbstractTestCase
</code>
 in its .class files (provided it was using
methods inherited from <code>AbstractTestCase
</code>
). Thus when you bring in the new
framework and put it in the runtime classpath of your other code, it will fail with
a <code>NoClassDefFoundError
</code>
!</p>

<p>What it means is that preserving binary compatibility is difficult and is something
that strongly impacts how you design your APIs. Using delegation has to be preffered
over class inheritance as it will allow you to change the implementation without breaking
binary compatibility.</p>

<p>That's what was new to me. So far I had been designing simply using the OO concepts and 
choosing the pattern the most adapted. Now, I've discovered that I also need to introduce
the binary compatibility aspect in the picture and that it drives my design choices!</p>

<p>Evolving Java-based APIs is really difficult...</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-07-13T09:47:32+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000080_back_from_tsss.html">
<title>Back from TSSS</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000080_back_from_tsss.html</link>
<description><![CDATA[<p>I spent the last 4 days at the TSS Symposium in Boston. It was just great! I think I can say it was the best conference I've been to so far.
The speakers were great, and it was very well organized. Kudos to Floyd, Jay and their team.</p>
<p>I was able to meet all my "heroes of the web": <a href="http://blogs.atlassian.com/rebelutionary/">Mike Cannon-Brookes</a>, 
<a href="http://roller.anthonyeden.com/page/jcarreira">Jason Carreira</a>, 
<a href="http://www.freeroller.net/page/cpurdy/">Cameron Purdy</a>, 
<a href="http://beust.com/weblog">Cedric Beust</a>, 
<a href="http://hibernate.sourceforge.net/">Gavin King</a>, 
<a href="http://www.freeroller.net/page/hlship">Howard Lewis Ship</a>, 
<a href="http://www.ehatchersolutions.com/servlets/blogscene/">Erik Hatcher</a>
and I also met some others great guys I had not met online before: 
<a href="http://www.amazon.com/exec/obidos/tg/detail/-/1861007841/ref=cm_bg_f_1/103-6274960-3399024?v=glance">Rod Johnson</a>, 
<a href="http://www.nofluffjuststuff.com/speakers/Tate_spotlight.jsp">Bruce Tate</a>, 
<a href="http://christophe.batisseurs.com/author.htm">Christophe Ney</a>, 
<a href="http://www.ronin-intl.com/company/scottAmbler.html">Scott Ambler</a> and a few others (sorry if I forgot you).</p>
<p>I also met Marjan Bace from Manning, who is editing my <a href="http://www.manning.com/massol/">JUnit in Action book</a>.</p>
<p>To top it all, I won a Tivo (not sure it works in France but we shall see).</p>
<p>I had the chance to speak in front of this great audience and it was cool. The talks I presented were:</p>
<ul>
<li>Unit testing J2EE applications. <a href="http://www.pivolis.com/pdf/Unit_Testing_J2EE_V1.1.pdf">Here are the slides</a>. 
All source code for the examples in the slides are available on the 
<a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/junitbook/junitbook/">JUnit in Action code website on SourceForge</a> (all source code was donated to open source under an Apache Public License).</li>
<li>Building J2EE applications with Maven. <a href="http://www.pivolis.com/pdf/J2EE_projects_Maven_V1.1.pdf">Here are the slides</a>. The source code for the Maven Everest project described in the slides is available 
<a href="http://blogs.codehaus.org/people/vmassol/archives/everest.zip">here</a>.</li>
</ul>
<p>I was also invited to sit on the Open Source panel to answer the public's questions (along with Bill Burke, Christophe Ney, Gavin King, Mike Canon-Brookes and Erik Hatcher - Some pictures are available 
<a href="http://photos.autenroad.com/album13">here</a>) and finally 
I recorded a TSS Tech Talk on "Agile Offshore Software Development" (this is what we are doing at <a href="http://www.pivolis.com">Pivolis</a>).</p>
<p>I will not go in the detail of the sessions as it has already been well covered by Cameron and a few others (see <a href="http://www.freeroller.net/page/cpurdy/20030630#tss_symposium_links">Cameron's links</a>).
<p>I'm looking forward to the next TSSS. Would be cool if it were in Europe. Maybe we could also do it on a cruise boat next time!</p>
<p><i>PS: Mike, you were not the last one to blog about TSSS... :-)</i></p>
]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-07-03T20:13:44+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000066_theserverside_symposium.html">
<title>TheServerSide Symposium</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000066_theserverside_symposium.html</link>
<description><![CDATA[<p>In a few days, I'll fly to Boston for the
<a href="http://www.theserverside.com/symposium">TheServerSide symposium</a>. I'm doing 2 presentations there:</p>
<ul>
<li><b>Unit testing J2EE applications</b>: I will try to cover the full set of J2EE components using different techniques: MockObjects and Cactus. The hard part is understanding what each brings you and when to use them. I will also cover automating tests and continuous integration using Ant and Maven. I wanted to cover unit testing with an AOP framework but I'm not sure I'll have the time to research that enough... Most of the examples will be taken from my <a href="http://www.manning.com/massol">JUnit in Action</a> book.</li>
<li><b>Building a J2EE application with Maven</b>: This talk will explain Maven and I will then do a step by step build of a J2EE application, dividing the full projet into Maven projects and proposing a strategy for organizing a J2EE project. I will also cover continuous integration with Maven.</li>
</ul>
<p>If you're going there and want to meet up, leave me a message!</p>
<p>Note: I'm also looking forward to open a U.S. bank account there but I have no clue what paper I need to bring and how easy (or hard) it is. Any clue is most welcome :-)</p>
]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-06-22T20:21:34+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000039_javaone_2003_blogs.html">
<title>JavaOne 2003 blogs</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000039_javaone_2003_blogs.html</link>
<description><![CDATA[<p>Here are some persons that will be blogging from JavaOne 2003</p>
<ul>
<li><a href="http://www.simongbrown.com/blog/index.jsp">http://www.simongbrown.com/blog/index.jsp</a></li>
<li><a href="http://www.oreillynet.com/pub/au/113">http://www.oreillynet.com/pub/au/113</a></li>
<li><a href="http://www.eugenebelyaev.com/begblog/general/000014.html">http://www.eugenebelyaev.com/begblog/general/000014.html</a></li>
<li><a href="http://blog.fuzzymagic.com/blog/rss/sean">http://blog.fuzzymagic.com/blog/rss/sean</a></li>
<li><a href="http://blogs.application-servers.com/blogs/page/doj&mag/">http://blogs.application-servers.com/blogs/page/doj&mag/</a> [in French]</li>
<li><a href="http://www2.theserverside.com/rss/theserverside-0.9.rdf">http://www2.theserverside.com/rss/theserverside-0.9.rdf</a></li>
</ul>
<p>If you know others blogging from JavaOne, let me know and I'll add them.</p>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-06-08T21:55:16+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000036_eclipse_plugin_for_subversion.html">
<title>Eclipse plugin for Subversion</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000036_eclipse_plugin_for_subversion.html</link>
<description><![CDATA[<p>Some time ago, I <a href="http://blogs.codehaus.org/people/vmassol/archives/000008.html">blogged about Subversion</a>. One of things I noticed was the lack of a good Eclipse plugin.</p>
<p>Daniel Bradby has informed me he has just released an <a href="http://subclipse.sourceforge.net">Eclipse plugin</a> for Subversion.</p>
<p>I haven't tried it yet... If you have I'll be happy to know what you think.</p>
<p><b>Update 22/07/2004:</b> There is now a <a href="http://ar.geocities.com/itcrespo/eclipse/">TortoiseSVN wrapper plugin for Eclipse</a> which seems quite nice.</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-06-02T09:12:37+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000033_maven_checkstyle_plugin_now_supports_checkstyle_31.html">
<title>[Maven] Checkstyle plugin now supports Checkstyle 3.1</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000033_maven_checkstyle_plugin_now_supports_checkstyle_31.html</link>
<description><![CDATA[<p>I have just rewritten the <a href="http://maven.apache.org/reference/plugins/checkstyle/">Checkstyle plugin for Maven</a> (version is now 2.0) so that it supports the excellent <a href="http://checkstyle.sourceforge.net">Checkstyle</a> 3.1 tool.</p>
<p>The new plugin is currently located in <a href="http://cvs.apache.org/viewcvs.cgi/maven/src/plugins-build/checkstyle/">Maven CVS</a> and you need to build Maven from its sources to use it. In other words, it has not been released yet.</p>
<p>Note this new checkstyle plugin for Maven has only been tested with Maven 1.0 beta 10 and is not expected to work with other versions (but it may...)</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-05-30T16:09:21+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000030_book_junit_in_action.html">
<title>Book: JUnit In Action</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000030_book_junit_in_action.html</link>
<description><![CDATA[<p>I'm pleased to announce the new book I am writing with Ted Husted: <a href="http://www.amazon.com/exec/obidos/tg/detail/-/1930110995/qid=1053534165/sr=8-1/ref=sr_8_1/103-9369132-2572614?v=glance&s=books&n=507846">JUnit In Action</a>.</p>
<p>Here's the book description:</p>
<table>
  <tr><td><p>
A guide to unit testing Java applications (including J2EE applications) using the JUnit framework and its extensions, this book provides techniques for solving real-world problems such as unit testing legacy applications, writing real tests for real objects, automating tests, testing in isolation, and unit testing J2EE and database applications. Using a sample-driven approach, various unit testing strategies are covered, such as how to unit test EJBs, database applications, and how to unit test JSPs, and Taglibs. Also addressed are testing strategies using freely available open source frameworks and tools, and how to unit test in isolation with Mock Objects. Testing J2EE applications by running tests from inside the container for performing integration unit tests is discussed, as is how to automate unit testing in automated builds (such as Ant and Maven) for performing continuous integration.</p>
</td>
<td><img alt="JUnit in Action" src="http://codehaus.org/~vmassol/blog/jia.jpg" width="120" height="150" border="0" /></td>
</tr>
</table>
<p>The book will soon be part of the Manning Early-Access Program, which will allow subscribers to get access to all the book chapters as they are ready without having to wait for the book final publication.</p>]]></description>
<dc:subject>Personal events</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-05-27T10:16:17+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000028_maven_plugin_for_cactus_30_in_cvs.html">
<title>[Maven] Plugin for Cactus 3.0 in CVS</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000028_maven_plugin_for_cactus_30_in_cvs.html</link>
<description><![CDATA[<p>I have just committed a full rewrite of the <a href="http://maven.apache.org/reference/plugins/cactus/">Maven Cactus Plugin</a>. As it is a rewrite, I have increased the version to 3.0 (it was 2.1-SNAPSHOT before). Note that the 3.0 version is still in development and is not released yet. I'm waiting for more feedback before releasing it.</p>
<p>The new version of the Cactus plugin now relies on the newest Cactus/Ant integration which has completely changed since version 2.0 of the Maven plugin. Thanks to the new Cactus/Ant, some features have also been added. The plugin now uses the new <cactifywar> and <cactus> Ant tasks (see the <a href="http://jakarta.apache.org/cactus/integration/ant/index.html">Cactus/Ant Integration</a> page for more details).</p>
<p>Note that version 2.1-SNAPSHOT will never get released as 1/ a bug had been introduced and 2/ the direction is to use the Cactus/Ant integration which has been changed in Cactus CVS.</p>
<p>Please give it a try and report any issue on the Maven mailing lists/JIRA. You can find a read-made test application in <a href="http://cvs.apache.org/viewcvs.cgi/maven/src/plugins-build/cactus/sample/">here</a> if you wish.</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-05-23T22:31:05+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000023_project_documentation_wiki_cvs_ml_html.html">
<title>Project Documentation: Wiki -&gt; CVS -&gt; ML -&gt; HTML</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000023_project_documentation_wiki_cvs_ml_html.html</link>
<description><![CDATA[<p>Having project documentation written in XML (xdocs) and stored in the project's CVS is great as it allows changing the style without chasnging the content. It also allows to easily write directly the docs in XML format</p>
<p>That said, lots of persons do find that writing xdocs is a pain. Moreover wouldn't it be nice if end users could easily contribute to the documentation?</p>
<p>Here's a solution:</p>
<ul>
  <li>Use a Wiki for the project's web site. But not any wiki. Use a wiki that stores it's web pages in XML format, such as <a href="http://moin.sourceforge.net/">MoinMoin</a> (Here's an <a href="http://wiki.truemesh.com/mockobjects/FrontPage?action=format&mimetype=text/xml">example of generated XML</a>. Use View Source for IE users).</li>
  <li>Then write a hook (script) in that wiki so that the modifications get saved to your project's CVS (or even better use CVS as the underlying storage for the Wiki). <i>Question: is that directly supported by MoinMoin?</i></li>
  <li>(optional). Use a CVS syncmail script to send CVS commit diffs to the project's development mailing list. This allows everyone subscribed to see the changes to the documentation (and to the sources of course).</li>
  <li>(optional). Now that we have our XML doc sources saved in the project's CVS we can (if we wish) generate the docs in an HTML format different than the wiki we are using, for packaging them in the project's distirbution for example.</li>
</ul>
<p>Nice, no?</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-05-17T11:05:25+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000022_mock_objects_releases.html">
<title>Mock Objects Releases</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000022_mock_objects_releases.html</link>
<description><![CDATA[<p><a href="http://nmock.sourceforge.net/">NMock v1.0</a> has been released yesterday by Joe Walnes. It is a dynamic mock object library for .NET.</p>
<p>On a related note, I've released version 0.09 of the <a href="http://www.mockobjects.com">MockObjects.com</a> framework yesterday too. This release contains several improvements in provided Mock Objects but little modifications to the core, apart from the introduction of a new library: the Dynamic Mock API (or DynaMock for short). It is based on dynamic proxies (same as <a href="http://www.easymock.org">EasyMock</a> but I think with a more powerful and cleaner syntax), which means the mocks are created at runtime.</p>
<p><b>Warning</b>: This first cut of the DynaMock API is not stable at all. Actually, a big refactoring has happened in the MockObjects CVS and a better API has been developed (very similar but which fixes the quircks from the first cut). Thus, if you use this DynaMok API, be prepared to refactor your applications when version 0.10 is out!</p>
<p>Here is a short example using DynaMock 0.09:</p>
<div id="source"><pre>[...]
import com.mockobjects.constraint.Constraint;
import com.mockobjects.dynamic.C;
import com.mockobjects.dynamic.Mock;

public class TestAdminServlet extends TestCase
{
    private Mock mockRequest;
    private Mock mockResponse;
    private HttpServletRequest request;
    private HttpServletResponse response;
    private AdminServlet servlet;
    
    public void setUp()
    {
        servlet = new AdminServlet();

        mockRequest = new Mock(HttpServletRequest.class);
        request = (HttpServletRequest) mockRequest.proxy();

        mockResponse = new Mock(HttpServletResponse.class);
        response = (HttpServletResponse) mockResponse.proxy();
    }

    public void tearDown()
    {
        mockRequest.verify();
        mockResponse.verify();
    }
        
    public void testDoGet() throws Exception
    {
        mockRequest.expectAndReturn("getParameter", "command", 
            "SELECT...");

        // Verify that the result of executing the command has been
        // stored in the HTTP request as an attribute that will be
        // passed to the JSP page.
        mockRequest.expect("setAttribute", C.args(C.eq("result"), 
            C.isA(Collection.class)));

        servlet.doGet(request, response);
    }

}
</pre></div>
<p>Update: Thanks to Chris Lenz, fixed the testDoGet() method and removed not needed asserts</p>
]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-05-17T09:30:38+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000020_cactus_news_through_rss_feed.html">
<title>Cactus news through RSS feed</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000020_cactus_news_through_rss_feed.html</link>
<description><![CDATA[<p>I've just added a RSS feed for Jakarta Cactus news. It is available at <a href="http://jakarta.apache.org/cactus/news.rdf">http://jakarta.apache.org/cactus/news.rdf</a>.</p>
<p>The update process is quite nice too: we change the RDF file in CVS. Then every night Gump builds the <a href="http://cvs.apache.org/builds/gump/latest/jakarta-cactus-documentation.html">Cactus project documentation</a> (we transform the RDF file to HTML using XSLT in this process) and if the build is successful, upload it to <a href="http://jakarta.apache.org/cactus">http://jakarta.apache.org/cactus</a>. Thus we get automated updates from CVS to your RSS feed reader!</p>]]></description>
<dc:subject>Open source involvement</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-05-15T13:06:27+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000017_starteam_woes_followup.html">
<title>StarTeam woes (followup)</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000017_starteam_woes_followup.html</link>
<description><![CDATA[<p>Scott Stirling has posted a nice <a href="http://users.rcn.com/scottstirling/2003/05/13.html#a26">followup</a> of the initial <a href="http://blogs.codehaus.org/people/vmassol/archives/000008.html">StarTeam woes</a> I posted some time ago.</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-05-13T09:13:05+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000014_rss_feed_reader.html">
<title>Rss feed reader</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000014_rss_feed_reader.html</link>
<description><![CDATA[<p>I knew I was missing something! For some time I've had this feeling that everyone was enjoying some way of getting interesting news that I wasn't aware of... Now I know it was true... :-)</p>
<p>I've, at last, discovered the joy of RSS syndication. This is a revolution for me. I was used to opening my browser every morning and scanning my favorite sites... No longer. I'm now using <a href="http://www.feedreader.com">FeedReader</a>, a very nice windows application that automatically polls your favorite RSS feeds and displays them in a nice manner.</p>
<p>The other nice features are</p>
<ul>
  <li>automatic pop up notification when news arrive</li>
  <li>automatic scans for news every N minutes</li>
  <li>start automatically upon windows start up in the systray</li>
  <li>integrated browser (IE) for easy navigation</li>
</ul>
<p>To get you started, here is my list of <a href="http://blogs.codehaus.org/people/vmassol/subscriptions.xml">subscriptions</a> (FeedReader format). Drop this file in your <code>Documents and Settings/yourusername/Application Data/FeedReader
</code>
 directory or simply merge it with your existing subscription file.</p>
<p><b>Update:</b>: I've just discovered that there are some other very nice RSS feed readers (I haven't tried them yet though): <a href="http://www.yole.ru/projects/syndirella/">Syndirella</a> and <a href="http://www.hutteman.com/weblog/2003/04/06.html#000056">SharpReader</a>.</p>
<p><b>Update:</b>: Thanks to Scott Stirtling for the best <a href="http://www.hebig.org/blogs/archives/main/000877.php">RSS Feed Reader / News Aggregators Directory</a> he's seen.</p>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-05-12T11:24:03+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000008_subversion_pros_and_cons.html">
<title>Subversion pros and cons</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000008_subversion_pros_and_cons.html</link>
<description><![CDATA[<p>This morning I've started reading about <a href="http://subversion.tigris.org">Subversion</a>. I am very excited and have a few reservations. On the positive side:</p>
<ul>
  <li>Whenever you check out a file, the Subversion client puts a pristine copy of this file in a special .svn directory (equivalent to the CVS/ one for CVS). This means that whenever you later edit this file, Subversion is able to tell you <b>without going to the server</b> what changes you have made to the file. It is also able to revert your changes again without calling the server side. But the best is that when you perform a commit it is thus able to only send the <b>difference</b> whether you are working on text or binary files! That really rocks!</li>
  <li>Ability to version anything (directories, etc)</li>
  <li>Supports move of files, directories, branches, etc</li>
  <li>Uses HTTP(S) and WebDAV (well, a specific version of it see below)</li>
  <li> Some nice GUI clients (especially TortoiseSVN which I haven't tried but which looks very nice)</li>
  <li>Lots of another nice features described on the Subversion web site</li>
</ul>
<p>On the negative side, it is still missing the following to be perfect:</p>
<ul>
  <li>It does not support locks at all. CVS did not support locks but add the watch/edit feature which could be used (the current version of Subversion does not have this feature). Not having locks can be a pain when you have a big team working on binary files such as Word documents, Powerpint presentations, Rose .cat files, etc.</li>
  <li>Missing a nice Eclipse plugin (there is some work in progress but nothing visible at this point in time</li>
  <li>Does not really support the Generic WebDAV clients such as the WebFolder in Windows. Details about this can be found <a href="http://svnbook.red-bean.com/book.html#svn-app-d-sect-2">here</a>.
</ul>
]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-05-05T23:07:04+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/vmassol/archives/000007_starteam_woes.html">
<title>StarTeam woes</title>
<link>http://blogs.codehaus.org/people/vmassol/archives/000007_starteam_woes.html</link>
<description><![CDATA[I have been working on a new project with the StarTeam SCM. Here are the drawbacks I have found when using Starteam vs CVS/Subversion:
<ul>
  <li>No "clean checkout" option. That is, if a file is deleted from the StarTeam repository, even if you perform a checkout all, the deleted files will not be removed from your local working copy. 
    <ul><li>
    <b>Update:</b> Scott Stirling has told me that by using the StarTeam CLI, you can run <code>stcmd update-status $st_opts "$STARTEAM_URL" -cmp $ST_DEST
</code>
 and then <code>stcmd delete-local $st_opts "$STARTEAM_URL" -cmp $ST_DEST -filter N > /dev/null
</code>
. This is still far far more complex that just doing a <code>cvs update
</code>
 in CVS.
  </li></ul>
  </li>
  <li>No server-side hooks. For example there is no way to get email check-in notifications (containing diff of the check-in as with CVS/Subversion). The way to do it is to manually go in the StarTeam client GUI, check the 'out-of-dates' files and perform a manual diff for each file that you wish to check...</li>
  <li>StarTeam is very bandwidth intensive, especially if you work using the default locking mechanism. For every file that you need to edit, you'll need to acquire a lock which results in a network operation. There might be a mode to work without locks but that's not the way our StarTeam administrator has set it up (thus resulting in everyone chasing each other to release locks on files - quite improductive especially in a distributed development team...)</li>
  <li>Very expensive especially when compared with CVS/Subversion. It is so expensive that we only have a few floating livenses which means we get disconnected every 15 minutes to let others use the repository... :-(</li>
  <li>The StarTeam GUI does not show directories that are not in StarTeam, i.e. you don't know if there are directories that you have not yet committed!</li>
  <li>StarTeam does not have nice IDE integration like CVS has and the StarTeam GUI client is far from being as nice as TortoiseCVS for example, which integrates seamlessly in the Windows Exlporer. BTW, we've had to extend the Maven Changelog plugin to make it work with StarTeam (as it was only supporting CVS)...</li>
  <li>No user community, no place to easily ask questions, no dynamic...</li>
  <li>I haven't found yet the equivalent of ViewCVS for StarTeam but it may exist</li>
</ul>]]></description>
<dc:subject>Think tank</dc:subject>
<dc:creator>vmassol</dc:creator>
<dc:date>2003-05-05T23:06:29+00:00</dc:date>
</item>


</rdf:RDF>
