<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-34341551</id><updated>2011-10-14T21:17:32.848+01:00</updated><category term='install'/><category term='web application'/><category term='solr'/><category term='felix'/><category term='eprints'/><category term='path'/><category term='java 5'/><category term='development'/><category term='hosting'/><category term='adrian'/><category term='scaling'/><category term='release:prepare'/><category term='open source'/><category term='upgrade'/><category term='whiteboard pattern'/><category term='validation'/><category term='presentation'/><category term='roadmap'/><category term='EntityBroker'/><category term='quality assurance'/><category term='jslint'/><category term='accessibility'/><category term='bootcamp'/><category term='formatter'/><category term='license header'/><category term='css'/><category term='configuration'/><category term='spring'/><category term='fedora commons'/><category term='findbugs'/><category term='email'/><category term='performance'/><category term='developer'/><category term='privatepaste'/><category term='or09'/><category term='eclipse'/><category term='Marist College'/><category term='maintenance team'/><category term='community process'/><category term='training'/><category term='started'/><category term='DAO'/><category term='generator'/><category term='phpcs'/><category term='patch'/><category term='sakai'/><category term='facebook'/><category term='xml'/><category term='ajp'/><category term='dash'/><category term='RSF'/><category term='duraspace'/><category term='macintosh'/><category term='workshop'/><category term='pax-web'/><category term='authentication'/><category term='attribute name'/><category term='south africa'/><category term='Javascript'/><category term='start level'/><category term='text sharing'/><category term='schema'/><category term='keynote'/><category term='botcamp'/><category term='valencia'/><category term='best practices'/><category term='fieldtype'/><category term='pom'/><category term='sling'/><category term='release management'/><category term='maven2'/><category term='mailing list'/><category term='cloud'/><category term='OSX'/><category term='release plugin'/><category term='Groovy'/><category term='filter'/><category term='tetra'/><category term='stringbuilder'/><category term='java 6'/><category term='maven plugin'/><category term='start level service'/><category term='anniversary'/><category term='doccomment'/><category term='optimization'/><category term='dependency'/><category term='quality'/><category term='TSE'/><category term='framework'/><category term='testing'/><category term='cafe'/><category term='notification'/><category term='RAD tool'/><category term='plugins'/><category term='exclusion'/><category term='json'/><category term='compiler'/><category term='unicon'/><category term='svn'/><category term='subversion'/><category term='google'/><category term='rob'/><category term='setup'/><category term='scotland'/><category term='comment'/><category term='public'/><category term='online tools'/><category term='analyzer'/><category term='pastebin'/><category term='debugging'/><category term='debugger'/><category term='perl'/><category term='AJAX'/><category term='textfield'/><category term='aptana studio'/><category term='maven 2'/><category term='validator'/><category term='match'/><category term='apache felix'/><category term='grid'/><category term='string'/><category term='appbuilder'/><category term='entity broker'/><category term='address'/><category term='frontier'/><category term='ivy'/><category term='javaforge'/><category term='wicket'/><category term='plugin'/><category term='analysis'/><category term='jetty'/><category term='licensing'/><category term='eclipse plugin'/><category term='tuning'/><category term='range'/><category term='Grails'/><category term='learning'/><category term='markup'/><category term='update'/><category term='apache'/><category term='dspace'/><category term='bundle-fragment'/><category term='debug'/><category term='crash'/><category term='hibernate'/><category term='java collections list set map performance speed reference'/><category term='hyphen'/><category term='indenter'/><category term='OSGi'/><category term='apache sling'/><category term='spring framework'/><category term='REST'/><category term='php'/><category term='cpan'/><category term='header'/><category term='tutorial'/><category term='codesniffer'/><category term='configure'/><category term='strfield'/><category term='entity provider'/><category term='compatibility mode'/><category term='modules'/><category term='yslow'/><category term='web framework'/><category term='Java'/><category term='simplexml'/><category term='JDBC'/><category term='yahoo performance rules'/><category term='versioning'/><category term='privnote'/><category term='DeveloperHelperService'/><category term='GenericDao'/><category term='twitter'/><category term='closure'/><category term='text paste'/><category term='search'/><category term='find java conflict class duplicate'/><category term='winxp'/><category term='command line'/><category term='ddl'/><category term='Wiki'/><category term='failure'/><category term='bundle'/><category term='eurosakai'/><category term='profiling'/><category term='gmail'/><category term='open repositories'/><title type='text'>Aaron Zeckoski OpenSource</title><subtitle type='html'>Aaron Zeckoski is an open source developer working on projects like &lt;a href="http://sakaiproject.org/"&gt;Sakai&lt;/a&gt; and &lt;a href="http://www.dspace.org/"&gt;DSpace&lt;/a&gt;. This is a technical blog about Java, REST, OSGi, PHP, Spring, Python, and whatever else.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>54</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-34341551.post-9109300403377331368</id><published>2010-09-15T15:32:00.000+01:00</published><updated>2010-09-15T15:32:20.159+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='text paste'/><category scheme='http://www.blogger.com/atom/ns#' term='pastebin'/><category scheme='http://www.blogger.com/atom/ns#' term='privatepaste'/><category scheme='http://www.blogger.com/atom/ns#' term='privnote'/><category scheme='http://www.blogger.com/atom/ns#' term='text sharing'/><title type='text'>Sending text like a pro</title><content type='html'>These are great tools for sending chunks of text around to others. If you are a developer and used to using IM then tools like these are invaluable since they make your content readable or protect it from prying eyes.&lt;div&gt;&lt;ol&gt;&lt;li&gt;Pastebin (&lt;a href="http://pastebin.com/"&gt;http://pastebin.com/&lt;/a&gt;)&lt;br /&gt;Full featured, well supported, and fast. Pastebin has been around for awhile and has some very nifty options like automatic support for subdomains (e.g. &lt;a href="http://azeckoski.pastebin.com/"&gt;http://azeckoski.pastebin.com/&lt;/a&gt;), format highlight support, expiration, and even limited privacy settings.&lt;/li&gt;&lt;li&gt;Privnote (&lt;a href="https://privnote.com/"&gt;https://privnote.com/&lt;/a&gt;)&lt;br /&gt;This is great for sending someone a password, id number, or anything that you do not want to send over the open wire or via email. Once the user clicks the link and views the content it is deleted.&lt;br /&gt;The formatting of the text is lost here though so it is not good for sending formatted text.&lt;/li&gt;&lt;li&gt;Private Paste (&lt;a href="https://privatepaste.com/"&gt;https://privatepaste.com/&lt;/a&gt;)&lt;br /&gt;An excellent tool for sending along large blocks of formatted text that you do not want others to see. This supports expiration, format highlights and line numbering, and security key auth.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-9109300403377331368?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/9109300403377331368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=9109300403377331368' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/9109300403377331368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/9109300403377331368'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2010/09/sending-text-like-pro.html' title='Sending text like a pro'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3451371973764466201</id><published>2010-03-03T11:01:00.004Z</published><updated>2010-03-03T11:45:06.551Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='release management'/><category scheme='http://www.blogger.com/atom/ns#' term='quality assurance'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><category scheme='http://www.blogger.com/atom/ns#' term='maintenance team'/><title type='text'>EuroSakai: Sakai QA and How to get Involved</title><content type='html'>Alan Berg, Anthony Whyte, Jean-François Lévêque, and I finished our final two presentations at the &lt;a href="http://sakaiproject.org/sakai-european-regional-conference-2010"&gt;EuroSakai Valencia 2010&lt;/a&gt; conference today. The overall theme of these presentations was "Get Involved". The presentations are &lt;a href="http://confluence.sakaiproject.org/display/CNF/What+is+Sakai+QA"&gt;What is Sakai QA&lt;/a&gt; and &lt;a href="http://confluence.sakaiproject.org/display/CNF/10+ways+to+make+a+good+Sakai+release"&gt;10 ways to make a good Sakai release&lt;/a&gt; (my apologies to the attendees but 8:30am is just too early for a session). I hope that our main point got across and I hope we provided helpful information for those brave enough to attend.&lt;br /&gt;A few highlights for those who could not make it:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Alan did another Mexican wave&lt;/li&gt;&lt;li&gt;I (and others) was still half asleep during the morning session&lt;/li&gt;&lt;li&gt;Jean-François made a lot of food related jokes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://icanhascheezburger.com/"&gt;lolcatz&lt;/a&gt; were involved&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Our major theme was "Blood and Treasure" (stolen from Anthony Whyte). If you have assets (people) then you have blood to contribute. If you are looking for ways to get involved please consider these opportunities. If you answer yes to any of these questions, or even if you don't, you may want to sign up to participate in one of these teams.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://confluence.sakaiproject.org/display/MNT"&gt;Sakai Maintenance Team&lt;/a&gt; - are you a java developer? an SVN wizard? want to learn more about Sakai codebase? do you love issue management and/or JIRA? do you like to write unit tests?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://confluence.sakaiproject.org/display/REL"&gt;Release Management&lt;/a&gt; - are you a master of subversion? do you have a passion for merging code? are you running a 2.*.x branch in production?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://confluence.sakaiproject.org/display/REL"&gt;Quality Assurance&lt;/a&gt; - can you use a web browser? do you like trying every little thing in software? are you tired of hearing complaints from users after you upgrade?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The other primary and very critical way to get involved is with treasure. If you have some money you can spend on open source and/or Sakai then you have treasure. Consider putting this money into foundation dues or buying into commercial support. Check out the end of the &lt;a href="http://confluence.sakaiproject.org/display/CNF/What+is+Sakai+QA"&gt;What  is Sakai QA&lt;/a&gt; presentation for a few options to get involved when you have money but no people (or if you have money AND people).&lt;br /&gt;One final point from our talk. If you are involved, thank you. If you see others who are involved, please thank them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3451371973764466201?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3451371973764466201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3451371973764466201' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3451371973764466201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3451371973764466201'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2010/03/eurosakai-sakai-qa-and-how-to-get.html' title='EuroSakai: Sakai QA and How to get Involved'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-6586256983800942721</id><published>2010-03-02T16:37:00.003Z</published><updated>2010-03-02T18:26:21.156Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='bootcamp'/><category scheme='http://www.blogger.com/atom/ns#' term='unicon'/><category scheme='http://www.blogger.com/atom/ns#' term='eurosakai'/><category scheme='http://www.blogger.com/atom/ns#' term='valencia'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><category scheme='http://www.blogger.com/atom/ns#' term='maintenance team'/><title type='text'>EuroSakai Bootcamp</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_gYJbpIL6GOI/S41YJI9P2rI/AAAAAAAAACs/pbBsMmD2W0A/s1600-h/bootcamp-logo.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 296px; height: 68px;" src="http://3.bp.blogspot.com/_gYJbpIL6GOI/S41YJI9P2rI/AAAAAAAAACs/pbBsMmD2W0A/s320/bootcamp-logo.png" alt="" id="BLOGGER_PHOTO_ID_5444104438607239858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Anthony Whyte and I presented the &lt;a href="http://confluence.sakaiproject.org/display/BOOT/Bootcamp+Topics+%28Valencia+2010%29"&gt;programmers cafe bootcamp&lt;/a&gt; at &lt;a href="http://sakaiproject.org/sakai-european-regional-conference-2010"&gt;EuroSakai Valencia 2010&lt;/a&gt; on Monday March 1st. This also coincided with my first official act as a Uniconer (short for &lt;a href="http://www.unicon.net/"&gt;Unicon&lt;/a&gt; employee) and my first presentation as the &lt;a href="http://confluence.sakaiproject.org/display/MNT/Home"&gt;Sakai Maintenance Team&lt;/a&gt; lead.&lt;br /&gt;We had around 30 people in attendance with the majority from Spain. I felt like it went as well as these 1 day technical introductions to Sakai can reasonably go (i.e. a major overload for the participants) and I hope that the attendees had a good experience and learned something valuable. Anyone who wants to let us know what they thought of it can &lt;a href="http://www.surveymonkey.com/s/LX9SPNK"&gt;fill out our survey&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-6586256983800942721?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/6586256983800942721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=6586256983800942721' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6586256983800942721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6586256983800942721'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2010/03/eurosakai-bootcamp.html' title='EuroSakai Bootcamp'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_gYJbpIL6GOI/S41YJI9P2rI/AAAAAAAAACs/pbBsMmD2W0A/s72-c/bootcamp-logo.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-6209062627130667229</id><published>2010-03-02T16:14:00.005Z</published><updated>2010-03-02T18:28:32.400Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='best practices'/><category scheme='http://www.blogger.com/atom/ns#' term='eurosakai'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><title type='text'>EuroSakai presentation - Sakai Best Practices</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_gYJbpIL6GOI/S40-iQqcQ5I/AAAAAAAAACk/2cFK_Dxh8oY/s1600-h/Screen+shot+2010-03-02+at+17.13.23.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 230px;" src="http://1.bp.blogspot.com/_gYJbpIL6GOI/S40-iQqcQ5I/AAAAAAAAACk/2cFK_Dxh8oY/s320/Screen+shot+2010-03-02+at+17.13.23.png" alt="" id="BLOGGER_PHOTO_ID_5444076282870252434" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Alan Berg and I just finished our &lt;a href="http://confluence.sakaiproject.org/display/CNF/Sakai+Best+practices"&gt;presentation on Sakai Best Practices&lt;/a&gt; at &lt;a href="http://sakaiproject.org/sakai-european-regional-conference-2010"&gt;EuroSakai Valencia 2010&lt;/a&gt;. It started with a mexican wave (all Alan's fantastic idea) and included tips for creating JIRA tickets, an overview of best ways to take advantage of foundation resources, and some development best practices.&lt;br /&gt;One key point we made during the presentation bears repeating. In many ways the &lt;a href="http://sakaiproject.org/"&gt;Sakai&lt;/a&gt; community is a &lt;a href="http://www.communitywiki.org/en/DoOcracy"&gt;do-ocracy&lt;/a&gt;.&lt;br /&gt;&lt;blockquote&gt;A &lt;strong&gt;do-ocracy&lt;/strong&gt; is an  organizational structure in which individuals choose roles and tasks for  themselves and execute them. Responsibilities attach to people who &lt;strong&gt;do&lt;/strong&gt;  the work, rather than elected or selected officials.&lt;br /&gt;&lt;/blockquote&gt;I have also heard people refer to Sakai as a meritocracy and perhaps in some ways it is. But much more than that I think it is driven forward by those willing to act. I hope that we are encouraging people to get involved and act because that is the lifeblood of community source.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-6209062627130667229?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/6209062627130667229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=6209062627130667229' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6209062627130667229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6209062627130667229'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2010/03/eurosakai-presentation-sakai-best.html' title='EuroSakai presentation - Sakai Best Practices'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_gYJbpIL6GOI/S40-iQqcQ5I/AAAAAAAAACk/2cFK_Dxh8oY/s72-c/Screen+shot+2010-03-02+at+17.13.23.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-6223676564522364658</id><published>2009-08-28T14:09:00.005+01:00</published><updated>2009-08-28T14:43:06.389+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='validator'/><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='indenter'/><category scheme='http://www.blogger.com/atom/ns#' term='formatter'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='online tools'/><category scheme='http://www.blogger.com/atom/ns#' term='validation'/><title type='text'>Helpful online tools</title><content type='html'>These are a bunch of online tools which I find indispensable when I need to do some quick validation, encoding, or formatting/indenting.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;XML escaping - &lt;a href="http://escapehtmlforxml.com/"&gt;http://escapehtmlforxml.com/&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;XML indenting (critical when trying to read ugly XML) - &lt;a href="http://xmlindent.com/"&gt;http://xmlindent.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;JSlint (javascript code checker) - &lt;a href="http://www.jslint.com/"&gt;http://www.jslint.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;JSONlint (JSON validator and formatter) - &lt;a href="http://www.jsonlint.com/"&gt;http://www.jsonlint.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;W3C HTML validator - &lt;a href="http://validator.w3.org/"&gt;http://validator.w3.org/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;W3C CSS validator - &lt;a href="http://jigsaw.w3.org/css-validator/"&gt;http://jigsaw.w3.org/css-validator/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;WDG tools (web validators) - &lt;a href="http://htmlhelp.com/tools/"&gt;http://htmlhelp.com/tools/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;XHTML/CSS page validator - &lt;a href="http://xhtml-css.com/"&gt;http://xhtml-css.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;shell tools (xml, base64, md5/sha1, and more) - &lt;a href="http://www.shell-tools.net/"&gt;http://www.shell-tools.net/&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;Hope this list of tools is helpful!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-6223676564522364658?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/6223676564522364658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=6223676564522364658' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6223676564522364658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6223676564522364658'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/08/helpful-online-tools.html' title='Helpful online tools'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-8439735354016113647</id><published>2009-08-08T14:47:00.008+01:00</published><updated>2009-08-08T15:24:09.257+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='maven 2'/><category scheme='http://www.blogger.com/atom/ns#' term='licensing'/><category scheme='http://www.blogger.com/atom/ns#' term='license header'/><category scheme='http://www.blogger.com/atom/ns#' term='maven plugin'/><title type='text'>Easy license headers with maven</title><content type='html'>If you are like me you probably hate trying to maintain &lt;a href="http://www.apache.org/legal/src-headers.html"&gt;license headers&lt;/a&gt; on your source code files. It has to be done for pretty much all of my projects (since I deal in &lt;a href="http://en.wikipedia.org/wiki/Open_source"&gt;open source&lt;/a&gt; 99% of the time) but it is pure &lt;a href="http://www.thefreedictionary.com/drudgery"&gt;drudgery&lt;/a&gt;. I found a great &lt;a href="http://maven.apache.org/plugins/"&gt;plugin for maven 2&lt;/a&gt; which makes this a piece of cake (very easy). The &lt;a href="http://code.google.com/p/maven-license-plugin"&gt;maven-license-plugin&lt;/a&gt; can (optionally) check your source files for headers (you control which ones or just use the defaults) and add in or replace the headers for you. Forget about doing this manually anymore; those days are over. You just specify a license header template like this (i.e. create a file, I use LICENSE_HEADER):&lt;blockquote&gt;&lt;pre&gt;&lt;br /&gt;Copyright (C) ${year} ${holder} &lt;${contact}&gt;&lt;br /&gt;&lt;br /&gt;This file is part of ${name}.&lt;br /&gt;&lt;br /&gt;Licensed under the Apache License, Version 2.0 (the "License");&lt;br /&gt;you may not use this file except in compliance with the License.&lt;br /&gt;You may obtain a copy of the License at&lt;br /&gt;&lt;br /&gt; http://www.apache.org/licenses/LICENSE-2.0&lt;br /&gt;&lt;br /&gt;Unless required by applicable law or agreed to in writing, software&lt;br /&gt;distributed under the License is distributed on an "AS IS" BASIS,&lt;br /&gt;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br /&gt;See the License for the specific language governing permissions and&lt;br /&gt;limitations under the License.&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Then add something like this to your project pom.xml (in the &lt;span style="font-weight: bold;"&gt;build&lt;/span&gt; section under &lt;span style="font-weight: bold;"&gt;plugins&lt;/span&gt;):&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;plugin&amp;gt;&lt;br /&gt;&amp;lt;groupId&amp;gt;com.google.code.maven-license-plugin&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;lt;artifactId&amp;gt;maven-license-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;   &amp;lt;header&amp;gt;${basedir}/LICENSE_HEADER&amp;lt;/header&amp;gt;&lt;br /&gt;   &amp;lt;excludes&amp;gt;&lt;br /&gt;       &amp;lt;exclude&amp;gt;target/**&amp;lt;/exclude&amp;gt;&lt;br /&gt;       &amp;lt;exclude&amp;gt;m2-target/**&amp;lt;/exclude&amp;gt;&lt;br /&gt;       &amp;lt;exclude&amp;gt;**/*.properties&amp;lt;/exclude&amp;gt;&lt;br /&gt;   &amp;lt;/excludes&amp;gt;&lt;br /&gt;   &amp;lt;properties&amp;gt;&lt;br /&gt;       &amp;lt;name&amp;gt;${project.name}&amp;lt;/name&amp;gt;&lt;br /&gt;       &amp;lt;year&amp;gt;${project.inceptionYear}&amp;lt;/year&amp;gt;&lt;br /&gt;       &amp;lt;holder&amp;gt;Aaron Zeckoski&amp;lt;/holder&amp;gt;&lt;br /&gt;       &amp;lt;contact&amp;gt;azeckoski@gmail.com&amp;lt;/contact&amp;gt;&lt;br /&gt;   &amp;lt;/properties&amp;gt;&lt;br /&gt;   &amp;lt;encoding&amp;gt;UTF-8&amp;lt;/encoding&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;lt;executions&amp;gt;&lt;br /&gt;   &amp;lt;execution&amp;gt;&lt;br /&gt;       &amp;lt;goals&amp;gt;&lt;br /&gt;           &amp;lt;goal&amp;gt;check&amp;lt;/goal&amp;gt;&lt;br /&gt;       &amp;lt;/goals&amp;gt;&lt;br /&gt;   &amp;lt;/execution&amp;gt;&lt;br /&gt;&amp;lt;/executions&amp;gt;&lt;br /&gt;&amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You need to add in the plugin repo in the &lt;span style="font-weight: bold;"&gt;pluginRepositories&lt;/span&gt; section:&lt;pre class="brush:xml"&gt;&lt;br /&gt;&amp;lt;pluginRepository&amp;gt;&lt;br /&gt;&amp;lt;id&amp;gt;mc-release&amp;lt;/id&amp;gt;&lt;br /&gt;&amp;lt;url&amp;gt;http://mc-repo.googlecode.com/svn/maven2/releases&amp;lt;/url&amp;gt;&lt;br /&gt;&amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That config will cause the check to run on every build (ignoring properties files is a good idea since the plugin has trouble with them). Files with a missing license header will cause the build to fail ensuring you remember to run the command to format them. The properties you set there will fill in the &lt;span style="font-style: italic;"&gt;${field}&lt;/span&gt; vars in the license header template.&lt;br /&gt;&lt;br /&gt;Now run the maven command to check for license headers:&lt;br /&gt;&lt;blockquote style="font-family: courier new;"&gt;mvn license:check&lt;/blockquote&gt;or simply do a build (which will also run the check):&lt;br /&gt;&lt;blockquote style="font-family: courier new;"&gt;mvn clean install&lt;/blockquote&gt;You should get a report about the files missing license headers.&lt;br /&gt;Run this command and all the license headers will be added or updated to match your template:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;mvn license:format&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;One final note, you can remove all the license headers using "&lt;span style="font-family:courier new;"&gt;mvn license:remove&lt;/span&gt;". Very cool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-8439735354016113647?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/8439735354016113647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=8439735354016113647' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/8439735354016113647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/8439735354016113647'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/08/easy-license-headers-with-maven.html' title='Easy license headers with maven'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-5744920251575952843</id><published>2009-07-27T11:27:00.008+01:00</published><updated>2009-07-27T19:30:31.209+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='web application'/><category scheme='http://www.blogger.com/atom/ns#' term='tuning'/><category scheme='http://www.blogger.com/atom/ns#' term='analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='yslow'/><category scheme='http://www.blogger.com/atom/ns#' term='yahoo performance rules'/><category scheme='http://www.blogger.com/atom/ns#' term='profiling'/><title type='text'>Keys to High Performance Web Applications</title><content type='html'>I know &lt;a href="http://en.wikipedia.org/wiki/Web_application"&gt;web application&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Computer_performance"&gt;performance&lt;/a&gt; has been &lt;a href="http://www.eggheadcafe.com/articles/20010314.asp"&gt;discussed&lt;/a&gt; &lt;a href="http://dotnetslackers.com/articles/aspnet/ImproveWebApplicationPerformance.aspx"&gt;about&lt;/a&gt; &lt;a href="http://www.oreillynet.com/pub/a/javascript/2002/06/27/web_tuning.html"&gt;100&lt;/a&gt; &lt;a href="http://www.javaperformancetuning.com/tips/appservers.shtml"&gt;times&lt;/a&gt; &lt;a href="http://www.devx.com/webdev/Article/42277"&gt;before&lt;/a&gt;, but it bears repeating (if only briefly and mostly with links) since it is such an important topic.&lt;br /&gt;&lt;br /&gt;If you have never tried to ensure your web application will run well then my rule #1 is to not change your application architecture. Program performance is a &lt;a href="http://stevesouders.com/hpws/index.php"&gt;separate issue&lt;/a&gt; that rarely is a problem compared to &lt;a href="http://en.wikipedia.org/wiki/Latency_%28engineering%29#Packet-switched_networks"&gt;network latency&lt;/a&gt; and &lt;a href="http://www.die.net/musings/page_load_time/"&gt;server request overhead&lt;/a&gt;. I am not saying it is never a problem but you should try things that are much easier first before diving into a restructuring or a rewrite of your app (&lt;a href="http://www.codinghorror.com/blog/archives/001198.html"&gt;in most cases buying more hardware is cheaper&lt;/a&gt; and safer). As &lt;a href="http://en.wikiquote.org/wiki/Donald_Knuth"&gt;Donald Knuth&lt;/a&gt; says, "&lt;span style="font-style: italic;"&gt;Premature optimization is the root of all evil (or at least most of it) in programming&lt;/span&gt;"&lt;br /&gt;&lt;br /&gt;Now that you have done nothing to start (so far so good right?) it is time to do something. Get the &lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow analyzer&lt;/a&gt; for &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt; and run it against your web application. It will provide you with a report which you can use to identify possible performance issue. The &lt;a href="http://getfirebug.com/net.html"&gt;Firebug network monitor&lt;/a&gt; and to a lesser extent the &lt;a href="http://developer.apple.com/safari/library/documentation/AppleApplications/Conceptual/Safari_Developer_Guide/UsingtheWebInspector/UsingtheWebInspector.html"&gt;Safari Web Inspector&lt;/a&gt; are also good tools for profiling the requests on a page.&lt;br /&gt;Here is a list of a few more performance apps from the &lt;a href="http://www.razorspeed.com/blog/2009/07/02/build-high-performance-web-apps.html"&gt;RazorSpeed&lt;/a&gt; blog and around the web:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.httpwatch.com/"&gt;HttpWatch&lt;/a&gt; - browser plugin for IE and Firfox for profiling page loads&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/speed/page-speed/"&gt;PageSpeed&lt;/a&gt; - browser plugin for Firefox for profiling page loads&lt;/li&gt;&lt;li&gt;&lt;a href="http://stevesouders.com/hammerhead/"&gt;Hammerhead&lt;/a&gt; - an addon for Firebug for profiling page loads&lt;/li&gt;&lt;li&gt;&lt;a href="http://rockstarapps.com/joomla-1.5.8/products/jslex-web-optimizer/css-a-javascript-optimization.html"&gt;RockStar Optimizer&lt;/a&gt; - an eclipse plugin (&lt;a href="http://www.rockstarapps.com/update-beta"&gt;update site&lt;/a&gt;) for optimizing HTML/CSS/JS/IMG&lt;/li&gt;&lt;li&gt;&lt;a href="http://rockstarapps.com/joomla-1.5.8/products/razor-web-profiler/overview.html"&gt;Rockstar Profiler&lt;/a&gt; - a robust profiler application which uses proxies&lt;/li&gt;&lt;/ul&gt;No discussion of web app performance would be complete without including a link to &lt;a href="http://stevesouders.com/"&gt;Steve Souders' blog&lt;/a&gt;. While you are there check out &lt;a href="http://stevesouders.com/compare.php"&gt;compare&lt;/a&gt;. Some of the results are surprising and others not so much.&lt;br /&gt;&lt;br /&gt;Many tuning option are in the hands of your &lt;a href="http://en.wikipedia.org/wiki/System_administrator"&gt;system administrator&lt;/a&gt; so if that is not you then you can relax a little bit. However, as a web application developer (&lt;a href="http://en.wikipedia.org/wiki/Web_developer"&gt;frontend/web developer&lt;/a&gt; or backend engineer), you should at least know where the common problems lie and this is where the &lt;a href="http://developer.yahoo.com/performance/rules.html"&gt;bible of web application performance (Yahoo performance rules)&lt;/a&gt; comes in. It is a list of &lt;a href="http://en.wikipedia.org/wiki/Best_practice"&gt;best practices &lt;/a&gt;which can be roughly summarized as reduce requests, spread the load, utilize caching and compression, and structure pages for efficiency. If you want the shorter list then check out &lt;a href="http://stevesouders.com/hpws/rules.php"&gt;14 Rules for Faster-Loading Web Sites&lt;/a&gt; (it is just a list of rules taken from the bible with samples). If you prefer an alternative list then try the &lt;a href="http://code.google.com/speed/page-speed/docs/rules_intro.html"&gt;PageSpeed rules&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you are lucky you are using an environment that has performance tuning built in (like the &lt;a href="http://www.grails.org/plugin/ui-performance"&gt;grails ui performance plugin&lt;/a&gt; or the &lt;a href="http://www.rockstarapps.com/update-beta/"&gt;RockStarApps eclipse/aptana plugin&lt;/a&gt;) which will do most of what the performance rules suggest automatically (what can be done in the app anyway). Most web servers provide &lt;a href="http://httpd.apache.org/docs/2.0/mod/mod_deflate.html"&gt;support for compression&lt;/a&gt; so that usually is best handled at that layer anyway. For the rest of the best practices, you will just have to learn and apply the &lt;a href="http://developer.yahoo.com/performance/rules.html"&gt;performance rules best practices&lt;/a&gt;. In most cases it will be well worth your time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-5744920251575952843?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/5744920251575952843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=5744920251575952843' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5744920251575952843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5744920251575952843'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/07/keys-to-high-performance-web.html' title='Keys to High Performance Web Applications'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3264199723058826582</id><published>2009-07-20T16:00:00.005+01:00</published><updated>2009-07-20T16:11:05.912+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javaforge'/><category scheme='http://www.blogger.com/atom/ns#' term='authentication'/><category scheme='http://www.blogger.com/atom/ns#' term='hosting'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><category scheme='http://www.blogger.com/atom/ns#' term='public'/><title type='text'>JavaForge requires authn to access SVN</title><content type='html'>I went to setup an account on &lt;a href="http://javaforge.com/"&gt;JavaForge&lt;/a&gt; for &lt;a href="http://www.steeple.org.uk/"&gt;Steeple&lt;/a&gt; today. Everything went pretty smoothly with the initial setup. It was easy to create an account and setup a new project. The site allows for fine-grained permissions which are easy to configure and has a very nice wiki. It also included code analysis and build tools (which are why I decided to try it out in the first place).&lt;br /&gt;&lt;br /&gt;I hit the first bump after creating the &lt;a href="http://en.wikipedia.org/wiki/Subversion_%28software%29"&gt;SVN repository&lt;/a&gt;. I could not find the URL to the respository anywhere. After searching around for ahile I figured out that the URL was:&lt;br /&gt;&lt;a href="http://svn.javaforge.com/svn/steeple"&gt;http://svn.javaforge.com/svn/steeple&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The next issue, which ended up being insurmountable, was related to access to the SVN respository. Try as I might there was no way to allow public access to it. Anyone trying to access the public URL will receive a &lt;a href="http://en.wikipedia.org/wiki/Basic_access_authentication"&gt;basicauth&lt;/a&gt; challenge. Just to view the respository a user has to enter in the username of "anonymous" with a password of "anon". As a result I had to drop javaforge and go with my backup of &lt;a href="http://code.google.com/"&gt;google code&lt;/a&gt; for now.&lt;br /&gt;&lt;br /&gt;I did post a &lt;a href="http://javaforge.com/proj/forum/viewMessage.do?thread_id=49988&amp;amp;msg_id=49988&amp;amp;thread_members=true"&gt;question on the javaforge forums&lt;/a&gt; about this but from reading the other forum messages I think it is just not possible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3264199723058826582?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3264199723058826582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3264199723058826582' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3264199723058826582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3264199723058826582'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/07/javaforge-requires-authn-to-access-svn.html' title='JavaForge requires authn to access SVN'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-9044142083964876842</id><published>2009-07-16T12:30:00.009+01:00</published><updated>2009-07-16T14:42:56.104+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plugins'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='maven 2'/><category scheme='http://www.blogger.com/atom/ns#' term='closure'/><category scheme='http://www.blogger.com/atom/ns#' term='ivy'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>My first week with Groovy and Grails</title><content type='html'>I spent time over the last week learning about &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt; (a dynamic language for the JVM) and &lt;a href="http://www.grails.org/"&gt;Grails&lt;/a&gt; (a code by convention web application framework built on Groovy) so I thought I would write up my impressions and some of the fun things I learned.&lt;br /&gt;So you have a sense of where I am coming from, I am a long time Web applications and Java/PHP/Javascript/Perl developer. I am somewhat newer to Python and Ruby but I prefer Python. I am a &lt;a href="http://en.wikipedia.org/wiki/REST"&gt;REST&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Open_source"&gt;Open Source&lt;/a&gt; advocate when I am in the right mood.&lt;br /&gt;&lt;br /&gt;If you are totally unfamiliar with Groovy then I recommend you take a look at this post as it lays out the reasons why you might want to learn more about it:&lt;br /&gt;&lt;a href="http://codetojoy.blogspot.com/2009/06/case-for-groovy.html"&gt;http://codetojoy.blogspot.com/2009/06/case-for-groovy.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you know you are going to be writing web-apps then just skip Groovy and go straight for Grails. If you are looking to do some &lt;a href="https://scripting.dev.java.net/"&gt;JSR-223 (Java Scripting)&lt;/a&gt; stuff  (&lt;a href="http://groovy.codehaus.org/JSR+223+Scripting+with+Groovy"&gt;with Groovy&lt;/a&gt;) then Groovy is the place to focus on. Either way, you will need to get familiar with the basics of Groovy so look at these:&lt;br /&gt;&lt;a href="http://groovy.codehaus.org/Quick+Start"&gt;http://groovy.codehaus.org/Quick+Start&lt;/a&gt;&lt;br /&gt;&lt;a href="http://groovy.codehaus.org/Collections"&gt;http://groovy.codehaus.org/Collections&lt;/a&gt;&lt;br /&gt;Feel free to checkout some &lt;a href="http://azsandbox.googlecode.com/svn/trunk/groovy-experimenting/src/main/groovy/"&gt;sample Groovy scripts&lt;/a&gt; I made which illustrate many of the key concepts.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://groovy.codehaus.org/Getting+Started+Guide"&gt;Getting Started Guide&lt;/a&gt; for Groovy is huge and not really a very good place to try to get started unfortunately. That said, the &lt;a href="http://groovy.codehaus.org/Beginners+Tutorial"&gt;Beginners Tutorial&lt;/a&gt; is pretty good, especially the &lt;a href="http://groovy.codehaus.org/Tutorial+2+-+Code+as+data%2C+or+closures"&gt;section on closures&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you want to get going with Grails then it is a little bit easier since it mostly builds on Groovy. Grails borrows heavily from &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; so if you are familiar with it then things will come to you quickly. This is the best place to start (not surprisingly):&lt;br /&gt;&lt;a href="http://www.grails.org/Quick+Start"&gt;http://www.grails.org/Quick+Start&lt;br /&gt;&lt;/a&gt;I really liked the &lt;a href="http://www.grails.org/screencasts"&gt;screencasts&lt;/a&gt; (which are oddly &lt;a href="http://www.grails.org/Grails+Screencasts"&gt;located here&lt;/a&gt; also). They provided a nice introduction to Grails without much effort. When you are ready for a little more the &lt;a href="http://www.grails.org/Tutorials"&gt;tutorials&lt;/a&gt; are a good next step.&lt;br /&gt;&lt;br /&gt;Things I learned in no particular order:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Maven and Grails do not get along&lt;/span&gt; - There is some really &lt;a href="http://www.grails.org/Maven+Integration"&gt;weak maven integration&lt;/a&gt; available but it does not work very well. The structure of grails (e.g. src/groovy) does not match the maven standard structure (e.g. src/main/groovy). Mostly maven just allows you to run the grails build commands which is easier to do with grails itself. I struggled with this for awhile before just giving up on using maven.  The Grails team recommends using &lt;a href="http://grails.org/Ivy+Integration"&gt;Ivy&lt;/a&gt; if you want to add dependency management (or Grails plugins which are preferred if they are available).&lt;br /&gt;The grails and groovy artifacts are available in maven repositories which is nice.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Grails and Eclipse don't easily integrate&lt;/span&gt; - The &lt;a href="http://groovy.codehaus.org/Eclipse+Plugin"&gt;Groovy plugin&lt;/a&gt; is pretty good (not great) but the build integration is pretty poor and requires you to jump through hoops. It seems like the integration with &lt;a href="http://www.jetbrains.com/idea/"&gt;IDEA&lt;/a&gt; is a lot better and &lt;a href="http://www.grails.org/IDE+Integration"&gt;recommended by the Grails team&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Groovy supports closures&lt;/span&gt; - The &lt;a href="http://en.wikipedia.org/wiki/Closure_%28computer_science%29"&gt;closure&lt;/a&gt; &lt;a href="http://groovy.codehaus.org/Closures"&gt;support in groovy&lt;/a&gt; is great and very easy to use. I found myself writing closures like crazy (even more than in &lt;a href="http://www.javascriptkit.com/javatutors/closures.shtml"&gt;Javascript&lt;/a&gt;) and it made the code very clean.&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;NOTE:&lt;/span&gt; I ran across one weird bug where passing in a String[] to a closure causes it to be misinterpreted as a collection of separate arguments for each array entry. There are hacks to get around this but be aware that it may bite you.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Grails has a great plugin system&lt;/span&gt; - &lt;a href="http://www.grails.org/Plugins"&gt;Grails has a pretty powerful plugin system&lt;/a&gt; which allows easy extension of a grails app. The plugins seems to be &lt;a href="http://www.grails.org/doc/1.0.x/ref/Command%20Line/install-plugin.html"&gt;very easy to install&lt;/a&gt; and &lt;a href="http://www.grails.org/Creating+Plugins"&gt;fairly easy to write&lt;/a&gt;. There is &lt;a href="http://www.grails.org/The+Plug-in+Developers+Guide"&gt;a complete guide&lt;/a&gt; if you are interested in developing your own plugins.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Grails app creation puts in too much stuff&lt;/span&gt; - The structure generated by grails create-app has a lot of stuff in it which you will probably want to cleanup (like the hibernate plugin by default for example). There is no uninstall for plugins so just remove the dir of the plugin to get rid of it. Be careful to not leave in a lot of things you are not going to use and clean out the sample stuff under web-app as well.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Grails convention is not very flexible&lt;/span&gt; - Grails prides itself on "&lt;span style="font-style: italic;"&gt;code by convention&lt;/span&gt;" and "&lt;span style="font-style: italic;"&gt;convention over configuration&lt;/span&gt;" and it does a good job of establishing a lot of conventions. It takes a little while to get used to them but if you follow them then things are pretty easy. Unfortunately, this implies that it is possible to override the convention using configuration if needed and in many cases it is not. I have been bitten a few times already when I tried to do things that are not "on the rail".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Grails uses prototype.js by default&lt;/span&gt; - The built in javascript engine in Grails is the portal/multi-framework unfriendly prototype.js. I can't use it so I am playing around with using &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; instead (so far this is proving to be manageable). There is a &lt;a href="http://www.grails.org/jQuery+Plugin"&gt;jQuery plugin&lt;/a&gt; which helps make this easier.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I am still getitng used to things but I am not sure what Groovy/Grails gains me over using Jython/&lt;some&gt;. It seems like &lt;a href="http://www.jython.org/"&gt;Jython&lt;/a&gt; does everything Groovy does plus it has the massive &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; &lt;a href="http://www.python.org/community/"&gt;community&lt;/a&gt; for support.&lt;br /&gt;As far as &lt;a href="http://en.wikipedia.org/wiki/Scripting_language"&gt;scripting languages&lt;/a&gt; go I think I prefer &lt;a href="http://en.wikipedia.org/wiki/PHP"&gt;PHP&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Javascript"&gt;Javascript&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Python_%28programming_language%29"&gt;Python&lt;/a&gt;, and &lt;a href="http://en.wikipedia.org/wiki/Perl"&gt;Perl&lt;/a&gt; (in that order) over Groovy but this may just due to a lack of familiarity on my part.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-9044142083964876842?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/9044142083964876842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=9044142083964876842' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/9044142083964876842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/9044142083964876842'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/07/my-first-week-with-groovy-and-grails.html' title='My first week with Groovy and Grails'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-2557251706000337465</id><published>2009-07-04T01:01:00.004+01:00</published><updated>2009-07-07T14:24:04.443+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RAD tool'/><category scheme='http://www.blogger.com/atom/ns#' term='wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='appbuilder'/><category scheme='http://www.blogger.com/atom/ns#' term='update'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse plugin'/><title type='text'>Sakai AppBuilder Plugin updated to 0.8.7</title><content type='html'>The &lt;a href="http://confluence.sakaiproject.org/display/BOOT/Sakai+App+Builder"&gt;Sakai AppBuilder Eclipse Plugin&lt;/a&gt; is updated to a new version (0.8.8&lt;del&gt;0.8.7&lt;/del&gt;) which includes updates for &lt;a href="http://confluence.sakaiproject.org/display/REL/Kernel+1+%28K1%29"&gt;Sakai K1&lt;/a&gt; and support for &lt;a href="http://wicket.apache.org/"&gt;Wicket&lt;/a&gt;. Many thanks to &lt;a href="http://confluence.sakaiproject.org/display/%7Esteve.swinsburg/Home"&gt;Steve Swinsburg&lt;/a&gt; who did all the heavy lifting on this update. You can install the plugin using &lt;a href="http://confluence.sakaiproject.org/display/BOOT/Sakai+App+Builder"&gt;instructions here&lt;/a&gt; or update it to the new version from within eclipse if you have installed it before.&lt;br /&gt;&lt;blockquote&gt;The Sakai AppBuilder is a RAD tool that allows you to quickly create &lt;a href="http://sakaiproject.org/" rel="nofollow"&gt;Sakai&lt;/a&gt; webapp projects in &lt;a href="http://confluence.sakaiproject.org/display/BOOT/Eclipse+Tips" title="Eclipse Tips"&gt;Eclipse&lt;/a&gt; that will work in the &lt;a href="http://confluence.sakaiproject.org/display/BOOT/Developing+with+the+Sakai+Framework" title="Developing with the Sakai Framework"&gt;Sakai Framework&lt;/a&gt;. Use these as a basis for the projects that you want to make without all the busy work of creating the structures and adding in all the dependencies. You can choose various UI layer options and implementation types to get you started quickly.&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;NOTE:&lt;/span&gt; Updated for the 0.8.8 release (minor fix from 0.8.7)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-2557251706000337465?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/2557251706000337465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=2557251706000337465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/2557251706000337465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/2557251706000337465'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/07/sakai-appbuilder-plugin-updated-to-087.html' title='Sakai AppBuilder Plugin updated to 0.8.7'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-7875079012449213972</id><published>2009-07-01T15:22:00.004+01:00</published><updated>2009-07-01T15:54:38.348+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OSX'/><category scheme='http://www.blogger.com/atom/ns#' term='java 5'/><category scheme='http://www.blogger.com/atom/ns#' term='aptana studio'/><category scheme='http://www.blogger.com/atom/ns#' term='upgrade'/><category scheme='http://www.blogger.com/atom/ns#' term='java 6'/><category scheme='http://www.blogger.com/atom/ns#' term='crash'/><title type='text'>Aptana Studio 1.2 crash and upgrading to 1.3</title><content type='html'>I recently upgraded &lt;a href="http://java.sun.com/javase/6/"&gt;Java to version 1.6&lt;/a&gt; (build 1.6.0_13-b03-211) on my macbook pro running &lt;a href="http://www.apple.com/macosx/"&gt;OSX&lt;/a&gt; 10.5.7 (leopard). It was a bit of a chore but it mostly sped things up and allowed me to run some of the newer apps that require Java 6.&lt;br /&gt;&lt;br /&gt;I had a major casualty though when &lt;a href="http://www.aptana.com/studio"&gt;Aptana Studio&lt;/a&gt; stopped working. It would simply crash without even giving a decent error message and the logs were not helpful.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gYJbpIL6GOI/Skt4as5KAkI/AAAAAAAAACU/H8B1XQrES50/s1600-h/Aptana-1.2.7-error.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 114px;" src="http://2.bp.blogspot.com/_gYJbpIL6GOI/Skt4as5KAkI/AAAAAAAAACU/H8B1XQrES50/s320/Aptana-1.2.7-error.png" alt="" id="BLOGGER_PHOTO_ID_5353504982182789698" border="0" /&gt;&lt;/a&gt;I normally run the &lt;a href="http://www.aptana.com/studio/download"&gt;standalone version of Aptana Studio&lt;/a&gt; (1.2.7) which is built on &lt;a href="http://www.eclipse.org/"&gt;eclipse&lt;/a&gt; 3.2. This seems to no longer run on OSX and Java 6 so I went in search of a fix. After lots of &lt;a href="http://forums.aptana.com/"&gt;forum browsing&lt;/a&gt;, tweaking configurations, and reinstalling I ended up retiring version 1.2 and trying out version 1.3 (still in beta). It was hard to find the &lt;a href="http://www.aptana.com/blog/jlam/aptana_studio_andretti_alpha"&gt;1.3 downloads page so here is a link&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It installs quite easily and ran which was a major improvement. However, when I tried to install the features (plugins) I am used to, they all indicated that they were incompatible and would not install. This seemingly hopeless situation was actually easily fixed by updating Aptana Studio (&lt;span style="font-style: italic;"&gt;Help -&gt; Software Updates&lt;/span&gt;). Once that was done (definitely restart here) I installed the features (&lt;span style="font-style: italic;" class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;php&lt;/span&gt;&lt;span style="font-style: italic;"&gt;, &lt;/span&gt;&lt;span style="font-style: italic;" class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;pydev&lt;/span&gt;&lt;span style="font-style: italic;"&gt;, git&lt;/span&gt;) and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;plugins&lt;/span&gt; (&lt;span style="font-style: italic;"&gt;epic&lt;/span&gt;) that I like and everything seems to work fine again.&lt;br /&gt;&lt;br /&gt;Hopefully this will save someone a little pain.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-7875079012449213972?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/7875079012449213972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=7875079012449213972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/7875079012449213972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/7875079012449213972'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/07/aptana-studio-12-crash-and-upgrading-to.html' title='Aptana Studio 1.2 crash and upgrading to 1.3'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_gYJbpIL6GOI/Skt4as5KAkI/AAAAAAAAACU/H8B1XQrES50/s72-c/Aptana-1.2.7-error.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-2004488890619058348</id><published>2009-06-17T17:52:00.010+01:00</published><updated>2009-06-17T19:07:56.748+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='attribute name'/><category scheme='http://www.blogger.com/atom/ns#' term='dash'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='hyphen'/><category scheme='http://www.blogger.com/atom/ns#' term='simplexml'/><title type='text'>PHP dash in class and method names</title><content type='html'>I ran into what seems like a common issue when working with &lt;a href="http://php.net/"&gt;PHP&lt;/a&gt; and &lt;a href="http://php.net/manual/en/ref.simplexml.php"&gt;SimpleXML&lt;/a&gt; today. Parsing XML is normally pretty easy:&lt;pre class="brush: php"&gt;&amp;lt;?php&lt;br /&gt;header('Content-type: text/plain');&lt;br /&gt;&lt;br /&gt;$xmlData = &amp;lt;&amp;lt;&amp;lt;XML&lt;br /&gt;&amp;lt;?xml version='1.0'?&amp;gt;&lt;br /&gt;&amp;lt;trees&amp;gt;&lt;br /&gt; &amp;lt;fruit&amp;gt;&lt;br /&gt;   &amp;lt;apple name='apple' type='Deciduous' has-fruit='Y' /&amp;gt;&lt;br /&gt;   &amp;lt;pear name='pear' type='Deciduous' has-fruit='Y' /&amp;gt;&lt;br /&gt; &amp;lt;/fruit&amp;gt;&lt;br /&gt; &amp;lt;pine&amp;gt;&lt;br /&gt;   &amp;lt;white name='whitepine' type='Coniferous' has-fruit='N' /&amp;gt;&lt;br /&gt; &amp;lt;/pine&amp;gt;&lt;br /&gt;&amp;lt;/trees&amp;gt;&lt;br /&gt;XML;&lt;br /&gt;&lt;br /&gt;$xml = simplexml_load_string($xmlData);&lt;br /&gt;&lt;br /&gt;echo "Testing SimpleXml";&lt;br /&gt;echo "\n".$xmlData;&lt;br /&gt;echo "\nName:".$xml-&amp;gt;fruit-&amp;gt;apple-&amp;gt;getName();&lt;br /&gt;echo " Type:".$xml-&amp;gt;fruit-&amp;gt;apple-&amp;gt;attributes()-&amp;gt;type;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;Output:&lt;br /&gt;Name:apple Type:Deciduous&lt;br /&gt;&lt;br /&gt;However, if you decide to include a hyphen or a dash in the name of your attribute things get a bit more interesting. The code has to be adjusted since the name of a class method cannot contain "-". To make it work, the attribute name has to include braces and single quotes (e.g. "{'name'}").&lt;br /&gt;&lt;pre class="brush: php"&gt;echo "\n".$xmlData;&lt;br /&gt;echo "\nName:".$xml-&amp;gt;fruit-&amp;gt;apple-&amp;gt;getName();&lt;br /&gt;echo " Type:".$xml-&amp;gt;fruit-&amp;gt;apple-&amp;gt;attributes()-&amp;gt;type;&lt;br /&gt;echo "\nFruit?:".$xml-&amp;gt;fruit-&amp;gt;apple-&amp;gt;attributes()-&amp;gt;{'has-fruit'};&lt;br /&gt;&lt;/pre&gt;Output:&lt;br /&gt;Name:apple Type:Deciduous&lt;br /&gt;Fruit?:Y&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-2004488890619058348?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/2004488890619058348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=2004488890619058348' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/2004488890619058348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/2004488890619058348'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/06/php-dash-in-class-and-method-names.html' title='PHP dash in class and method names'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-964947210295482409</id><published>2009-06-12T14:19:00.008+01:00</published><updated>2009-06-12T15:14:49.323+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='analyzer'/><category scheme='http://www.blogger.com/atom/ns#' term='solr'/><category scheme='http://www.blogger.com/atom/ns#' term='schema'/><category scheme='http://www.blogger.com/atom/ns#' term='textfield'/><category scheme='http://www.blogger.com/atom/ns#' term='strfield'/><category scheme='http://www.blogger.com/atom/ns#' term='filter'/><category scheme='http://www.blogger.com/atom/ns#' term='search'/><category scheme='http://www.blogger.com/atom/ns#' term='fieldtype'/><category scheme='http://www.blogger.com/atom/ns#' term='failure'/><title type='text'>Tricky SOLR schema issue with StrField</title><content type='html'>I have been setting up &lt;a href="http://lucene.apache.org/solr"&gt;SOLR&lt;/a&gt; (version 1.3) as a search index for the &lt;a href="http://www.darwinproject.ac.uk/"&gt;Darwin Correspondence project&lt;/a&gt;. While making a few changes I ran into a really annoying issue today related to the way the schema configuration works. The &lt;a href="http://wiki.apache.org/solr/SchemaXml"&gt;SOLR schema&lt;/a&gt; (schema.xml) allows you to setup &lt;a href="http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters"&gt;Analyzers and Filters&lt;/a&gt; which allow control of how terms are indexed and searches are executed.&lt;br /&gt;&lt;br /&gt;I needed to make it so we could match names when the case is not exact and when the chars are special (i.e. "u" needs to match a name with "ü"). The field started out like this:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;fieldType name="name" class="solr.StrField" sortMissingLast="true" omitNorms="true" compressed="false" indexed="true" stored="true"&amp;gt;&lt;br /&gt;&lt;/pre&gt;For my first attempt I added an analyzer to the field like so:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;fieldType name="name" class="solr.StrField" sortMissingLast="true" omitNorms="true" compressed="false" indexed="true" stored="true"&amp;gt;&lt;br /&gt;&amp;lt;analyzer type="index"&amp;gt;&lt;br /&gt;  &amp;lt;tokenizer class="solr.HTMLStripStandardTokenizerFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.StandardFilterFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.ISOLatin1AccentFilterFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.LowerCaseFilterFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.TrimFilterFactory" /&amp;gt;&lt;br /&gt;&amp;lt;/analyzer&amp;gt;&lt;br /&gt;&amp;lt;analyzer type="query"&amp;gt;&lt;br /&gt;  &amp;lt;tokenizer class="solr.StandardTokenizerFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.LowerCaseFilterFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.RemoveDuplicatesTokenFilterFactory"/&amp;gt;&lt;br /&gt;&amp;lt;/analyzer&amp;gt;&lt;br /&gt;&amp;lt;/fieldType&amp;gt;&lt;br /&gt;&lt;/pre&gt;I loaded data into SOLR and tried out some searches and go no results. I was getting exact matches only (as if I had no analyzers). When I checked the solr admin analysis page it indicated that the filters were working and the tests there even seemed to show that things were ok. Unfortuantely, I found out that SOLR does not actually execute the analyzers if the field class is set to &lt;span style="font-weight: bold;"&gt;solr.StrField&lt;/span&gt;. It doesn't fail or indicate errors in the logs but your searches will not work the way you expect them to. Changing the field over to class &lt;span style="font-weight: bold;"&gt;solr.TextField&lt;/span&gt; fixed the problem.&lt;br /&gt;The correct configuration for the field is this:&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;fieldType name="name" class="solr.TextField" sortMissingLast="true" omitNorms="true" compressed="false" indexed="true" stored="true"&amp;gt;&lt;br /&gt;&amp;lt;analyzer type="index"&amp;gt;&lt;br /&gt;  &amp;lt;tokenizer class="solr.HTMLStripStandardTokenizerFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.StandardFilterFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.ISOLatin1AccentFilterFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.LowerCaseFilterFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.TrimFilterFactory" /&amp;gt;&lt;br /&gt;&amp;lt;/analyzer&amp;gt;&lt;br /&gt;&amp;lt;analyzer type="query"&amp;gt;&lt;br /&gt;  &amp;lt;tokenizer class="solr.StandardTokenizerFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.LowerCaseFilterFactory"/&amp;gt;&lt;br /&gt;  &amp;lt;filter class="solr.RemoveDuplicatesTokenFilterFactory"/&amp;gt;&lt;br /&gt;&amp;lt;/analyzer&amp;gt;&lt;br /&gt;&amp;lt;/fieldType&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I spent a few hours figuring this out so I hope that this saves someone a little time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-964947210295482409?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/964947210295482409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=964947210295482409' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/964947210295482409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/964947210295482409'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/06/tricky-solr-schema-issue-with-strfield.html' title='Tricky SOLR schema issue with StrField'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3115786005710708169</id><published>2009-05-25T10:08:00.009+01:00</published><updated>2009-05-25T15:25:51.751+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='doccomment'/><category scheme='http://www.blogger.com/atom/ns#' term='codesniffer'/><category scheme='http://www.blogger.com/atom/ns#' term='comment'/><category scheme='http://www.blogger.com/atom/ns#' term='header'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='phpcs'/><title type='text'>PHP CodeSniffer tips</title><content type='html'>I really love tools which help my code be more correct and more readable. I have referred to tools like &lt;a href="http://www.jslint.com/"&gt;JSLint&lt;/a&gt; (JS) and &lt;a href="http://findbugs.sourceforge.net/"&gt;FindBugs&lt;/a&gt; (Java) in previous posts and now I am going to write some tips about using &lt;a href="http://pear.php.net/package/PHP_CodeSniffer"&gt;PHP CodeSniffer&lt;/a&gt; (PHP) (a.k.a. phpcs). It is probably the most aggressive of the three and can be especially tricky on the requirements it puts on your file headers.&lt;br /&gt;&lt;br /&gt;Here is a sample file header:&lt;pre class="brush: php"&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;/**&lt;br /&gt;* Presto - a lightweight REST framework for PHP&lt;br /&gt;*&lt;br /&gt;* Presto is a simple to use and very lightweight REST framework for PHP,&lt;br /&gt;* it will help you to handle rest routing and input/output of data without&lt;br /&gt;* getting in your way&lt;br /&gt;*&lt;br /&gt;* PHP Version 5&lt;br /&gt;*&lt;br /&gt;* LICENSE:&lt;br /&gt;* Licensed under the Apache License, Version 2.0 (the "License");&lt;br /&gt;* you may not use this file except in compliance with the License.&lt;br /&gt;* You may obtain a copy of the License at&lt;br /&gt;* http://www.apache.org/licenses/LICENSE-2.0&lt;br /&gt;* Unless required by applicable law or agreed to in writing, software&lt;br /&gt;* distributed under the License is distributed on an "AS IS" BASIS,&lt;br /&gt;* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br /&gt;* See the License for the specific language governing permissions and&lt;br /&gt;* limitations under the License.&lt;br /&gt;*&lt;br /&gt;* @category  File&lt;br /&gt;* @package   Presto&lt;br /&gt;* @author    Aaron Zeckoski &amp;lt;azeckoski@vt.edu&amp;gt;&lt;br /&gt;* @copyright 2009 Aaron Zeckoski&lt;br /&gt;* @license   http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0&lt;br /&gt;* @version   SVN: $Id:$&lt;br /&gt;* @link      https://link/to/your/project/site&lt;br /&gt;* @since     inception&lt;br /&gt;*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A few comments about the header:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The copyright cannot have a comma after the year but the year can be a range. "2002-2009 AZ" is ok, "2009, AZ" is not&lt;/li&gt;&lt;li&gt;The license should appear inside the header like shown, not above it (this would cause an ERROR in phpcs)&lt;/li&gt;&lt;li&gt;The alignment of the data after the tags (e.g. @license, @version) is not optional, misaligned data causes an ERROR&lt;/li&gt;&lt;/ul&gt;Sample class:&lt;pre class="brush: php"&gt;&lt;br /&gt;/**&lt;br /&gt;* My class which does some stuff&lt;br /&gt;*&lt;br /&gt;* @category Class&lt;br /&gt;* @package  Presto&lt;br /&gt;* @author   Aaron Zeckoski &amp;lt;azeckoski@vt.edu&amp;gt;&lt;br /&gt;* @license  http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0&lt;br /&gt;* @link     https://link/to/the/project/again&lt;br /&gt;*/&lt;br /&gt;class RestController&lt;br /&gt;{&lt;br /&gt; const DEFAULT_RESOURCES_DIR = 'resources';&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * This is a method in my class&lt;br /&gt;  *&lt;br /&gt;  * @param object $_resourcesPath [optional] the resource path&lt;br /&gt;  *&lt;br /&gt;  * @return void&lt;br /&gt;  */&lt;br /&gt; protected function loadResources($_resourcesPath = self::DEFAULT_RESOURCES_DIR)&lt;br /&gt; {&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There are also a few of the rules about classes that caught me out as well:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Class methods must use camelCase. myMethodName is good, my_method_name is not&lt;/li&gt;&lt;li&gt;Classes MUST have a comment on them and it has to include a lot of the fields from the header. The ones I list in the sample above are the minimum (seriously).&lt;/li&gt;&lt;li&gt;The space between @params and @return is not optional&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Just a note on constants in PHP, you use &lt;span style="font-weight: bold;"&gt;const&lt;/span&gt; inside classes and &lt;span style="font-style: italic;"&gt;define&lt;/span&gt; outside&lt;/li&gt;&lt;/ul&gt;Take a look at the sample file and class headers here for more details: &lt;a href="http://pear.php.net/manual/en/standards.sample.php"&gt;http://pear.php.net/manual/en/standards.sample.php&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3115786005710708169?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3115786005710708169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3115786005710708169' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3115786005710708169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3115786005710708169'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/05/php-codesniffer-tips.html' title='PHP CodeSniffer tips'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-2115092917082673484</id><published>2009-05-24T00:57:00.002+01:00</published><updated>2009-05-24T01:29:49.313+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eprints'/><category scheme='http://www.blogger.com/atom/ns#' term='plugins'/><category scheme='http://www.blogger.com/atom/ns#' term='or09'/><category scheme='http://www.blogger.com/atom/ns#' term='open repositories'/><category scheme='http://www.blogger.com/atom/ns#' term='duraspace'/><category scheme='http://www.blogger.com/atom/ns#' term='fedora commons'/><category scheme='http://www.blogger.com/atom/ns#' term='dspace'/><title type='text'>Open Repositories 09 developer view</title><content type='html'>I just got back from the &lt;a href="https://or09.library.gatech.edu/"&gt;Open Repositories 2009&lt;/a&gt; conference in Atlanta, GA, US and wanted to highlight a few things which were interesting to me (from a developer's perspective).&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Pluggable (extendable) repository systems&lt;br /&gt;&lt;a href="http://wiki.dspace.org/index.php/DSpace_2.0"&gt;DSpace 2&lt;/a&gt; was initially designed to support plugins and there were some suggestions which will improve it further. The &lt;a href="http://www.eprints.org/"&gt;Eprints&lt;/a&gt; team showed off a really cool proof of concept of a plugins store which allows browsing, downloading, and installing from within eprints. The &lt;a href="http://www.fedora-commons.org/"&gt;Fedora Commons&lt;/a&gt; team indicated interest in using &lt;a href="http://www.osgi.org/Main/HomePage"&gt;OSGi&lt;/a&gt; to manage their services and enable plugin points.&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;ReST&lt;/a&gt; interfaces&lt;br /&gt;All the major systems have some &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;ReST&lt;/a&gt; in place now and are working on having fully &lt;a href="http://microformats.org/wiki/rest/urls"&gt;restful&lt;/a&gt; access available in the fairly near future. I think (and hope) this will lead to more mashup style integrations and easier access to repository data which can only be a good thing.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://duraspace.org/"&gt;DuraSpace&lt;/a&gt;&lt;br /&gt;The merging of the &lt;a href="http://www.dspace.org/"&gt;DSpace&lt;/a&gt; and Fedora Commons communities into &lt;a href="http://duraspace.org/"&gt;DuraSpace&lt;/a&gt; is cool because it means 2 teams of great developers will now be one. They also showed off the DuraCloud distributed storage service which is interesting from a scaling and backup perspective.&lt;/li&gt;&lt;li&gt;&lt;a href="http://dev8d.jiscinvolve.org/2009/05/20/repochallenge-winners/"&gt;Developer Repo Challenge&lt;/a&gt;&lt;br /&gt;There were some really cool projects and ideas demonstrated for the repo challenge. My personal favorite was the EprintsAppStore. I also really liked the FedoraFS entry from a technical coolness perspective and MentionIt (the winner) for its simplicity.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-2115092917082673484?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/2115092917082673484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=2115092917082673484' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/2115092917082673484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/2115092917082673484'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/05/open-repositories-09-developer-view.html' title='Open Repositories 09 developer view'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-2563091716535797323</id><published>2009-05-19T14:39:00.006+01:00</published><updated>2009-05-19T16:48:13.703+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='start level service'/><category scheme='http://www.blogger.com/atom/ns#' term='start level'/><category scheme='http://www.blogger.com/atom/ns#' term='compatibility mode'/><category scheme='http://www.blogger.com/atom/ns#' term='bundle'/><title type='text'>OSGi system and bundle start levels</title><content type='html'>&lt;a href="http://www.osgi.org/"&gt;OSGi&lt;/a&gt; has a concept of start levels. This is fairly well documented in the &lt;a href="http://www.osgi.org/download/r4v41/r4.core.pdf"&gt;r4 core spec&lt;/a&gt; but there seems to be some confusion around how they work so here is a quick summary for my own reference (and in case it helps anyone else).&lt;br /&gt;&lt;br /&gt;Start Levels determine the start order of bundles (not services). There are two types of start levels in an OSGi system. The system start level and the bundle start level (set for each bundle). The default start level of an OSGi system will be 1 (this is called the &lt;span style="font-style: italic;"&gt;beginning start level&lt;/span&gt; and can be configured) and the bundles installed in an OSGi system will use the default start level when they are installed unless this is changed manually. An OSGi system has a current level (called the &lt;span style="font-style: italic;"&gt;active start level&lt;/span&gt;) which determines the bundles which are allowed to be started. If a bundle has a start level higher than the active start level it will not start when the OSGi system starts up and it will not start if given a manual start command. If the active start level increases to be greater than or equal to the level of the bundle it will be started. Likewise, if the active start level changes to be below the level of a bundle, it will be shutdown.&lt;br /&gt;&lt;br /&gt;Here are a few points about start levels that were not completely obvious to me:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The bundles at a given start level will all have their &lt;span style="font-style: italic;"&gt;start()&lt;/span&gt; method completely executed before any bundles at a higher level are started. Start order within the start level is indeterminate.&lt;/li&gt;&lt;li&gt;When the active start level is changed, the system will move in increments of 1 until the desired level is reached. For example, from 5 to 10 means the system will do 6, 7, 8, 9, and finally 10.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If the start level is changed many times rapidly it must completely reach all requested levels in sequence. The system will not give up on level 3 if it was requested and has not been reached yet just because level 15 was requested while it was moving to level 3.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The system bundle is always located at start level 0. This cannot be changed.&lt;/li&gt;&lt;li&gt;Start level should &lt;span style="font-weight: bold;"&gt;NOT&lt;/span&gt; be used as a way to control service startup order. This is considered a programming error in OSGi as service start orders are not guaranteed and services may come and go at will.&lt;/li&gt;&lt;li&gt;Start level can be used as a way to reduce load on a system by setting non-critical parts as high start levels. This allows the level to be reduced in order to reduce the load and shutdown non-critical services and bundles.&lt;/li&gt;&lt;li&gt;OSGi has a compatibility mode which forces all bundles to use start level 1 (this is a good way to check to make sure you are not depending on the start levels as a way to ensure service start order).&lt;/li&gt;&lt;/ul&gt;NOTE: If you are working with &lt;a href="http://felix.apache.org/"&gt;apache felix 1.6.0&lt;/a&gt; there is a confusing error in the default config file. The system start level property is commented out as &lt;span style="font-style: italic;"&gt;org.osgi.framework.startlevel&lt;/span&gt; but the correct value is &lt;span style="font-style: italic;"&gt;org.osgi.framework.startlevel.beginning&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.osgi.org/download/r4v41/r4.core.pdf"&gt;OSGi spec&lt;/a&gt; (section 8, page 2o3) has more details about start levels.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-2563091716535797323?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/2563091716535797323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=2563091716535797323' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/2563091716535797323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/2563091716535797323'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/05/osgi-system-and-bundle-start-levels.html' title='OSGi system and bundle start levels'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-6336729507429954761</id><published>2009-04-27T16:08:00.006+01:00</published><updated>2009-04-27T17:31:37.318+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OSX'/><category scheme='http://www.blogger.com/atom/ns#' term='install'/><category scheme='http://www.blogger.com/atom/ns#' term='macintosh'/><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='frontier'/><category scheme='http://www.blogger.com/atom/ns#' term='cpan'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Installing perl modules in OSX</title><content type='html'>This should not have been hard but it ended up being a big pain for me so I thought I would document the process for installing a perl module on Mac OSX. It ended up being tricky because there were two ways I found to do it. I will first list the way I ended up NOT using.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Install &lt;a href="http://developer.apple.com/TOOLS/xcode/"&gt;Xcode&lt;/a&gt; - this is required for installing and running darwin ports (a.k.a macports)&lt;br /&gt;This is a disk image with a binary installer which is about 900 MBs in size and takes a few minutes to install, it also requires an &lt;a href="https://connect.apple.com/"&gt;apple developer connection&lt;/a&gt; membership before you can download it&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Install &lt;a href="http://darwinports.com/"&gt;DarwinPorts&lt;/a&gt; - this is required for installing yum&lt;br /&gt;Download the disk image and run the binary installer, you have to fill in your name and email address to download&lt;br /&gt;Run this command as root once you finish running the installer:&lt;span align="left"&gt;&lt;pre&gt;sudo port -d selfupdate&lt;/pre&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span align="left"&gt;Install &lt;a href="http://yum.darwinports.com/"&gt;Yum&lt;/a&gt; - this is required to install the perl module&lt;br /&gt;Run this command (takes a long long time) to as root to cause darwin ports to install yum:&lt;br /&gt;&lt;pre&gt;sudo port install yum&lt;/pre&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span align="left"&gt;Use yum to install the perl module&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;yum -y install perl-Frontier-RPC&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;After doing all this and facing failure I searched around more and found the instructions here:&lt;br /&gt;&lt;a href="http://triopter.com/archive/how-to-install-perl-modules-on-mac-os-x-in-4-easy-steps/"&gt;http://triopter.com/archive/how-to-install-perl-modules-on-mac-os-x-in-4-easy-steps/&lt;/a&gt;&lt;br /&gt;For the same module (Frontier) the commands ended up being (after installing Xcode, much like linux):&lt;br /&gt;&lt;pre&gt;sudo su&lt;br /&gt;perl -MCPAN -e shell&lt;br /&gt;install Frontier::Client&lt;br /&gt;&lt;/pre&gt;This worked out a lot better for me (though the process took about 15 minutes total). Make sure you run this as root since it will produce lots of fun failures otherwise.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-6336729507429954761?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/6336729507429954761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=6336729507429954761' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6336729507429954761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6336729507429954761'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/04/installing-perl-modules-in-osx.html' title='Installing perl modules in OSX'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-6372264406680070297</id><published>2009-04-16T13:21:00.005+01:00</published><updated>2009-04-17T07:51:22.523+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bundle-fragment'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='configure'/><category scheme='http://www.blogger.com/atom/ns#' term='pax-web'/><category scheme='http://www.blogger.com/atom/ns#' term='apache felix'/><category scheme='http://www.blogger.com/atom/ns#' term='ajp'/><category scheme='http://www.blogger.com/atom/ns#' term='apache sling'/><title type='text'>Configuring Jetty in the pax-web OSGi bundle</title><content type='html'>It took awhile for me to figure out how to configure &lt;a href="http://www.mortbay.org/jetty/"&gt;Jetty&lt;/a&gt; as deployed in the &lt;a href="http://wiki.ops4j.org/display/paxweb/Pax+Web"&gt;pax-web&lt;/a&gt; web service bundle. It took even longer to figure out how to enable AJP in Jetty using the bundle fragment. Unfortunately, &lt;a href="http://wiki.ops4j.org/display/paxweb/Advanced+Jetty+Configuration"&gt;the steps on the pax-web site&lt;/a&gt; are incorrect (now fixed: 2009-04-17) for the current version of pax-web (0.6.0). Hopefully this will save someone else from having to go through this "fun".&lt;br /&gt;&lt;br /&gt;Note that this will only work in pax-web version 0.5.2 or higher and requires an OSGi container that supports OSGi bundle fragments. I was doing this in Felix 1.6.0 (inside Sling).&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Checkout my bundle fragment source code&lt;br /&gt;&lt;a href="https://source.caret.cam.ac.uk/camtools/trunk/sling/sling-jetty-config"&gt;https://source.caret.cam.ac.uk/camtools/trunk/sling/sling-jetty-config&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Edit the jetty.xml file to suit your taste&lt;br /&gt;(the one in there enables AJP)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Build using Maven 2&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;mvn clean install -Pajp&lt;br /&gt;&lt;/span&gt;(Leave off the &lt;span style="font-style: italic;"&gt;-Pajp&lt;/span&gt; if you are not enabling/using ajp)&lt;/li&gt;&lt;li&gt;Install the bundle fragment into your OSGi container using whatever mechanism you are used to. It tends to work best to install it with the same level as the bundle it is being used with.&lt;/li&gt;&lt;li&gt;Restart the OSGi container&lt;br /&gt;(this is not always required but I find it tends to work a lot better if you do)&lt;/li&gt;&lt;/ol&gt;Unfortunately, I could not find a very good way to verify that this works other than putting a breakpoint at line 66 of &lt;span style="font-style: italic;"&gt;/pax-web/bundle/src/main/java/org/ops4j/pax/web/service/internal/JettyServerImpl.java&lt;/span&gt;. You should see the jetty.xml file get loaded (resource will be non-null). You could also just check to see if Jetty is behaving as you would expect with the changes.&lt;br /&gt;&lt;br /&gt;If there are problems (the fragment seems to have no effect) then here are a few debugging steps that may work:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;If you are using felix then you can run the &lt;span style="font-weight: bold;"&gt;resolve&lt;/span&gt; command from the felix command shell for your fragment. If you get nothing then you are probably good to go, if you get a failure then the &lt;span style="font-style: italic;"&gt;Fragment-Host: org.ops4j.pax.web.pax-web-service&lt;/span&gt; value probably does not match the one in your container. Make sure the value is the same as the symbolic name of your installed pax-web-service-*.jar.&lt;/li&gt;&lt;li&gt;Try making sure your &lt;a href="http://docs.codehaus.org/display/JETTY/Walkthrough+jetty.xml"&gt;jetty.xml&lt;/a&gt; actually works with Jetty. There are &lt;a href="http://docs.codehaus.org/display/JETTY/Newbie+Guide+to+Jetty"&gt;instructions&lt;/a&gt; on the Jetty website.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-6372264406680070297?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/6372264406680070297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=6372264406680070297' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6372264406680070297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6372264406680070297'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/04/configuring-jetty-in-pax-web-osgi.html' title='Configuring Jetty in the pax-web OSGi bundle'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3704514096110109625</id><published>2009-04-08T15:25:00.016+01:00</published><updated>2009-04-08T18:33:17.507+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='findbugs'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='filter'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='exclusion'/><title type='text'>Filtering in FindBugs</title><content type='html'>Here is an example &lt;a href="http://findbugs.sourceforge.net/"&gt;findbugs&lt;/a&gt; exclusion &lt;a href="http://findbugs.sourceforge.net/manual/filter.html"&gt;filter&lt;/a&gt; which is generally useful for most projects. I could not seem to find a good example of something general anywhere so hopefully this will be a helpful reference to others. If you placed an xml file like this into your project in eclipse you can configure findbugs to use it as an exclusion filter.&lt;br /&gt;&lt;br /&gt;Here is the sample xml (&lt;a href="http://escapehtmlforxml.com/"&gt;escaped&lt;/a&gt;):&lt;br /&gt;&lt;pre class="brush: xml"&gt;&amp;lt;FindBugsFilter&amp;gt;&lt;br /&gt;    &amp;lt;!-- filter out test classes with medium (2) or low (3) warnings --&amp;gt;&lt;br /&gt;    &amp;lt;Match&amp;gt;&lt;br /&gt;      &amp;lt;Or&amp;gt;&lt;br /&gt;          &amp;lt;Class name="~.*\.AbstractTest.+" /&amp;gt;&lt;br /&gt;          &amp;lt;Class name="~.*Test" /&amp;gt;&lt;br /&gt;      &amp;lt;/Or&amp;gt;&lt;br /&gt;      &amp;lt;Bug category="PERFORMANCE,MALICIOUS_CODE,STYLE,SECURITY" /&amp;gt;&lt;br /&gt;    &amp;lt;/Match&amp;gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;!-- remove the rules which require all passed vars to be immutable --&amp;gt;&lt;br /&gt;   &amp;lt;Match&amp;gt;&lt;br /&gt;       &amp;lt;Bug code="EI,EI2" /&amp;gt;&lt;br /&gt;   &amp;lt;/Match&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- Filter out certain categories of bugs --&amp;gt;&lt;br /&gt;    &amp;lt;Match&amp;gt;&lt;br /&gt;      &amp;lt;Bug category="STYLE" /&amp;gt;&lt;br /&gt;    &amp;lt;/Match&amp;gt;&lt;br /&gt;&amp;lt;/FindBugsFilter&amp;gt;&lt;/pre&gt;&lt;br /&gt;To make this work in eclipse (with findbugs plugin installed) just do the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create an xml file in your project with the contents from above&lt;/li&gt;&lt;li&gt;Right click the project name and select &lt;span style="font-weight: bold;"&gt;Properties&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Choose &lt;span style="font-weight: bold;"&gt;FindBugs&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Check the box marked &lt;span style="font-weight: bold;"&gt;Run FindBugs automatically&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Click on the &lt;span style="font-weight: bold;"&gt;Filter files&lt;/span&gt; tab at the top&lt;/li&gt;&lt;li&gt;Click the &lt;span style="font-weight: bold;"&gt;Add&lt;/span&gt; button next to &lt;span style="font-weight: bold;"&gt;Exclude filter files:&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Select the xml file you created&lt;/li&gt;&lt;li&gt;Click &lt;span style="font-weight: bold;"&gt;OK&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;You can adjust the filter using the &lt;a href="http://findbugs.sourceforge.net/manual/filter.html"&gt;findbugs guide&lt;/a&gt; and the full list of &lt;a href="http://findbugs.sourceforge.net/bugDescriptions.html"&gt;bug types and categories&lt;/a&gt; is available.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3704514096110109625?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3704514096110109625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3704514096110109625' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3704514096110109625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3704514096110109625'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/04/filtering-in-findbugs.html' title='Filtering in FindBugs'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3842607524793649160</id><published>2009-04-07T10:50:00.041+01:00</published><updated>2009-07-07T14:22:39.249+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debugger'/><category scheme='http://www.blogger.com/atom/ns#' term='sling'/><category scheme='http://www.blogger.com/atom/ns#' term='configuration'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='setup'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='felix'/><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='started'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='whiteboard pattern'/><title type='text'>Developing with OSGi and Apache Sling</title><content type='html'>These are notes I compiled while working on a &lt;a href="http://groups.google.co.uk/group/sakai-kernel"&gt;project&lt;/a&gt; which uses &lt;a href="http://en.wikipedia.org/wiki/OSGi"&gt;OSGi&lt;/a&gt; (&lt;a href="http://felix.apache.org/site/index.html"&gt;Apache Felix&lt;/a&gt;) and &lt;a href="http://en.wikipedia.org/wiki/Apache_Sling"&gt;Apache Sling&lt;/a&gt; as the foundational framework. Sling is essentially Felix with JCR and templating bundles installed and a REST bundle. I will tell you how I got going with the basics of OSGi and Sling and some of the issues I ran into. First a few important links:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Apache Sling - &lt;a href="http://sling.apache.org/"&gt;http://sling.apache.org/&lt;/a&gt; (graduated) &lt;del&gt;&lt;a href="http://incubator.apache.org/sling/site/index.html"&gt;http://incubator.apache.org/sling/site/index.html&lt;/a&gt;&lt;/del&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Apache Felix - &lt;a href="http://felix.apache.org/site/index.html"&gt;http://felix.apache.org/&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sling SVN (trunk) - &lt;a href="http://svn.apache.org/repos/asf/sling/trunk/"&gt;http://svn.apache.org/repos/asf/sling/trunk/&lt;/a&gt; (graduated) &lt;del&gt;&lt;a href="http://svn.eu.apache.org/repos/asf/incubator/sling/trunk"&gt;http://svn.eu.apache.org/repos/asf/incubator/sling/trunk&lt;br /&gt;&lt;/a&gt;&lt;/del&gt;&lt;/li&gt;&lt;/ul&gt;Before we really get started I want to mention something about &lt;a href="http://en.wikipedia.org/wiki/OSGi"&gt;OSGi&lt;/a&gt; in general. OSGi is basically a system for making Java code modular and handling isolation of dependencies (no slop allowed). This is done via a lot of really complex classloader graphing. A chunk of code in OSGi is called a module and a system will typically be made up of many modules. Inside modules there are packages which can be used internally (private), exported so others can use them (this is how services dependencies are shared), and imported (this is how a bundle would get the dependencies it needs to use an external service). OSGi completely manages the lifecycle of the the bundles in the system. Bundles define an activator (implements &lt;a href="http://www.osgi.org/javadoc/r4v41/org/osgi/framework/BundleActivator.html"&gt;BundleActivator&lt;/a&gt;) which allows the developer to control startup and shutdown actions and register services. The modular nature of OSGi means services could go away at any time (or may not be started when your bundle is starting). Because of this, bundle code should be written to expect that a service might not be ready to use when it is starting. Waiting for services to be available is bad also because OSGi activators are expected to be quick so delaying them will cause failures. This generally means using the listeners and trackers provided by OSGi. The practice is called the &lt;span style="font-weight: bold;"&gt;Whiteboard Pattern&lt;/span&gt; (basically inverted listeners, those familiar with &lt;a href="http://confluence.sakaiproject.org/confluence/display/SAKDEV/Entity+Provider+and+Broker"&gt;EntityBroker&lt;/a&gt;/&lt;a href="http://code.google.com/p/entitybus/"&gt;EntityBus&lt;/a&gt; will recognize this as how providers work). These links are a good intro and you will want to be familiar with this conceptually before you attempt to create your first real bundle (helloworld not included):&lt;br /&gt;&lt;a href="http://www.theserverside.com/tt/articles/article.tss?l=WhiteboardForOSGi"&gt;http://www.theserverside.com/tt/articles/article.tss?l=WhiteboardForOSGi&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.knopflerfish.org/osgi_service_tutorial.html"&gt;http://www.knopflerfish.org/osgi_service_tutorial.html&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;Here are the steps I took to get Sling up and running (&lt;a href="http://incubator.apache.org/sling/site/discover-sling-in-15-minutes.html"&gt;more details&lt;/a&gt; on the Sling site):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Checkout the source code using &lt;a href="http://subversion.tigris.org/"&gt;subversion&lt;/a&gt;:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;svn co http://svn.apache.org/repos/asf/sling/trunk sling&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;(I checked out revision 758703 since the current revision was not working)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Build the source using &lt;a href="http://maven.apache.org/"&gt;maven 2&lt;/a&gt;:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cd sling&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;mvn clean install&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Run Sling using the built in &lt;a href="http://www.mortbay.org/jetty/"&gt;Jetty webserver&lt;/a&gt; (as an executable jar):&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;java -jar launchpad/app/target/org.apache.sling.launchpad.app-5-SNAPSHOT.jar&lt;/span&gt;&lt;br /&gt;(&lt;span style="font-weight: bold;"&gt;Note:&lt;/span&gt; the version of the jar will change over time)&lt;br /&gt;(you can also run drop a sling war into your own &lt;a href="http://en.wikipedia.org/wiki/Servlet_container#Servlet_containers"&gt;servlet container&lt;/a&gt;)&lt;br /&gt;(you can change the port by adding "-p #" (where # is the port number like 9090))&lt;br /&gt;(you can cause all logs to go to the console by adding "-f -")&lt;br /&gt;(you can change the logging level of sling by adding "-l #" (where # is 0-4 with 4=debug))&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Test out sling using your &lt;a href="http://en.wikipedia.org/wiki/Web_browser"&gt;web browser&lt;/a&gt;:&lt;br /&gt;Go to http://localhost:8080/&lt;br /&gt;Click on the console link (login as admin/admin)&lt;/li&gt;&lt;/ol&gt;Now, if you are going to do anything in Sling (or Felix) at all you are likely to need to debug it, so here are the steps to use a debugger with Sling (generally applies to any java app really).&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Run Sling with debugging options enabled:&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;java -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=9001,server=y,suspend=n -jar launchpad/app/target/org.apache.sling.launchpad.app-5-SNAPSHOT.jar&lt;/span&gt;&lt;br /&gt;(You should see this in the logs: Listening for transport dt_socket at address: 9001)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Attach the &lt;a href="http://en.wikipedia.org/wiki/Debugger"&gt;debugger&lt;/a&gt; from &lt;a href="http://en.wikipedia.org/wiki/Eclipse_%28software%29"&gt;eclipse&lt;/a&gt; (or use whatever debugger you like):&lt;br /&gt;Run -&gt; Debug Configurations&lt;br /&gt;Right click Remote Java Application -&gt; New&lt;br /&gt;Connect tab: Set Port to 9001&lt;br /&gt;Source tab: Add the imported Sling code and your OSGi bundle project&lt;br /&gt;Click the Debug button at the bottom&lt;br /&gt;(You should not get an error if everything connects up)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ibm.com/developerworks/library/os-ecbug/"&gt;Place a breakpoint&lt;/a&gt; in Runtime class on the gc method&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Click on System Information and then the Run button next to Garbage Collection&lt;br /&gt;(the debugger should pick up the call and pause the JVM at the breakpoint)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use the debugger to trace through if you like (but bear in mind that the admin console is not actually part of Sling, it is part of &lt;a href="http://felix.apache.org/site/index.html"&gt;Apache Felix&lt;/a&gt; so you will need the source for Felix)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Now you probably want to deploy a bundle so here are the steps to make a really simple one you can build and deploy into sling. I use the maven-bundle-plugin for this example, see the links for more details about it:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html" target="_blank"&gt;http://felix.apache.org/site/&lt;wbr&gt;apache-felix-maven-bundle-&lt;wbr&gt;plugin-bnd.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://felix.apache.org/site/apache-felix-bundle-plugin-faq.html" target="_blank"&gt;http://felix.apache.org/site/&lt;wbr&gt;apache-felix-bundle-plugin-&lt;wbr&gt;faq.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://aqute.biz/Code/Bnd" target="_blank"&gt;http://aqute.biz/Code/Bnd&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Here is the part of the maven pom that configures the bundle manifest:&lt;pre class="brush: xml"&gt;&amp;lt;dependencies&amp;gt;&lt;br /&gt;&amp;lt;!-- OSGi --&amp;gt;&lt;br /&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;&amp;lt;groupId&amp;gt;org.osgi&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;lt;artifactId&amp;gt;osgi_R4_core&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&amp;lt;dependency&amp;gt;&lt;br /&gt;&amp;lt;groupId&amp;gt;org.osgi&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;lt;artifactId&amp;gt;osgi_R4_compendium&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;lt;/dependency&amp;gt;&lt;br /&gt;&amp;lt;/dependencies&amp;gt;&lt;br /&gt;&amp;lt;build&amp;gt;&lt;br /&gt;&amp;lt;plugins&amp;gt;&lt;br /&gt;&amp;lt;plugin&amp;gt;&lt;br /&gt;&amp;lt;groupId&amp;gt;org.apache.felix&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;lt;artifactId&amp;gt;maven-bundle-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;lt;extensions&amp;gt;true&amp;lt;/extensions&amp;gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;&amp;lt;instructions&amp;gt;&lt;br /&gt;  &amp;lt;Bundle-Activator&amp;gt;org.azeckoski.osgi.SampleActivator&amp;lt;/Bundle-Activator&amp;gt;&lt;br /&gt;&amp;lt;/instructions&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;br /&gt;&amp;lt;/plugin&amp;gt;&lt;br /&gt;&amp;lt;/plugins&amp;gt;&lt;br /&gt;&amp;lt;/build&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;ol&gt;&lt;li&gt;Checkout the sample bundle code:&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;svn co &lt;a href="https://source.sakaiproject.org/contrib/caret/osgi-sample/tags/sample-1.1/"&gt;https://source.sakaiproject.org/contrib/caret/osgi-sample/tags/sample-1.1/&lt;/a&gt; osgi-sample&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Build the bundle using &lt;a href="http://maven.apache.org/"&gt;maven 2&lt;/a&gt;:&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;cd osgi-sample&lt;br /&gt;mvn clean install&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Access the Felix console for bundles (included in Sling):&lt;br /&gt;http://localhost:8080/system/console/bundles&lt;/li&gt;&lt;li&gt;Browse and select the bundle (target/sample-1.1.jar)&lt;/li&gt;&lt;li&gt;Click &lt;span style="font-weight: bold;"&gt;Install or Update&lt;/span&gt; and then &lt;span style="font-weight: bold;"&gt;Refresh Packages&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Scroll down to the &lt;span style="font-weight: bold;"&gt;Sample OSGi Bundle&lt;/span&gt;&lt;br /&gt;If it is listed then you have a properly installed bundle!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Click the &lt;span style="font-weight: bold;"&gt;Start&lt;/span&gt; and then &lt;span style="font-weight: bold;"&gt;Stop&lt;/span&gt; buttons to the right of the bundle&lt;/li&gt;&lt;li&gt;You should see something like this in the logs:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Sample starting at: Mon Apr 13 13:15:27 BST 2009&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Sample stopping at: Mon Apr 13 13:15:29 BST 2009&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Now click &lt;span style="font-weight: bold;"&gt;Start&lt;/span&gt; to make sure the bundle is running&lt;/li&gt;&lt;li&gt;Restart Sling (use the admin console or just kill it and rerun the command)&lt;/li&gt;&lt;li&gt;You should see that the bundle is running (it was started automatically) and in the startup logs the &lt;span style="font-style: italic;"&gt;Sample starting...&lt;/span&gt; should appear&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Here is the (very) simple code from the activator class (comments removed). It just prints out a message when the bundle starts and another when it stops.&lt;br /&gt;&lt;pre class="brush: java"&gt;import java.util.Date;&lt;br /&gt;import org.osgi.framework.BundleActivator;&lt;br /&gt;import org.osgi.framework.BundleContext;&lt;br /&gt;&lt;br /&gt;public class SampleActivator implements BundleActivator {&lt;br /&gt;public void start(BundleContext context) throws Exception {&lt;br /&gt;System.out.println("Sample starting at: " + new Date());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void stop(BundleContext context) throws Exception {&lt;br /&gt;System.out.println("Sample stopping at: " + new Date());&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Congratulations. You have installed you first bundle. If you want to try out the debugging you can put breakpoints in the start and stop methods. It only took me a couple days to get to this point which I think is not great so I hope this tutorial has really sped up the process for you.&lt;br /&gt;&lt;br /&gt;Now for the advanced bit. Creating your own bundle. I have a somewhat realistic set of bundles where one depends on another and one uses the http.service (and other bundles) so chances are you won't face things that are too much more complex than this.&lt;br /&gt;There are a few things that I learned going through this that were not all that apparent so hopefully I can save you some digging with these pro-tips:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;OSGi start order does not guarantee service start order - The order which bundles start does not guarantee that their services will also be started. In fact, relying on this is a mistake since OSGi is meant to be modular and services could go away at any time (see the note at the top about OSGi and whiteboard pattern). Code should be written to expect that a service might not be ready to use when the bundle starts. Waiting for services to be available is bad also because OSGi activators are expected to be quick so delaying them will cause failures.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Bundles should import the packages they export - This is not obvious but it makes sense when you think about it. Since there may be other bundles of higher rank that are exporting packages that match yours, you should use the highest priority, even in your own bundle. This behavior is actually taken care of my most bundle making tools automatically so just don't be surprised to see your packages in the imports.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;javax packages will need to be imported - Only java.* is available to your bundle by default so all the dom,xml,net,wtc. stuff from javax has to imported. If you do not import it and happen to use it then your bundle will fail at runtime. Luckily, most OSGi installations have a core which already exports most of this stuff so just put it into your import-package as optional like so (just an example):&lt;br /&gt;org.w3c.dom;resolution:=optional,org.xml.*;resolution:=optional,javax.*;resolution:=optional,*&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Services in the manifest are deprecated - As of OSGi R4, listing services (using export/import-services) is deprecated. All exports/imports are handled as packages now and the registration of the services is done in the activator.&lt;/li&gt;&lt;li&gt;Felix shell access inside Sling - There is a &lt;a href="http://felix.apache.org/site/apache-felix-remote-shell.html"&gt;felix remote shell&lt;/a&gt; which can be used to access the &lt;a href="http://felix.apache.org/site/apache-felix-shell-service.html"&gt;felix shell service&lt;/a&gt;. It can be installed by just installing &lt;a href="http://felix.apache.org/site/downloads.cgi"&gt;a couple bundles&lt;/a&gt; (shell, shell remote). This will allow you to run &lt;a href="http://felix.apache.org/site/apache-felix-usage-documentation.html"&gt;felix shell commands&lt;/a&gt; inside Sling via telnet.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I strongly suggest you use code that you know works already when building your first functional bundle. Pick something that does not have a lot of dependencies as well. For the following tutorial steps I will take you through the download, build, activate, and test process with my bundles and then look at some of the code.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Checkout the sample bundle code:&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;svn co &lt;a href="https://source.sakaiproject.org/contrib/caret/osgi-eb/tags/eb-1.0/"&gt;https://source.sakaiproject.org/contrib/caret/osgi-eb/tags/eb-1.0/&lt;/a&gt; osgi-eb&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Build the bundle using &lt;a href="http://maven.apache.org/"&gt;maven 2&lt;/a&gt;:&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;cd osgi-eb&lt;br /&gt;mvn clean install&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Use the Felix console for bundles to install and start the eb-services and eb-rest bundles:&lt;br /&gt;(should be eb-component/target/eb-services-1.0.jar and eb-webapp/target/eb-rest-1.0.jar)&lt;/li&gt;&lt;li&gt;Verify they started by refreshing and making sure they appear to be running:&lt;br /&gt;For some reason there are no errors logged to the console by default when a bundle fails to start and no messages appear in the web interface. As a result you simply get a silent failure where it seems to have worked but is actually just installed and inactive. The bundle should say &lt;span style="font-weight: bold;"&gt;Active&lt;/span&gt; next to it (make sure you refresh).&lt;br /&gt;NOTE: The errors will be logged into SLING_HOME/logs/error.log&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Go to the URL that is setup for the bundles (http://localhost:8080/eb), it should load up the description page for the rest webapp portion&lt;/li&gt;&lt;/ol&gt;For this sample code I have used the OSGi &lt;a href="http://www.osgi.org/javadoc/r4v41/org/osgi/util/tracker/ServiceTracker.html"&gt;ServiceTracker&lt;/a&gt; and &lt;a href="http://www.osgi.org/javadoc/r4v41/org/osgi/framework/ServiceListener.html"&gt;ServiceListener&lt;/a&gt; with a bit of &lt;a href="http://azsandbox.googlecode.com/svn/tags/osgi-utils-1.2/"&gt;utilities scaffolding&lt;/a&gt; (&lt;a href="http://azsandbox.googlecode.com/svn/tags/osgi-utils-1.2/src/main/java/org/azeckoski/osgi/utils/ServiceTracker2.java"&gt;ServiceTracker2&lt;/a&gt; and &lt;a href="http://azsandbox.googlecode.com/svn/tags/osgi-utils-1.2/src/main/java/org/azeckoski/osgi/utils/ServicesTracker.java"&gt;ServicesTracker&lt;/a&gt;) to setup my bundles and services in the whiteboard pattern. While this works fine for a smaller use case, I would suggest looking into OSGi DS (&lt;a href="http://www.eclipsezone.com/eclipse/forums/t96740.html"&gt;Declarative Services&lt;/a&gt;) and the &lt;a href="http://felix.apache.org/site/apache-felix-maven-scr-plugin.html"&gt;Maven SCR Plugin&lt;/a&gt; when working with a large number of bundles and services.&lt;br /&gt;&lt;br /&gt;Here is the start method from the &lt;a href="https://source.sakaiproject.org/contrib/caret/osgi-eb/tags/eb-1.0/eb-component/src/main/java/org/sakaiproject/eb/osgi/EBActivator.java"&gt;EB services activator&lt;/a&gt; showing an example of how services are registered and tracked. This also demonstrates one way to track things which are used by our services. Pre-OSGi Java programming might require the EntityProvider to be manually registered with the EB system using a register method. By leveraging OSGi's ability to lookup services, we can instead simply have developers create their providers and register them with OSGi as services. Then the eb-services bundle picks up the registered providers and handles the registration automatically.&lt;br /&gt;&lt;pre class="brush: java"&gt;public void start(BundleContext context) throws Exception {&lt;br /&gt;   System.out.println("INFO: Starting EB module");&lt;br /&gt;&lt;br /&gt;   // Create the EB core services&lt;br /&gt;   coreServiceManager = new EntityBrokerCoreServiceManager();&lt;br /&gt;&lt;br /&gt;   // register trackers to handle the optional services&lt;br /&gt;   eipTracker = new ServiceTrackerPlus&amp;lt;ExternalIntegrationProvider&amp;gt;(context, ExternalIntegrationProvider.class) {&lt;br /&gt;       @Override&lt;br /&gt;       protected void serviceUpdate(ServiceEvent event, ExternalIntegrationProvider service)&lt;br /&gt;       throws Exception {&lt;br /&gt;           coreServiceManager.getEntityBrokerManager().setExternalIntegrationProvider(getService());&lt;br /&gt;       }&lt;br /&gt;   };&lt;br /&gt;&lt;br /&gt;   // register a tracker for the entity providers (will find them as osgi services and handle registration)&lt;br /&gt;   providerTracker = new ServiceTrackerPlus&amp;lt;EntityProvider&amp;gt;(context, EntityProvider.class) {&lt;br /&gt;       @Override&lt;br /&gt;       protected void serviceUpdate(ServiceEvent event, EntityProvider service)&lt;br /&gt;       throws Exception {&lt;br /&gt;           EntityProvider provider = getService(event);&lt;br /&gt;           if (event.getType() == ServiceEvent.UNREGISTERING) {&lt;br /&gt;               coreServiceManager.getEntityProviderManager().unregisterEntityProvider(provider);&lt;br /&gt;           } else {&lt;br /&gt;               coreServiceManager.getEntityProviderManager().registerEntityProvider(provider);&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;   };&lt;br /&gt;&lt;br /&gt;   // look up a service we optionally want to use but do not require&lt;br /&gt;   ServiceTrackerPlus&amp;lt;DeveloperHelperService&amp;gt; dhsTracker =&lt;br /&gt;       new ServiceTrackerPlus&amp;lt;DeveloperHelperService&amp;gt;(context, DeveloperHelperService.class);&lt;br /&gt;   DeveloperHelperService dhs = dhsTracker.getService();&lt;br /&gt;   System.out.println("DeveloperHelperService is currently: " + dhs);&lt;br /&gt;&lt;br /&gt;   // register the core services from this bundle&lt;br /&gt;   ebRegistration = context.registerService( EntityBroker.class.getName(), coreServiceManager.getEntityBroker(), null);&lt;br /&gt;   ebManagerRegistration = context.registerService( EntityBrokerManager.class.getName(), coreServiceManager.getEntityBrokerManager(), null);&lt;br /&gt;   ebProviderManagerRegistration = context.registerService( EntityProviderManager.class.getName(), coreServiceManager.getEntityProviderManager(), null);&lt;br /&gt;   ebEVAPManagerRegistration = context.registerService( EntityViewAccessProviderManager.class.getName(), coreServiceManager.getEntityViewAccessProviderManager(), null);&lt;br /&gt;   ebHSAPManagerRegistration = context.registerService( HttpServletAccessProviderManager.class.getName(), coreServiceManager.getHttpServletAccessProviderManager(), null);&lt;br /&gt;&lt;br /&gt;   System.out.println("INFO: Started EB module and registered services");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this code example, we see the code to handle the start of the &lt;a href="https://source.sakaiproject.org/contrib/caret/osgi-eb/tags/eb-1.0/eb-webapp/src/main/java/org/sakaiproject/eb/rest/osgi/EBRestActivator.java"&gt;EB rest activator&lt;/a&gt;. This allows the eb-services bundle to be stopped and started without having to manually do anything to the rest bundle (whose services depend on the ones in the eb-services bundle). It will shutdown the rest services until the core services it requires are available again.&lt;br /&gt;&lt;pre class="brush: java"&gt;public void start(BundleContext context) throws Exception {&lt;br /&gt;   System.out.println("INFO: Starting EB ReST module");&lt;br /&gt;   // initialize tracker&lt;br /&gt;   this.requiredServicesTracker = new ServicesTracker(context, HttpService.class, EntityBrokerManager.class) {&lt;br /&gt;       @Override&lt;br /&gt;       protected void requiredServicesReady(Object service, ServiceTracker2 changed,&lt;br /&gt;               Map&amp;lt;String, ServiceTracker2&amp;gt; serviceTrackers) throws Exception {&lt;br /&gt;           // required services are ready so startup&lt;br /&gt;           startServices(getService(HttpService.class), getService(EntityBrokerManager.class));&lt;br /&gt;       }&lt;br /&gt;       @Override&lt;br /&gt;       protected void requiredServicesChanged(Object service, ServiceTracker2 changed,&lt;br /&gt;               Map&amp;lt;String, ServiceTracker2&amp;gt; serviceTrackers) throws Exception {&lt;br /&gt;           // required services changed so stop and restart&lt;br /&gt;           stopServices(getService(HttpService.class));&lt;br /&gt;           startServices(getService(HttpService.class), getService(EntityBrokerManager.class));&lt;br /&gt;       }&lt;br /&gt;       @Override&lt;br /&gt;       protected void requiredServicesDropped(Object service, ServiceTracker2 changed,&lt;br /&gt;               Map&amp;lt;String, ServiceTracker2&amp;gt; serviceTrackers) throws Exception {&lt;br /&gt;           // required services gone so shutdown&lt;br /&gt;           stopServices(getService(HttpService.class));&lt;br /&gt;       }&lt;br /&gt;   };&lt;br /&gt;&lt;br /&gt;   // optional services trackers&lt;br /&gt;   dhsTracker = new ServiceTrackerPlus&amp;lt;DeveloperHelperService&amp;gt;(context, DeveloperHelperService.class) {&lt;br /&gt;       @Override&lt;br /&gt;       protected void serviceUpdate(ServiceEvent event, DeveloperHelperService service)&lt;br /&gt;       throws Exception {&lt;br /&gt;           DeveloperHelperService dhs = getService();&lt;br /&gt;           if (servlet != null) {&lt;br /&gt;               servlet.updateDHS(dhs);&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;   };&lt;br /&gt;   // TODO need to handle the case of the hsapm changing?&lt;br /&gt;   hsapmTracker = new ServiceTrackerPlus&amp;lt;HttpServletAccessProviderManager&amp;gt;(context, HttpServletAccessProviderManager.class);&lt;br /&gt;&lt;br /&gt;   // register the servlet if services are ready&lt;br /&gt;   this.requiredServicesTracker.startCheck();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here are some more links to OSGi materials that may be helpful:&lt;br /&gt;&lt;a href="http://neilbartlett.name/blog/osgi-articles/"&gt;http://neilbartlett.name/blog/osgi-articles/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.osgi.org/About/HowOSGi"&gt;http://www.osgi.org/About/HowOSGi&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;NOTE:&lt;/span&gt; Updated for the graduation of sling and changes in URLs that resulted&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3842607524793649160?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3842607524793649160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3842607524793649160' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3842607524793649160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3842607524793649160'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/04/developing-with-osgi-and-apache-sling.html' title='Developing with OSGi and Apache Sling'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-5600737022404451500</id><published>2009-04-06T12:04:00.016+01:00</published><updated>2009-05-25T16:00:50.179+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='quality'/><category scheme='http://www.blogger.com/atom/ns#' term='accessibility'/><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jslint'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>High Quality Javascript</title><content type='html'>Writing good javascript is still more art than science, but there are a growing number of tools out there to help those who are less artsy. I have tried to compile the ones that I use and a few tips which I think are helpful.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;jQuery&lt;/span&gt; (&lt;a href="http://jquery.com/"&gt;http://jquery.com/&lt;/a&gt;) - a great javascript framework built for developers&lt;br /&gt;If you are still writing javascript without using a framework like jQuery then you are punishing yourself. Stop that! This framework makes javascript work like it probably should have anyway and it is very reliable and widely used. It helps protect you from browser incompatibilities and makes ajax very easy. There are a large number of addons and extensions which provide flashy widgets and things to make your UI look snazzy.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;JSLint&lt;/span&gt; (&lt;a href="http://www.jslint.com/"&gt;http://www.jslint.com/&lt;/a&gt;) - this website / tool is similar to findbugs for java and helps with correctness and valid code practices (NOTE: Can enable JSlint in Aptana Studio, see tips below)&lt;br /&gt;JSLint is a JavaScript program that looks for problems in JavaScript programs. Just paste your javascript file into the box and click JSLint. I use the following options (good starting point if you are not sure what to use):&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Assume a browser&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;Disallow undefined variables&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;Disallow leading _ in identifiers&lt;/span&gt;, and &lt;span style="font-style: italic;"&gt;Disallow == and !=&lt;/span&gt;&lt;br /&gt;You should strive to have no errors indicated. I recommend you avoid the &lt;span style="font-style: italic;"&gt;Strict white space&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;Require parens around immediate invocations&lt;/span&gt; options as these are more likely to cause frustration than be helpful. JSLint will also provide you with a list of all functions, members, and Globals in your code which is helpful as a reference.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;jqUnit&lt;/span&gt; (&lt;a href="http://code.google.com/p/jqunit/"&gt;http://code.google.com/p/jqunit/&lt;/a&gt;) - a test writing framework (like jUnit for java)&lt;br /&gt;This is a test framework which allows a developer to write tests which exercise and validate their javascript code. It is compatible with &lt;a href="http://jsunit.net/"&gt;JSUnit&lt;/a&gt; but has special handling for jQuery and since you are using jQuery anyway you may as well get the benefits. The tests run in the browser and normally are accessed by loading a page (e.g project/test.html). I won't go into the reasons why you should always have &lt;a href="http://en.wikipedia.org/wiki/Unit_testing"&gt;unit tests&lt;/a&gt; but if you want high quality code then they are not optional. This will have a huge impact on the reliability and change tolerance of your code and since JS code in general tends to change a lot this is critical.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Fluid Infusion&lt;/span&gt; (&lt;a href="http://fluidproject.org/products/fluid-infusion/"&gt;http://fluidproject.org/products/fluid-infusion/&lt;/a&gt;) - framework for accessible javascript&lt;br /&gt;The fluid project is trying to ensure that javascript enabled pages are accessible to everyone. They have a framework which includes widgets which are specially designed to be accessible and also have a lot of &lt;a href="http://wiki.fluidproject.org/display/fluid/JavaScript+Resources"&gt;documentation for developers&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Aptana Studio&lt;/span&gt; (&lt;a href="http://www.aptana.com/studio"&gt;http://www.aptana.com/studio&lt;/a&gt;) - IDE for javascript, HTML, DOM, CSS&lt;br /&gt;This is an eclipse based IDE for the web. It provides code completion, formatting, validation, and the things you might expect to get from an IDE. This makes writing javascript a heck of a lot easier and it looks better than textedit/notepad. I just use &lt;del&gt;the eclipse plugin rather than&lt;/del&gt; the full product now and if you are web designer or just trying it out then the full option is probably best (as it seems it does not uninstall from eclipse cleanly).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;General Tips&lt;/span&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Always &lt;a href="http://en.wikipedia.org/wiki/Namespace"&gt;namespace&lt;/a&gt; your javascript functions and vars - &lt;a href="http://www.dustindiaz.com/namespace-your-javascript/"&gt;http://www.dustindiaz.com/namespace-your-javascript/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Write &lt;a href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript"&gt;unobtrusive javascript&lt;/a&gt; (this basically means avoid writing code in your html except for a few lines at the bottom to run scripts and pass in values as needed) - &lt;a href="http://www.onlinetools.org/articles/unobtrusivejavascript/"&gt;http://www.onlinetools.org/articles/unobtrusivejavascript/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Always use &lt;span style="font-weight: bold;"&gt;var&lt;/span&gt; in front of variables, if you don't they will become globals and when you are namespacing (which you should be) this is considering leaking&lt;/li&gt;&lt;li&gt;Declare globals at the top of your JS file in a comment like so:&lt;br /&gt;&lt;pre&gt;/*global jQuery, myGlobal */&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;&lt;del&gt;Always refer to globally used variables at the top of your script so it will fail if the global is missing. This will make JSLint happy and keeps things from appearing to work when globals are not available. Example:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;blockquote&gt;var $ = $ || function() { throw "JQuery undefined"; };&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt;&lt;/del&gt;&lt;/li&gt;&lt;li&gt;Check to make sure you found something when you use jQuery selectors (if you always except to find something). This protects you from thinking you have actually found something based on an id when there is nothing by that id available. Example:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;var adhocArea = $("#"+adhocAreaId);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; if (adhocArea.length &gt; 0) {&lt;br /&gt;// do something&lt;br /&gt;} else {&lt;br /&gt;throw "failed to find thing with id: "+&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;adhocAreaId;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;Use script blocks to initialize javascript when the DOM it is working with has loaded rather than always (ever?) using onLoad. This will cause the javascript to start quicker on slow loading pages and avoid ugly issues like resetting selections made by the user or clearing fields which had loaded before the whole page loaded and the onLoad executed. For example, if you are adding a simple numeric validator to a field, you should place the script tag to load the JS (from a namespaced variable in a separate file) after the form. This way the script executes as soon as the DOM it will act on is loaded.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Be familiar the concept of &lt;a href="http://en.wikipedia.org/wiki/Closure_%28computer_science%29"&gt;closures&lt;/a&gt; in javascript - &lt;a href="http://www.jibbering.com/faq/faq_notes/closures.html"&gt;http://www.jibbering.com/faq/faq_notes/closures.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.quirksmode.org/"&gt;Quirksmode&lt;/a&gt; is a good reference for javascript cross browser compatibility&lt;/li&gt;&lt;li&gt;Enable JSLint validator in Aptana Studio: Preferences -&gt; Aptana -&gt; Editors -&gt; Javascript -&gt; Validation -&gt; Check &lt;span style="font-style: italic;"&gt;JSLint Javascript Validator&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;It is probably a good idea to glance at &lt;a href="http://ajaxian.com/"&gt;AJAXian&lt;/a&gt; every once in awhile as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-5600737022404451500?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/5600737022404451500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=5600737022404451500' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5600737022404451500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5600737022404451500'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/04/high-quality-javascript.html' title='High Quality Javascript'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3529950875310249178</id><published>2009-02-18T10:26:00.003Z</published><updated>2009-02-18T11:09:20.592Z</updated><title type='text'>Debugging Jetty when running mvn jetty:run</title><content type='html'>It took me awhile to get this to work so hopefully this will save someone some time. If you want to debug a webapp that is run using the &lt;span style="font-weight: bold;"&gt;mvn jetty:run&lt;/span&gt; or &lt;span style="font-weight: bold;"&gt;mvn jetty:run-war&lt;/span&gt; commands then these steps will help you get going quickly.&lt;br /&gt;1) setup your webapp to run using jetty: &lt;a href="http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin"&gt;Maven Jetty Plugin Guide&lt;/a&gt;&lt;br /&gt;2) setup the debugger in one of the following ways:&lt;br /&gt;(A) setup your MAVEN_OPTS (environment variable) to include debugging by adding this "-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n".&lt;br /&gt;Mine looks like this: MAVEN_OPTS='-Xms256m -Xmx512m -XX:PermSize=64m -XX:MaxPermSize=128m -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n'&lt;br /&gt;If you want it to suspend until the debugger is attached then just set suspend=y&lt;br /&gt;Note that this will stop you from running more than one mvn process&lt;br /&gt;(B) execute mvn using the mvndebug script (skip step 3)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;mvndebug jetty:run&lt;/span&gt;&lt;br /&gt;The only issue with this is that it suspends always and you cannot kill it without attaching to it with a debugger (this annoys me so I use the first option)&lt;br /&gt;Note that you can only have one mvndebug process running at once&lt;br /&gt; 3) Execute &lt;span style="font-weight: bold;"&gt;mvn jetty:run&lt;/span&gt;&lt;br /&gt;4) Attach a debugger (like the one in eclipse) to port 8000 and you are ready to debug&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3529950875310249178?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3529950875310249178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3529950875310249178' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3529950875310249178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3529950875310249178'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/02/debugging-jetty-when-running-mvn.html' title='Debugging Jetty when running mvn jetty:run'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-1360886300446248355</id><published>2009-01-28T16:02:00.003Z</published><updated>2009-01-28T16:27:23.104Z</updated><title type='text'>SVN 1.5.5 for OSX installer</title><content type='html'>If you are using OSX and you need to upgrade &lt;a href="http://subversion.tigris.org/"&gt;Subversion (SVN)&lt;/a&gt; to 1.5.5 (or higher) you have probably gone to the &lt;a href="http://subversion.tigris.org/getting.html#osx"&gt;subversion website&lt;/a&gt; and found out that you need fink or macports or some such. Since I more of the point and click type when it comes to my OS, I prefer installers, so here is the place to get one:&lt;br /&gt;&lt;a href="http://www.open.collab.net/downloads/apple/index.html"&gt;http://www.open.collab.net/downloads/apple/index.html&lt;/a&gt;&lt;br /&gt;It is as easy as: download =&gt; install =&gt; use =&gt; done&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-1360886300446248355?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.open.collab.net/downloads/apple/index.html' title='SVN 1.5.5 for OSX installer'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/1360886300446248355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=1360886300446248355' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/1360886300446248355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/1360886300446248355'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/01/svn-155-for-osx-installer.html' title='SVN 1.5.5 for OSX installer'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3257540444191924763</id><published>2009-01-06T15:43:00.006Z</published><updated>2009-01-06T17:23:55.532Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='java collections list set map performance speed reference'/><title type='text'>Java Collection Performance</title><content type='html'>This is just a helpful reference when trying to decide which &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collection.html"&gt;collections&lt;/a&gt; to use in Java. I use this for my personal reference but it may help others as well. The links go to the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/index.html"&gt;Sun Javadocs&lt;/a&gt;. The collections of each type are ordered based on performance (i.e. the highest performance (highest speed) ones are listed first and will be the fastest for most operations)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/List.html"&gt;List&lt;/a&gt; - this is an ordered list of objects, insertion order is maintained and retrieval order is in the list order but items can also be random accessed, duplicate items are allowed, generally allow storage of null values (the ones below do), generally fast to iterate and find items by position but slow to do lookups&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/ArrayList.html"&gt;ArrayList&lt;/a&gt; - Unsychronized, nulls allowed (fastest)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Vector.html"&gt;Vector&lt;/a&gt; - Synchronized, only slightly slower in tests of sizes under 100000&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Stack.html"&gt;Stack&lt;/a&gt; - Synchronized, same speed as Vector, LIFO queue&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/LinkedList.html"&gt;LinkedList&lt;/a&gt; - Unsynchronized, allows two way iteration and modification of items (like a stack or queue)&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CopyOnWriteArrayList.html"&gt;CopyOnWriteArrayList&lt;/a&gt; - Synchronized, significantly slower in tests of large numbers of items or average list changes, only slightly slower when used with very small numbers (&lt;100)&gt;&lt;/ul&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Set.html"&gt;Set&lt;/a&gt; - this a set of items with no duplicates (no two items can compare as equal), ordering is typically inconsistent over multiple set iterations depending on the implementation but you should assume the order is effectively random unless the set specifies ordered iteration, generally ok to iterate and fast to do lookups&lt;ul&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/HashSet.html"&gt;HashSet&lt;/a&gt; - Unsychronized (fastest), slower than HashMap which it is built on, allows nulls&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/LinkedHashSet.html"&gt;LinkedHashSet&lt;/a&gt; - Unsychronized, ordered by insertion, allows nulls&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/TreeSet.html"&gt;TreeSet&lt;/a&gt; - Unsychronized, ordered by the natural ordering of the items or a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html"&gt;comparator&lt;/a&gt; provided at construction, allows nulls but there are &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4804498"&gt;issues with removing them&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CopyOnWriteArraySet.html"&gt;CopyOnWriteArraySet&lt;/a&gt; - Synchronized, significantly slower in tests of large numbers of items or average set changes, only slightly slower when used with very small numbers (&lt;100)&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Map.html"&gt;Map&lt;/a&gt; - Stores key/value pairs (maps keys to values) where the keys must be unique, order of iteration over keys, values, or pairs is highly dependent on the implementation of the map, allowed nulls also vary by implementation, generally very fast to lookup keys and slow to lookup values&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/IdentityHashMap.html"&gt;IdentityHashMap&lt;/a&gt; - Unsychronized (fastest), uses reference equality (==) instead of object equality (equals) to compare keys, actually violates the Map interface guarantee, all iterators are unordered, allows null keys and values&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/HashMap.html"&gt;HashMap&lt;/a&gt; - Unsychronized, this is the fastest general purpose map, all iterators are unordered, allows null keys and values&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html"&gt;ConcurrentHashMap&lt;/a&gt; - Synchronized, all iterators are unordered, does not allow null keys or values&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Hashtable.html"&gt;Hashtable&lt;/a&gt; - Synchronized, all iterators are unordered, does not allow null keys or values&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/LinkedHashMap.html"&gt;LinkedHashMap&lt;/a&gt; - Unsychronized, all iterators are ordered based on insertion order of the original key (does not change if a key is reinserted), allows null values but null keys are not allowed&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/TreeMap.html"&gt;TreeMap&lt;/a&gt; - Unsychronized, iterators are ordered by the natural or &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html"&gt;comparator&lt;/a&gt; ordering of the keys, allows null keys and values but the comparator needs to understand them&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3257540444191924763?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3257540444191924763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3257540444191924763' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3257540444191924763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3257540444191924763'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2009/01/java-collection-performance.html' title='Java Collection Performance'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-8395633848230291714</id><published>2008-12-12T12:50:00.004Z</published><updated>2008-12-12T14:11:21.163Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='release:prepare'/><category scheme='http://www.blogger.com/atom/ns#' term='maven 2'/><category scheme='http://www.blogger.com/atom/ns#' term='release plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><title type='text'>Workaround for mvn release:prepare failures</title><content type='html'>If you are using &lt;a href="http://subversion.tigris.org/"&gt;subversion&lt;/a&gt; 1.5.1+ like me you are likely to be frustrated by constant failures while attempting to use the &lt;a href="http://maven.apache.org/plugins/maven-release-plugin/"&gt;Maven Release Plugin&lt;/a&gt; to prepare and perform releases.&lt;br /&gt;There is a simple workaround for this which works like so:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Run &lt;span style="font-weight: bold;"&gt;mvn release:prepare&lt;/span&gt;&lt;/li&gt;&lt;li&gt;After if fails run &lt;span style="font-weight: bold;"&gt;svn update&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Run &lt;span style="font-weight: bold;"&gt;mvn release:prepare&lt;/span&gt; again&lt;/li&gt;&lt;li&gt;Success!&lt;/li&gt;&lt;/ol&gt;The errror here appears to be caused by changes in &lt;a href="http://subversion.tigris.org/"&gt;subversion&lt;/a&gt; 1.5.1 so hopefully that will be fixed in the future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-8395633848230291714?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/8395633848230291714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=8395633848230291714' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/8395633848230291714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/8395633848230291714'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2008/12/workaround-for-mvn-releaseprepare.html' title='Workaround for mvn release:prepare failures'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-5121358006112720978</id><published>2008-08-11T09:57:00.003+01:00</published><updated>2008-08-11T10:04:46.159+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='find java conflict class duplicate'/><title type='text'>Using find to locate duplicate or missing classes</title><content type='html'>I found this super useful find command on the &lt;a href="http://webspherehelp.blogspot.com/"&gt;webspherehelp blog&lt;/a&gt; which I am pasting below:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;find . -name '*.jar' -o -name '*.war' -o -name '*.ear' -type f |xargs -i bash -c "jar -tvf {}| tr / . | grep CLASSNAME &amp;amp;&amp;amp; echo {}"&lt;/span&gt;&lt;br /&gt;Just change the sample Classname to the one you are getitng a conflict with.&lt;br /&gt;It will search though all files in the current directory (or whereever you point the find command) and locate every class file which matches the CLASSNAME text. Very useful.&lt;br /&gt;I needed this to track down a java.lang.LinkageError recently and it worked like a charm.&lt;br /&gt;Here is the &lt;a href="http://webspherehelp.blogspot.com/2007/12/java-class-finder-with-unix-command.html"&gt;original blog posting&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-5121358006112720978?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/5121358006112720978/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=5121358006112720978' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5121358006112720978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5121358006112720978'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2008/08/using-find-to-locate-duplicate-or.html' title='Using find to locate duplicate or missing classes'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-6233841053483589706</id><published>2008-07-22T23:33:00.004+01:00</published><updated>2008-07-22T23:41:30.598+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='email'/><category scheme='http://www.blogger.com/atom/ns#' term='gmail'/><category scheme='http://www.blogger.com/atom/ns#' term='address'/><category scheme='http://www.blogger.com/atom/ns#' term='match'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Gmail address matching craziness</title><content type='html'>This is so crazy it must be blogged about. I got an email which I should have gotten even though it was not actually addressed to me. You are thinking that I am crazy because email does not work that way. Normally I would agree, but check this out:&lt;br /&gt;&lt;span class="HcCDpe"&gt;An email sent to &lt;span style="font-weight: bold;"&gt;azechoski@gmail.com&lt;/span&gt; was delivered to me.&lt;br /&gt;Note that my real address is: azeckoski@gmail.com&lt;br /&gt;&lt;br /&gt;Here are the headers to prove it (chopped out some extra bits to protect the sender):&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;Delivered-To: azeckoski@gmail.com&lt;br /&gt;Received: by 10.151.102.11 with SMTP id e11cs256039ybm;&lt;br /&gt;      Tue, 22 Jul 2008 11:02:35 -0700 (PDT)&lt;br /&gt;Received: by 10.100.205.13 with SMTP id c13mr2655883ang.47.1216749755360;&lt;br /&gt;      Tue, 22 Jul 2008 11:02:35 -0700 (PDT)&lt;br /&gt;Received: from mail2.stellaronecorp.com (mail2.stellarone.com [64.203.182.58])&lt;br /&gt;      by mx.google.com with ESMTP id c40si8810491anc.30.2008.07.22.11.02.34;&lt;br /&gt;      Tue, 22 Jul 2008 11:02:35 -0700 (PDT)&lt;br /&gt;Content-class: urn:content-classes:message&lt;br /&gt;MIME-Version: 1.0&lt;br /&gt;Content-Type: multipart/alternative;&lt;br /&gt;boundary="----_=_NextPart_001_01C8EC25.00DD8ED8"&lt;br /&gt;X-MimeOLE: Produced By Microsoft Exchange V6.5&lt;br /&gt;X-OriginalArrivalTime: 22 Jul 2008 18:01:01.0106 (UTC) FILETIME=[E68D5920:01C8EC24]&lt;br /&gt;Subject: Transfer&lt;br /&gt;Date: Tue, 22 Jul 2008 14:01:45 -0400&lt;br /&gt;Message-ID: &lt;7925a85885c9454897dba459745e840d5aa877@west-exch1.stellaronecorp.com&gt;&lt;br /&gt;To: azechoski@gmail.com&lt;azechoski@gmail.com&gt;&lt;/azechoski@gmail.com&gt;&lt;/pre&gt;&lt;span class="HcCDpe"&gt;&lt;br /&gt;Seriously, how cool is that?&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-6233841053483589706?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/6233841053483589706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=6233841053483589706' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6233841053483589706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6233841053483589706'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2008/07/gmail-address-matching-craziness.html' title='Gmail address matching craziness'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-7159846157810375727</id><published>2008-06-07T12:31:00.004+01:00</published><updated>2008-06-07T12:57:45.273+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='training'/><category scheme='http://www.blogger.com/atom/ns#' term='botcamp'/><category scheme='http://www.blogger.com/atom/ns#' term='workshop'/><category scheme='http://www.blogger.com/atom/ns#' term='Marist College'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><title type='text'>Marist Sakai Bootcamp</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_gYJbpIL6GOI/SEpzwIdoITI/AAAAAAAAAAw/8LmrFK25HYI/s1600-h/IMG011.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_gYJbpIL6GOI/SEpzwIdoITI/AAAAAAAAAAw/8LmrFK25HYI/s320/IMG011.JPG" alt="" id="BLOGGER_PHOTO_ID_5209103189750063410" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;We just wrapped up the &lt;a href="http://confluence.sakaiproject.org/confluence/display/BOOT/Marist+College"&gt;Sakai Marist Bootcamp&lt;/a&gt; which ran from June 2nd through the 6th at Marist College in PoughKeepsie, New York, USA. There were 32 participants from universities in Michigan, New York, Maryland, Ohio, Hawaii, Canada (not comprehensive) and commercial groups like IBM, rSmart, Unicon, and Serensoft. This is the first Sakai bootcamp of 2008 and I guess something like the 10th one I have taught overall.&lt;br /&gt;Topics covered included Sakai installation and development environments, Eclipse usage, Sakai code structure, development practices and tips, and various Java development tips. Participants had quite a varied level of knowledge from those who were new to Java and Sakai to those who had been using Java for 10+ years and Sakai for 3+ years. There were participatns from higher ed and K-12. Marist is helping provide Sakai services for K-12 schools around NY state and I had a chance to see how they are using Sakai. I felt like the workshop went really well and I enjoyed my time in Poughkeepsie, NY.&lt;br /&gt;Our hosts at Marist treated us very well and provided lunch and snacks every day and a great location to have the workshop. We went to Shadows (a semi open air restaurant along the river) on Tuesday evening and had a good time with fairly traditional upscale american dining. I was honored to have a chance to meet a dean and the president of the college on the last day.&lt;br /&gt;Cheers to everyone who organized things and gave me a chance to come to NY and hopefully expand the Sakai community.&lt;br /&gt;&lt;br /&gt;Flickr photos are posted here: &lt;a href="http://www.flickr.com/photos/tags/sakaimaristbootcamp/"&gt;http://www.flickr.com/photos/tags/sakaimaristbootcamp/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-7159846157810375727?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://confluence.sakaiproject.org/confluence/display/BOOT/Marist+College' title='Marist Sakai Bootcamp'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/7159846157810375727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=7159846157810375727' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/7159846157810375727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/7159846157810375727'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2008/06/marist-sakai-bootcamp.html' title='Marist Sakai Bootcamp'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_gYJbpIL6GOI/SEpzwIdoITI/AAAAAAAAAAw/8LmrFK25HYI/s72-c/IMG011.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-5437171431843078844</id><published>2008-05-17T15:08:00.002+01:00</published><updated>2008-05-17T15:25:58.542+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='maven2'/><category scheme='http://www.blogger.com/atom/ns#' term='pom'/><category scheme='http://www.blogger.com/atom/ns#' term='ddl'/><category scheme='http://www.blogger.com/atom/ns#' term='generator'/><title type='text'>Maven2 hibernate DDL generation</title><content type='html'>I needed a way to get hibernate to generate DDL for me and I ended up using the hibernate maven plugin. It took a lot of trial and error to get it working so hopefully this will save someone some time when they try to do the same thing.&lt;br /&gt;&lt;br /&gt;In case you are not familiar, &lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt; is an ORM package for Java that allows you to treat your database like a collection of objects (sort of). &lt;a href="http://maven.apache.org/"&gt;Maven2&lt;/a&gt; is a java build system (like ant or make). &lt;a href="http://en.wikipedia.org/wiki/Data_Definition_Language"&gt;DDL is data definition language&lt;/a&gt; and tends to be unique for every database so if you want a project to work with multiple databases then you have to create DDL for each one. That's where this comes in to play. Normally hibernate will generate DDL and run it for you but this is not always desirable. Especially when dealing with production systems which already have a large database. This will allow you to generate the DDL right in the source of your project and then simply commit the DDL files back to your source repository. If you change your hibernate mapping files then regenerate the DDL and commit the changes.&lt;br /&gt;&lt;br /&gt;I created a simple folder with the right pom.xml and the other needed support files to allow a developer to generate DDL by just running mvn install in their ddl folder (the one with these files). You can &lt;a href="http://confluence.sakaiproject.org/confluence/download/attachments/24019059/maven2-hibernate-ddl.zip"&gt;download that&lt;/a&gt; to get started. There is a little bit of setup required which is detailed on my wiki page about &lt;a href="http://confluence.sakaiproject.org/confluence/display/BOOT/Maven2+hibernate+DDL+generator+POM"&gt;generating DDL using hibernate and maven2&lt;/a&gt;. Checkout the &lt;a href="http://confluence.sakaiproject.org/confluence/download/attachments/24019059/readme.txt"&gt;readme&lt;/a&gt; which explains how to use it. I would think it is probably 10 minutes of effort to add this to an existing hibernate project which is using maven 2.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-5437171431843078844?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://confluence.sakaiproject.org/confluence/display/BOOT/Maven2+hibernate+DDL+generator+POM' title='Maven2 hibernate DDL generation'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/5437171431843078844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=5437171431843078844' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5437171431843078844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5437171431843078844'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2008/05/maven2-hibernate-ddl-generation.html' title='Maven2 hibernate DDL generation'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-7285431606997763631</id><published>2008-05-12T00:20:00.009+01:00</published><updated>2008-05-12T01:02:19.797+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dependency'/><category scheme='http://www.blogger.com/atom/ns#' term='maven 2'/><category scheme='http://www.blogger.com/atom/ns#' term='versioning'/><category scheme='http://www.blogger.com/atom/ns#' term='range'/><title type='text'>Fun with Maven 2 dependencies</title><content type='html'>I learned some new &lt;a href="http://maven.apache.org/"&gt;Maven 2&lt;/a&gt; tricks this weekend while experimenting with things. In general it can be a real pain when you are developing a piece of framework code which a few projects depend on and you find a minor issue which requires a new release. Typically you have to go around updating lots of POMs. Well, no longer! In maven 2 you can now specify version ranges which can save you a lot of updating when newer versions of packages come out.&lt;br /&gt;Normal maven 2 depedencies look like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;br /&gt;     &amp;lt;dependency&amp;gt;&lt;br /&gt;        &amp;lt;groupId&amp;gt;org.sakaiproject.entitybroker&amp;lt;/groupId&amp;gt;&lt;br /&gt;        &amp;lt;artifactId&amp;gt;entitybroker-api&amp;lt;/artifactId&amp;gt;&lt;br /&gt;        &amp;lt;version&amp;gt;1.3.3&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;&lt;br /&gt;     &amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, if a bug fix is released for this which is 1.3.4 then I will not pick up on the new version and would have to explicitly put it in. However, if I want to pick up any minor version updates for a project and I want the minimum version to be 1.3.3 (but less than 1.4.0) I can do this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;br /&gt;     &amp;lt;dependency&amp;gt;&lt;br /&gt;        &amp;lt;groupId&amp;gt;org.sakaiproject.entitybroker&amp;lt;/groupId&amp;gt;&lt;br /&gt;        &amp;lt;artifactId&amp;gt;entitybroker-api&amp;lt;/artifactId&amp;gt;&lt;br /&gt;        &amp;lt;version&amp;gt;[1.3.3,1.4.0)&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;&lt;br /&gt;     &amp;lt;/dependency&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;A word of warning though, if the packages you are using do not adhere to standards of versioning you can really get in trouble if a new version comes out with an incompatible interface. Of course, if that happens you simply adjust the version range in the POM.&lt;br /&gt;&lt;br /&gt;More info here: http://docs.codehaus.org/display/MAVEN/Dependency+Mediation+and+Conflict+Resolution&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-7285431606997763631?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/7285431606997763631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=7285431606997763631' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/7285431606997763631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/7285431606997763631'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2008/05/fun-with-maven-2-dependencies.html' title='Fun with Maven 2 dependencies'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-938936545926127144</id><published>2008-05-08T12:25:00.004+01:00</published><updated>2008-05-08T12:42:12.388+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='entity provider'/><category scheme='http://www.blogger.com/atom/ns#' term='developer'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='EntityBroker'/><category scheme='http://www.blogger.com/atom/ns#' term='entity broker'/><category scheme='http://www.blogger.com/atom/ns#' term='DeveloperHelperService'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><title type='text'>EntityBroker 1.3.3 released</title><content type='html'>The new 1.3.3 version of &lt;a href="http://confluence.sakaiproject.org/confluence/display/SAKDEV/Entity+Provider+and+Broker"&gt;EntityBroker&lt;/a&gt; is released. This includes a bunch of new features to make working with Sakai easier but the biggest improvement is full support for &lt;a href="http://microformats.org/wiki/rest/urls"&gt;RESTful URLs&lt;/a&gt;. Now a developer can &lt;a href="http://confluence.sakaiproject.org/confluence/display/SAKDEV/Defining+EntityProviders"&gt;write an EntityProvider&lt;/a&gt; and implement a handful of interfaces and end up with REST access to their entities. This now allows developers to expose data from within Sakai to be read and written via REST calls by other Sakai apps, Sakai helpers, external apps (PHP, Perl, etc.), and client side widgets. This includes support for transformation of entity POJOs to and from JSON and XML automatically. Like everything else in EB, this can be disabled or controlled explicitly if desired. More details on the &lt;a href="http://confluence.sakaiproject.org/confluence/display/SAKDEV/EntityBroker+RESTful+URL+support"&gt;RESTful entities page&lt;/a&gt;.&lt;br /&gt;The other major change in this release is the &lt;a href="https://source.sakaiproject.org/svn/entitybroker/trunk/api/src/java/org/sakaiproject/entitybroker/DeveloperHelperService.java"&gt;DeveloperHelperService&lt;/a&gt;. This is a shared service that the EntityBroker provides. This service makes it easier to deal with current Sakai data as entity references. Methods include getting current user/location/tool and generating URLs to work with entites and within Sakai. It also provides for some protection against shifting Sakai service APIs as this service API will remain stable and allow access to common things like current user and site without requiring knowledge of the Sakai service structure.&lt;br /&gt;There are few minor improvements in the new version like support for persistent entity properties (without using hibernate) and support for persistent entity tags. There are also improvements in the classloader handling to ensure that the entity system will not hold onto class resources when a classloader reloads (e.g. webapp reload). Thanks to testing by Stephen Marquard this release should be fully backwards compatible with the pervious version.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-938936545926127144?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://confluence.sakaiproject.org/confluence/display/SAKDEV/Entity+Provider+and+Broker' title='EntityBroker 1.3.3 released'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/938936545926127144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=938936545926127144' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/938936545926127144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/938936545926127144'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2008/05/entitybroker-133-released.html' title='EntityBroker 1.3.3 released'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3648311067620385527</id><published>2008-05-04T17:55:00.005+01:00</published><updated>2008-05-04T19:12:39.437+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DAO'/><category scheme='http://www.blogger.com/atom/ns#' term='JDBC'/><category scheme='http://www.blogger.com/atom/ns#' term='spring framework'/><category scheme='http://www.blogger.com/atom/ns#' term='GenericDao'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><title type='text'>GenericDao 0.9.5</title><content type='html'>The 0.9.5 version of &lt;a href="http://confluence.sakaiproject.org/confluence/display/BOOT/Generic+DAO+package"&gt;GenericDao&lt;/a&gt; is now available. This provides the biggest leap in functionality yet with enhancements including support for &lt;a href="http://en.wikipedia.org/wiki/Java_Database_Connectivity"&gt;JDBC&lt;/a&gt; and pure SQL (along with &lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt;) and new search methods which use a generalized Search object to make it easy to control restrictions, limits, ordering and bascially everything you would want to put in a search for an object.&lt;br /&gt;For anyone unfamiliar with the package it is mostly a bunch of convenience code to make it a little easier to have &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping"&gt;ORM&lt;/a&gt; like functionality and not have to write the same boring create/update/find/delete methods over and over again. It also provides a simple and extendable interface for working with persistent objects.&lt;br /&gt;I am using the new version to replace the previous hibernate usage in a couple of projects and things seem to work quite well so far. The new version builds on some of the Apache projects like &lt;a href="http://commons.apache.org/beanutils/"&gt;BeanUtils&lt;/a&gt;, Google projects like &lt;a href="http://code.google.com/p/google-guice/"&gt;Guice&lt;/a&gt;, and the &lt;a href="http://springframework.org/"&gt;Spring Framework&lt;/a&gt;.&lt;br /&gt;I hope to add in support for &lt;a href="http://en.wikipedia.org/wiki/Data_Definition_Language"&gt;DDL&lt;/a&gt; generation using &lt;a href="http://db.apache.org/ddlutils/"&gt;Apache DDLUtils&lt;/a&gt; in the next release.&lt;br /&gt;&lt;br /&gt;Download (Maven2):&lt;a href="https://source.sakaiproject.org/maven2/org/sakaiproject/generic-dao/"&gt;https://source.sakaiproject.org/maven2/org/sakaiproject/generic-dao/&lt;/a&gt;&lt;br /&gt;Maven site: &lt;span class="nobr"&gt;&lt;a href="https://source.sakaiproject.org/maven2/org/sakaiproject/generic-dao/site/" rel="nofollow"&gt;https://source.sakaiproject.org/maven2/org/sakaiproject/generic-dao/site/&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;Javadocs: &lt;span class="nobr"&gt;&lt;a href="https://source.sakaiproject.org/maven2/org/sakaiproject/generic-dao/site/apidocs/index.html" rel="nofollow"&gt;https://source.sakaiproject.org/maven2/org/sakaiproject/generic-dao/site/apidocs/&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;On a related note, this release was made using the &lt;a href="http://maven.apache.org/"&gt;Maven 2&lt;/a&gt; release plugin which made the process very clean and easy. I recommend it highly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3648311067620385527?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://confluence.sakaiproject.org/confluence/display/BOOT/Generic+DAO+package' title='GenericDao 0.9.5'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3648311067620385527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3648311067620385527' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3648311067620385527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3648311067620385527'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2008/05/genericdao-095.html' title='GenericDao 0.9.5'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-5167120468476021834</id><published>2008-02-27T13:02:00.002Z</published><updated>2008-02-27T13:13:25.794Z</updated><title type='text'>Subversion Keywords</title><content type='html'>I finally got around to putting in &lt;a href="http://svnbook.red-bean.com/en/1.4/svn.advanced.props.special.keywords.html"&gt;SVN keywords&lt;/a&gt; in some of the files for the &lt;a href="http://confluence.sakaiproject.org/confluence/display/EVALSYS"&gt;Evaluation System&lt;/a&gt; project. It took me a little while to figure this out but they don't start working automatically. You have to take the extra step of telling &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; (via properties) that you want it to actually do the keyword substitution. Luckily the steps are pretty easy once you figure it out.&lt;br /&gt;&lt;br /&gt;1) Add some keywords to your files like so:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$Id$&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;$URL$&lt;/span&gt;&lt;br /&gt;2) Run this command from the base directory of your project (this will add all the keywords, just remove the ones you don't want from the string):&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;svn propset -R svn:keywords "Date Revision Author URL Id" .&lt;/span&gt;&lt;br /&gt;3) Commit the code (this will take awhile because it is going to commit a new revision of every file in your project). The keywords will be replaced and look more like this:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;$Id: EvalConstants.java 46025 2008-02-27 13:01:48Z aaronz@vt.edu $&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;$URL: https://source.sakaiproject.org/contrib/evaluation/trunk/$&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Disappointingly this will not work for all files going forward so you will have to reapply this for new files or just do the whole set every once in awhile.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-5167120468476021834?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/5167120468476021834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=5167120468476021834' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5167120468476021834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5167120468476021834'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2008/02/subversion-keywords.html' title='Subversion Keywords'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-1095944944415196458</id><published>2008-01-27T11:45:00.001Z</published><updated>2008-01-27T13:45:50.356Z</updated><title type='text'>Silverlight</title><content type='html'>I was roaming around the web and ran into a web application that used &lt;a href="http://www.microsoft.com/silverlight/"&gt;Silverlight&lt;/a&gt; this weekend. I did a little investigating and this weems to be &lt;a href="http://www.microsoft.com/"&gt;Microsoft&lt;/a&gt;'s answer for &lt;a href="http://www.adobe.com/products/flashplayer/"&gt;Flash&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Rich_Internet_application"&gt;Rich Internet Applications&lt;/a&gt; in general. They make a lot of interesting claims about cross browser compatibility (&lt;a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx"&gt;IE&lt;/a&gt;, &lt;a href="http://www.mozilla.com/firefox/"&gt;Firefox&lt;/a&gt;, and &lt;a href="http://www.apple.com/safari/"&gt;Safari&lt;/a&gt;) and compatibility with existing backends and &lt;a href="http://en.wikipedia.org/wiki/AJAX"&gt;AJAX&lt;/a&gt;. The big score for it though seems to be the claim that it is fully &lt;a href="http://en.wikipedia.org/wiki/Accessible"&gt;accessible&lt;/a&gt; and that the toolkit helps you make your apps more accessible and &lt;a href="http://en.wikipedia.org/wiki/Internationalization_and_localization"&gt;l10n&lt;/a&gt;. Overall, it looks pretty compelling and &lt;a href="http://silverlight.net/Learn/"&gt;fairly easy to learn&lt;/a&gt; so I plan to keep an eye on it and see where it goes.&lt;br /&gt;&lt;br /&gt;Main websites:&lt;br /&gt;&lt;a href="http://silverlight.net/"&gt;http://silverlight.net/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.microsoft.com/silverlight/"&gt;http://www.microsoft.com/silverlight/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A really cool use of Silverlight:&lt;br /&gt;&lt;a href="http://www.microsoft.com/silverlight/halo3.aspx"&gt;http://www.microsoft.com/silverlight/halo3.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A blog/analysis of it from a developer prespective:&lt;br /&gt;&lt;a href="http://www.gskinner.com/blog/archives/2007/05/a_flash_of_silv.html"&gt;http://www.gskinner.com/blog/archives/2007/05/a_flash_of_silv.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A demo/interview of Silverlight on Youtube:&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=JEUrQEj6Sd4"&gt;http://www.youtube.com/watch?v=JEUrQEj6Sd4&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Linux related project (Moonlight):&lt;br /&gt;&lt;a href="http://www.mono-project.com/Moonlight"&gt;http://www.mono-project.com/Moonlight&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Related (competing) projects:&lt;br /&gt;Adobe AIR: &lt;a href="http://labs.adobe.com/technologies/air/"&gt;http://labs.adobe.com/technologies/air/&lt;/a&gt;&lt;br /&gt;Google Gears: &lt;a href="http://code.google.com/apis/gears/"&gt;http://code.google.com/apis/gears/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-1095944944415196458?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://silverlight.net/' title='Silverlight'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/1095944944415196458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=1095944944415196458' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/1095944944415196458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/1095944944415196458'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2008/01/silverlight.html' title='Silverlight'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-1032397647999740029</id><published>2007-12-24T23:48:00.000Z</published><updated>2007-12-24T23:58:30.037Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='notification'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><title type='text'>Working with Twitter</title><content type='html'>I have been playing with &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt; a little bit recently. It is a service that allows you share what you are doing with people via little messages. I can just be used for fun, but it can also be a valuable way to keep up with coworkers and colleagues. Updates can be sent via the website, IM, or even SMS texts from your phone.&lt;br /&gt;I have been experimenting with the &lt;a href="http://facebook.com/"&gt;facebook&lt;/a&gt; integration and it is pretty good (via the &lt;a href="http://apps.facebook.com/twittersync/"&gt;TwitterSync&lt;/a&gt; app). This is the best way I have found to keep your facebook status synced up with Twitter.&lt;br /&gt;I am most curious to see how use of twitter in a professional setting evolves. I think it could be a great way for split project team members to keep up with each other.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-1032397647999740029?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://twitter.com/' title='Working with Twitter'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/1032397647999740029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=1032397647999740029' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/1032397647999740029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/1032397647999740029'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/12/working-with-twitter.html' title='Working with Twitter'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-4300001082508265942</id><published>2007-12-22T13:40:00.000Z</published><updated>2007-12-22T14:52:49.446Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='stringbuilder'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='string'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='compiler'/><title type='text'>Strings and StringBuilder optimizations</title><content type='html'>I keep running across code like this:&lt;br /&gt;&lt;pre&gt;public String THIS = "this ";&lt;br /&gt;...&lt;br /&gt;StringBuilder sb = new StringBuilder();&lt;br /&gt;sb.append(THIS);&lt;br /&gt;sb.append("is ").append("a ");&lt;br /&gt;sb.append("test: ");&lt;br /&gt;sb.append(5);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It is hard to read and maintain, and wastes the time of the developer who wrote it because there is basically no benefit to writing it. The (Sun) Java compiler will do some optimizations which end up allowing coders to write nicer looking code and avoid lots of extra typing or copy and paste. Let's rewrite the same code the way we would like to if we were not trying to over optimize.&lt;br /&gt;&lt;pre&gt;  String test = THIS + "is " + "a " + "test: " + 5;&lt;br /&gt;&lt;/pre&gt;That's easier to read and the compiler turns this into a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html"&gt;StringBuilder&lt;/a&gt; anyway. It is easily prove n by runing this code through a debugger and tracing it.&lt;br /&gt;There is another related trick that the compiler will do for Strings.&lt;br /&gt;&lt;pre&gt;  String test = "this " + "is " + "a " + "test: " + 5;&lt;br /&gt;&lt;/pre&gt;That becomes "this is a test: 5" in the bytecode (this is in the language spec). Very easy to read and zero cost at runtime.&lt;br /&gt;&lt;br /&gt;As always, the old rule of thumb applies. Always optimize last (or never). Readable and maintainable code is far more important that a minor optimization which possibly saves a few nanoseconds (and in this case saves none).&lt;br /&gt;&lt;br /&gt;Before anyone gets the wrong impression, there are perfectly viable cases for writing &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html"&gt;StringBuilders&lt;/a&gt; in your code. Creating a string from a large number of smaller strings within a loop is the most common use case. For example:&lt;br /&gt;&lt;pre&gt;StringBuilder sb = new StringBuilder();&lt;br /&gt;sb.append("Counting: ");&lt;br /&gt;for (int i = 0; i &lt;&gt;&lt;br /&gt; sb.append(" ").append(i);&lt;br /&gt;}&lt;br /&gt;String test = sb.toString();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this case, using a single string and writing += would be more costly and should be avoided for any code that will run often.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;NOTE:&lt;/span&gt; There is a pitfall here that one can fall into fairly easily. This example of what NOT to do shows how easy this is:&lt;br /&gt;&lt;pre&gt;StringBuilder sb = new StringBuilder();&lt;br /&gt;sb.append("Counting: ");&lt;br /&gt;for (int i = 0; i &lt;&gt;&lt;br /&gt; sb.append(" " + i + " ");&lt;br /&gt;}&lt;br /&gt;String test = sb.toString();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this case, there will be a new &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html"&gt;StringBuilder&lt;/a&gt; created for each iteration through the loop. Do not use "+" concatenation with variables inside the loop (as shown inside the inner append above). This will end up producing another &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html"&gt;StringBuilder&lt;/a&gt; if there is a variable (it is fine if you are using constants). The loss from the creation of many additional &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html"&gt;StringBuilder&lt;/a&gt; objects will offset the gains from using the outer &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html"&gt;StringBuilder&lt;/a&gt;.&lt;br /&gt;&lt;pre&gt;sb.append(" " + i + " ");&lt;/pre&gt;is efficiently written (when inside a loop) as:&lt;br /&gt;&lt;pre&gt;sb.append(" ").append(i).append(" ");&lt;/pre&gt;&lt;br /&gt;The rule of thumb I use is that if I am concatenating strings on a single line of code then I use "+", otherwise I use a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html"&gt;StringBuilder&lt;/a&gt;. I sometimes break that rule if I am just concatenating on 2 or 3 lines and the code would be more readable if I used "+" (since the savings are so small in that case).&lt;br /&gt;&lt;br /&gt;For those of you runing Java 1.4, the optimization is still there but uses &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/StringBuffer.html"&gt;StringBuffer&lt;/a&gt; instead.&lt;br /&gt;&lt;br /&gt;The key takeaway here is that writing readable and maintainable code should always be a priority over writing optimized code and this is one case where the compiler makes that a little bit easier on the developer.&lt;br /&gt;&lt;br /&gt;A few helpful related links for more in depth study:&lt;br /&gt;&lt;a href="http://nicklothian.com/blog/2005/06/09/on-java-string-concatenation/"&gt;http://nicklothian.com/blog/2005/06/09/on-java-string-concatenation/&lt;br /&gt;&lt;/a&gt;&lt;a href="http://java.sun.com/developer/JDCTechTips/2002/tt0305.html"&gt;http://java.sun.com/developer/JDCTechTips/2002/tt0305.html&lt;br /&gt;&lt;/a&gt; &lt;a href="http://www.precisejava.com/javaperf/j2se/StringAndStringBuffer.htm"&gt;http://www.precisejava.com/javaperf/j2se/StringAndStringBuffer.htm&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-4300001082508265942?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/4300001082508265942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=4300001082508265942' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/4300001082508265942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/4300001082508265942'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/12/strings-and-stringbuilder-optimizations.html' title='Strings and StringBuilder optimizations'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3847169479700410021</id><published>2007-12-15T14:57:00.000Z</published><updated>2007-12-15T15:16:08.663Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='scaling'/><category scheme='http://www.blogger.com/atom/ns#' term='TSE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='grid'/><title type='text'>Scaling Java with Grids and Clouds</title><content type='html'>There has been a lot of talk about using &lt;a href="http://en.wikipedia.org/wiki/Data_grid"&gt;grids&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Space_based_architecture"&gt;spaces&lt;/a&gt; to handle large scale java applications at &lt;a href="http://www.thespringexperience.com/conference/hollywood/2007/12/index.html"&gt;The Spring Experience 2007&lt;/a&gt;. The compelling thing about this for me is the idea that these applications allow architects to abstract the concept of clustering. Developers can effectively program as if they are running on a single server (with some minor APIs here and there depending on the solution). Most solutions scale up very well and provide failover support.&lt;br /&gt;&lt;br /&gt;These solutions are being recommended as production ready solutions and apparently large companies (like banks) are already using them in massive scale production. It will be interesting to see how these impact Java enterprise development in the future.&lt;br /&gt;&lt;br /&gt;Here are some of the solutions I heard mentioned at TSE 2007:&lt;br /&gt;&lt;a href="http://www.terracotta.org/"&gt;Terracota&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.openspaces.org/"&gt;OpenSpaces&lt;/a&gt; (API/aggregation site)&lt;br /&gt;&lt;a href="http://www.gigaspaces.com/"&gt;GigaSpaces XAP&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.oracle.com/products/middleware/coherence/index.html"&gt;Coherence&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www-1.ibm.com/support/docview.wss?uid=swg27006432"&gt;ObjectGrid&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3847169479700410021?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3847169479700410021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3847169479700410021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3847169479700410021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3847169479700410021'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/12/scaling-java-with-grids-and-clouds.html' title='Scaling Java with Grids and Clouds'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-307380906788746710</id><published>2007-12-15T02:50:00.000Z</published><updated>2007-12-15T03:01:51.474Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='adrian'/><category scheme='http://www.blogger.com/atom/ns#' term='TSE'/><category scheme='http://www.blogger.com/atom/ns#' term='OSGi'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='rob'/><category scheme='http://www.blogger.com/atom/ns#' term='keynote'/><title type='text'>Spring Dynamic Modules</title><content type='html'>&lt;a href="http://blog.interface21.com/main/author/adrianc/"&gt;Adrian Colyer&lt;/a&gt; did an incredible demo of &lt;a href="http://www.springframework.org/osgi/"&gt;Spring OSGi&lt;/a&gt; at &lt;a href="http://www.thespringexperience.com/conference/hollywood/2007/12/index.html"&gt;The Spring Experience&lt;/a&gt; on Friday, 14 Dec, 2007 to show the things that are up and coming. The demo included a 3 layer app (web, logic, dao) running with each layer as a separate module in &lt;a href="http://en.wikipedia.org/wiki/OSGi"&gt;OSGi&lt;/a&gt;. During the demo he intentionally shutdown the logic module, clicked a link on the web page, restarted the logic module, and then went back to the page which had magically worked without failing. Apparently Spring OSGi will proxy the layers until a timeout is reached or the module can restart. This allows some amazing things (like upgrades without server shutown). It can also control access to the modules so they can effectively operate in a hierarchy. I think they said it should be released in a few months.&lt;br /&gt;&lt;br /&gt;On a side note, Adrian and Rob did a great keynote with some singing and roleplaying. It was easily the best keynote I have ever seen. Cheers to all who planned and executed it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-307380906788746710?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.springframework.org/osgi/' title='Spring Dynamic Modules'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/307380906788746710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=307380906788746710' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/307380906788746710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/307380906788746710'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/12/spring-dynamic-modules.html' title='Spring Dynamic Modules'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-7643418193859846132</id><published>2007-12-14T04:48:00.000Z</published><updated>2007-12-14T05:18:00.627Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='TSE'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='RSF'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><title type='text'>The Spring Experience and RSF</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_gYJbpIL6GOI/R2ISAPChDBI/AAAAAAAAAAU/paTAH_3r1mI/s1600-h/AZ-TSE.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_gYJbpIL6GOI/R2ISAPChDBI/AAAAAAAAAAU/paTAH_3r1mI/s320/AZ-TSE.jpg" alt="" id="BLOGGER_PHOTO_ID_5143693519656913938" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I am attending &lt;a href="http://www.thespringexperience.com/conference/hollywood/2007/12/index.html"&gt;the Spring Expereience in Hollywood, Florida&lt;/a&gt; this week (Dec 14, 2007) along with Antranig. It is exciting and scary to be around so many really great developers. It feels like everyone we talk to is doing something impressive and advanced with &lt;a href="http://www.springframework.org/"&gt;Spring&lt;/a&gt;. It is pretty intimidating to be around and talk to all these really great developers.&lt;br /&gt;&lt;br /&gt;The sesssions have been really great so far. It is really hard to decide which sessions to attend because there have been a few slots where I wanted to attend all five talks. The presenters have actually written code in front of people which is great to see. I have had a chance to learn about the new Spring annotations, &lt;a href="http://en.wikipedia.org/wiki/AspectJ"&gt;AspectJ&lt;/a&gt;, @MVC, and &lt;a href="http://en.wikipedia.org/wiki/Automated_testing"&gt;Testing&lt;/a&gt;. The material is advanced but that is what I want.&lt;br /&gt;&lt;br /&gt;Antranig and I presented a &lt;a href="http://www.thespringexperience.com/show_session_view.jsp?presentationId=340&amp;amp;showId=46"&gt;rapid fire session on RSF&lt;/a&gt;. It was a one hour introduction to the goals and basics of &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/"&gt;RSF&lt;/a&gt;. We had a bit of technical trouble and the talk before us ran long but overall I felt really positive about the session. There were lots of good questions and we had about 25 people in the session. We even got a compliment on the &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/"&gt;wiki and documentation&lt;/a&gt;. I hope we will have a chance to talk with more people about RSF during the remainder of the conference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-7643418193859846132?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.thespringexperience.com/show_session_view.jsp?presentationId=340&amp;showId=46' title='The Spring Experience and RSF'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/7643418193859846132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=7643418193859846132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/7643418193859846132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/7643418193859846132'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/12/spring-experience-and-rsf.html' title='The Spring Experience and RSF'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_gYJbpIL6GOI/R2ISAPChDBI/AAAAAAAAAAU/paTAH_3r1mI/s72-c/AZ-TSE.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3414077562000430511</id><published>2007-10-16T21:08:00.001+01:00</published><updated>2007-10-16T21:20:22.558+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='markup'/><category scheme='http://www.blogger.com/atom/ns#' term='validation'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Validating CSS online</title><content type='html'>I recently had a problem with a webapp where things were showing up but I could not figure out why. The CSS seemed correct at a glance but someone else had written it so I was not very familiar with it. After struggling for awhile I did the smart thing and asked &lt;a href="http://bugs.sakaiproject.org/confluence/display/~gsilver"&gt;Gonzalo Silverio&lt;/a&gt; if he had any ideas (which of course, he did). He pointed me to this awesome CSS validator at &lt;a href="http://jigsaw.w3.org/css-validator/"&gt;http://jigsaw.w3.org/css-validator/&lt;/a&gt;. You can upload a css file or simply provide a URL to the file and it will give you a nice little report that tells you what is wrong.&lt;br /&gt;A similar service for validating your markup is available at &lt;a href="http://validator.w3.org/"&gt;http://validator.w3.org/&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3414077562000430511?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3414077562000430511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3414077562000430511' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3414077562000430511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3414077562000430511'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/10/validating-css-online.html' title='Validating CSS online'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-3060442636610041907</id><published>2007-10-07T21:06:00.000+01:00</published><updated>2007-10-07T23:37:55.524+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='roadmap'/><category scheme='http://www.blogger.com/atom/ns#' term='community process'/><category scheme='http://www.blogger.com/atom/ns#' term='framework'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><title type='text'>Roadmaps, Kernels, and Community?</title><content type='html'>There has been a bit of traffic on the mailing lists about &lt;a href="http://en.wikipedia.org/wiki/Kernel_(computer_science)"&gt;Kernels&lt;/a&gt; and &lt;a href="http://www.sakaiproject.org/"&gt;Sakai&lt;/a&gt; community processes recently. I personally hope that it will encourage more open communication in the community and more transparency around decision making. I have high hopes that some of the proposals I have posted in the &lt;a href="http://confluence.sakaiproject.org/confluence/display/SAKDEV/Home"&gt;Sakai Dev space&lt;/a&gt; on &lt;a href="http://confluence.sakaiproject.org/confluence/"&gt;Sakai Confluence&lt;/a&gt; will spark conversations and encourage people to get involved in various framework improvement efforts.&lt;br /&gt;&lt;br /&gt;In particular, I am hoping the following things are worked out BEFORE or AT the &lt;a href="https://sakai.educonference.com/conference/"&gt;Sakai conference in December&lt;/a&gt;.&lt;br /&gt;1) What does the &lt;a href="http://confluence.sakaiproject.org/confluence/display/SAKDEV/Sakai+Roadmap"&gt;Sakai Roadmap&lt;/a&gt; look like?&lt;br /&gt;2) What is a &lt;a href="http://confluence.sakaiproject.org/confluence/display/SAKDEV/Best+Practices+for+framework+updates"&gt;framework team&lt;/a&gt;? What does it do? Who are the initial members?&lt;br /&gt;3) How does the voting process work in Sakai and what kinds of things should be voted on?&lt;br /&gt;4) Do we have a &lt;a href="http://confluence.sakaiproject.org/confluence/display/SAKDEV/Kernel+Release"&gt;Sakai Kernel&lt;/a&gt; and if so, what does that mean (what is it)?&lt;br /&gt;5) Should we have a &lt;a href="http://confluence.sakaiproject.org/confluence/display/SAKDEV/Best+Practices+for+framework+updates"&gt;code approval process for the Sakai framework&lt;/a&gt; and what should it look like?&lt;br /&gt;&lt;br /&gt;What are the right answers to these questions? Frankly, that is outside my core area of expertise which is mostly designing and writing software. I have some proposals out there in the hopes that someone smarter will come along and rip them apart and replace them with something that is better. Even if that doesn't happen, I hope they will at least encourage discussion. Isn't that how we arrive at decisions that will benefit us all as a community? I mean, we don't really need someone to make all the decisions for us and tell us what to do... do we?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-3060442636610041907?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/3060442636610041907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=3060442636610041907' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3060442636610041907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/3060442636610041907'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/10/roadmaps-kernels-and-community.html' title='Roadmaps, Kernels, and Community?'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-6894058160939115568</id><published>2007-08-25T11:17:00.000+01:00</published><updated>2007-08-25T11:34:38.278+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RAD tool'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='appbuilder'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><title type='text'>Sakai AppBuilder 0.82 available</title><content type='html'>Version 0.82 of the &lt;a href="http://confluence.sakaiproject.org/confluence/display/BOOT/Sakai+App+Builder"&gt;Sakai AppBuilder&lt;/a&gt; is now available on the Sakai &lt;a href="http://www.eclipse.org/articles/Article-Update/keeping-up-to-date.html"&gt;eclipse update site&lt;/a&gt; (&lt;a href="http://source.sakaiproject.org/appbuilder/update/"&gt;http://source.sakaiproject.org/appbuilder/update/&lt;/a&gt;). This version will now generate maven 1 project files and maven 2 pom files and will create the links to the local repository for the eclipse classpath for either maven 1 or 2. This also includes updates to the most recent jars being used with &lt;a href="http://sakaiproject.org/"&gt;Sakai&lt;/a&gt; including the recent release of &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/"&gt;RSF 0.7.2RC1&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;img id="BLOGGER_PHOTO_ID_5102584413918715394" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://bp0.blogger.com/_gYJbpIL6GOI/RtAFfWQR3gI/AAAAAAAAAAM/D_YVBBjMAe4/s320/AppBuilderImage.png" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-6894058160939115568?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/6894058160939115568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=6894058160939115568' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6894058160939115568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/6894058160939115568'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/08/sakai-appbuilder-082-available.html' title='Sakai AppBuilder 0.82 available'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_gYJbpIL6GOI/RtAFfWQR3gI/AAAAAAAAAAM/D_YVBBjMAe4/s72-c/AppBuilderImage.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-4058021483587960700</id><published>2007-08-24T22:09:00.000+01:00</published><updated>2007-08-24T22:30:35.413+01:00</updated><title type='text'>Cafe trunk using Maven 2</title><content type='html'>The &lt;a href="https://source.sakaiproject.org/svn/cafe/trunk/"&gt;cafe trunk distribution&lt;/a&gt; for &lt;a href="http://sakaiproject.org/"&gt;Sakai&lt;/a&gt; is finally working and available for download. The cafe distribution is part of the &lt;a href="http://bugs.sakaiproject.org/confluence/display/BOOT/"&gt;Sakai programmers cafe&lt;/a&gt; and the primary goal is to create a smaller distribution which makes development in Sakai easy and reduces the memory footprint. This is the first cafe distro available which uses &lt;a href="http://maven.apache.org/"&gt;Maven 2&lt;/a&gt; (like the rest of Sakai). The really notable thing about this cafe is that it is the smallest one yet (in terms of projects) and probably the smallest distribution of Sakai currently available.&lt;br /&gt;&lt;br /&gt;Ian Boston and I have been tracking down intra-project dependencies in Sakai and removing them in order to create a small and clean kernel for Sakai. This cleanup has resulted in a better kernel and will eventually lead to a more solid service foundation in Sakai. The cafe distribution represents that kernel distribution plus the standard Sakai portal (charon). It should make development in Sakai easier and faster since restarts should take less time and there are less projects to checkout and keep up to date.&lt;br /&gt;&lt;br /&gt;In order to make this distribution for Sakai with Maven 2 we had to create a &lt;a href="https://source.sakaiproject.org/svn/cafe/trunk/pom.xml"&gt;special base pom&lt;/a&gt; that lists only the projects in the distribution. We are use &lt;a href="http://svnbook.red-bean.com/en/1.0/ch07s03.html"&gt;svn externals&lt;/a&gt; to setup the download of the correct projects from the main Sakai source tree. There is one bit of hackery involved with getting this to work which is needed if only part of the project is desired (for example, we can only use parts of the user project since some parts pull in undesirable dependencies). This involves creating a &lt;a href="https://source.sakaiproject.org/svn/cafe/trunk/user/pom.xml"&gt;new base pom for the main project (user)&lt;/a&gt; and then removing the modules from that pom file which are not included in the externals. We did this for 4 projects in the cafe distribution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-4058021483587960700?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/4058021483587960700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=4058021483587960700' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/4058021483587960700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/4058021483587960700'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/08/cafe-trunk-using-maven-2.html' title='Cafe trunk using Maven 2'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-2540974873058523851</id><published>2007-07-28T13:33:00.000+01:00</published><updated>2007-07-28T13:43:03.845+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wiki'/><category scheme='http://www.blogger.com/atom/ns#' term='anniversary'/><category scheme='http://www.blogger.com/atom/ns#' term='RSF'/><category scheme='http://www.blogger.com/atom/ns#' term='mailing list'/><title type='text'>RSF Mailing List</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Reasonable_Server_Faces"&gt;Reasonable Server Faces (RSF)&lt;/a&gt; now has a &lt;a href="http://en.wikipedia.org/wiki/Mailing_list"&gt;mailing list&lt;/a&gt; for users! Please sign up for &lt;a href="https://mail.caret.cam.ac.uk/mailman/listinfo/list-rsfusers"&gt;this list&lt;/a&gt; if you are using RSF or thinking about using it. More info on &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=EmailLists"&gt;joining the list&lt;/a&gt; is available on the &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/"&gt;RSF Wiki&lt;/a&gt; but ideally we will use this list to answer questions, send out announcements, and all the normal stuff email lists are good for.&lt;br /&gt;&lt;br /&gt;This is not meant to replace &lt;a href="http://ponder.org.uk/rsf/"&gt;the RSF forums&lt;/a&gt; but to just supplement them.&lt;br /&gt;&lt;br /&gt;Along with this, I am happy to announce the &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=Anniversaries"&gt;second anniversary of RSF&lt;/a&gt; is today (27 July 2007)! Please celebrate in whatever way is appropriate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-2540974873058523851?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/2540974873058523851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=2540974873058523851' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/2540974873058523851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/2540974873058523851'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/07/rsf-mailiing-list.html' title='RSF Mailing List'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-8788996725850620868</id><published>2007-07-24T22:44:00.000+01:00</published><updated>2007-07-24T23:11:10.780+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wiki'/><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='web framework'/><category scheme='http://www.blogger.com/atom/ns#' term='RSF'/><title type='text'>RSF Wiki refactor and AJAX samples</title><content type='html'>I have spent many hours over the past couple weeks working on the &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/"&gt;RSF Wiki&lt;/a&gt;. For those who are not familiar with &lt;a href="http://en.wikipedia.org/wiki/Reasonable_Server_Faces"&gt;Reasonable Server Faces (RSF)&lt;/a&gt;, it is an &lt;a href="http://en.wikipedia.org/wiki/Open-source_software"&gt;open source&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Java_%28programming_language%29"&gt;Java&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Web_framework"&gt;web framework&lt;/a&gt; which is based on the &lt;a href="http://www.springframework.org/"&gt;Spring framework&lt;/a&gt; and supports &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=PureXHTMLTemplating"&gt;pure XHTML templating&lt;/a&gt;. The &lt;a href="http://en.wikipedia.org/wiki/Wiki"&gt;Wiki&lt;/a&gt; is the canonical source of documentation for RSF and needed a lot of updates and additions to be more developer friendly. After comparing the websites and Wikis for a lot of open source projects I settled on a set of left hand navigation topic areas and links and then started editing. At this point, the majority of the layout changes are complete and it should be a lot easier for developers to &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=GettingStarted"&gt;get started with RSF&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Along with the refactoring, I also added pages to describe how to use &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=AJAX"&gt;AJAX in RSF&lt;/a&gt;. RSF includes the &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=UniversalViewBus"&gt;UVB (or Universal View Bus)&lt;/a&gt; which makes calling a method in your application code from &lt;a href="http://en.wikipedia.org/wiki/Ajax_(programming)"&gt;AJAX&lt;/a&gt; and getting back the results easy. Developers will now find detailed notes about how UVB works and the use of the &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=RSFJSLibrary"&gt;RSF Javascript library&lt;/a&gt;. There is also a new &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=SampleRSFApps"&gt;RSF sample app&lt;/a&gt; which demonstrate a &lt;a href="https://saffron.caret.cam.ac.uk/svn/projects/RSFSamples/trunk/AjaxAutocompleteSimple/"&gt;simple autocomplete using RSF&lt;/a&gt; and UVB (this is also available as a &lt;a href="https://saffron.caret.cam.ac.uk/svn/projects/SakaiRSFSamples/trunk/AjaxAutocompleteSimple/"&gt;sample Sakai tool&lt;/a&gt;). I encourage anyone using RSF (and even those who aren't) to &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/"&gt;check out the Wiki&lt;/a&gt; and post feedback.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-8788996725850620868?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/8788996725850620868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=8788996725850620868' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/8788996725850620868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/8788996725850620868'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/07/rsf-wiki-refactor-and-ajax-samples.html' title='RSF Wiki refactor and AJAX samples'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-8576625781921146619</id><published>2007-07-23T17:48:00.000+01:00</published><updated>2007-07-23T18:14:51.190+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='winxp'/><category scheme='http://www.blogger.com/atom/ns#' term='command line'/><category scheme='http://www.blogger.com/atom/ns#' term='patch'/><category scheme='http://www.blogger.com/atom/ns#' term='path'/><title type='text'>Using patch (as in .patch files) in WinXP</title><content type='html'>I had to apply a large set of &lt;a href="http://en.wikipedia.org/wiki/Patch_(Unix)"&gt;patch&lt;/a&gt; files (and I mean &lt;a href="http://en.wikipedia.org/wiki/Patch_(Unix)"&gt;.patch files&lt;/a&gt;) to a project today using a &lt;a href="http://www.microsoft.com/windows/products/windowsxp/"&gt;Windows XP&lt;/a&gt; machine. It was a lot more painful than I thought it would be so I am recording it here in case it helps anyone else avoid the pain.&lt;br /&gt;&lt;br /&gt;You should have all your patch files in a directory (I am assuming one called &lt;strong&gt;patches&lt;/strong&gt; but use anything you like, just remember to tweak the commands). You will need the &lt;a href="http://gnuwin32.sourceforge.net/packages/patch.htm"&gt;patch program for windows&lt;/a&gt; installed (which proved to be fairly hard to find) and on your &lt;a href="http://www.computerhope.com/issues/ch000549.htm"&gt;Path&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;How to apply a directory full of patches with a single command in windows XP.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Open a command line (Start -&gt;Run... -&gt; cmd) and go to the directory where you are applying the patches (should have a patches directory here also)&lt;/li&gt;&lt;li&gt;Run the following command to test your patch syntax:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for %f in (patches\*.patch) do type %f patch -p0 --dry-run&lt;/span&gt;&lt;/li&gt;&lt;li&gt;If you got no errors then just remove the &lt;strong&gt;--dry-run&lt;/strong&gt; from the end and run it again to actually apply the patches, for example:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;for %f in (patches\*.patch) do type %f patch -p0&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;You would not think that would have taken hours to figure out would you?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;em&gt;For the unix folks out there, here is the command (though I suspect most everyone knows this one already):&lt;br /&gt;&lt;/em&gt;&lt;span style="font-family:courier new;"&gt;for patch in patches/*.patch ; do patch --dry-run -p0 &lt; $patch ; done&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You might want to go ahead and get the &lt;a href="http://gnuwin32.sourceforge.net/packages/coreutils.htm"&gt;core GnuWin32 utilities&lt;/a&gt; if you want to run more unix type commands in winXP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-8576625781921146619?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/8576625781921146619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=8576625781921146619' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/8576625781921146619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/8576625781921146619'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/07/using-patch-as-in-patch-files-in-winxp.html' title='Using patch (as in .patch files) in WinXP'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-4393045939167992519</id><published>2007-07-22T10:24:00.000+01:00</published><updated>2007-07-22T11:16:50.419+01:00</updated><title type='text'>Maven2, Continuum, and Sakai</title><content type='html'>I have been doing a lot with &lt;a href="http://maven.apache.org/"&gt;Maven2&lt;/a&gt; these days. I have been adding Maven2 builds to various Sakai tools I am responsible for like &lt;a href="http://confluence.sakaiproject.org/confluence/x/F7M"&gt;Entity Broker&lt;/a&gt; and &lt;a href="http://bugs.sakaiproject.org/confluence/display/EVALSYS/Home"&gt;Evaluation&lt;/a&gt;. I have also been updating the &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/"&gt;RSF wiki&lt;/a&gt; to include the &lt;a href="http://www2.caret.cam.ac.uk/maven2/"&gt;CARET Maven2 Repository&lt;/a&gt; and &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=SampleRSFApps"&gt;sample RSF projects&lt;/a&gt; that use Maven2. The RSF poms are now updated to run various reports and &lt;a href="http://maven.apache.org/plugins/maven-javadoc-plugin/"&gt;generate javadocs&lt;/a&gt; and &lt;a href="http://maven.apache.org/plugins/maven-site-plugin/"&gt;Maven 2 sites&lt;/a&gt; which are linked to (or will be soon) on the &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=Developers"&gt;RSF Developer page&lt;/a&gt;. I am currently running into an &lt;a href="http://www.nabble.com/Maven-2-site-reporting-with-mutliple-projects-tf4115724s177.html"&gt;issue with Maven 2 where I cannot generate a site for a project which has a base pom&lt;/a&gt; with no code in it and modules which have the code (I get failures in the build when I try to build the site from the base). I'm hoping to get some help from the &lt;a href="http://www.nabble.com/Maven---Users-f178.html"&gt;Maven users list&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://maven.apache.org/continuum/"&gt;Continuum&lt;/a&gt; has been an interesting experience in pleasure and pain. The &lt;a href="http://saffron.caret.cam.ac.uk/continuum/"&gt;CARET Continuum server&lt;/a&gt; (version 1.0.3) is building &lt;a href="https://source.sakaiproject.org/svn/sakai/trunk/"&gt;Sakai trunk&lt;/a&gt;, &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=TrunkCode"&gt;RSF&lt;/a&gt;, and all the CARET related tools nightly. It is allowing us to keep track of our projects and know if there are any build problems. Unfortunately, I have managed to create 5 continuum projects which were corrupted and had to be removed by our system admin. On the plus side, I am learning a lot about how Continuum integrates with Maven2 and most of the poms are getting nice updates as a result. Hopefully we will soon have full code reports being generated nightly that we can review as needed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-4393045939167992519?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/4393045939167992519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=4393045939167992519' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/4393045939167992519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/4393045939167992519'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/07/maven2-continuum-and-sakai.html' title='Maven2, Continuum, and Sakai'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-5539513616342332298</id><published>2007-05-07T08:10:00.000+01:00</published><updated>2007-05-07T08:28:25.965+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scotland'/><category scheme='http://www.blogger.com/atom/ns#' term='tetra'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><title type='text'>Tetra Skye meeting</title><content type='html'>The Tetra group technical meeting was held last week on the &lt;a href="http://www.skye.co.uk/"&gt;Isle of Skye&lt;/a&gt; in Scotland. Tetra currently consists of the following UK higher education institutions: &lt;a href="http://www.uhi.ac.uk/"&gt;UHI Millenium Institute&lt;/a&gt; (hosting), &lt;a href="http://www.cam.ac.uk/"&gt;University of Cambridge&lt;/a&gt;, &lt;a href="http://www.ox.ac.uk/"&gt;University of Oxford&lt;/a&gt;, and &lt;a href="http://www.hull.ac.uk/"&gt;University of Hull&lt;/a&gt;. The meeting took place on the &lt;a href="http://www.smo.uhi.ac.uk/"&gt;Sabhal Mòr Ostaig&lt;/a&gt; campus on the Isle of Skye.&lt;br /&gt;&lt;br /&gt;The team discussed various Sakai related issues including hierarchical groups, &lt;a href="http://confluence.sakaiproject.org/confluence/display/BOOT/Entity+2.0+ideas"&gt;entity system updates&lt;/a&gt;, and local projects such as &lt;a href="http://confluence.sakaiproject.org/confluence/display/EVALSYS/Home"&gt;evaluation system&lt;/a&gt; and &lt;a href="http://confluence.sakaiproject.org/confluence/display/BREEZE/Home"&gt;breeze link tool&lt;/a&gt;. Possible &lt;a href="http://www.jisc.ac.uk/"&gt;JISC&lt;/a&gt; funded projects and future plans were also discussed.&lt;br /&gt;&lt;br /&gt;Evening activities included boating to pubs, skimming stones on the Sound of Sleat, and debating whether wheat is corn. Pictures are available of the event under the &lt;a href="http://www.flickr.com/photos/tags/tetraskyemay07/"&gt;flickr tag: tetraskyemay07&lt;/a&gt;. There is also a &lt;a href="http://www.flickr.com/photos/azeckoski/sets/72157600163755387/"&gt;flickr image set created by myself&lt;/a&gt; that you are welcome to view. Thanks and Kudos to Sean Mehan of UHI for doing and excellent job of organizing the meeting and evening events.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-5539513616342332298?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.flickr.com/photos/azeckoski/sets/72157600163755387/' title='Tetra Skye meeting'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/5539513616342332298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=5539513616342332298' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5539513616342332298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/5539513616342332298'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/05/tetra-skye-meeting.html' title='Tetra Skye meeting'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-766189554794191518</id><published>2007-04-19T13:56:00.000+01:00</published><updated>2007-04-19T14:20:14.027+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bootcamp'/><category scheme='http://www.blogger.com/atom/ns#' term='south africa'/><category scheme='http://www.blogger.com/atom/ns#' term='sakai'/><category scheme='http://www.blogger.com/atom/ns#' term='cafe'/><title type='text'>South Africa Programmers Cafe</title><content type='html'>We are currently running the &lt;a href="http://confluence.sakaiproject.org/confluence/display/BOOT/South+Africa"&gt;South Africa Programmers Cafe Bootcamp&lt;/a&gt; in &lt;a href="http://maps.google.co.uk/maps?f=q&amp;hl=en&amp;amp;q=Potchefstroom,+South+Africa&amp;layer=&amp;amp;amp;ie=UTF8&amp;z=5&amp;amp;ll=-26.684889,27.043533&amp;spn=18.242089,41.52832&amp;amp;om=1"&gt;Potchefstroom, South Africa&lt;/a&gt;. The cafe is running from April 16th - April 20th, 2007. There are about 22 people from various South African institutions in attendance. Aaron Zeckoski (me), Antranig Basman, and Tony Atkins are presenting on various topics ranging from Sakai development and &lt;a href="http://www2.caret.cam.ac.uk/rsfwiki/"&gt;RSF&lt;/a&gt; to Server configuration and deployment. We have &lt;a href="http://www.flickr.com/photos/tags/programerscafe07za/"&gt;pictures from the cafe available in Flickr&lt;/a&gt; if anyone wants to take a look.&lt;br /&gt;The weather has been fairly nice the whole time we have been here. Our hosts from NWU have taken excellent care of everyone and arrangements have been fantastic. Many thanks go to Boeta and Adell at NWU in Potchefstroom for all their hard work in getting things running smoothly and taking care of the roudy and jetlagged presenters. A special thanks and mention here goes to David Horwitz for helping get the funds and generating interest so we could have this event.&lt;br /&gt;Being here in South Africa has been a great experience for me so far and I feel like I have learned a lot about this country in tha past few days here. They have limited internet options available and we currently have to pay for all the data going in and out. The exchange rate has been a nice plus since we get 14 Rand for 1 British Pound (things are quite affordable). I love the South African accent and don't understand a single word of Afrikans but I am having a great time talking to the bootcamp participants and seeing the local area. We will have a chance to see the local area a bit after the cafe ends on friday and I am looking forward to it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-766189554794191518?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://confluence.sakaiproject.org/confluence/display/BOOT/South+Africa' title='South Africa Programmers Cafe'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/766189554794191518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=766189554794191518' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/766189554794191518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/766189554794191518'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2007/04/south-africa-programmers-cafe.html' title='South Africa Programmers Cafe'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-1061268644817648801</id><published>2006-11-15T04:13:00.000Z</published><updated>2006-11-15T04:30:54.918Z</updated><title type='text'>Sakai AppBuilder 0.7 and update site</title><content type='html'>Version 0.7 of the &lt;a href="https://content.cc.vt.edu/confluence/display/DEV/Sakai+App+Builder"&gt;Sakai AppBuilder&lt;/a&gt; is finally to a point where I am ready to inflict it on other people. It took awhile to get the Velocity templates to a point where I was happy with them. More &lt;a href="https://content.cc.vt.edu/confluence/display/DEV/Sakai+App+Builder"&gt;info about the plugin itself and installing it&lt;/a&gt; is available on the website.&lt;br /&gt;&lt;br /&gt;I am also excited to say that we now have an "official" &lt;a href="http://www.eclipse.org/"&gt;eclipse&lt;/a&gt; update site that is part of the &lt;a href="http://www.sakaiproject.org/"&gt;Sakai project&lt;/a&gt; (plus the update site should be working again, we broke it with version 0.6). Here is the link to put in eclipse for the update site (installation instructions at the link above):&lt;br /&gt;&lt;a href="http://source.sakaiproject.org/appbuilder/update/"&gt;http://source.sakaiproject.org/appbuilder/update/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hope this is helpful for everyone who uses it and please send me feedback about it so I can improve it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-1061268644817648801?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://content.cc.vt.edu/confluence/display/DEV/Sakai+App+Builder' title='Sakai AppBuilder 0.7 and update site'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/1061268644817648801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=1061268644817648801' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/1061268644817648801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/1061268644817648801'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2006/11/sakai-appbuilder-07-and-update-site.html' title='Sakai AppBuilder 0.7 and update site'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-115979352151388533</id><published>2006-10-02T13:45:00.000+01:00</published><updated>2006-11-14T03:00:43.587Z</updated><title type='text'>Sakai App Builder 0.5 released</title><content type='html'>The very beta first release of the &lt;a href="https://content.cc.vt.edu/confluence/display/DEV/Sakai+App+Builder"&gt;Sakai App Builder plugin&lt;/a&gt; for Eclipse 3.2 is now available for developers to try out. Here is the blurb from the page linked above:&lt;br /&gt;&lt;em&gt;The Sakai AppBuilder is a RAD tool that allows you to quickly create &lt;/em&gt;&lt;a title="Visit page outside Confluence" href="http://sakaiproject.org/" rel="nofollow"&gt;&lt;em&gt;Sakai&lt;/em&gt;&lt;/a&gt;&lt;em&gt; webapp projects in the &lt;/em&gt;&lt;a title="Eclipse SDK" href="https://content.cc.vt.edu/confluence/display/DEV/Eclipse+SDK"&gt;&lt;em&gt;Eclipse SDK&lt;/em&gt;&lt;/a&gt;&lt;em&gt; that will work in the &lt;/em&gt;&lt;a title="Visit page outside Confluence" href="http://sakaiproject.org/" rel="nofollow"&gt;&lt;em&gt;Sakai&lt;/em&gt;&lt;/a&gt;&lt;em&gt; framework. Use these as a basis for the projects that you want to make without all the busy work of creating the structures and adding in all the dependencies. You can choose various UI layer options and implementation types to get you started quickly. This will not write your entire app for your, but it should help you get started quickly.&lt;/em&gt;&lt;br /&gt;This was alpha tested on the folks who attended the Tetra ELF cafe workshop in Oxford, England the last week of September (and they were quite good sports about it).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-115979352151388533?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://content.cc.vt.edu/confluence/display/DEV/Sakai+App+Builder' title='Sakai App Builder 0.5 released'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/115979352151388533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=115979352151388533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/115979352151388533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/115979352151388533'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2006/10/sakai-app-builder-05-released.html' title='Sakai App Builder 0.5 released'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-115918779490627871</id><published>2006-09-25T13:33:00.000+01:00</published><updated>2006-11-14T03:00:43.464Z</updated><title type='text'>Generic DAO version 0.7</title><content type='html'>I will be demoing the initial release of my Generic Dao package at the &lt;a href="http://bugs.sakaiproject.org/confluence/display/BOOT/Oxford+Tetra+ELF"&gt;Tetra ELF Cafe Workshop&lt;/a&gt; in Oxford, England this week. This package allows a developer who is using Spring and Hibernate to avoid the tedium of writing DAOs. It is very compact and has extensive javadocs. More information is available at the VT confluence site here:&lt;br /&gt;&lt;a href="https://content.cc.vt.edu/confluence/display/DEV/Generic+Dao"&gt;https://content.cc.vt.edu/confluence/display/DEV/Generic+Dao&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-115918779490627871?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://content.cc.vt.edu/confluence/display/DEV/Generic+Dao' title='Generic DAO version 0.7'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/115918779490627871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=115918779490627871' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/115918779490627871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/115918779490627871'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2006/09/generic-dao-version-07.html' title='Generic DAO version 0.7'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-115824016620662786</id><published>2006-09-14T14:16:00.000+01:00</published><updated>2006-11-14T03:00:43.281Z</updated><title type='text'>Cafe 2.2.x distro created</title><content type='html'>I created a &lt;a href="https://source.sakaiproject.org/contrib/programmerscafe/sakai-cafe-2.2.x/"&gt;2.2.x distibution&lt;/a&gt; of the &lt;a href="https://source.sakaiproject.org/contrib/programmerscafe/sakai-cafe/"&gt;sakai-cafe&lt;/a&gt; that is specifically for version &lt;a href="https://source.sakaiproject.org/svn/sakai/branches/sakai_2-2-x/"&gt;2.2.x of the Sakai code base&lt;/a&gt; today. This is because the current &lt;a href="https://source.sakaiproject.org/svn/sakai/trunk/"&gt;2.3 trunk code&lt;/a&gt; breaks the cafe distribution and I don't have a good way to fix it for now without making the cafe distribution huge and bloated.&lt;br /&gt;I have been meaning to do this for awhile anyway so that developers have a way to do their development work on a specific version of Sakai (probably the one they are running on their campus).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-115824016620662786?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://source.sakaiproject.org/contrib/programmerscafe/sakai-cafe-2.2.x/' title='Cafe 2.2.x distro created'/><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/115824016620662786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=115824016620662786' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/115824016620662786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/115824016620662786'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2006/09/cafe-22x-distro-created.html' title='Cafe 2.2.x distro created'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34341551.post-115816075649738538</id><published>2006-09-13T16:16:00.000+01:00</published><updated>2006-11-14T03:00:43.093Z</updated><title type='text'>Upcoming Tetra ELF Cafe</title><content type='html'>There will be a &lt;a href="http://bugs.sakaiproject.org/confluence/display/BOOT/Home"&gt;Sakai Cafe&lt;/a&gt; (bootcamp) at the Tetra conference at Oxford, England from September 27-28. The training will be on writing Sakai tools and best practices. Antranig Basman and Ian Boston will be present. It should be a good time and there will be a lots of new materials in the cafe as a result. Writing Sakai apps should become a lot easier soon if we can get everything to line up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34341551-115816075649738538?l=aaronz-sakai.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aaronz-sakai.blogspot.com/feeds/115816075649738538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34341551&amp;postID=115816075649738538' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/115816075649738538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34341551/posts/default/115816075649738538'/><link rel='alternate' type='text/html' href='http://aaronz-sakai.blogspot.com/2006/09/upcoming-tetra-elf-cafe.html' title='Upcoming Tetra ELF Cafe'/><author><name>Aaron Zeckoski</name><uri>http://www.blogger.com/profile/08720686868620505220</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://2.bp.blogspot.com/_gYJbpIL6GOI/S8NjLqWiclI/AAAAAAAAAC0/JrzJ1Uom6tw/S220/azeckoski.jpg'/></author><thr:total>0</thr:total></entry></feed>
