<?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-4112415</id><updated>2011-07-07T15:11:46.799-07:00</updated><title type='text'>Caffeine Induced</title><subtitle type='html'>Lance Hankins</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lhankins.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>27</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4112415.post-107092509258340034</id><published>2003-12-08T15:11:00.000-08:00</published><updated>2010-04-26T09:20:30.746-07:00</updated><title type='text'>My Blog has Moved...</title><content type='html'>&lt;p&gt;My blog has moved &lt;a href="http://caffeineinduced.wordpress.com/"&gt;over to WordPress&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-107092509258340034?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/107092509258340034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/107092509258340034'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_12_07_archive.html#107092509258340034' title='My Blog has Moved...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-105984380459923385</id><published>2003-08-02T10:03:00.000-07:00</published><updated>2003-08-02T10:19:21.460-07:00</updated><title type='text'>More on Drive Cleanliness...</title><content type='html'>&lt;p&gt;I blogged a couple of weeks back on &lt;a href="http://lhankins.blogspot.com/2003_06_22_lhankins_archive.html#105657541908359024"&gt;setting up automated nightly defrags on WinXP&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The other day, as drive space was getting a little tight for my comfort,  I ran the excellent utility &lt;a href="http://www.jgoodies.com/freeware/jdiskreport/index.html"&gt;JDiskReport from JGoodies&lt;/a&gt; to see just where all my drivespace was allocated  and made an alarming discovery.&lt;/p&gt;

&lt;p&gt; 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\&lt;font color="red"&gt;&amp;lt;username&amp;gt;&lt;/font&gt;\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_&amp;lt;PortNumber&amp;gt;__&amp;lt;WarName&amp;gt;  (where &amp;lt;PortNumber&amp;gt; and &amp;lt;WarName&amp;gt; are your respective jetty listening port and war names).&lt;/p&gt;

&lt;p&gt;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).&lt;/P&gt;

&lt;p&gt;Anyway - I decided to update my automated nightly defrag task to cleanup this stuff too.   Here's the updated version - &lt;b&gt;USE WITH CAUTION&lt;/b&gt; - 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\&lt;font color="red"&gt;&amp;lt;username&amp;gt;&lt;/font&gt;\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 : &lt;/P&gt;

&lt;div class="codeSnippit"&gt;
&lt;pre&gt;
::--- 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%\*" &gt; c:\temp\Defrag_CleanOutTemp.txt 2&gt;&amp;1
rmdir /S /Q "%TEMP%" &gt;&gt; c:\temp\Defrag_CleanOutTemp.txt 2&gt;&amp;1


::--- defrag your local drives

defrag /v /f c: &gt; c:\temp\Defrag_C.txt 2&gt;&amp;1
defrag /v /f d: &gt; c:\temp\Defrag_D.txt 2&gt;&amp;1
&lt;/pre&gt;
&lt;/div&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-105984380459923385?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105984380459923385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105984380459923385'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_07_27_archive.html#105984380459923385' title='More on Drive Cleanliness...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-105743464693894778</id><published>2003-07-05T12:50:00.000-07:00</published><updated>2003-10-29T10:43:04.133-08:00</updated><title type='text'>Precompiling JSP's under JBoss/Jetty 3.2.1...</title><content type='html'>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.&lt;p/&gt;

First, a high-level rundown of the process :
&lt;ol&gt;
&lt;li&gt;Using Jasper (a JSP compiler), we'll transform the JSP's into .java files (servlets).&lt;/li&gt;
&lt;li&gt;Jasper will also spit out a web.xml fragment with servlet definitions and mappings for each of the above generated servlets.&lt;/li&gt;
&lt;li&gt;We'll use the ant jspc task to make the previous two bullets a little easier.&lt;/li&gt;
&lt;li&gt;We'll compile the .java files into .class files and then copy them into the WEB-INF/classes directory of the WAR&lt;/li&gt;
&lt;li&gt;We'll insert the web.xml fragment generated by Jasper into your normal web.xml file (at a very specific place).&lt;/li&gt;
&lt;li&gt;build your war as normal&lt;/li&gt;
&lt;/ol&gt;

Ok, so here's the build target which generates the war in question (disregard project specific stuff) : 

&lt;div class="codeSnippit"&gt;
&lt;pre&gt;
&amp;lt;target name="dist" depends="compile"&amp;gt;

   &amp;lt;!-- copy required libs to WEB-INF/lib--&amp;gt;
   &amp;lt;copy todir="${dir.webinf}/lib"&amp;gt;
      &amp;lt;fileset dir="${dir.thirdpartytools.struts}/lib"/&amp;gt;
      &amp;lt;fileset dir="${dir.thirdpartytools.jstl}/lib"/&amp;gt;
      &amp;lt;fileset dir="${dir.search}/dist/lib" includes="${jar.name.search-domain}, ${jar.name.search-services}"/&amp;gt;
   &amp;lt;/copy&amp;gt;

   &amp;lt;!-- copy classes we built earlier to WEB-INF/classes --&amp;gt;
   &amp;lt;copy todir="${dir.webinf}/classes"&amp;gt;
      &amp;lt;fileset dir="${classes}"/&amp;gt;
   &amp;lt;/copy&amp;gt;

   &amp;lt;!-- copy the tld's we're using to WEB-INF/tld --&amp;gt;
   &amp;lt;copy todir="${dir.webinf}/tld"&amp;gt;
      &amp;lt;fileset dir="${dir.thirdpartytools.struts}/tld" includes="*.tld"/&amp;gt;
      &amp;lt;fileset dir="${dir.thirdpartytools.jstl}/tld" includes="*.tld"/&amp;gt;
      &amp;lt;fileset dir="${dir.config}/tld" includes="*.tld"/&amp;gt;
   &amp;lt;/copy&amp;gt;

   &amp;lt;!-- these two properties are the generated web.xml fragment, and the resulting merged xml--&amp;gt;
   &amp;lt;property name="jspc.webxml.fragment" value="${dir.jspc.temp}/jspc-web-xml-fragment.xml"/&amp;gt;
   &amp;lt;property name="jspc.webxml.merged" value="${dir.jspc.temp}/merged-web.xml"/&amp;gt;

   &amp;lt;path id="jspc.classpath"&amp;gt;
      &amp;lt;path refid="cp.jspc"/&amp;gt;
      &amp;lt;path refid="cp.jboss"/&amp;gt;
      &amp;lt;path refid="cp.webclient-thirdparty.tools"/&amp;gt;
      &amp;lt;path refid="build.classpath"/&amp;gt;
      &amp;lt;fileset dir="${classes}"/&amp;gt;
      &amp;lt;fileset dir="${dir.webinf}/lib" includes="*.jar"/&amp;gt;
   &amp;lt;/path&amp;gt;


   &amp;lt;!-- JSP -&amp;gt; .java --&amp;gt;
   &amp;lt;jspc srcdir="${dir.docroot}"
         destdir="${dir.jspc.gensrc}"
         verbose="9"
         classpathref="jspc.classpath"
         webinc="${jspc.webxml.fragment}"&amp;gt;

     &amp;lt;include name="**/*.jsp"/&amp;gt;
   &amp;lt;/jspc&amp;gt;

   &amp;lt;!-- .java -&amp;gt; .class --&amp;gt;
   &amp;lt;javac deprecation="${deprecation.javac}"
          fork="${fork.javac}"
          source="${source}"
          debug="${debug}"
          srcdir="${dir.jspc.gensrc}"
          destdir="${dir.webinf}/classes"
          classpathref="jspc.classpath"/&amp;gt;


   &amp;lt;!-- merge the jspc generated web.xml fragment with the real web.xml--&amp;gt;
   &amp;lt;loadfile property="jspc.webxml.fragment.contents" srcFile="${jspc.webxml.fragment}"/&amp;gt;
   &amp;lt;copy file="${dir.webinf}/web.xml" tofile="${jspc.webxml.merged}"/&amp;gt;

   &amp;lt;replace file="${jspc.webxml.merged}"&amp;gt;
      &amp;lt;replacefilter token="&amp;amp;lt;!-- @JSPC-INSERT-HERE@ --&amp;amp;gt;" value="${jspc.webxml.fragment.contents}"/&amp;gt;
   &amp;lt;/replace&amp;gt;

   &amp;lt;!-- Now war everything up --&amp;gt;
   &amp;lt;war destfile="${dist}/lib/${jar.name.epcportal-presentation}"
      webxml="${jspc.webxml.merged}"&amp;gt;
      &amp;lt;fileset dir="${dir.docroot}"/&amp;gt;
      &amp;lt;classes dir="${classes}"/&amp;gt;
      &amp;lt;classes dir="${dir.property.file}"&amp;gt;
         &amp;lt;include name="**/*.properties"/&amp;gt;
      &amp;lt;/classes&amp;gt;
   &amp;lt;/war&amp;gt;
&amp;lt;/target&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;

In the above fragment, the following two properties are defined earlier : &lt;p/&gt;

&lt;div class="codeSnippit"&gt;
&lt;pre&gt;
&amp;lt;property name="dir.jspc.temp" value="${dist}/tmp/jspc"/&amp;gt;
&amp;lt;property name="dir.jspc.gensrc" value="${dir.jspc.temp}/gensrc"/&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;

And cp.jspc is defined as the following : &lt;p/&gt;

&lt;div class="codeSnippit"&gt;
&lt;pre&gt;
&amp;lt;path id="cp.jspc"&amp;gt;
   &amp;lt;pathelement location="${jboss.home}/server/default/deploy/jbossweb-jetty.sar/jasper-compiler.jar"/&amp;gt;
   &amp;lt;pathelement location="${jboss.home}/server/default/deploy/jbossweb-jetty.sar/jasper-runtime.jar"/&amp;gt;
   &amp;lt;pathelement location="${ant_home}/lib/ant.jar"/&amp;gt;
&amp;lt;/path&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;

Now, modify your existing web.xml file to have the following comment in it, just AFTER the last &amp;lt;servlet&amp;gt; tag and just BEFORE the first &amp;lt;servlet-mapping&amp;gt; tag.  
&lt;div class="codeSnippit"&gt;
&lt;pre&gt;
      &amp;lt;!-- @JSPC-INSERT-HERE@ --&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
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 :&lt;p/&gt;

&lt;div class="codeSnippit"&gt;
&lt;pre&gt;
&amp;lt;?xml version="1.0" encoding="ISO-8859-1"?&amp;gt;

&amp;lt;!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'&amp;gt;
&amp;lt;web-app&amp;gt;


   &amp;lt;!-- Struts Action Servlet Configuration --&amp;gt;
   &amp;lt;servlet&amp;gt;
      &amp;lt;servlet-name&amp;gt;action&amp;lt;/servlet-name&amp;gt;
      &amp;lt;servlet-class&amp;gt;org.apache.struts.action.ActionServlet&amp;lt;/servlet-class&amp;gt;
      &amp;lt;init-param&amp;gt;
         &amp;lt;param-name&amp;gt;application&amp;lt;/param-name&amp;gt;
         &amp;lt;param-value&amp;gt;ApplicationResources&amp;lt;/param-value&amp;gt;
      &amp;lt;/init-param&amp;gt;
      &amp;lt;init-param&amp;gt;
         &amp;lt;param-name&amp;gt;config&amp;lt;/param-name&amp;gt;
         &amp;lt;param-value&amp;gt;/WEB-INF/struts-config.xml&amp;lt;/param-value&amp;gt;
      &amp;lt;/init-param&amp;gt;
      &amp;lt;init-param&amp;gt;
         &amp;lt;param-name&amp;gt;debug&amp;lt;/param-name&amp;gt;
         &amp;lt;param-value&amp;gt;0&amp;lt;/param-value&amp;gt;
      &amp;lt;/init-param&amp;gt;
      &amp;lt;init-param&amp;gt;
         &amp;lt;param-name&amp;gt;detail&amp;lt;/param-name&amp;gt;
         &amp;lt;param-value&amp;gt;0&amp;lt;/param-value&amp;gt;
      &amp;lt;/init-param&amp;gt;
      &amp;lt;init-param&amp;gt;
         &amp;lt;param-name&amp;gt;validate&amp;lt;/param-name&amp;gt;
         &amp;lt;param-value&amp;gt;true&amp;lt;/param-value&amp;gt;
      &amp;lt;/init-param&amp;gt;
      &amp;lt;load-on-startup&amp;gt;2&amp;lt;/load-on-startup&amp;gt;
   &amp;lt;/servlet&amp;gt;





   &amp;lt;!-- JSP-PRECOMPILER INSERTION POINT, DO NOT REMOVE, MODIFY OR MOVE THE FOLLOWING LINE--&amp;gt;
   &amp;lt;!-- @JSPC-INSERT-HERE@ --&amp;gt;





   &amp;lt;!-- Action Servlet Mapping --&amp;gt;
   &amp;lt;servlet-mapping&amp;gt;
      &amp;lt;servlet-name&amp;gt;action&amp;lt;/servlet-name&amp;gt;
      &amp;lt;url-pattern&amp;gt;*.do&amp;lt;/url-pattern&amp;gt;
   &amp;lt;/servlet-mapping&amp;gt;


   &amp;lt;!-- The Welcome File List --&amp;gt;
   &amp;lt;welcome-file-list&amp;gt;
      &amp;lt;welcome-file&amp;gt;index.jsp&amp;lt;/welcome-file&amp;gt;
   &amp;lt;/welcome-file-list&amp;gt;

   &amp;lt;error-page&amp;gt;
      &amp;lt;error-code&amp;gt;404&amp;lt;/error-code&amp;gt;
      &amp;lt;location&amp;gt;/error404.jsp&amp;lt;/location&amp;gt;
   &amp;lt;/error-page&amp;gt;

   &amp;lt;error-page&amp;gt;
      &amp;lt;error-code&amp;gt;400&amp;lt;/error-code&amp;gt;
      &amp;lt;location&amp;gt;/error400.jsp&amp;lt;/location&amp;gt;
   &amp;lt;/error-page&amp;gt;

   &amp;lt;error-page&amp;gt;
      &amp;lt;error-code&amp;gt;401&amp;lt;/error-code&amp;gt;
      &amp;lt;location&amp;gt;/error401.jsp&amp;lt;/location&amp;gt;
   &amp;lt;/error-page&amp;gt;

	&amp;lt;error-page&amp;gt;
      &amp;lt;error-code&amp;gt;500&amp;lt;/error-code&amp;gt;
      &amp;lt;location&amp;gt;/error500.jsp&amp;lt;/location&amp;gt;
   &amp;lt;/error-page&amp;gt;

   &amp;lt;!-- Struts Tag Library Descriptors --&amp;gt;
   &amp;lt;taglib&amp;gt;
      &amp;lt;taglib-uri&amp;gt;/tags/struts-bean&amp;lt;/taglib-uri&amp;gt;
      &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/struts-bean.tld&amp;lt;/taglib-location&amp;gt;
   &amp;lt;/taglib&amp;gt;

   &amp;lt;taglib&amp;gt;
      &amp;lt;taglib-uri&amp;gt;/tags/struts-html&amp;lt;/taglib-uri&amp;gt;
      &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/struts-html.tld&amp;lt;/taglib-location&amp;gt;
   &amp;lt;/taglib&amp;gt;

   &amp;lt;taglib&amp;gt;
      &amp;lt;taglib-uri&amp;gt;/tags/struts-logic&amp;lt;/taglib-uri&amp;gt;
      &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/struts-logic.tld&amp;lt;/taglib-location&amp;gt;
   &amp;lt;/taglib&amp;gt;
  &amp;lt;taglib&amp;gt;
    &amp;lt;taglib-uri&amp;gt;/tags/struts-nested&amp;lt;/taglib-uri&amp;gt;
    &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/struts-nested.tld&amp;lt;/taglib-location&amp;gt;
  &amp;lt;/taglib&amp;gt;

  &amp;lt;taglib&amp;gt;
    &amp;lt;taglib-uri&amp;gt;/tags/struts-tiles&amp;lt;/taglib-uri&amp;gt;
    &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/struts-tiles.tld&amp;lt;/taglib-location&amp;gt;
  &amp;lt;/taglib&amp;gt;

   &amp;lt;!-- JSTL --&amp;gt;
   &amp;lt;taglib&amp;gt;
     &amp;lt;taglib-uri&amp;gt;/tags/jstl-c&amp;lt;/taglib-uri&amp;gt;
     &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/c.tld&amp;lt;/taglib-location&amp;gt;
   &amp;lt;/taglib&amp;gt;

   &amp;lt;taglib&amp;gt;
     &amp;lt;taglib-uri&amp;gt;/tags/jstl-c-rt&amp;lt;/taglib-uri&amp;gt;
     &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/c-rt.tld&amp;lt;/taglib-location&amp;gt;
   &amp;lt;/taglib&amp;gt;

   &amp;lt;taglib&amp;gt;
     &amp;lt;taglib-uri&amp;gt;/tags/jstl-fmt&amp;lt;/taglib-uri&amp;gt;
     &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/fmt.tld&amp;lt;/taglib-location&amp;gt;
   &amp;lt;/taglib&amp;gt;

   &amp;lt;taglib&amp;gt;
     &amp;lt;taglib-uri&amp;gt;/tags/jstl-fmt-rt&amp;lt;/taglib-uri&amp;gt;
     &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/fmt-rt.tld&amp;lt;/taglib-location&amp;gt;
   &amp;lt;/taglib&amp;gt;

   &amp;lt;taglib&amp;gt;
     &amp;lt;taglib-uri&amp;gt;/tags/jstl-x&amp;lt;/taglib-uri&amp;gt;
     &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/x.tld&amp;lt;/taglib-location&amp;gt;
   &amp;lt;/taglib&amp;gt;

   &amp;lt;taglib&amp;gt;
     &amp;lt;taglib-uri&amp;gt;/tags/x-rt&amp;lt;/taglib-uri&amp;gt;
     &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/x-rt.tld&amp;lt;/taglib-location&amp;gt;
   &amp;lt;/taglib&amp;gt;

   &amp;lt;!-- Project Specific Tag Libs --&amp;gt;
   &amp;lt;taglib&amp;gt;
     &amp;lt;taglib-uri&amp;gt;/tags/epc&amp;lt;/taglib-uri&amp;gt;
     &amp;lt;taglib-location&amp;gt;/WEB-INF/tld/epc.tld&amp;lt;/taglib-location&amp;gt;
   &amp;lt;/taglib&amp;gt;

&amp;lt;/web-app&amp;gt;

&lt;/pre&gt;
&lt;/div&gt;

OK - that's about it.   A couple of things to watch out for :
&lt;ul&gt;
&lt;li&gt;The ant jspc task and jasper are VERY sensitive to the directory structure of your webapp.   To get jasper to work, I had to make our pre-war directory structure pretty much exactly like the war archive structure.   In other words, I had to make sure that the directory at task execution time was exactly like it would be in when looking at it in the war -  all the classes that were destined to be in WEB-INF/classes were already there, all the libs which were destined to be in WEB-INF/lib were already there, all the TLD's were in their final destination (somewhere under WEB-INF), the web.xml file was already in WEB-INF, etc.   This might seem obvious, but the ant &amp;lt;war&amp;gt; task will let you leave libs and classes in various directories and then bind them together into the appropriate archive with nested &amp;lt;lib&amp;gt; and &amp;lt;classes&amp;gt; tags&lt;/li&gt;
&lt;li&gt;Make sure you have at least Ant 1.5.3 (latest version of the ant jspc task)&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/4112415-105743464693894778?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105743464693894778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105743464693894778'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_06_29_archive.html#105743464693894778' title='Precompiling JSP&apos;s under JBoss/Jetty 3.2.1...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-105657541908359024</id><published>2003-06-25T14:10:00.000-07:00</published><updated>2003-07-28T16:32:51.416-07:00</updated><title type='text'>Automated nightly defrags on Windows XP...</title><content type='html'>On my machine I have two partitions : C &amp; 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. &lt;p/&gt; 

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..&lt;p/&gt; 

Anyway – you can setup Windows built in defrag tool to run on a recurring basis.   Here’s how :&lt;p/&gt; 

Create a batch file (e.g. c:\bin\DefragLocalDrives.cmd) with the contents similar to the following (customize to your local drive structure): &lt;p/&gt;
 
&lt;div class="codeSnippit"&gt;
&lt;pre&gt;
   defrag /v /f c: &gt; d:\temp\Defrag_C.txt

   defrag /v /f d: &gt; d:\temp\Defrag_D.txt
&lt;/pre&gt;
&lt;/div&gt;
 
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. &lt;p/&gt; 

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.&lt;p/&gt;

That’s it… &lt;p/&gt;

UPDATE - As &lt;a href="http://www.brainopolis.com/roller/page/lance
"&gt;Lance Lavandowska&lt;/a&gt; kindly pointed out - this only works on XP (defrag.exe is not present on Win2k installations)&lt;p/&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-105657541908359024?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105657541908359024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105657541908359024'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_06_22_archive.html#105657541908359024' title='Automated nightly defrags on Windows XP...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-105643400047774745</id><published>2003-06-23T22:53:00.000-07:00</published><updated>2003-06-23T22:53:29.983-07:00</updated><title type='text'>CruiseControl version 2.2.1 is out...</title><content type='html'>Just noticed that a new version of Cruise Control has been released&lt;p&gt;

&lt;a href="http://sourceforge.net/project/shownotes.php?release_id=167306"&gt;http://sourceforge.net/project/shownotes.php?release_id=167306&lt;/a&gt;&lt;p&gt;

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.


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-105643400047774745?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105643400047774745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105643400047774745'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_06_22_archive.html#105643400047774745' title='CruiseControl version 2.2.1 is out...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-105640643494436338</id><published>2003-06-23T15:13:00.000-07:00</published><updated>2003-06-23T15:17:35.116-07:00</updated><title type='text'>Mozilla: Helpful Quick Reference Sidebars for Developers...</title><content type='html'>Mozilla has some really cool "quick reference" sidebars for developers.  For example : &lt;p&gt;

&lt;ul&gt;
&lt;li&gt;HTML 4.01&lt;/li&gt;
&lt;li&gt;CSS 2&lt;/li&gt;
&lt;li&gt;Javascript (Reference and Guide)&lt;/li&gt;
&lt;li&gt;XSLT&lt;/li&gt;
&lt;/ul&gt;

You can get them from here : &lt;a href="http://devedge.netscape.com/toolbox/sidebars/"&gt;http://devedge.netscape.com/toolbox/sidebars&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-105640643494436338?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105640643494436338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105640643494436338'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_06_22_archive.html#105640643494436338' title='Mozilla: Helpful Quick Reference Sidebars for Developers...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-105563137231802121</id><published>2003-06-14T15:56:00.000-07:00</published><updated>2003-06-22T10:47:07.770-07:00</updated><title type='text'>Experiences migrating from JBoss 3.0.4 -&gt; JBoss 3.2.1...</title><content type='html'>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.&lt;p/&gt;

Here are the things that caused problems :&lt;p/&gt;

1. Some of the JBoss client jars were reorganized / renamed (e.g. jaas.jar -&gt; jboss-jaas.jar, jmx-rmi-adaptor.sar -&gt; 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.&lt;p/&gt;

2. There are new jars required for the client (e.g. jboss-transaction-client.jar).&lt;p/&gt;

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).&lt;p/&gt;

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.&lt;p/&gt;

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).&lt;p/&gt;

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).&lt;p/&gt;

&lt;div class="codeSnippit"&gt;
&lt;pre&gt;
   &amp;lt;!-- HACK: This entry is only present to make IE treat the resulting
          HTTP response as a JNLP file instead of a JSP file. --&amp;gt;
      &amp;lt;servlet&amp;gt;
         &amp;lt;servlet-name&amp;gt;FakeJNLP-IE-Workaround&amp;lt;/servlet-name&amp;gt;
         &amp;lt;description&amp;gt;our dynamically generated JNLP file (generated by this JSP)&amp;lt;/description&amp;gt;
         &amp;lt;jsp-file&amp;gt;/FsxWebStart.jsp&amp;lt;/jsp-file&amp;gt;
      &amp;lt;/servlet&amp;gt;
      &amp;lt;servlet-mapping&amp;gt;
         &amp;lt;servlet-name&amp;gt;FakeJNLP-IE-Workaround&amp;lt;/servlet-name&amp;gt;
         &amp;lt;url-pattern&amp;gt;/FsxWebStart.jnlp&amp;lt;/url-pattern&amp;gt;
      &amp;lt;/servlet-mapping&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-105563137231802121?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105563137231802121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/105563137231802121'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_06_08_archive.html#105563137231802121' title='Experiences migrating from JBoss 3.0.4 -&gt; JBoss 3.2.1...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-200371117</id><published>2003-06-01T15:40:00.000-07:00</published><updated>2003-06-21T22:21:17.220-07:00</updated><title type='text'>Similarities between the Matrix Reloaded and the Wheel of Time (minor spoilers)</title><content type='html'>(spoiler warning)&lt;p/&gt;&lt;p/&gt;&lt;p/&gt;





Finally got a chance to see Matrix Reloaded about a week ago.  &lt;p/&gt;

Is it just me or are there a lot of overlapping themes in Matrix Reloaded and &lt;a href="http://www.amazon.com/exec/obidos/tg/feature/-/111751/002-4980626-5607208"&gt;Robert Jordan's Wheel of Time Series &lt;/a&gt;...?    For example : &lt;p/&gt;

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) :&lt;p/&gt;
&lt;i&gt;
"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."
&lt;/i&gt;
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.&lt;p/&gt;

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).&lt;p/&gt;

Other similarities - The Matrix and the Pattern...?   &lt;p/&gt;

All in all, I enjoyed the movie...   Can't wait for Revolutions...&lt;p/&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-200371117?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/200371117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/200371117'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_06_01_archive.html#200371117' title='Similarities between the Matrix Reloaded and the Wheel of Time (minor spoilers)'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-200368713</id><published>2003-05-31T17:02:00.000-07:00</published><updated>2003-06-21T22:21:49.830-07:00</updated><title type='text'>Good tool for Debugging IE Dom...</title><content type='html'>A fellow blogger had a link to this very helpful tool the other day: &lt;p/&gt;

&lt;a href="http://www.cheztabor.com/IEDocMon"&gt;http://www.cheztabor.com/IEDocMon&lt;/a&gt;&lt;p/&gt;

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.&lt;p/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-200368713?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/200368713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/200368713'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_05_25_archive.html#200368713' title='Good tool for Debugging IE Dom...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-200314389</id><published>2003-05-19T18:13:00.000-07:00</published><updated>2003-05-19T18:32:38.000-07:00</updated><title type='text'>Nice Little Article on Black Box Testing for WebApps with HttpUnit</title><content type='html'>Came across a nice little 2 page article on black box testing for webapps over at OnJava.com... &lt;a href="http://www.onjava.com/pub/a/onjava/2003/05/07/blackboxwebtest.html?page=1"&gt;Here's the Link...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-200314389?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/200314389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/200314389'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_05_18_archive.html#200314389' title='Nice Little Article on Black Box Testing for WebApps with HttpUnit'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-90418830</id><published>2003-03-06T19:46:00.000-08:00</published><updated>2003-06-21T22:22:29.776-07:00</updated><title type='text'>Maslow's Hierarchy of Needs: Food, Shelter, RAM...</title><content type='html'>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.  &lt;p/&gt;

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.&lt;p/&gt;

The things I need running to do development on my current project.
&lt;UL&gt;&lt;LI&gt;IDEA&lt;/li&gt;&lt;LI&gt;JBOSS/Jetty&lt;/li&gt;&lt;LI&gt;Oracle 9i&lt;/li&gt;&lt;LI&gt;Javac (when building/executing tests)&lt;/li&gt;&lt;/ul&gt;
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 &amp; 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 :
&lt;pre&gt;   RAM = GOOD&lt;/pre&gt;
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...&lt;p/&gt;

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 :)&lt;p/&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-90418830?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90418830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90418830'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_03_02_archive.html#90418830' title='Maslow&apos;s Hierarchy of Needs: Food, Shelter, RAM...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-90412688</id><published>2003-03-05T17:10:00.000-08:00</published><updated>2003-06-21T22:25:14.613-07:00</updated><title type='text'>Keep IDEA from Hanging for significant periods of time while doing GC...</title><content type='html'>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.&lt;p/&gt;

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) :&lt;p/&gt;
&lt;pre&gt;
	lax.nl.java.option.additional=-XX:+UseConcMarkSweepGC 
&lt;/pre&gt;
The full thread is here if anyone's interested :&lt;p/&gt;
&lt;pre&gt;
        &lt;a href="http://www.intellij.net/tracker/idea/viewSCR?publicId=9910"&gt;http://www.intellij.net/tracker/idea/viewSCR?publicId=9910&lt;/a&gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-90412688?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90412688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90412688'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_03_02_archive.html#90412688' title='Keep IDEA from Hanging for significant periods of time while doing GC...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-90402537</id><published>2003-03-03T17:58:00.000-08:00</published><updated>2003-06-21T22:25:28.790-07:00</updated><title type='text'>Wish I had a JavaScript IDE...</title><content type='html'>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...&lt;p/&gt;

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.&lt;p/&gt;

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.&lt;p/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-90402537?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90402537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90402537'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_03_02_archive.html#90402537' title='Wish I had a JavaScript IDE...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-390328764</id><published>2003-02-15T15:49:00.000-08:00</published><updated>2003-02-16T06:29:48.000-08:00</updated><title type='text'>Nasty Webstart Classloader Bug Revisited...</title><content type='html'>I blogged about a nasty &lt;a href="http://lhankins.blogspot.com/2003_01_26_lhankins_archive.html#90247707"&gt;webstart classloader bug&lt;/a&gt; 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 :
&lt;pre&gt;
      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...
         }
      }
&lt;/pre&gt;
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).
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-390328764?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/390328764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/390328764'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_02_09_archive.html#390328764' title='Nasty Webstart Classloader Bug Revisited...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-90321893</id><published>2003-02-13T22:12:00.000-08:00</published><updated>2003-06-21T22:25:50.876-07:00</updated><title type='text'>Travel Lightly...</title><content type='html'>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. &lt;p/&gt;

Here’s an excerpt from Scott Ambler’s Agile site (&lt;a href="http://www.agilemodeling.com/principles.htm"&gt;http://www.agilemodeling.com/principles.htm&lt;/a&gt;) that I thought reiterated the same point :&lt;p/&gt;
&lt;i&gt;
"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."
&lt;/i&gt;
 
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-90321893?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90321893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90321893'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_02_09_archive.html#90321893' title='Travel Lightly...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-90294648</id><published>2003-02-07T23:32:00.000-08:00</published><updated>2003-06-21T22:26:18.646-07:00</updated><title type='text'>Phoenix...</title><content type='html'>I really love the Phoenix browser. Its an ultra-lightweight browser packaged off the Mozilla codebase. &lt;p/&gt;

The entire install is only 6 MB. Its very good, very fast and very small. &lt;p/&gt;

I absolutely LOVE its support for tabbed browsing (middle click on a link and it loads the link in a new tab in the same browser - great if you want to open a bunch of links at once without having to manage a ton of browser windows). You can also middle click on a tab to close it. It also has lots of the convenience shortcuts like IE (forward and back on the 4th/5th mousebuttons, CTRL enter changes "acme" -&gt; http://www.acme.com, CTRL mousewheel increases/reduces font size, and many more). I strongly encourage everyone to try it out. I like it better than IE, Netscape and Mozilla. &lt;p/&gt;

&lt;a href="http://mozilla.org/projects/phoenix/phoenix-release-notes.html"&gt;Here's the link for Phoenix 0.5 &lt;/a&gt;&lt;p/&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-90294648?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90294648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90294648'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_02_02_archive.html#90294648' title='Phoenix...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-90251821</id><published>2003-01-30T00:24:00.000-08:00</published><updated>2003-06-21T22:26:45.900-07:00</updated><title type='text'>C# vs. Java, Public Classes and Package Structure  </title><content type='html'>I strongly agree with &lt;a href="http://freeroller.net/page/matsh/20030124#we_all_wish_good_luck"&gt;Mats&lt;/a&gt; regarding the bogus argument that C# allows you to define more than one public class per file is really an advantage.&lt;p/&gt;

I used C++ for years and I was a freak about making the directory structure consistent for all source code.  It really annoyed me when people put files in random places or tried to cram 12 public classes in a single file.   Yuck.   I think the fact that Java enforces a heuristic like one public class per file is great.  &lt;p/&gt;

I think an even greater advantage for Java is that it forces your physical directory structure to mimic your logical package structure.  What a great idea - consistency.  Some might argue that this is taking their "flexibility" away, but who need's to waste mental bandwidth thinking like things like this...?  And who wants to put up with the situation where people make bad decisions about source code directory structure (and then you either have to live with it or fix it)...?    The Java way is better. &lt;p/&gt;

I'm sure this simple constraint makes life much easier on the ide vendors too.   Its real easy to tell my IDE - "this is my root source directory, you'll find my package structure underneath this, as well as all my sources..."   &lt;p/&gt;

All in all, the designers of the Java language chose simplicity over "options" at the language level  - I think this is a good thing.   Sure you can implement any XYZ concept as a language feature, but should you...?   Probably not.  Java's approach is to favor implemention of this concept in a class library.   This is why the grammar for Java is a fraction of the size of the grammar for C++ (which means Java parsers have much less ambiguity to deal with).   The fact that the language is so small and tight makes it easier for development tools to deal with Java source.&lt;p/&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-90251821?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90251821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90251821'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_26_archive.html#90251821' title='C# vs. Java, Public Classes and Package Structure  '/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-90247707</id><published>2003-01-28T19:44:00.000-08:00</published><updated>2003-06-22T13:42:27.043-07:00</updated><title type='text'>Nasty Webstart Classloader Bug...</title><content type='html'>Came across a nasty webstart bug late last week, here's an excerpt from our bugzilla database (and a solution).&lt;p/&gt;

---------------- &lt;p/&gt;

I'm going to open a bug on this so we don't forget about it.   There are a few 
places in our code where we've had to explicitly set the classloader to get
around a classloader bug in WebStart.&lt;p/&gt;
 
To find all of these places, do a search for the following in our codebase (its
mostly done in areas where we're looking up an object from JNDI on the client): &lt;p/&gt;
 
   Thread.currentThread().setContextClassLoader
 
The bug in WebStart only occurs when the console output is turned OFF (if the
console is on, you won't see the errors - dangerous).&lt;p/&gt;
 
For some background on this, issue see: &lt;p/&gt;
 
   &lt;a href="http://forum.java.sun.com/thread.jsp?forum=38&amp;amp;thread=301640"&gt;http://forum.java.sun.com/thread.jsp?forum=38&amp;thread=301640&lt;/a&gt;
   &lt;a href="http://forum.java.sun.com/thread.jsp?forum=38&amp;amp;thread=71223"&gt;http://forum.java.sun.com/thread.jsp?forum=38&amp;thread=71223&lt;/a&gt;
 
&lt;p/&gt;
------- Additional Comments From Lance Hankins 2003-01-22 16:37 -------&lt;p/&gt;

For now this has been reduced to a single place in the code where we have to call:&lt;p/&gt;
 
   Thread.currentThread().setContextClassLoader&lt;p/&gt;
 
This is now called in the initialize() method of AbstractFSXMain (for both the
main thread and the main Swing event thread).&lt;p/&gt;
 
Once a new version of Webstart is released (JDK 1.4.2..?), we can test to see if
this is still neccessary.&lt;p/&gt;
 

----------------- &lt;p/&gt;

The workaround we did is this (called a single time from the startup of our application) :&lt;p/&gt;

&lt;div class="codeSnippit"&gt;
&lt;pre&gt;
  /**
   * this method is a fix for a Webstart bug - see Bugzilla Bug #1485
   */

   protected void fixWebStartClassLoaderIssue()
   {
      final Runnable setClassLoaderCmd = new Runnable(){
         public void run()
         {
            //--- use some project specific class with the right classloader here...
            Thread.currentThread().setContextClassLoader(SomeClass.class.getClassLoader());
         }
      };

 
      //--- this will execute in the main thread...
      setClassLoaderCmd.run();
 
      //--- this will execute in the main Swing event thread...
      SwingUtilities.invokeLater(setClassLoaderCmd);
   }
&lt;/pre&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-90247707?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90247707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/90247707'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_26_archive.html#90247707' title='Nasty Webstart Classloader Bug...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-390234995</id><published>2003-01-25T22:30:00.000-08:00</published><updated>2003-01-26T06:44:38.000-08:00</updated><title type='text'>A few thoughts on Optimization and the Joys of our Craft...</title><content type='html'>The current project I'm working on is starting to mature to the point where its actually usable (its a Business Process Modelling Tool).  Last week we imported/uploaded about 200 MB worth of models from a previous version of the product and it sure uncovered a lot of performance issues.

My friend &lt;a href="http://home.earthlink.net/~huston2/dp/patterns.html"&gt;Vince Huston&lt;/a&gt; used to always quote : "Make it run... Make it run right... Make it fast... Make it small..."   

The point he was making is this: Don't cloud your design with premature attempts at things you "think" will be optimizations.  

I tend to think a lot about usage patterns and scalability during the initial architectural definition phase of the project.  Once I feel like we have come up with a solid architecture with respect to the performance/scalability forces, I tend to shift gears and focus more on logical design.   

When you're fleshing out your vision in a day to day cycle of design / implementation / refactoring, I think its beneficial to the thought process to be able to put the smaller performance issues on the backburner and concentrate on the big picture rather than trying to figure out how you can squeeze the last little bit of performance out of XYZ operation.   Delving into some tangental optimization thread of thinking regarding optimization is certainly not conducive to solving the problem at hand (it can be really distracting).

Nonetheless, &lt;u&gt;when the time comes&lt;/u&gt; for optimization - &lt;b&gt;oh what fun ;)&lt;/b&gt;.   I am an Engineer by training and cut my teeth as a programmer (many years ago) writing C under the 640k barrier.   The first few years of my programming career, I used to really take pride in finding obscure ways to represent data structures in a minimal amount of space (you had to be much more space conscious back then).   Even now, once I get going on optimization - I become obsessed with it (probably why I try to put it out of my mind until the time is right).   Its something I can tinker with for hours on end.   I woke up at 3:00 AM this morning with an idea and couldn't sleep until I'd seen how much it improved performance.

There's nothing quite as satisfying as cutting a 6 minute operation into 30 second one (and striving after that to cut it to a 5 second one).

One of the &lt;a href="http://web.media.mit.edu/~tpminka/brooks.html"&gt;"Joys of the Craft"&lt;/a&gt;, in my opinion is when you can refactor an existing solution (that you wrote) into something thats smaller, tighter and faster.   

Speaking of the joys of the craft, I think one of the things that magnifies and validates this joy is being able to share your daily obstacles and victories with a few close and respected peers.   How boring would your existence be if you couldn't bounce a hairy problem off one of your friends or share an exceptionally cool piece of code with them...?

This touchs on the XP threads I've seen lately : &lt;a href="http://roller.anthonyeden.com/page/rickard/20030122"&gt;Rickard&lt;/a&gt;, &lt;a href="http://roller.anthonyeden.com/page/chiara/20030121"&gt;Chiara&lt;/a&gt;, &lt;a href="http://freeroller.net/page/cbeust/20030121"&gt;Cedric&lt;/a&gt; and &lt;a href="http://crazybob.org/roller/page/crazybob/20030119"&gt;Crazy Bob&lt;/a&gt; have been debating the merits of pair programming.      I have never done formal pair programming - I imagine I would have a very hard time with it, as I am very particular about my environment and my conventions (and I would probably have to sit on my hands to avoid having a seizure if forced to watch someone who didn't use an IDE or who was a slow typist).   

Nonetheless, I have several peers that I respect a great deal that I regularly sit with for intervals when resolving outstanding design issues or particular problems.   I remember one 2-3 month timeframe where a friend and I would grab our laptops and go into a big conference room (with plenty of whiteboard) and sit side by side (each with our own machines) and work on the same system.   We'd regularly stop and discuss important topics (and draw diagrams on the whiteboard), and occasionaly we'd even sit at the same machine for a few minutes to flesh out a particularly cloudly or difficult area, but once we were both on the same page vision-wise, we'd fan out again (each on our own machines).   We regularly reviewed (and used) each others code.    I enjoyed it a lot and we were extremely effective in that arrangement - much more so than if we had to share a machine.

I think the important thing that comes out of pair programming is communication and review.   You can cultivate an environment which promotes these principals without mandating that people program in pairs.

For what its worth - I think &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0201699699/ref=pd_sr_ec_ir_/002-6821572-0761623"&gt;Cockburn's Agile Software Development Book&lt;/a&gt; has some great observations on these things.   


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-390234995?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/390234995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/390234995'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_19_archive.html#390234995' title='A few thoughts on Optimization and the Joys of our Craft...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-87662897</id><published>2003-01-18T19:11:00.000-08:00</published><updated>2003-06-21T22:29:38.163-07:00</updated><title type='text'>My latest wireless experience</title><content type='html'>Just bought one of the new 802.11.G Linksys Wireless Routers and a corresponding network card for my laptop.&lt;p/&gt;

&lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/B00007KDVI/qid=/br=1-/ref=br_lf_e_//102-1713923-2330547?v=glance&amp;amp;amp;amp;s=electronics&amp;amp;amp;amp;n=598262"&gt; link on Amazon&lt;/a&gt;&lt;p/&gt;

I must say - its pretty cool.  &lt;p/&gt;

I have noticed one annoying thing though.  Everytime our cordless phone rings, I lose my network connection.   We have 2 Panasonic 2.4 Ghz cordless phones in the house which operate on the same radio spectrum as does the 802.11.g standard.&lt;p/&gt;

All in all - I'm pleased though.  On my current project - it takes about 40 minutes to do a complete rebuild + execute all of the build verification tests (load the database, deploy the newly built app, run the suite of junit tests).&lt;p/&gt;

I've found that I can now grab the latest from the CVS repository and then kick off one of these big mama builds (with the laptop downstairs in the main kitchen area).  I can do my thing downstairs while still keeping tabs on the build...&lt;p/&gt;

Heck, I guess I could even take the laptop to the bathroom with me now.... Hmmm....&lt;p/&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-87662897?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87662897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87662897'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_12_archive.html#87662897' title='My latest wireless experience'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-87601855</id><published>2003-01-17T10:47:00.000-08:00</published><updated>2003-06-21T22:30:03.543-07:00</updated><title type='text'>A little known law of Physics</title><content type='html'>A little known law of Physics (that I seem rather fond of demonstrating):&lt;p/&gt;

&lt;i&gt;"The more insignificant you think your change is, the more likely it is to break the build."&lt;/i&gt;&lt;p/&gt;

Imagine - You've just finished integrating your latest round of major changes. Its 2:50 AM, and after 30 minutes of waiting around, you proudly note that all 287 JUnit tests have successfully passed. You commit all of your changes and are just about to call it a night, when you see a silly little error that you could easily fix. What the heck, you make the change, verify it with a few Junit tests which pertain to that package, and commit the lone remaining file. You stumble off to bed and call it a night...&lt;p/&gt;

Of course you're tiny little change has had unforseen consequences on some other area and you've just doomed the forthcoming build.&lt;p/&gt;

You'd think I'd learn after a while...&lt;p/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-87601855?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87601855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87601855'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_12_archive.html#87601855' title='A little known law of Physics'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-87601693</id><published>2003-01-17T10:44:00.000-08:00</published><updated>2003-06-21T22:30:28.763-07:00</updated><title type='text'>JBoss 3.0.5 is out...</title><content type='html'>Looks like it contains quite a few bugfixes :&lt;p/&gt;

      &lt;a href="http://sourceforge.net/project/shownotes.php?release_id=129789"&gt;Release notes&lt;/a&gt;&lt;p/&gt;

We had some wierd classloader exceptions with our JAAS stuff (had to serialize/de-serialize to get around them), perhaps this will fix it.&lt;p/&gt;

Woo-hoo, time to upgrade...&lt;p/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-87601693?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87601693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87601693'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_12_archive.html#87601693' title='JBoss 3.0.5 is out...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-87598259</id><published>2003-01-17T09:25:00.000-08:00</published><updated>2003-06-21T22:31:15.943-07:00</updated><title type='text'>Layering Strategies in J2EE Systems:</title><content type='html'>I wanted to take a poll on what people thought about layering strategies for J2EE systems. On my current project, we have been following the layering strategy outlined in the EJB Design Patterns book (see excerpt from our coding standards document below).&lt;p/&gt;

In a nutshell, for each service based component, we partition into the following layers (there are two others related to presentation or application layer things, but these are irrelevant to this discussion).&lt;p/&gt;
&lt;UL&gt;
   &lt;LI&gt;Persistence&lt;/li&gt;&lt;LI&gt;Domain&lt;/li&gt;&lt;LI&gt;Services&lt;/li&gt;
&lt;/ul&gt;
Do you guys try to maintain insulation of your domain layer from your services layers for J2EE systems??? We've come across several instances where it makes sense for the domain layer of one component to know about the services layer of another component. In some cases, we've even run across instances where it makes sense for a domain layer of Component A to know about the services layer of Component A (or at least to know about services that end up being exposed via its service layer)&lt;p/&gt;

This type of scenario makes me want to give in to the dark side and collapse the domain and services layer for that component into one layer.&lt;p/&gt;

Maybe this discussion hinges on the definition of the domain layer. We've tried to isolate as much of our business logic in our domain layer as possible. We're building a distributed system - in many cases the business logic for one component depends on a service provided by some sibling component (therein lies the rub).&lt;p/&gt;

BTW - you can get around the problem of "domain layer needing service layer" in a number of ways. For example : by defining interfaces in the domain layer that are implemented by classes in the service layer and using a factory to create them, but this really makes it seem like your jumping through a lot of hoops to hide the fact that your domain layer is dependent on your services layer (and using this solution, your domain layer code is still dependent on your service layer code at runtime). In this situation, wouldn't it make more sense to just collapse the two layers...?&lt;p/&gt;

I feel like we've expended a lot of effort to maintain this isolation, and am wondering if we haven't made things harder than they have to be. Here's an excerpt from the coding standards document on my current project:&lt;p/&gt;

Directory Structure and Build Outputs&lt;p/&gt;

We are following the layering strategy outlined in EJB Design Patterns (Marinescu, 2002). For details on this layering strategy, see chapters 6 and 7 from this book. For a free soft copy of this book, please see the following url :&lt;p/&gt;

&lt;a href="http://www.theserverside.com/books/EJBDesignPatterns/index.jsp"&gt;http://www.theserverside.com/books/EJBDesignPatterns/index.jsp&lt;/a&gt;&lt;p/&gt;

In short, any component can be decomposed into the following layers :&lt;p/&gt;

&lt;ul&gt;&lt;li&gt;persistence&lt;/li&gt;&lt;li&gt;domain&lt;/li&gt;&lt;li&gt;services&lt;/li&gt; &lt;li&gt;application&lt;/li&gt; &lt;li&gt;presentation&lt;/li&gt;&lt;/ul&gt;&lt;p/&gt;

NOTE: Not all components will requires each of these layers. For example, some components may have only a domain layer, many components will not have a presentation or application layer, etc. It would be common to see components with a persistence, domain and service layer.&lt;p/&gt;

For literal Java translation, we will use the following directory structure for layers which are included for a component :&lt;p/&gt;

ComponentX
&lt;ul&gt;
    &lt;li&gt;persistence&lt;/li&gt;&lt;ul&gt;&lt;li&gt;src&lt;/li&gt;&lt;li&gt;config&lt;/li&gt;&lt;li&gt;test&lt;/li&gt;&lt;/ul&gt;
    &lt;li&gt;domain&lt;/li&gt;&lt;ul&gt;&lt;li&gt;src&lt;/li&gt;&lt;li&gt;config&lt;/li&gt;&lt;li&gt;test&lt;/li&gt;&lt;/ul&gt;
    &lt;li&gt;services&lt;/li&gt;&lt;ul&gt;&lt;li&gt;src&lt;/li&gt;&lt;li&gt;config&lt;/li&gt;&lt;li&gt;test&lt;/li&gt;&lt;/ul&gt;
    &lt;li&gt;application&lt;/li&gt;&lt;ul&gt;&lt;li&gt;src&lt;/li&gt;&lt;li&gt;config&lt;/li&gt;&lt;li&gt;test&lt;/li&gt;&lt;/ul&gt;
    &lt;li&gt;presentation&lt;/li&gt;&lt;ul&gt;&lt;li&gt;docroot&lt;/li&gt;&lt;li&gt;src&lt;/li&gt;&lt;li&gt;config&lt;/li&gt;&lt;li&gt;test&lt;/li&gt;&lt;li&gt;src&lt;/li&gt;&lt;/ul&gt;
    &lt;li&gt;ide (optional)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;idea&lt;/li&gt;&lt;li&gt;jbuilder&lt;/li&gt;&lt;li&gt;etc.&lt;/li&gt;&lt;/ul&gt;
&lt;/ul&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-87598259?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87598259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87598259'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_12_archive.html#87598259' title='Layering Strategies in J2EE Systems:'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-87598236</id><published>2003-01-17T09:24:00.000-08:00</published><updated>2003-01-26T00:47:07.000-08:00</updated><title type='text'>Good Coding Music...</title><content type='html'>Picked up the latest Paul Oakenfold CD a week or so ago - Bunnka. If you like techno - you'll like Oakenfold.

He's the guy who did the SwordFish soundtrack.

Its good coding music....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-87598236?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87598236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87598236'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_12_archive.html#87598236' title='Good Coding Music...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-87598171</id><published>2003-01-17T09:23:00.000-08:00</published><updated>2003-06-21T22:33:12.850-07:00</updated><title type='text'>IDEA</title><content type='html'>I love IDEA. Its an order of magnitude better than any other IDE I've ever used, and I really think it does a good job of attacking the accidental complexity associated with software development.&lt;p/&gt;

Its the only IDE I've ever seen that makes the hardcore emacs or VI guys give up emacs/VI in favor of an IDE.&lt;p/&gt;

My favorite refactorings are : "Move/Rename", "Delegate", "Introduce Variable", "Move Members Up", etc.&lt;p/&gt;

I'm a real stickler for names. Often times I'll create a new class, and I don't feel good about the name I give it (but can't think of a good one at that time). It'll sit there in the back of my head and bug me until I fix it. Finally, I'll think of a more appropriate name and then go change it (this used to take some time - I'd have to search for everywhere it was used, rename it, fix the places I missed, etc). Not so with IDEA. Shift-F6, give it the new name, and move on. IDEA does the rest.&lt;p/&gt;

IMHO - This is an example of reducing the accidental complexity associated with software development. IDEA really helps to let you concentrate on the problem at hand (without losing your train of thought).   For example - you've got CTRL-B (go to definition) and CTRL-ALT-B (goto implementations). These are REAL timesavers. Another really great feature is the CTRL-Q feature (popup Javadoc for whatever it is you have your cursor on). Again - a perfect examploe of letting you keep you train of thought (instead of having to alt-tab out to a browser, go look for the link to XYZ class, etc).&lt;p/&gt;

ALT-F7 (Show Usages) is also indispensible.&lt;p/&gt;

If you're ever trying to understand what's going on in an open source tool like JBoss or Lucene, just create an IDEA project for it and start browsing. It makes my life so much easier. Thanks Intellij ;)&lt;p/&gt;

Speaking of IDEA - I wrote my first plugin the other day - its a plugin that will generate a new GUID and paste it at the current cursor location. Its available on the intellij.org plugins page (which has many extremely cool plugins) :&lt;p/&gt;

&lt;a href="http://www.intellij.org/twiki/bin/view/Main/GenerateGuidPlugin"&gt;http://www.intellij.org/twiki/bin/view/Main/GenerateGuidPlugin&lt;/a&gt;&lt;p/&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-87598171?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87598171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87598171'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_12_archive.html#87598171' title='IDEA'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-87598136</id><published>2003-01-17T09:22:00.000-08:00</published><updated>2003-06-21T22:32:36.283-07:00</updated><title type='text'>A great time...</title><content type='html'>A regular occurence in my day: I read random people's blogs and I discover some new and very cool open source tool I didn't known about previously.&lt;p/&gt;

I've been employed as a full-time software development professional for about 6 years now (and did non-professional for about 4 years before that).&lt;p/&gt;

Though this is a profound statement of the obvious : the open source movement simply rocks.
&lt;p/&gt;
I can think back to the first several projects I worked on after grad-school (back in '96 or so), and I don't think we used a single open source tool. Back then it seemed like I used to spend so much time just writing tools, building blocks, utilities, etc (none of which were ever open sourced, but many of which seemed to find there way along with me from project to project). I've always loved building horizontal, reusable stuff (probably more so than working on vertical customer specific logic).&lt;p/&gt;

What a stark contrast these days. There are so many wonderful open source tools and libraries at everyone's fingertips. Man that's great!!! I love Xerces and Xalan, Ant , JUnit, HttpUnit, and CruiseControl. Lucene simply rocks. Log4j is wonderful. JBoss has become my AppServer of choice. CVS, Bugzilla, Postgresql, MySQL, the list goes on and on.&lt;p/&gt;

These days - you can be up and running on a project so much quicker. You pick and choose the building blocks and tools you need, and then hit the ground running - concentrating on the specific problem at hand.&lt;p/&gt;

What a great time to be a software developer :)&lt;p/&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-87598136?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87598136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87598136'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_12_archive.html#87598136' title='A great time...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-4112415.post-87508634</id><published>2003-01-15T18:06:00.000-08:00</published><updated>2003-01-26T00:49:12.000-08:00</updated><title type='text'>Moved over to blogger...</title><content type='html'>Gonna switch my Blog to this site, FreeRoller's getting hammered lately...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4112415-87508634?l=lhankins.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87508634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4112415/posts/default/87508634'/><link rel='alternate' type='text/html' href='http://lhankins.blogspot.com/2003_01_12_archive.html#87508634' title='Moved over to blogger...'/><author><name>Lance Hankins</name><uri>http://www.blogger.com/profile/08546769472856541729</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>
