<$BlogRSDUrl$>

Monday, December 08, 2003

My Blog has Moved... 

My blog has moved over to WordPress


Saturday, August 02, 2003

More on Drive Cleanliness... 

I blogged a couple of weeks back on setting up automated nightly defrags on WinXP.

The other day, as drive space was getting a little tight for my comfort, I ran the excellent utility JDiskReport from JGoodies to see just where all my drivespace was allocated and made an alarming discovery.

It seems that when I go through my normal work pattern of "start Jboss/Jetty, then hot-deploy, re-hot-deploy, re-hot-deploy (etc)...", it leaves behind expanded war-file directories in my c:\Documents and Settings\<username>\Local Settings\temp directory (NOTE: Local Settings is a hidden folder - so you have to have your view options set correctly to see it). The directories have the name pattern : Jetty_0_0_0_0_<PortNumber>__<WarName> (where <PortNumber> and <WarName> are your respective jetty listening port and war names).

I just got a new machine about a month and a half back, and in that time I had already accumulated about 1.2 GB worth of temporary files in such a manner (I go throught the, change/build/hot-deploy cycle many times a day).

Anyway - I decided to update my automated nightly defrag task to cleanup this stuff too. Here's the updated version - USE WITH CAUTION - the options I'm passing to DEL and RMDIR are equivalent to "do this recursively and don't prompt me whether I really want to delete all this stuff". The %TEMP% environment variable should expand to C:\Documents and Settings\<username>\Local Settings\temp directory by default. You might want to test this manually from the command prompt a few times just to make sure you've typed it in correctly :

::--- recursively remove all files in the temp directory, without
::    prompting, then recursively remove all directories below the
::    temp directory, without prompting

del /F /S /Q "%TEMP%\*" > c:\temp\Defrag_CleanOutTemp.txt 2>&1
rmdir /S /Q "%TEMP%" >> c:\temp\Defrag_CleanOutTemp.txt 2>&1


::--- defrag your local drives

defrag /v /f c: > c:\temp\Defrag_C.txt 2>&1
defrag /v /f d: > c:\temp\Defrag_D.txt 2>&1

Saturday, July 05, 2003

Precompiling JSP's under JBoss/Jetty 3.2.1... 

One of the things I've been meaning to do for quite some time now was to modify our build process to precompile our JSP's. With so many other higher priority things this kept getting pushed to the back burner... After the 10th time someone reported a bug which amounted to "first access to webpage seems abysmally slow", I finally broke down and started on this on the plane ride home from Montreal this week. Here's a summation of what is required to get JSP precompilation going under JBoss/Jetty 3.2.1.

First, a high-level rundown of the process :

  1. Using Jasper (a JSP compiler), we'll transform the JSP's into .java files (servlets).
  2. Jasper will also spit out a web.xml fragment with servlet definitions and mappings for each of the above generated servlets.
  3. We'll use the ant jspc task to make the previous two bullets a little easier.
  4. We'll compile the .java files into .class files and then copy them into the WEB-INF/classes directory of the WAR
  5. We'll insert the web.xml fragment generated by Jasper into your normal web.xml file (at a very specific place).
  6. build your war as normal
Ok, so here's the build target which generates the war in question (disregard project specific stuff) :
<target name="dist" depends="compile">

   <!-- copy required libs to WEB-INF/lib-->
   <copy todir="${dir.webinf}/lib">
      <fileset dir="${dir.thirdpartytools.struts}/lib"/>
      <fileset dir="${dir.thirdpartytools.jstl}/lib"/>
      <fileset dir="${dir.search}/dist/lib" includes="${jar.name.search-domain}, ${jar.name.search-services}"/>
   </copy>

   <!-- copy classes we built earlier to WEB-INF/classes -->
   <copy todir="${dir.webinf}/classes">
      <fileset dir="${classes}"/>
   </copy>

   <!-- copy the tld's we're using to WEB-INF/tld -->
   <copy todir="${dir.webinf}/tld">
      <fileset dir="${dir.thirdpartytools.struts}/tld" includes="*.tld"/>
      <fileset dir="${dir.thirdpartytools.jstl}/tld" includes="*.tld"/>
      <fileset dir="${dir.config}/tld" includes="*.tld"/>
   </copy>

   <!-- these two properties are the generated web.xml fragment, and the resulting merged xml-->
   <property name="jspc.webxml.fragment" value="${dir.jspc.temp}/jspc-web-xml-fragment.xml"/>
   <property name="jspc.webxml.merged" value="${dir.jspc.temp}/merged-web.xml"/>

   <path id="jspc.classpath">
      <path refid="cp.jspc"/>
      <path refid="cp.jboss"/>
      <path refid="cp.webclient-thirdparty.tools"/>
      <path refid="build.classpath"/>
      <fileset dir="${classes}"/>
      <fileset dir="${dir.webinf}/lib" includes="*.jar"/>
   </path>


   <!-- JSP -> .java -->
   <jspc srcdir="${dir.docroot}"
         destdir="${dir.jspc.gensrc}"
         verbose="9"
         classpathref="jspc.classpath"
         webinc="${jspc.webxml.fragment}">

     <include name="**/*.jsp"/>
   </jspc>

   <!-- .java -> .class -->
   <javac deprecation="${deprecation.javac}"
          fork="${fork.javac}"
          source="${source}"
          debug="${debug}"
          srcdir="${dir.jspc.gensrc}"
          destdir="${dir.webinf}/classes"
          classpathref="jspc.classpath"/>


   <!-- merge the jspc generated web.xml fragment with the real web.xml-->
   <loadfile property="jspc.webxml.fragment.contents" srcFile="${jspc.webxml.fragment}"/>
   <copy file="${dir.webinf}/web.xml" tofile="${jspc.webxml.merged}"/>

   <replace file="${jspc.webxml.merged}">
      <replacefilter token="&lt;!-- @JSPC-INSERT-HERE@ --&gt;" value="${jspc.webxml.fragment.contents}"/>
   </replace>

   <!-- Now war everything up -->
   <war destfile="${dist}/lib/${jar.name.epcportal-presentation}"
      webxml="${jspc.webxml.merged}">
      <fileset dir="${dir.docroot}"/>
      <classes dir="${classes}"/>
      <classes dir="${dir.property.file}">
         <include name="**/*.properties"/>
      </classes>
   </war>
</target>
In the above fragment, the following two properties are defined earlier :

<property name="dir.jspc.temp" value="${dist}/tmp/jspc"/>
<property name="dir.jspc.gensrc" value="${dir.jspc.temp}/gensrc"/>
And cp.jspc is defined as the following :

<path id="cp.jspc">
   <pathelement location="${jboss.home}/server/default/deploy/jbossweb-jetty.sar/jasper-compiler.jar"/>
   <pathelement location="${jboss.home}/server/default/deploy/jbossweb-jetty.sar/jasper-runtime.jar"/>
   <pathelement location="${ant_home}/lib/ant.jar"/>
</path>
Now, modify your existing web.xml file to have the following comment in it, just AFTER the last <servlet> tag and just BEFORE the first <servlet-mapping> tag.
      <!-- @JSPC-INSERT-HERE@ -->
This comment will serve as the insertion point where we'll include the jspc generated web.xml fragment. Here's an example of our web.xml file :

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

<!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'>
<web-app>


   <!-- Struts Action Servlet Configuration -->
   <servlet>
      <servlet-name>action</servlet-name>
      <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
      <init-param>
         <param-name>application</param-name>
         <param-value>ApplicationResources</param-value>
      </init-param>
      <init-param>
         <param-name>config</param-name>
         <param-value>/WEB-INF/struts-config.xml</param-value>
      </init-param>
      <init-param>
         <param-name>debug</param-name>
         <param-value>0</param-value>
      </init-param>
      <init-param>
         <param-name>detail</param-name>
         <param-value>0</param-value>
      </init-param>
      <init-param>
         <param-name>validate</param-name>
         <param-value>true</param-value>
      </init-param>
      <load-on-startup>2</load-on-startup>
   </servlet>





   <!-- JSP-PRECOMPILER INSERTION POINT, DO NOT REMOVE, MODIFY OR MOVE THE FOLLOWING LINE-->
   <!-- @JSPC-INSERT-HERE@ -->





   <!-- Action Servlet Mapping -->
   <servlet-mapping>
      <servlet-name>action</servlet-name>
      <url-pattern>*.do</url-pattern>
   </servlet-mapping>


   <!-- The Welcome File List -->
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>

   <error-page>
      <error-code>404</error-code>
      <location>/error404.jsp</location>
   </error-page>

   <error-page>
      <error-code>400</error-code>
      <location>/error400.jsp</location>
   </error-page>

   <error-page>
      <error-code>401</error-code>
      <location>/error401.jsp</location>
   </error-page>

	<error-page>
      <error-code>500</error-code>
      <location>/error500.jsp</location>
   </error-page>

   <!-- Struts Tag Library Descriptors -->
   <taglib>
      <taglib-uri>/tags/struts-bean</taglib-uri>
      <taglib-location>/WEB-INF/tld/struts-bean.tld</taglib-location>
   </taglib>

   <taglib>
      <taglib-uri>/tags/struts-html</taglib-uri>
      <taglib-location>/WEB-INF/tld/struts-html.tld</taglib-location>
   </taglib>

   <taglib>
      <taglib-uri>/tags/struts-logic</taglib-uri>
      <taglib-location>/WEB-INF/tld/struts-logic.tld</taglib-location>
   </taglib>
  <taglib>
    <taglib-uri>/tags/struts-nested</taglib-uri>
    <taglib-location>/WEB-INF/tld/struts-nested.tld</taglib-location>
  </taglib>

  <taglib>
    <taglib-uri>/tags/struts-tiles</taglib-uri>
    <taglib-location>/WEB-INF/tld/struts-tiles.tld</taglib-location>
  </taglib>

   <!-- JSTL -->
   <taglib>
     <taglib-uri>/tags/jstl-c</taglib-uri>
     <taglib-location>/WEB-INF/tld/c.tld</taglib-location>
   </taglib>

   <taglib>
     <taglib-uri>/tags/jstl-c-rt</taglib-uri>
     <taglib-location>/WEB-INF/tld/c-rt.tld</taglib-location>
   </taglib>

   <taglib>
     <taglib-uri>/tags/jstl-fmt</taglib-uri>
     <taglib-location>/WEB-INF/tld/fmt.tld</taglib-location>
   </taglib>

   <taglib>
     <taglib-uri>/tags/jstl-fmt-rt</taglib-uri>
     <taglib-location>/WEB-INF/tld/fmt-rt.tld</taglib-location>
   </taglib>

   <taglib>
     <taglib-uri>/tags/jstl-x</taglib-uri>
     <taglib-location>/WEB-INF/tld/x.tld</taglib-location>
   </taglib>

   <taglib>
     <taglib-uri>/tags/x-rt</taglib-uri>
     <taglib-location>/WEB-INF/tld/x-rt.tld</taglib-location>
   </taglib>

   <!-- Project Specific Tag Libs -->
   <taglib>
     <taglib-uri>/tags/epc</taglib-uri>
     <taglib-location>/WEB-INF/tld/epc.tld</taglib-location>
   </taglib>

</web-app>

OK - that's about it. A couple of things to watch out for :

Wednesday, June 25, 2003

Automated nightly defrags on Windows XP... 

On my machine I have two partitions : C & D. The C partition has the OS, all Programs like Office, IDEA, Oracle, etc on it. The D drive just has data - mostly source code, project directories, personal files, etc.

I’ve noticed that when I’m doing development, the D drive gets fragmented very quickly (even in one days time). After a full day's coding, I usually manage to create 1000 or so fragmented files (even when the machine has been completely defragged the day before). This is after doing full rebuilds, re-installations of the appserver (we have an ant target to completely wipe out our Jboss directory and re-install it), pulls from CVS, etc..

Anyway – you can setup Windows built in defrag tool to run on a recurring basis. Here’s how :

Create a batch file (e.g. c:\bin\DefragLocalDrives.cmd) with the contents similar to the following (customize to your local drive structure):

   defrag /v /f c: > d:\temp\Defrag_C.txt

   defrag /v /f d: > d:\temp\Defrag_D.txt
Now create a scheduled task to run this batch file. Goto Start | Control Panel | Scheduled Tasks and click on “Add Scheduled Task” Point the new scheduled task at the batch file you created in step 1 and set up the recurrence to your preferred frequency.

I set mine up to run every morning at 4:30 AM. At first I thought this would be overkill, but I’ve noticed that when doing development I always have some fragmentation, even after only a day’s use.

That’s it…

UPDATE - As Lance Lavandowska kindly pointed out - this only works on XP (defrag.exe is not present on Win2k installations)


Monday, June 23, 2003

CruiseControl version 2.2.1 is out... 

Just noticed that a new version of Cruise Control has been released

http://sourceforge.net/project/shownotes.php?release_id=167306

We're using 2.0.2 on my current project and we love it. It takes a bit of maintenance and troubleshooting here and there (especially as the size of the project and number of tools grows), but it is definitely worth the investment to set your projects up in this.


Mozilla: Helpful Quick Reference Sidebars for Developers... 

Mozilla has some really cool "quick reference" sidebars for developers. For example :

You can get them from here : http://devedge.netscape.com/toolbox/sidebars

Saturday, June 14, 2003

Experiences migrating from JBoss 3.0.4 -> JBoss 3.2.1... 

A while back I decided to upgrade my current project from JBoss 3.0.4 to JBoss 3.2.1. I was hopeful it wouldn't take too long, but it ended up being one of the more painful JBoss upgrades we've been through (total time spent ~8 hours). This is probably due in part that our project has grown in size and scope quite a bit since the last upgrade.

Here are the things that caused problems :

1. Some of the JBoss client jars were reorganized / renamed (e.g. jaas.jar -> jboss-jaas.jar, jmx-rmi-adaptor.sar -> jmx-adaptor-plugin.jar). We have a Swing client (launched through webstart) and a web based client. For the webstat app, we have to sign all the jars (and list all the jars in the webstart JNLP file) so anytime these change, it causes a little bit of pain.

2. There are new jars required for the client (e.g. jboss-transaction-client.jar).

3. Had all manner of problems getting our oracle datasource to work. In 3.0.4 we were using an oracle-service.xml file to do this, I got multiple wierd errors trying to use this same deployment file in 3.2.1. I finally ended up having to go with an oracle-ds.xml file (which, I must admit is much simpler).

4. From what I could see, anything which was a compliance warning in JBoss 3.0.4 is pretty much guaranteed to be an error in 3.2.1. Granted - we should've fixed the warnings a long time back... These are silly things like a method on an EJB interface forgetting the RemoteException in its throws clause, etc.

5. It looks like they implemented cusom tag pooling starting with JBoss/Jetty 3.2.1... It was always my understanding that the servlet container would call release() on each TagHandler instance for custom tags before it re-used them, but I guess that was a slight misunderstanding of the spec. The actual behavior exhibited here is that the container will eventually call release() on the custom tag, but not between usages. I had to rearrange some of the "reset to default values" logic in a few custom tags to get around this (not too hard to fix once I figured out what was going on).

6. The move broke our WebStart client for IE users... Our webstart JNLP file is generated from a JSP file (pretty common). The mime type is set very early on for this file to be of type "application/x-java-jnlp-file", but for some reason, when we switched to JBoss 3.2.1, anytime an IE user clicked on our webstart link, it would popup the download dialog and ask the user where they wanted to save the local file. After a bit of consternation, I was able to get around the problem by defining a servlet mapping which makes IE thinks its really hitting a JNLP file for the webstart link (when in reality its still hitting the JSP).

   <!-- HACK: This entry is only present to make IE treat the resulting
          HTTP response as a JNLP file instead of a JSP file. -->
      <servlet>
         <servlet-name>FakeJNLP-IE-Workaround</servlet-name>
         <description>our dynamically generated JNLP file (generated by this JSP)</description>
         <jsp-file>/FsxWebStart.jsp</jsp-file>
      </servlet>
      <servlet-mapping>
         <servlet-name>FakeJNLP-IE-Workaround</servlet-name>
         <url-pattern>/FsxWebStart.jnlp</url-pattern>
      </servlet-mapping>

Sunday, June 01, 2003

Similarities between the Matrix Reloaded and the Wheel of Time (minor spoilers) 

(spoiler warning)

Finally got a chance to see Matrix Reloaded about a week ago.

Is it just me or are there a lot of overlapping themes in Matrix Reloaded and Robert Jordan's Wheel of Time Series ...? For example :

First similarity - the whole concept of the recurring, cyclic struggle between the savior and the bad guys (according to the Architect, Neo is the 6th Anomaly - the 6th "One"). This concept of a repeating cycle is a very overt theme in the Wheel of Time series. The first chapter in each of the 10 WOT books starts off with the same passage (something like this) :

"The Wheel of time turns, and Ages come and pass, leaving memories that become legend. Legend fades to myth, and even myth is long forgotten when the Age that gave it birth comes again." In the Matrix, Neo is "The One". In the WOT, Rand is "The Dragon Reborn". Both were foretold through prophecy to essentially save the world. The concept of a Messiah character is very common theme in literature, but the part which is a little too similar to me, is the concept of the cycle repeating itself over and over. Neo is not the first "One". Rand is not the first "Dragon". They are both destined to fullfil their role in the enternal, recurring struggle between good and evil, and unless something breaks the cycle, the same struggle will be repeated by a future Messiah character some time later.

Second similarity - Agent Smith is Padain Fain. Smith started out as an agent, but something happened to him at the end of M1 that turned him into "something much more than an agent". He is a renegade from the other baddies in the Matrix world, and he is obsessed with Neo. Padain Fain started out as a Darkfriend. He was given special powers by the Dark One to become his "hound" (his sole purpose was hunt down the reborn Dragon). Then Fain became something much more through his Shadar Logoth ordeal (he's now some wierd mixture of Padain Fain, Mordeth and something else). Fain is now a renegade from the Dark One (and has been ordered killed by the Forsaken and/or the DO). Fain is definitely obsessed with Rand. Fain is nutso about his Dagger - I found it funny that the human character Smith possessed was also a little nutso about his knife (cutting his own hand, etc).

Other similarities - The Matrix and the Pattern...?

All in all, I enjoyed the movie... Can't wait for Revolutions...


Saturday, May 31, 2003

Good tool for Debugging IE Dom... 

A fellow blogger had a link to this very helpful tool the other day:

http://www.cheztabor.com/IEDocMon

It basically does the same thing for IE as the Dom Inspector does for Mozilla. Very useful for debugging, or just looking at how someone's web-page is structured.


Monday, May 19, 2003

Nice Little Article on Black Box Testing for WebApps with HttpUnit 

Came across a nice little 2 page article on black box testing for webapps over at OnJava.com... Here's the Link...

Thursday, March 06, 2003

Maslow's Hierarchy of Needs: Food, Shelter, RAM... 

Flying back from Montreal right now and its become painfully apparent to me that my laptop (alone) is inadequate as a development machine on my current project. The sad part is, this was a state of the art laptop a little over a year ago. Its a Dell Latitude C810 with a PIII-1.13 Ghz Processor and 512MB of RAM.

Why Dell decided to cap the C810's at 512MB of RAM I will never understand. I would gladly shell out the required funds to buy a gig of RAM if the damn thing would take it.

The things I need running to do development on my current project.

The laptop works fine as a development platform if I can augment it with another machine. For example, at our Dallas office (and at home), I always have spare desktop machine. I map the network drives on the spare machine, keep a remote window up on it, and run JBoss/Jetty & Oracle on the desktop. This frees all the resources on the laptop for the IDE and the compile/test cycle and works MUCH better. In the grand scheme of universal truths, one could conclude that :
   RAM = GOOD
Oh well, at least my lack of RAM predicament gives me plenty of time to write blogs in notepad while I'm waiting around for a test to complete...

Speaking of - I really like the XP Remote Desktop Connection facility (its built on top of Terminal Server). Its much more like setting your display in X-Windows than Microsoft's previous support (e.g. NetMeeting). One of the things I really love about my laptop is the crisp 1600x1200 display. With Remote Desktop Connection I can login to a server with a crappy video card and still run at 1600x1200 (way cool). I know you could do this a decade or more ago on Unix, but hey - at least MS is improving :)


Wednesday, March 05, 2003

Keep IDEA from Hanging for significant periods of time while doing GC... 

We have a fairly sizeable project, about 3000 classes in 60 different source directories (each subystem is split into persistence, domain and services layers, each layer has its own source directory). Performance of IDEA has gotten pretty bad of late. Even with 250MB minimum JVM heap size, it frequently goes though big periods (30 seconds or so) where it will not respond. This is running on a PIII 1.13 Ghz with 512 MB of RAM.

I posted this to their bug tracking forum and got some helpful responses. Looks like you can add the following option to the IDEA/bin/idea.lax file to help with this problem (turns on concurrent GC) :

	lax.nl.java.option.additional=-XX:+UseConcMarkSweepGC 
The full thread is here if anyone's interested :

        http://www.intellij.net/tracker/idea/viewSCR?publicId=9910

Monday, March 03, 2003

Wish I had a JavaScript IDE... 

Been having to write a bit of JavaScript lately... Sure do wish I had a development environment that did for JavaScript what IDEA does for Java. Seems like this would be pretty easy for IDEA to add support for this. Sure would be nice...

Speaking of handy tools for web development, checkout Mozilla's built-in DOM Inspector. It basically has three panes. One shows a real, rendered web page, one shows the DOM tree for that web page, and another shows all DOM attributes of the currently selected node in the DOM Tree.

As you select different nodes in the DOM tree, the corresponding visual portion of the web page flashes. This is really great for analyzing some of the more sophisticated web sites out there.


Saturday, February 15, 2003

Nasty Webstart Classloader Bug Revisited... 

I blogged about a nasty webstart classloader bug a couple of weeks ago. I found a workaround for the bug at the time, but as it turns out, the the issue would still rear its ugly head under certain circumstances. We set the correct classloader during startup to get around the WebStart classloader bug described earlier. For our application, we have JBoss on the server and a Swing client that's usually run through webstart. All UI events are all dispatched via the AWT-EventQueue thread. Anytime an uncaught exception occurs as a result of one of these events, it would bubble all the way back to the top, and cause this thread to exit. A new AWT-EventQueue thread would then be started, but that new thread again have the wrong classloader (as per the WebStart classloader bug... sigh...). The solution to this problem was this : 1. Created a custom class to handle exceptions (see below). 2. Installed this class as the handler for uncaught AWT-Excpeptions (via the undocumented system property "sun.awt.exception.handler"). The class we used was basically this :
      public class UncaughtAwtExceptionHandler
      {
         public static void installAsUncaughtAwtExceptionHandler()
         {
            System.setProperty("sun.awt.exception.handler", UncaughtAwtExceptionHandler.class.getName() );
         }
         public UncaughtAwtExceptionHandler()
         {
         }
         public void handle (Throwable ex)
         {
            // log the error...
         }
      }
Now anytime an uncaught exception bubbles all the way to the top of the AWT-EventQueue thread, the handle method on UncaughtAwtExceptionHandler is called (and the AWT-EventQueue thread does not exit). The only constraints on one of these classes is that they must have a public, zero argument constructor and a method which matches the handle method signature (void return type, Throwable as the single parameter). I found this property by looking at the source for the AWT class EventDispatchThread (good thing they ship JDK's with the source). There is a comment on a private method which cautions that this property will one day go away when better API support for uncaught exceptions is provided (I believe this is scheduled for JDK 1.5). One other solution I explored while trying to solve this was defining a custom ThreadGroup in the main of the program, and creating a new main thread with the correct ClassLoader. Then I let the original webstart thread "end", while I started up our application in the newly created thread. You can override ThreadGroup's uncaughtException method to get a notification anytime a thread in that ThreadGroup dies (I was going to try to use this hook to send a runnable to the awt event queue via the SwingUtilities.invokeLater method that would reset the classloader in the new thread). Nonetheless, I could never quite get it to work the way I wanted (couldn't get the AWT-EventQueue to belong to my ThreadGroup in a Webstart application). I looked a thte source and it looks like the awt's dispatch thread uses the ThreadGroup and ClassLoader of the first thread that causes it to do anything (and I think WebStart was doing some awt stuff before our program even started). Anyway, it was around that time that I stumbled upon the property above, and I thought that would be a more foolproof solution (keep the event queue thread from dying in the first place). I really hope they fix this bug in the next version of WebStart (I'm suprised they haven't done it already).

Thursday, February 13, 2003

Travel Lightly... 

One of the arguments I really liked from Cockburn’s Agile Software Development book is that the goal of a software project is not to produce good documentation, but rather, to produce good software. Documentation such as UML Models are a means to an end. They serve the purpose of helping to communicate vision, architecture or design. Models are valuable tools for doing this – but the key point is, don’t get so enamored with them that you lose site of the real goal.

Here’s an excerpt from Scott Ambler’s Agile site (http://www.agilemodeling.com/principles.htm) that I thought reiterated the same point :

"Travel Light. Every artifact that you create, and then decide to keep, will need to be maintained over time. If you decide to keep seven models, then whenever a change occurs (a new/updated requirement, a new approach is taken by your team, a new technology is adopted, ...) you will need to consider the impact of that change on all seven models and then act accordingly. If you decide to keep only three models then you clearly have less work to perform to support the same change, making you more agile because you are traveling lighter. Similarly, the more complex/detailed your models are, the more likely it is that any given change will be harder to accomplish (the individual model is "heavier" and is therefore more of a burden to maintain). Every time you decide to keep a model you trade-off agility for the convenience of having that information available to your team in an abstract manner (hence potentially enhancing communication within your team as well as with project stakeholders). Never underestimate the seriousness of this trade-off. Someone trekking across the desert will benefit from a map, a hat, good boots, and a canteen of water they likely won't make it if they burden themselves with hundreds of gallons of water, a pack full of every piece of survival gear imaginable, and a collection of books about the desert. Similarly, a development team that decides to develop and maintain a detailed requirements document, a detailed collection of analysis models, a detailed collection of architectural models, and a detailed collection of design models will quickly discover they are spending the majority of their time updating documents instead of writing source code."


This page is powered by Blogger. Isn't yours?