<?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>Should Have Paid Me More &#187; Java</title>
	<atom:link href="http://shouldhavepaidmemore.com/category/technology/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://shouldhavepaidmemore.com</link>
	<description>Tales from the underpaid</description>
	<lastBuildDate>Sun, 29 Nov 2009 14:00:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The Do Not Click Button</title>
		<link>http://shouldhavepaidmemore.com/2009/the-do-not-click-button/</link>
		<comments>http://shouldhavepaidmemore.com/2009/the-do-not-click-button/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 19:15:03 +0000</pubDate>
		<dc:creator>spork</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Users]]></category>

		<guid isPermaLink="false">http://shouldhavepaidmemore.com/?p=151</guid>
		<description><![CDATA[It seemed only fitting to provide them with the one thing they couldn't screw up: the Do Not Click button.]]></description>
			<content:encoded><![CDATA[<p>Everyone&#8217;s seen at least one enormous red button with a label like &#8220;GLOBAL THERMONUCLEAR WAR INITIATOR VALVE &#8211; DO NOT PUSH!&#8221;, oui? Of course there&#8217;s always a villain around to press the button and ostensibly end the world, but the general concept prevails.</p>
<p>Given the tendency of Plus users to do the most illogical things possible while refusing to read or apply any kind of instructions given and then blame the software for behaving &#8220;unexpectedly&#8221;, it seemed only fitting to provide them with the one thing they couldn&#8217;t screw up: the Do Not Click button.<span id="more-151"></span></p>
<p>A lot of thought went into the Do Not Click button. Its placement was particularly important &#8211; it had to be accessible yet unobtrusive enough to go unnoticed for a while. The button itself had to be recognizable as capable of performing an action, yet simple enough to be overlooked by a casual glance. It had to display enough of a warning to be clear that clicking was ill-advised, yet low-key enough to beckon seductively. The final product is thus:</p>
<p><a rel="attachment wp-att-152" href="http://shouldhavepaidmemore.com/2009/the-do-not-click-button/donotclick/"><img class="aligncenter size-full wp-image-152" title="The Do Not Click Button" src="http://shouldhavepaidmemore.com/wp-content/uploads/2009/11/donotclick.png" alt="The Do Not Click Button" width="123" height="33" /></a>Fetching, no? It was placed at the very bottom of the About dialog, which I doubt anyone ever accesses unless by accident. If any one of the 150 users happens upon it, however, he&#8217;s all but guaranteed to email the other 149 to tell them about it. And <em>that&#8217;s</em> when the fun starts.</p>
<p>&#8220;What happens when the Do Not Click button is clicked?&#8221; one might ask curiously. Let me give you the most likely scenario:</p>
<blockquote><p><strong>User</strong>: &#8220;What&#8217;s this thing that looks like a stop sign with a white X in it? That looks weird. Wait, there are some hieroglyphs beside it&#8230;they say &#8216;d&#8217;&#8230;no, &#8216;D&#8217;&#8230;I&#8217;ve got it! It says &#8216;Do&#8217;! Phew, that was hard work. I&#8217;d better take a break so as not to strain myself.&#8221;</p>
<p>&lt;- four hours later -&gt;</p>
<p><strong>User</strong>: &#8220;Why is there a window that says &#8216;About&#8217; open? This stupid software, always doing things I don&#8217;t tell it to! I&#8217;m going to create a helpdesk ticket for IT to fix it! No, I should compose a poison-filled email about how crappy Plus is and how it&#8217;s always broken and send it to all of the other field technicians so they can join me in my uninformed griping!&#8221;</p>
<p>&lt;- two hours later -&gt;</p>
<p><strong>User</strong>: &#8220;All that typing made me hungry. I&#8217;m going to go to the expensive steakhouse down the road and charge a hefty three-course to my company credit card and then take a nap.&#8221;</p>
<p>&lt;- the next day -&gt;</p>
<p><strong>User</strong>: &#8220;Hmm, what&#8217;s this window that says &#8216;About&#8217;? There&#8217;s a button that has a stop sign with a white X in it. It doesn&#8217;t say what it does&#8230;&lt;click&gt; Nothing happened. &lt;click&gt; &lt;click&gt; &lt;CLICK&gt; Stupid Plus! How can I be expected to perform any work if this trashy program won&#8217;t do anything? Those idiots in IT are just trying to keep me from doing my job!&#8221;</p></blockquote>
<p>Sadly, this is probably a realistic depiction of events. However, the Do Not Click button <em>does</em> do something &#8211; it records the number of times it&#8217;s been clicked. Yes, that&#8217;s right &#8211; there&#8217;s a persisted click count. When the user submits work (which is supposed to happen once every few days), the cumulative click count is stored to a server-side database along with the user&#8217;s username. There it waits until an intranet-accessible web page is requested, wherein it&#8217;s included in a report showing the users clicking the Do Not Click button the most.</p>
<p>And here&#8217;s the best part: Any &#8220;bug&#8221; report about the Do Not Click button being broken can be closed with &#8220;The button works as intended. Do not click the Do Not Click button.&#8221; When the question of why the button exists comes up, the answer is &#8220;The button is there to keep an issue from occurring. When the button is clicked, the issue occurs. If the button is not clicked, the issue does not occur. This is why it says &#8216;Do Not Click&#8217; on the button.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://shouldhavepaidmemore.com/2009/the-do-not-click-button/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Change It Back!</title>
		<link>http://shouldhavepaidmemore.com/2009/change-it-back/</link>
		<comments>http://shouldhavepaidmemore.com/2009/change-it-back/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 18:13:14 +0000</pubDate>
		<dc:creator>spork</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Users]]></category>
		<category><![CDATA[coworkers]]></category>
		<category><![CDATA[plus]]></category>

		<guid isPermaLink="false">http://shouldhavepaidmemore.com/?p=142</guid>
		<description><![CDATA[He blamed me for "making changes without [his] knowledge".]]></description>
			<content:encoded><![CDATA[<p>Code comment written less than a month ago:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Added 10/7/2009 by specific request of sjohnson. Of course there's no HD
 * ticket or other documentation for the request because everyone knows
 * normal rules don't apply to the field staff.
 */</span></pre></div></div>

<p>Code comment written today:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Removed 11/5/2009 by specific request of sjohnson. Of course there's no HD ticket
 * or other documentation for the request because everyone knows normal rules don't apply
 * to the field staff. sjohnson swears this is a showstopper and must be removed because
 * now that he actually has to work in Plus on a daily basis he understands how
 * ridiculously foolish it is to clear out the time entry fields after every entry is
 * added to the table.
 */</span></pre></div></div>

<p><span id="more-142"></span>Mere days before a version of Plus was to be released, the manager in question demanded that the functionality be changed as it was &#8220;not the way the staff work&#8221;. He was made aware of the reason the product functioned the way it did and warned of the problems that would occur should his demand be met, but these logical beseechings fell upon deaf ears. He was given an opportunity (two full weeks) to test this change and he signed off on the final product. Almost exactly a month later, the manager had to take on the role of a field technician. As part of that, he had to use Plus, and blamed me for &#8220;making changes without [his] knowledge&#8221;.</p>
<p>This manager demanded that this and a second change be immediately coded and pushed into production as an &#8220;emergency&#8221; release&#8230;without any testing. He was warned of the expected problems of the second change and how testing helps ensure quality, but again he exhibited Deaf Man&#8217;s Vendetta. We&#8217;ll see how that turns out.</p>
<p><strong>Update</strong>: A week later (11/13/2009) the same manager went into another panic and demanded the functionality be reverted again, emailing &#8220;can you please verify and correct this issue immediately? This is the same issue we had in October!&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://shouldhavepaidmemore.com/2009/change-it-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jim&#8217;s Keys</title>
		<link>http://shouldhavepaidmemore.com/2009/jims-keys/</link>
		<comments>http://shouldhavepaidmemore.com/2009/jims-keys/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 18:49:09 +0000</pubDate>
		<dc:creator>spork</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Users]]></category>
		<category><![CDATA[coworkers]]></category>
		<category><![CDATA[plus]]></category>

		<guid isPermaLink="false">http://shouldhavepaidmemore.com/?p=106</guid>
		<description><![CDATA[He saw a set of blank data entry forms assigned to the new schedule instead of all the data he'd already entered under the old schedule.]]></description>
			<content:encoded><![CDATA[<p>Note: You may wish to read <a title="Jim's Comments" href="http://shouldhavepaidmemore.com/2009/10/02/jims-comments">Part I</a>, <a title="Jim's Themes and Dancing Monkeys" href="http://shouldhavepaidmemore.com/2009/10/08/jims-themes-and-dancing-monkeys">Part II</a>, <a title="Jim's Tables" href="http://shouldhavepaidmemore.com/2009/10/10/jims-tables/">Part III</a>, <a title="Jim's Tomcat Server" href="http://shouldhavepaidmemore.com/2009/10/17/jims-tomcat-server/">Part IV</a>, and <a title="Jim's Opus" href="http://shouldhavepaidmemore.com/2009/jims-opus/">Part V</a> of this series to gain context.</p>
<p>As relayed in previous posts in this series, the Plus application was meant to facilitate the transmission of data from field technicians to the home office. However, at some point it was decided that Plus should <em>also</em> be responsible for transmitting and displaying data from the home office to the field technicians. This information ended up being things like equipment-specific metadata, customer contact numbers, location of each piece of equipment, a directory of everyone employed at the company that developed Plus (no, I&#8217;m not kidding), and schedule data. All of this came from a poorly-standardized, non-normalized database used by the company&#8217;s CRM application, <a title="Clearview" href="http://www.nexterna.com/clearview" target="_blank">Nexterna Clearview</a>, which uses a batch-and-post system. <span id="more-106"></span></p>
<p>The schedule data was an important piece because it gave the field technicians a way to see scheduled work without having to use any brainpower. After adding this information to the Plus application the powers that be decided Plus should use it to automatically determine and display the appropriate data forms for the technician to fill out for each site visit. It was further decided that the forms themselves should dynamically change based on the equipment information from the CRM application.</p>
<p>Eventually this was all made ready and deployed to the field technicians. As usual, there were exclamations of &#8220;Wow, this is great!&#8221; and &#8220;This will make us so much more efficient!&#8221; at first. But soon the users started reporting problems. They&#8217;d enter data into a form and it would disappear the next time they downloaded schedule updates from the home office. It turned out Jim built Plus and the <a title="Jim's Tomcat Server" href="http://shouldhavepaidmemore.com/2009/jims-tomcat-server/" target="_blank">Plus server</a> to use auto-generated database record IDs as unique identifiers for schedule data. When a field technician entered form data, it was tied to the schedule&#8217;s database record ID. When the form data was sent to the home office, the Plus server displayed it to home office users by establishing a link between the schedule&#8217;s database record ID and the record ID in the returned data. In a normal world, this wouldn&#8217;t be a problem &#8211; using database keys guaranteed to be unique is good practice, right?</p>
<p>The issue came into play when one of the schedulers at the home office altered a schedule after a field technician had already used Plus to enter form data. The scheduler, called a &#8216;CSAM&#8217;, would change the schedule&#8217;s location, equipment, date, assigned technician, and even go so far as to delete the schedule altogether and create a new one in its stead. The next time the field technician used Plus, he saw a set of blank data entry forms assigned to the new schedule instead of all the data he&#8217;d already entered under the old schedule. In essence, data entered into Plus was &#8220;lost&#8221; due to the normal day-to-day operation of the CSAMs.</p>
<p>Later I found that there had been many a heated argument betwixt Jim and <a title="benson's profile" href="http://shouldhavepaidmemore.com/author/benson/" target="_blank">benson</a> about the use of auto-generated database record IDs as data keys. &#8220;That&#8217;s not how the users work!&#8221; benson would exclaim. &#8220;It&#8217;s the right way to do things!&#8221; Jim would shoot back. The end result was always the same &#8211; Jim would simply continue the way he wanted.</p>
<p>For quite some time people just blamed Plus for everything. &#8220;This stupid tool loses my data!&#8221; they&#8217;d gripe. &#8220;It eats my work!&#8221; Eventually I was able to show that a very small change to the existing CSAM scheduling process could avoid the majority of these situations, and the complaints changed to&#8230;well, they didn&#8217;t change at all. Everyone still made Plus the scapegoat, and the CSAM group refused to believe they could possibly have anything to do with the issues. Their leader wasn&#8217;t willing to even admit it was a possibility.</p>
<p>Finally I rewrote enormous chunks of the Plus application to use less volatile keys that mapped more directly to the way the users worked (vindication for you, <a title="benson's profile" href="http://shouldhavepaidmemore.com/author/benson/" target="_blank">benson</a>). Of course, at the same time the CSAM group finally conceded to make that one tiny change (it took the head of the company to get even that), and they&#8217;re taking credit for reducing the number of issues with Plus data. Oh well, only 11 more days&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://shouldhavepaidmemore.com/2009/jims-keys/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jim&#8217;s Tomcat Server</title>
		<link>http://shouldhavepaidmemore.com/2009/jims-tomcat-server/</link>
		<comments>http://shouldhavepaidmemore.com/2009/jims-tomcat-server/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 05:59:31 +0000</pubDate>
		<dc:creator>spork</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[coworkers]]></category>
		<category><![CDATA[plus]]></category>

		<guid isPermaLink="false">http://shouldhavepaidmemore.com/?p=92</guid>
		<description><![CDATA[The application just zipped the schedule data into a temp directory and sent the file path back to the client.]]></description>
			<content:encoded><![CDATA[<p>Note: You may wish to read <a title="Jim's Comments" href="http://shouldhavepaidmemore.com/2009/10/02/jims-comments">Part I</a>, <a title="Jim's Themes and Dancing Monkeys" href="http://shouldhavepaidmemore.com/2009/10/08/jims-themes-and-dancing-monkeys">Part II</a>, and <a title="Jim's Tables" href="http://shouldhavepaidmemore.com/2009/10/10/jims-tables/">Part III</a> of this series to gain context.</p>
<p>One of the prevailing requirements for <a href="http://shouldhavepaidmemore.com/2009/10/02/jims-comments/">the Plus application</a> was that it allow field staff to enter data offline and &#8220;sync&#8221; it over the Interwebs at their leisure. In addition, the application had to get updated schedule information and previously-synced data and show it to the user while offline. As you know, the most logical design that meets this requirement is a disconnected client-server model. Therefore, a server had to be built to accept connections from the client, process incoming data, and send back schedule  information and previously-synced data.<span id="more-92"></span></p>
<p>This by itself isn&#8217;t such a big deal, right? <a title="Tomcat" href="http://tomcat.apache.org/">Apache Tomcat</a> exists <em>just</em> for tasks of this nature. It&#8217;s an entire server container that&#8217;s mature, been heavily tested, well-maintained, and trusted by enormous companies that could easily afford to choose any server product on Earth. It includes all sorts of advanced configuration options, logging facilities, exception handling, and standards adherence. There&#8217;s even a Windows installer package available! Installation, configuration, and basic Java implementation is fast and easy.</p>
<p>But since this was Jim&#8217;s project, it wasn&#8217;t fast, easy, simple, logical, standards-based, or maintainable. Jim rolled his own Tomcat server instead. Yes, that&#8217;s right &#8211; he ignored the ready-built server software available and wrote his own software to do the same thing. However, his version didn&#8217;t have the benefit of testing&#8230;or configuration options&#8230;or exception handling&#8230;or standards compliance&#8230;or maintainability&#8230;or &#8211; well, you get the idea. As a result, Jim&#8217;s Tomcat didn&#8217;t really work.</p>
<blockquote><p>As anyone might imagine, the directory quickly grew and eventually consumed all disk space on the server, crashing it.</p></blockquote>
<p>Jim split the server implementation into two completely separate areas of the server itself. The actual application itself was only responsible for receiving client requests for schedule information &#8211; but not for sending the data itself back to the client. Instead, the application just zipped the schedule data into a temp directory and <strong>sent the file path</strong> back to the client. The client then connected to an SFTP server and downloaded the specified file. When the client needed to download previously-submitted data files, it connected to the same SFTP server, navigated to a hard-coded directory, and downloaded everything in it. Yes, that&#8217;s right &#8211; <strong>each user ended up downloading all data ever submitted by any of the 150 users every time the client updated</strong>. As anyone might imagine, the directory quickly grew and eventually consumed all disk space on the server, crashing it.</p>
<p>The <em>submission </em>of data, however, was handled by the client. The client connected to that same SFTP server, navigated to a hard-coded directory, and uploaded individual files to it. Then a cron job ran every 60 seconds, swept the directory, determined the type of each data file by matching the beginning of its filename, loaded the data into a database, and moved the files to the &#8220;submitted data&#8221; folder that every client downloaded. If a file couldn&#8217;t be read, the cron job died and any file not already loaded was left in the folder. The next time the cron job ran the same problem would occur&#8230;without any notification to anyone.</p>
<p>I inherited all of this when I was stuck with the Plus project. Had I known what I was getting into, I would&#8217;ve said &#8220;You&#8217;ve gotta pay me more.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://shouldhavepaidmemore.com/2009/jims-tomcat-server/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Insurolink Part I</title>
		<link>http://shouldhavepaidmemore.com/2009/insurolinki/</link>
		<comments>http://shouldhavepaidmemore.com/2009/insurolinki/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 19:39:45 +0000</pubDate>
		<dc:creator>rector</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://shouldhavepaidmemore.com/?p=79</guid>
		<description><![CDATA[Every time new code was added and changes were made, it broke everyone's local copies, and all the developers would play around with the code until one of them got it to compile.]]></description>
			<content:encoded><![CDATA[<p>A few years ago I interviewed with a regional insurance company for a &#8220;Senior Software Developer&#8221; position.    The application I would be working on was described as an Online application that allowed the companies agents to quote and sign business.  It was a &#8216;robust and flexible&#8217; system that had been developed and enhanced over 9 years.  The application was primarily developed by consultants (Boy THAT should have been a red flag), but the division was recently acquired by the regional insurance company and the new management wanted to do development in house.  I was to be the first of a dozen new hires.  I took the job.</p>
<p><span id="more-79"></span></p>
<p>On the first day, one of the contractors, Alicia,  was assigned to train me.   I should have known something was up when Alicia checked the code out and could not get it to compile.  She needed to go find Shaun, because &#8216;He had the working version&#8221;.  I asked, &#8220;Doesn&#8217;t everyone have a working version?&#8221;.  She replied, &#8220;No, Shaun does.&#8221;  It appeared that every time new code was added and changes were made, it broke everyone&#8217;s local copies, and all the developers would play around with the code until one of them got it to compile.  Then everyone would get that person to &#8216;recreate&#8217; what he/she did on their computers.</p>
<blockquote><p>Doesn&#8217;t everyone have a working version?</p></blockquote>
<p>Boy THAT should have been a red flag. Apparently, Shaun was the only person who could compile and deploy the code.  This week. Eventually, with Shaun&#8217;s help, the application was checked out of source control and compiled on my computer.  But for the next week, I saw PPT presentations of the &#8217;system design&#8217;, and code snippets on screen without actually having any interaction with the code.  When I finally pressed the point that I wanted a &#8216;walk through&#8217;, Alicia reluctantly agreed.  The application, being a J2EE implementation, was launched and the login page displayed.  Alicia then logged in using a test account and walked through the application, which bombed every other screen because &#8220;it can&#8217;t hit the service, you need to change the settings to point to a test service.&#8221;  Well, let&#8217;s do that, then&#8230;.</p>
<p>Fast forward ANOTHER week.  The application can finally run on my local machine, but there have been a half-dozen configuration changes to the local server, MANY changes to the local code, which, I am instructed to never check in, and any attempt to run the application in &#8216;debug&#8217; mode causes my laptop to freeze and crash&#8230;</p>
<p>Oh, and I saved the best part for last.  At some point during my &#8216;training&#8217;, I actually did look at the code.  I found the start of execution.  It was a Servlet.  It had over 2000 LOC in the doPost method.  It used reflection to dynamically instantiate dozens of other servlets who&#8217;s names and methods were contained in a Database.  It was the slowest running application on the planet.</p>
<p>I lasted 1 year exactly.  In that time dozens of developers were hired. Most left before me.</p>
<p>They really should have paid me more&#8230;.</p>
<p>Next, a glimpse into how this was coded.</p>
]]></content:encoded>
			<wfw:commentRss>http://shouldhavepaidmemore.com/2009/insurolinki/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
