<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Megatome &#187; Development</title>
	<atom:link href="http://www.megatome.com/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.megatome.com</link>
	<description>Just another idiot&#039;s ramblings</description>
	<lastBuildDate>Thu, 12 Jan 2012 00:45:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Open PDF in New Window with Seam</title>
		<link>http://www.megatome.com/2009/10/12/open-pdf-in-new-window-with-seam/</link>
		<comments>http://www.megatome.com/2009/10/12/open-pdf-in-new-window-with-seam/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 18:35:15 +0000</pubDate>
		<dc:creator>iamthechad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[Making]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[pdf]]></category>
		<category><![CDATA[seam]]></category>

		<guid isPermaLink="false">http://www.megatome.com/?p=76</guid>
		<description><![CDATA[A simple method to open PDFs in a new window while displaying validation errors in the original window. The PDF window will not open if there are validation or other messages.]]></description>
			<content:encoded><![CDATA[<p>For a recent Seam development project, I had the task of creating a PDF report from some user input and displaying the result in a new window.</p>
<p>Initially, I used a <code>&lt;h:commandLink/&gt;</code> with <code>target="_blank"</code>. This worked well until the user entered criteria that failed validation. The new window was still created, and the validation messages were shown in the new window. This was not a good solution, so after some research and experimentation I came up a solution that meets the following criteria:
</p>
<ul>
<li>Validation messages are shown in original window.</li>
<li>A new window is not created when there are validation messages.</li>
<li>A new window is not created when the entered criteria returns zero (0) results.</li>
</ul>
<h3>The Action Class</h3>
<p>For this example, the action class is very simple:</p>
<pre name="code" class="brush: java">
public String getReportURL() {
    return "/pdfpopup/reports/reportDisplay.seam";
}

// Getters and setters omitted

public List&lt;String&gt; getReportData() {
    return reportData;
}

public void doSearch() {
    // This is where the work would actually happen
    reportData = new ArrayList&lt;String&gt;();
    for (int i = 0; i < selectOneValue; i++) {
         reportData.add("Report Row " + (i + 1));
    }
    if (reportData.isEmpty()) {
        facesMessages.add("Report will be empty, not popping up");
    }
}
</pre>
<p>I added the <code>getReportURL()</code> method to the action because there may be occasions where the report URL differs based on criteria. In the application I worked on, we had to support PDF and Excel reports, so the method returned the correct URL.</p>
<p>The action simply takes the criteria specified on the JSF page and populates a list of results based on that criteria. The PDF generation page will access the list later.</p>
<h3>The JSF Page</h3>
<p>The JSF page looks like this:
</pre>
<pre class="brush:xml">
&lt;ui:define name="body">
  &lt;script type="text/javascript">
  //&lt;![CDATA[
  function showReport(conversationId) {
  if (document.getElementById("messages") != null) {
    return;
  }
  var reportWin = window.open('#{reportAction.reportURL}' + '?cid=' + conversationId);
  if (!reportWin) {
    alert("Could not open the report window. Please disable popup blocking for this website and try again.");
  }
  }
  // ]]&gt;
  &lt;/script>
  &lt;h:form id="generateReport">
  &lt;s:validateAll>
  &lt;h:panelGrid width="100%" columns="1" style="text-align: center; font-weight:bold; font-size: 12px">
    &lt;h:outputText value="Report Query"/>
  &lt;/h:panelGrid>
  &lt;h:panelGrid columns="2" border="0" frame="none" style="padding-top:30px;">
    &lt;h:outputLabel for="selectOneValue">Number of Output Rows&lt;/h:outputLabel>
    &lt;h:selectOneMenu id="selectOneValue" value="#{reportAction.selectOneValue}" required="true">
      &lt;f:selectItem itemLabel="Zero" itemValue="0"/>
      &lt;f:selectItem itemLabel="One" itemValue="1"/>
      &lt;f:selectItem itemLabel="Two" itemValue="2"/>
      &lt;f:selectItem itemLabel="Three" itemValue="3"/>
      &lt;f:selectItem itemLabel="Four" itemValue="4"/>
    &lt;/h:selectOneMenu>
    &lt;h:outputLabel for="startDate">Report Period:&lt;/h:outputLabel>
    &lt;h:panelGroup>
      &lt;rich:calendar id="startDate" enableManualInput="true"
        value="#{reportAction.startDate}" showWeeksBar="false" datePattern="MM/dd/yyyy"
        immediate="true" required="true" label="Report Start Date"/>
      &lt;h:outputLabel for="endDate">through&lt;/h:outputLabel>
      &lt;rich:calendar id="endDate" enableManualInput="true"
        value="#{reportAction.endDate}" showWeeksBar="false" datePattern="MM/dd/yyyy"
        immediate="true" required="true" label="Report End Date"/>
    &lt;/h:panelGroup>
    &lt;a4j:commandButton id="getReportLink" action="#{reportAction.doSearch}"
         value="Get Report" oncomplete="showReport('#{conversation.id}')"/>
  &lt;/h:panelGrid>
  &lt;/s:validateAll>
  &lt;/h:form>
&lt;/ui:define>
</pre>
<p>This is really the guts of the operation. When the <code>commandButton</code> is clicked, the <code>doSearch()</code> method will be executed. Once that call is complete, the <code>oncomplete</code> handler will be called. </p>
<p>The page template is configured so that any <code>FacesMessages</code> will be displayed in an element with id &#8220;<code>messages</code>&#8220;. If this element is present, we assume that either a validation error or no data message is being displayed and do not show the PDF. If the element is not present, everything is OK and we open the new window with the URL for the PDF. Note that it&#8217;s crucial to pass the conversation ID along so that the data loaded by the action will be visible to the page creating the PDF.
</p>
<h3>The PDF</h3>
<p>For completeness, here&#8217;s the sample page I&#8217;m using to create a PDF:</p>
<pre class="brush:xml">
&lt;p:document xmlns:p="http://jboss.com/products/seam/pdf"
   xmlns:ui="http://java.sun.com/jsf/facelets"
   xmlns:f="http://java.sun.com/jsf/core"
   title="Sample PDF Report">
&lt;f:facet name="header">
  &lt;p:font size="12">
    &lt;p:header borderWidthTop="0" borderWidthBottom="0.4" alignment="center">
      &lt;p:paragraph indentationLeft="50">REPORT HEADER&lt;/p:paragraph>
    &lt;/p:header>
    &lt;p:footer borderWidthTop="1" borderColorTop="black" borderWidthBottom="0" alignment="center">
      [&lt;p:pageNumber/>]
    &lt;/p:footer>
  &lt;/p:font>
&lt;/f:facet>
&lt;ui:repeat var="item" value="#{reportAction.reportData}">
  &lt;p:font size="8">
    &lt;p:table columns="1" headerRows="1" widthPercentage="100">
      &lt;p:font style="bold">
        &lt;p:cell verticalAlignment="bottom">Report Data&lt;/p:cell>
      &lt;/p:font>
      &lt;p:cell>#{item}&lt;/p:cell>
    &lt;/p:table>
  &lt;/p:font>
&lt;/ui:repeat>
&lt;/p:document>
</pre>
<h3>Full Sample Code</h3>
<p>You can view and download the full sample code for this solution from <a href="https://github.com/iamthechad/pdfpopup">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.megatome.com/2009/10/12/open-pdf-in-new-window-with-seam/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Phone Screen Works Both Ways</title>
		<link>http://www.megatome.com/2009/09/08/the-phone-screen-works-both-ways/</link>
		<comments>http://www.megatome.com/2009/09/08/the-phone-screen-works-both-ways/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 21:06:08 +0000</pubDate>
		<dc:creator>iamthechad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Living]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[interview]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jobs]]></category>

		<guid isPermaLink="false">http://www.megatome.com/?p=74</guid>
		<description><![CDATA[A phone screen is typically used to screen applicants for a job, but it gave me enough information to make a decision about not wanting to work for the company.]]></description>
			<content:encoded><![CDATA[<p>I recently applied for a position through a recruiting service. I jumped through the requisite hoops and was told that the prospective employer was very excited to talk to me.</p>
<p>The standard procedure for this employer is to give candidates a simple phone screen before arranging an interview. Personally, I feel that having one person make a decision about whether or not I&#8217;ll &#8220;fit well with the team&#8221; after 10 minutes on the phone is ludicrous, but that&#8217;s the game I had to play.</p>
<p><a href="http://www.flickr.com/photos/nichollsphotos/2906834393/"><img src="http://farm4.static.flickr.com/3254/2906834393_e4ef4ae70e_m.jpg" alt="Tin Can Phone" style="float:right; margin: 5px"/></a></p>
<p>During the phone call, I was asked several generic questions about Java. I gave what I felt was correct answers to the questions, but the interviewer wasn&#8217;t happy with my results. Every time I answered a question, I heard &#8220;Well, I was looking for&#8230;&#8221;, with the expected answer simply being a different wording of what I had said.</p>
<p>I chalked this up to the interviewer simply being used to different terminology than I for the same concepts, so I was a bit surprised when I wasn&#8217;t called in for an in-person interview. It wasn&#8217;t until a few days later that I realized that the answers I was expected to give told me quite a bit about the company, and that I wouldn&#8217;t have been happy working there had I been offered the job.</p>
<p>The particular question that stuck in my mind was a simple one. &#8220;What are some of the benefits of the introduction of generics in Java, especially in collections?&#8221;</p>
<p>I gave the answer that pretty much anybody familiar with Java generics would give: compile-time type checking, no need for casting objects, etc. What I got from the interviewer was &#8220;Well, I was looking for the fact that you don&#8217;t have to do <code>instanceof</code> checks all over any more.&#8221;</p>
<p>On the surface, this may seem like another way of saying what I said, but it&#8217;s actually quite different.</p>
<p>Before generics, you would need to cast objects to the proper class when retrieving them from a collection. This does not mean that you would be using <code>instanceof</code> to do this. The only situation I can think of that requires using <code>instanceof</code> with a collection is if there are a lot of heterogenous objects in the collection.</p>
<p>There are limited situations where storing different object types in the same collection makes sense. Most of the time, however, this is a sign of either lazy development or not understanding the collection mechanism very well.</p>
<p>
<a href="http://www.flickr.com/photos/davesag/8519770/"><br />
<img src="http://farm1.static.flickr.com/8/8519770_e9043bc645_m.jpg" alt="More Bad Code" style="float:left;margin:5px"/></a></p>
<p>It&#8217;s generally a good idea to only put one type of object into a collection. This makes it much easier to work with and avoids any need for <code>instanceof</code> checks. By &#8220;one type of object&#8221;, I don&#8217;t mean that all of the objects need to be the exact same class. Chances are good that all of the objects being placed into a collection have some relationship; perhaps they will all implement the same interface.</p>
<p>I may have completely misinterpreted the interviewer, but I have a very strong impression that he and perhaps others on his team are used to using collections as grab bags of widely different things. Personally, I wouldn&#8217;t want to maintain that code. I can hope that the addition of generics to Java has forced the interviewer to change at least one practice for the better. I&#8217;m glad I wasn&#8217;t called in for the job &#8211; who knows how many more &#8220;well, at least it works&#8221; practices are being followed? I&#8217;ve got enough of those at my current job; I don&#8217;t need to learn a new set.</p>
<p>Images:</p>
<p>Tin Can:
<div xmlns:cc="http://creativecommons.org/ns#" about="http://www.flickr.com/photos/nichollsphotos/2906834393/"><a rel="cc:attributionURL" href="http://www.flickr.com/photos/nichollsphotos/">http://www.flickr.com/photos/nichollsphotos/</a> / <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/2.0/">CC BY-NC-ND 2.0</a></div>
<p>Java Code:</p>
<div xmlns:cc="http://creativecommons.org/ns#" about="http://www.flickr.com/photos/davesag/8519770/"><a rel="cc:attributionURL" href="http://www.flickr.com/photos/davesag/">http://www.flickr.com/photos/davesag/</a> / <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC BY-NC-SA 2.0</a></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.megatome.com/2009/09/08/the-phone-screen-works-both-ways/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make It A Good Day</title>
		<link>http://www.megatome.com/2009/01/14/make-it-a-good-day/</link>
		<comments>http://www.megatome.com/2009/01/14/make-it-a-good-day/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 04:02:45 +0000</pubDate>
		<dc:creator>iamthechad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Health]]></category>
		<category><![CDATA[leadership]]></category>
		<category><![CDATA[Living]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[anxiety]]></category>
		<category><![CDATA[attitude]]></category>

		<guid isPermaLink="false">http://www.megatome.com/?p=63</guid>
		<description><![CDATA[Don't just wait for a good day to "happen". I've been able to make some attitude changes and make good days.]]></description>
			<content:encoded><![CDATA[<p>Back when I used to work out regularly, there was an older gentleman who was usually changing in the locker room at the same time as me. We would make small talk as people do to be polite. He might have told me his name; I don&#8217;t remember very much about him now.</p>
<p>The one thing that makes this man stand out in my memory is that whenever we parted ways, he would say &#8220;make it a good day&#8221;. I usually said &#8220;you, too&#8221;, or something similarly uninspired.</p>
<p>What he was saying finally struck me one day. He was not telling me to have a good day. He was telling me to make it a good day.</p>
<p>As nice as the sentiment sounded, I didn&#8217;t really see how it applied to me. My job sucked, and it was causing me all kinds of stress &#8211; even to the point of <a href="http://www.megatome.com/2006/09/14/burned-out/">visiting the emergency room</a>. I experienced a lot of anxiety and had a few panic attacks.</p>
<p>I got to the point where I reacted badly to everything that happened at work. I can remember telling my manager more than once that decisions made by upper management were going to cause me to have to take another trip to the hospital. He finally got tired of my complaining and told me that work was not causing me stress; it was my reaction to work that was causing stress. That was not the answer I was looking for, so I added him to my mental list of stressors.</p>
<p>Fast forward a couple of years to a new job. As I&#8217;ve <a href="http://www.megatome.com/2008/12/10/moving-to-agile-inertia/">mentioned before</a>, I&#8217;m now leading a pilot project using an agile process (Scrum). For the first several iterations everything annoyed me. My developers couldn&#8217;t follow simple instructions. They couldn&#8217;t write good code. They had to be constantly prodded to keep them going. Every day had its share of &#8220;what now?&#8221; moments.</p>
<p>For some reason I started thinking about the man at the gym again. This time, it paired perfectly with my old manager&#8217;s advice. Despite my annoyances, work continued to get done and things were working. It wasn&#8217;t the work that was bothering me. It was my reaction to work.</p>
<p>I&#8217;ve been trying to be very mindful of how I&#8217;m reacting to things at work. I still get pulled in a lot of different directions, and I&#8217;m still having trouble getting my team involved in the process. What I&#8217;m not doing is worrying about it. I&#8217;m learning to be more aggressive about my time management. Instead of wondering why my team can&#8217;t grasp simple process concepts, I&#8217;m asking them how I can explain or demonstrate it better.</p>
<p>Don&#8217;t get me wrong. There are a million things I&#8217;d like to change about my environment and my team every day, but instead of waiting for a good day to just &#8220;happen&#8221; to me, I&#8217;m becoming an active participant and &#8220;making it a good day&#8221;.</p>
<p>In the last several weeks, I&#8217;ve noticed that my anxiety level has plummeted, my stomach is not upset every day, and I&#8217;m sleeping better. That&#8217;s good enough for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.megatome.com/2009/01/14/make-it-a-good-day/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Amazon Wishlists with Yahoo! Pipes</title>
		<link>http://www.megatome.com/2009/01/05/amazon-wishlists-with-yahoo-pipes/</link>
		<comments>http://www.megatome.com/2009/01/05/amazon-wishlists-with-yahoo-pipes/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 22:05:23 +0000</pubDate>
		<dc:creator>iamthechad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[goodies]]></category>
		<category><![CDATA[Making]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[pipes]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[wishlist]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[yahoo pipes]]></category>

		<guid isPermaLink="false">http://www.megatome.com/2009/01/05/amazon-wishlists-with-yahoo-pipes/</guid>
		<description><![CDATA[Using Yahoo! Pipes to deliver Amazon wishlists as RSS. Get the pipe at http://pipes.yahoo.com/iamthechad/amazonrsswishlist]]></description>
			<content:encoded><![CDATA[<p>A couple of years ago, I switched away from using Amazon to host my wishlists. I mainly wanted to be able to add things to my list that weren’t available through Amazon. The current holiday season has shown me, however, that most people know how to use Amazon and other wishlists are apparently too complicated to use.</p>
<p>Amazon has added the ability to add third party items to wishlists, so I figured I could move back with little difficulty. One thing I quickly discovered was that I  couldn’t syndicate my list through <a href="http://www.whatisrss.com/">RSS</a> directly from Amazon. Some searching later, I found what appeared to be the answer: <a href="http://pipes.yahoo.com/edkohler/edsamazonrsswishlist">Ed’s Amazon RSS Wishlist</a>. It looked to be exactly what I was looking for, except for one small problem – it didn’t work.</p>
<p>I had never used either <a href="http://pipes.yahoo.com/pipes/">Yahoo! Pipes</a> or the <a href="http://aws.amazon.com/">Amazon Web Services</a> API before, but this looked like a good opportunity. I cloned Ed’s pipe and began updating the calls to work with version 4.0 of Amazon’s <a href="http://docs.amazonwebservices.com/AWSEcommerceService/4-0/">ECommerce Service (ECS)</a>.</p>
<p>Working with Yahoo! Pipes turned out to be quite a bit of fun, and the Amazon API is well documented. Output from my modified pipe can be seen at the bottom of this post.</p>
<p>If you’d like to use my pipe to create an RSS feed for your own Amazon wishlists, you can find it here: <a href="http://pipes.yahoo.com/iamthechad/amazonrsswishlist">http://pipes.yahoo.com/iamthechad/amazonrsswishlist</a></p>
<p><script src="http://pipes.yahoo.com/js/listbadge.js">{"pipe_id":"2cf061872a743fadfca93e22bf3c7e83","_btype":"list","pipe_params":{"PageNumber":"1","WishhlistID":"3JTDR3A82TKG"}}</script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.megatome.com/2009/01/05/amazon-wishlists-with-yahoo-pipes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving to Agile: Inertia</title>
		<link>http://www.megatome.com/2008/12/10/moving-to-agile-inertia/</link>
		<comments>http://www.megatome.com/2008/12/10/moving-to-agile-inertia/#comments</comments>
		<pubDate>Thu, 11 Dec 2008 03:49:23 +0000</pubDate>
		<dc:creator>iamthechad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[leadership]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[inertia]]></category>
		<category><![CDATA[scrum]]></category>

		<guid isPermaLink="false">http://www.megatome.com/?p=48</guid>
		<description><![CDATA[Switching to an Agile process shines the light on a developer who has been successfully hiding his lack of work, but what can I do to change his behavior?]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been given the dubious honor of leading a team using Scrum as a &#8220;pilot&#8221; to see how well it works for the company. I&#8217;ve used Scrum before and had a good amount of success, so I feel comfortable with the process.</p>
<p>The single largest variable on any development team is the developers. I&#8217;ve found that moving to an Agile process like Scrum can really expose developers who&#8217;ve been hiding behind &#8220;traditional&#8221; processes.</p>
<p>Therein lies one of the biggest problems I&#8217;ve run into. One of my developers is not what you could by any means call a self starter. He has been able to get along well with the official process, which does not do a good job of tracking what developers are working on. Now that he&#8217;s been thrown into Scrum, it&#8217;s become quite obvious that he really doesn&#8217;t do anything until somebody nags him long enough to get him going.</p>
<p>This is where inertia comes in. This developer is a textbook example of an object staying at rest until the team lead can poke and prod enough to finally get him moving. His previous lead had simply taken it as granted that he would have to spend a certain amount of time micromanaging to get any work out of the developer. I think it&#8217;s a waste of time and energy for me to constantly remind him to pick a task and work it, but that&#8217;s what I&#8217;ve been reduced to doing. This week, for example, it took two days of nagging to get him to perform a ten minute refactor. (I would have done the refactor myself, but I have to trust that my team can do their jobs, too.)</p>
<p>I don&#8217;t know how to engage this guy. I can spend time collecting data and create metrics, but I don&#8217;t think that&#8217;s an effective motivator. What I&#8217;d really like to see is a commitment to the team and to the project that leads into a desire to pull his fair share. I don&#8217;t even know if these are feelings I can engender in this developer.</p>
<p>Motivation is an issue for teams using any kind of development process. Every team member reacts differently to various inputs. Some members like recognition, while others prefer a bonus. Some just want to be left alone so they can do the bare minimum to get by. I&#8217;m hoping this isn&#8217;t the eventual outcome with this developer.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.megatome.com/2008/12/10/moving-to-agile-inertia/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Known Defects and FindBugs</title>
		<link>http://www.megatome.com/2008/05/30/known-defects-and-findbugs/</link>
		<comments>http://www.megatome.com/2008/05/30/known-defects-and-findbugs/#comments</comments>
		<pubDate>Fri, 30 May 2008 16:41:16 +0000</pubDate>
		<dc:creator>iamthechad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Making]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[annotation]]></category>
		<category><![CDATA[characterization test]]></category>
		<category><![CDATA[findbugs]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[knowndefect]]></category>
		<category><![CDATA[legacy]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.megatome.com/2008/05/30/known-defects-and-findbugs/</guid>
		<description><![CDATA[(Download KnownDefects) I ran into a bit of a quandary the other day. I had to modify a piece of legacy code in our system &#8211; one that has no tests written against it. My first task was to write as many JUnit tests as I could to document the behavior of the component to [...]]]></description>
			<content:encoded><![CDATA[<p>(<a href="http://subversion.megatome.com/projects/KnownDefects/trunk/KnownDefect.zip">Download KnownDefects</a>)  </p>
<p>I ran into a bit of a quandary the other day. I had to modify a piece of legacy code in our system &#8211; one that has no tests written against it. My first task was to write as many <a href="http://www.junit.org/">JUnit</a> tests as I could to document the behavior of the component to help ensure that I didn&#8217;t break existing functionality with my changes.  </p>
<p>After a few tests, however, I began to notice something troubling. The component I was writing tests against had some bugs in it, and in order to make my unit tests pass, I had to code to those bugs. This in itself did not bother me too much, since I had no expectation that the component I was testing was error-free.  </p>
<p>What bothered me is that unit tests are often the best documentation of how a system works, and I would be creating misleading documentation. So, I did what anyone in this situation would do: I emailed <a href="http://langrsoft.com/">someone a lot smarter than me</a>.&nbsp; </p>
<p>The reply email contained several suggestions, all of which I plan to implement. The first suggestion is to carefully name the test methods to make it clear which ones work because of defects. The second suggestion is to create an annotation that can be added to a method to indicate that it works because of a defect, coupled with some way to report on all uses of the annotation.  </p>
<p>After a few hours of coding, I&#8217;m happy to announce that I&#8217;ve created a Java annotation named <code>KnownDefect</code> as well as a detector plugin for <a href="http://findbugs.sourceforge.net/">FindBugs</a> to collect all of the annotation instances.  </p>
<p>In the parlance of &#8220;<a href="http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1212164658&amp;sr=1-1">Working Effectively with Legacy Code</a>&#8220;, I have been creating &#8220;<a href="http://www.artima.com/weblogs/viewpost.jsp?thread=198296">characterization tests</a>&#8220;. These tests look like normal unit tests, but they document the current state of the system, warts and all. Using the <code>KnownDefect</code> annotation helps make the warts stick out better.  </p>
<p>Here&#8217;s an example:  </p>
<p>
<pre name="code" class="brush: java">public void testValidateNullResponse() {
   try {
      ProtocolParser.validateResponse(null);
      fail();
   } catch (InvalidRequestException expected) {
      // Caught expected exception
   }
}</pre>
</p>
<p>This test documents the system as it currently exists, but the behavior is obviously not correct. The <code>ProtocolParser</code> class should be throwing an <code>InvalidResponseException</code>, not an <code>InvalidRequestException</code>. To document this defect, I change the method name and add the <code>KnownDefect</code> annotation to the test method, resulting in the following:
</p>
<p>
<pre name="code" class="brush: java">@KnownDefect("Should throw InvalidResponseException")
public void testValidateNullResponseShowsKnownDefect() {
   try {
      ProtocolParser.validateResponse(null);
      fail();
   } catch (InvalidRequestException expected) {
      // Caught expected exception
   }
}</pre>
</p>
<p>The correct behavior is now documented, and the test still passes.
</p>
<p>Instead of writing a new tool to manage the <code>KnownDefect</code> instances, I ended up writing a new plugin for FindBugs. The FindBugs detector will collect all instances of the annotation and group them under the &#8220;Correctness&#8221; heading so they&#8217;re all in one place. Bug reports can then be created and the defects fixed or not as business needs dictate. (Sadly, the FindBugs plugin for Eclipse does not find the annotation in Groovy code. The standalone version of FindBugs works fine, so I assume there&#8217;s a resource filtering issue with the Eclipse plugin.)</p>
<p>Instructions for using the annotation and the detector are included in the download file. Try it out &#8211; hopefully it will be useful to somebody other than myself.</p>
<p>(<a href="http://subversion.megatome.com/projects/KnownDefects/trunk/KnownDefect.zip">Download KnownDefects</a>) (Subversion: <a href="http://subversion.megatome.com/projects/KnownDefects/trunk">http://subversion.megatome.com/projects/KnownDefects/trunk</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.megatome.com/2008/05/30/known-defects-and-findbugs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Is Refactoring Really That Scary?</title>
		<link>http://www.megatome.com/2008/03/27/is-refactoring-really-that-scary/</link>
		<comments>http://www.megatome.com/2008/03/27/is-refactoring-really-that-scary/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 03:45:08 +0000</pubDate>
		<dc:creator>iamthechad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[leadership]]></category>
		<category><![CDATA[Making]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://www.megatome.com/2008/03/27/is-refactoring-really-that-scary/</guid>
		<description><![CDATA[I got admonished at my new job for coding practices that have become second nature to me. Is aggressive refactoring really that scary?]]></description>
			<content:encoded><![CDATA[<div class="floatleft"><a href="http://www.cafepress.com/agilestuff.26911153"><img src="http://images.cafepress.com/product/26911153_240x240_Front_Color-BlackWhite.jpg" alt="Born to Refactor Shirt"/>
<p>(Click to get the shirt)</p>
<p></a></div>
<p>I&#8217;ve been coding with an agile mindset for quite some time now. Some practices have become second nature to me over the years. One of these practices is aggressive code refactoring, coupled with test driven development (TDD).</p>
<p>I&#8217;ve been adding new functionality to our system at my new job, and as usual I&#8217;ve been following my standard techniques. My part of the system involves handling certain requests and responses. I wrote unit and functional tests for the request half of the equation, then began to tackle the response side. As I added (and tested) functionality, I began to notice a large amount of similarity in the code. This in turn led me to create an abstract base class for both request and response, pulling up all of the shared functionality. This resulted in the actual request and response classes being quite small, with just a few method implementations from the base class.</p>
<p>So far, this activity should seem pretty normal to most developers. As I said, it&#8217;s pretty much second nature for me, and I don&#8217;t even remember consciously making the decision to make the abstract class. Imagine my surprise when my team lead admonished me for creating and abstract class, and warned me not to do it again without explicit approval.</p>
<p>Of course I had to ask why we would not refactor code in this manner when the opportunity presented itself. My lead&#8217;s answer involved several parts, none of which have convinced me that refactoring is bad:</p>
<p>
<ol>
<li><strong>The abstract class is not consistent with the rest of the system.</strong> This, to me, seems to be a fault of the system. I&#8217;m not knocking consistency, but at some point you have to realize that you may be building something that&#8217;s consistently bloated/overcomplicated/etc.</li>
<li><strong>The abstract class changes the design.</strong> Huh? Sure, if I go generate a UML diagram of the system, there&#8217;s going to be this abstract class and inheritance there. This is the only place the design is different. Requests and responses are being correctly handled just like the legacy ones in the system.</li>
<li><strong>Too much refactoring is bad, and each case should be thoroughly examined before code is changed.</strong> This is how religious wars start. My lead claims that developers start out on the &#8220;no refactoring&#8221; end of the spectrum, simply because they don&#8217;t know any better. Once they learn about refactoring, they then swing to the &#8220;refactor everything&#8221; end of the spectrum where anything and everything is a potential target. Seasoned, knowledgeable developers fall somewhere in the middle. I got the impression from this speech that my lead considers me to be on the radical end of the spectrum.</li>
</ol>
<p>Why are people like my lead so scared of refactoring? The arguments given really seem more like rationalizations than actual reasons &#8211; they don&#8217;t really stand up to scrutiny. I have a hard time believing, for example, that my lead truly thinks that the system is better because each request and response is a totally separate class, albeit with most of the code copied and pasted from one to the other. If anything, he should know that this approach leads to more problems, no matter how pretty it keeps the class diagrams.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.megatome.com/2008/03/27/is-refactoring-really-that-scary/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JUnit Just Wants To Be Your Friend</title>
		<link>http://www.megatome.com/2008/03/14/junit-just-wants-to-be-your-friend/</link>
		<comments>http://www.megatome.com/2008/03/14/junit-just-wants-to-be-your-friend/#comments</comments>
		<pubDate>Sat, 15 Mar 2008 03:02:57 +0000</pubDate>
		<dc:creator>iamthechad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[fail]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[unit tests]]></category>

		<guid isPermaLink="false">http://www.megatome.com/2008/03/14/junit-just-wants-to-be-your-friend/</guid>
		<description><![CDATA[My co-worker tests his code with the toString() and visual grep method. I'm not sure he would have ever caught the bug on his own. I keep trying to explain that unit tests are a Good Thing...]]></description>
			<content:encoded><![CDATA[<p>This is why you&#8217;re not allowed to have alcohol in the workplace.</p>
<p><strong>Co-Worker (who does not believe in unit tests)</strong>: Okay. I just checked my changes in.</p>
<p><strong>Me</strong>: There&#8217;s a bug in your code.</p>
<p><strong>Co-Worker</strong>: How do you know? I just checked it in!</p>
<p><strong>Me</strong>: It broke my unit tests. It looks like you&#8217;re not setting the flibbergibbet value correctly.</p>
<p><strong>Co-Worker</strong>: What? How can you tell?</p>
<p><strong>Me</strong>: <a href="http://www.junit.org/">JUnit</a> showed me the difference.</p>
<p><strong>Co-Worker</strong>: Oh. I guess I&#8217;ll fix it now. I would have found it eventually&#8230;</p>
<p>For what it&#8217;s worth, we&#8217;re handling <a href="http://en.wikipedia.org/wiki/Electronic_Data_Interchange">Electronic Data Interchange</a> documents &#8211; things that look like a page or so of line noise at a time. The bug was that one character wasn&#8217;t getting written to the output. My co-worker tests his code with the <code>toString()</code> and <a href="http://catb.org/jargon/html/V/vgrep.html">visual grep</a> method. I&#8217;m not sure he would have ever caught the bug on his own. I keep trying to explain that unit tests are a <a href="http://catb.org/jargon/html/G/Good-Thing.html">Good Thing</a>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.megatome.com/2008/03/14/junit-just-wants-to-be-your-friend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some Things To Remember When Running A Small Business</title>
		<link>http://www.megatome.com/2008/02/10/some-things-to-remember-when-running-a-small-business/</link>
		<comments>http://www.megatome.com/2008/02/10/some-things-to-remember-when-running-a-small-business/#comments</comments>
		<pubDate>Mon, 11 Feb 2008 04:49:13 +0000</pubDate>
		<dc:creator>iamthechad</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[leadership]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[practices]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[teams]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.megatome.com/2008/02/10/some-things-to-remember-when-running-a-small-business/</guid>
		<description><![CDATA[Several years ago, I worked for a small software shop. The company had gone through its number of growing pains, but seemed to be well established by the time I joined. Time would prove me wrong, and also give me some things to remember if ever I start my own small business.]]></description>
			<content:encoded><![CDATA[<p>Several years ago, I worked for a small software shop. The company had gone through its number of growing pains, but seemed to be well established by the time I joined. Time would prove me wrong, and also give me some things to remember if ever I start my own small business.</p>
<ol>
<li><strong>Watch your finances.</strong> We attended a conference shortly after I joined. We stayed at expensive hotels and spent several hundreds of dollars a night on dining out an entertainment. The company covered all costs. Overspending can lead to problems&#8230; </li>
<li><strong>Be careful how you cuts costs.</strong> About six months after the conference, it was determined that the company was not making as much money as expected and that cuts would need to be made. In order to avoid laying off anybody, salaries were cut. My salary was decreased by 50%, which imposed quite a hardship. We were promised that the cuts were only temporary, and that as soon as salaries returned to normal, we would be reimbursed for all of the money we lost. Which leads to the next point&#8230; </li>
<li><strong>Don&#8217;t lie to your employees.</strong> Turns out that the whole promise of reimbursement was just a pipe dream. I wasn&#8217;t too surprised by that. What surprised me was that the pay cuts were not equal, as I was told in the initial meeting. I actually took the highest cut &#8211; other employees took a 10-15% cut. I don&#8217;t care what kind of policies you have about keeping salaries secret; people will talk. If everybody is not getting the same treatment, tell them so and why. Of course, this behavior continued right on through the end of my employment&#8230; </li>
<li><strong>If you&#8217;re laying off employees, do it right.</strong> This does not mean telling an employee that he needs to take all of his vacation time, then take unpaid leave until things &quot;turn around&quot;. This goes back to my previous point &#8211; we both knew that there will be no turning around, and that it was a ploy to keep from having to pay me for accrued vacation while screwing me out of employment benefits since I wasn&#8217;t formally laid off. Also, remember that you&#8217;re running a business&#8230; </li>
<li><strong>Don&#8217;t play favorites.</strong> Oddly enough, I was the only one on my team who got pseudo laid off. The other team members were old friends of the CEO and owners. Coincidence? I think not. My team lead had a habit of not showing up until almost noon and leaving to &quot;work from home&quot; around 2 in the afternoon. This usually meant that he checked in whatever code he had when he left, more often than not breaking the build. Whenever he worked from home, he seemed to always have problems that would prevent him from receiving IMs or email. The end result was that the entire team would be stalled until he came in the next day. He had been given many warnings, but he also played golf with the CEO quite frequently, and I think the CEO allowed his personal feelings to get in the way of business decisions.
<p>I&#8217;m not saying &quot;Oh, poor me&quot; here. I had my share of friction with my managers, so I was not surprised to get the axe. (Post coming soon on why managers don&#8217;t like me.) I was surprised that a guy who flat out refused to do work that was assigned to him would get to stay.</p>
</li>
</ol>
<p>I got fed up and told the company to suck it up and lay me off. Luckily, I found a job within a couple of weeks and didn&#8217;t need to file for unemployment. A couple of weeks after I found my new job, the entire company went belly up. Maybe with better management and practices, the company would still be around. Maybe it was doomed from the beginning. Either way, I came away with some hard earned lessons that I won&#8217;t forget any time soon. I may not ever own a company, but many of these points apply just as well to managers and team leads.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.megatome.com/2008/02/10/some-things-to-remember-when-running-a-small-business/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data Calculator</title>
		<link>http://www.megatome.com/2006/08/23/data-calculator/</link>
		<comments>http://www.megatome.com/2006/08/23/data-calculator/#comments</comments>
		<pubDate>Wed, 23 Aug 2006 17:36:53 +0000</pubDate>
		<dc:creator>iamthechad</dc:creator>
				<category><![CDATA[Data Calculator]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[oss]]></category>
		<category><![CDATA[privacy]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sourceforge]]></category>
		<category><![CDATA[swipe]]></category>
		<category><![CDATA[toolkit]]></category>

		<guid isPermaLink="false">http://www.megatome.com/2006/08/23/data-calculator/</guid>
		<description><![CDATA[This has been a pet project of mine for a while, and I'm happy to announce that I can finally let everybody else see it.]]></description>
			<content:encoded><![CDATA[<p>This has been a pet project of mine for a while, and I&#8217;m happy to announce that I can finally let everybody else see it.</p>
<p>The <a href="http://turbulence.org/Works/swipe/main.html">Swipe Toolkit</a> is a neat collection of projects highlighting privacy issues. For some reason, <a href="http://turbulence.org/Works/swipe/calculator.html">their Data Calculator</a> really reached out to me. The only problem I saw was that the calculator was only a Flash application. I wanted something I could run locally, so I recreated the calculator as a Java application.</p>
<p>The nice people of the Swipe Project have given me permission to release my version as an Open Source project, so I&#8217;ve created a <a href="http://www.sourceforge.net/projects/datacalculator">new Sourceforge project</a> for the development.</p>
<p><strike>Right now, the only version available is for use with <a href="http://java.sun.com/products/javawebstart/">Java Web Start</a>. Head on over to the <a href="http://www.megatome.com/data-calculator">information page</a> and fire it up. Special versions, including installers, will be available soon for Windows, OS X, and hopefully Linux.</strike> In addition to the <a href="http://java.sun.com/products/javawebstart/">Java Web Start</a> version, there are now packages for Windows and OS X, as well as a generic source package. Go hit the <a href="http://www.megatome.com/data-calculator">main Data Calculator page</a> for the downloads.     <br /><a href="http://www.megatome.com/data-calculator">Data Calculator </a></p>
<p><!-- technorati tags begin --></p>
<p style="font-size: 10px; text-align: right">technorati tags:<a href="http://technorati.com/tag/privacy" rel="tag">privacy</a>, <a href="http://technorati.com/tag/swipe" rel="tag">swipe</a>, <a href="http://technorati.com/tag/toolkit" rel="tag">toolkit</a>, <a href="http://technorati.com/tag/open%20source" rel="tag">open source</a>, <a href="http://technorati.com/tag/OSI" rel="tag">OSI</a>, <a href="http://technorati.com/tag/sourceforge" rel="tag">sourceforge</a>, <a href="http://technorati.com/tag/java" rel="tag">java</a>, <a href="http://technorati.com/tag/data" rel="tag">data</a>, <a href="http://technorati.com/tag/personal" rel="tag">personal</a>, <a href="http://technorati.com/tag/security" rel="tag">security</a>, <a href="http://technorati.com/tag/data%20calculator" rel="tag">data calculator</a></p>
<p><!-- technorati tags end --></p>
<p style="font-size: 8px; text-align: right">Blogged with <a title="Flock" href="http://www.flock.com" target="_new">Flock</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.megatome.com/2006/08/23/data-calculator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

