<?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-12766970</id><updated>2011-07-07T13:01:40.255-07:00</updated><title type='text'>Wheel Workshop</title><subtitle type='html'>Pain, opinion and sometimes even enlightenment from a couple of guys working with Java and JSP. You know, a couple more nerds who feel they have to share their experiences with the J2EE platform.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-12766970.post-4475938440019135743</id><published>2007-06-06T09:26:00.000-07:00</published><updated>2007-06-06T10:14:48.647-07:00</updated><title type='text'>Why Are You Not Prepared for an Interview?</title><content type='html'>First off, I have to say this post is pointless. If you are reading it, then you obviously don't fall into the category being addressed.&lt;br /&gt;&lt;br /&gt;Why don't candidates prepare for stinking job interviews? Why do they lie so badly on their resumes?&lt;br /&gt;I'm trying to add 3 Java/J2EE developers to my team. I would think that if you are going to a Java job interview, you might Google for "&lt;a href="http://google.com/search?q=java+interview+questions"&gt;java interview questions&lt;/a&gt;" and actually read a few pages. From my experience, as a job candidate, you could probably pass most interviews even if you knew absolutely nothing by simply doing that.&lt;br /&gt;&lt;br /&gt;So, the simple rules for getting a job:&lt;br /&gt;&lt;br /&gt;     Don't put crap you don't know on your resume. You &lt;span style="font-weight: bold;"&gt;will&lt;/span&gt; be busted.&lt;br /&gt;&lt;br /&gt;     Don't put every damn technology you have ever touched on your resume. I will not think you are a "Jack of All Trades", I will more likely think you can't keep a job.&lt;br /&gt;&lt;br /&gt;     Write your resume so that it is focused on the job you are trying to get. If you are looking for J2EE work, leave off the VB, MS Access, etc... Stuff in the middle is ok, Ruby/PHP/Python. Being well rounded is good. Just don't give me the kitchen sink.  I know PHP, Perl, VB, I don't advertise it.&lt;br /&gt;&lt;br /&gt;     Be very careful about how you put "team projects" on your resume. I don't care what your &lt;span style="font-style: italic;"&gt;team&lt;/span&gt; did. I want to know what &lt;span style="font-weight: bold;"&gt;you&lt;/span&gt; have done. In an interview, the more I here the "&lt;span style="font-style: italic;"&gt;we&lt;/span&gt;" word, the less I think &lt;span style="font-weight: bold;"&gt;you&lt;/span&gt; personally have done.&lt;br /&gt;&lt;br /&gt;     Be able to write code. If I prepared to interview you (I probably didn't, I'm busy) I will simply make you write some code and ask you questions related to your future job, and completely ignore your resume (its full of lies anyway).&lt;br /&gt;&lt;br /&gt;     Be able to answer questions about &lt;span style="font-weight: bold;"&gt;everything&lt;/span&gt; on your resume. If I did not prepare (more likely), I will be shooting from the hip, and we will focus on your resume. My experience is pretty broad, I'll instantly know if you are feeding me crap.&lt;br /&gt;&lt;br /&gt;And here's the gist of things. Even if you don't really know anything, if you spend an hour with Google and the job description, you can gain enough knowledge to pass most interviews. Hell, if you've at least prepared for the interview, you are well ahead of most. Why can't candidates at least lie well?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-4475938440019135743?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/4475938440019135743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=4475938440019135743' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/4475938440019135743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/4475938440019135743'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2007/06/why-are-you-not-prepared-for-interview.html' title='Why Are You Not Prepared for an Interview?'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-5598401102663120055</id><published>2007-02-11T15:48:00.000-08:00</published><updated>2007-02-11T16:02:18.003-08:00</updated><title type='text'>Process Overkill, A Developer Strikes Back</title><content type='html'>Recently, all of the developers in my group were hauled off for 'process' training. The managers of the shop want to take us to CMMI level 3. Rather than rant about the process, I'm willing to give it a fair shake. They are looking for a some benefits from the certification that go beyond the actual software.&lt;br /&gt;&lt;br /&gt;Then the instructor then covered unit testing. He said that we'd need a test plan (script) document for each of our unit tests. Now, if you use TDD (test driven development) you are thinking, that could be hundreds, if not thousands of documents. Each of these documents is a MS Word doc that is a minimum of about 7 pages.&lt;br /&gt;&lt;br /&gt;After recovering from shock (and the first impulse to polish off the resume), my lazy developer instincts kick in. Thinks I, why not embed some extra meta-data into the JUnit tests. Combine this with a custom doclet, and I can be drinking coffee while the documents write themselves.&lt;br /&gt;&lt;br /&gt;With the custom doclet and metadata, I can generate an XML file that represents the information that needs to go into the test plan.&lt;br /&gt;&lt;br /&gt;There is one last piece to make this all come together. As of version 2003 of MS Word, there is this capability to save MSWord documents as XML (WordML). So, I put some place holder tags in the word file and save it as XML. Next, I open it in a text editor, wrap the document in &amp;lt;xsl:stylesheet&amp;gt; tags, and just run searches for the placeholders written earlier. The placeholders are replaced with XSL tags to generate the desired output.&lt;br /&gt;&lt;br /&gt;I put together a proof of concept. Calling the custom doclet from javadoc generates XML files. Running a transformer makes a WordML from the sham XSL document and the XML file. Woohoo.&lt;br /&gt;Finally, a highly motivated intern spots this and gets conned into perfecting the XSL file.&lt;br /&gt;&lt;br /&gt;Now to see the manager's face when I say that 700 test plans are ready to be reviewed....&lt;br /&gt;&lt;a href="http://technorati.com/claim/qzgqqu655e" rel="me"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-5598401102663120055?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/5598401102663120055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=5598401102663120055' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/5598401102663120055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/5598401102663120055'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2007/02/process-overkill-developer-strikes-back.html' title='Process Overkill, A Developer Strikes Back'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-114737448674260891</id><published>2006-05-11T11:53:00.000-07:00</published><updated>2006-05-11T12:23:29.496-07:00</updated><title type='text'>HTML DOM Attributes</title><content type='html'>Ok, to start with this post is just dumb but, I just wanted to add a snippet.&lt;br /&gt;This &lt;a href="http://www.webmonkey.com/06/19/index3a.html"&gt;reference&lt;/a&gt; brought up an issue I had dealt with before when creating DOM nodes in IE.&lt;br /&gt;Trying to set the css class with &lt;tt&gt;node.setAttribute("class",className);&lt;/tt&gt; basically does nothing while working on every other browser.&lt;br /&gt;The Chris' solution is to use a loop to find the attribute node and set the value. I think mine might be a bit less complex:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;function setAttribute&lt;span style="color: rgb(255, 0, 0);"&gt;(&lt;/span&gt;node,name,value&lt;span style="color: rgb(255, 0, 0);"&gt;){&lt;/span&gt;&lt;br /&gt;   var att = node.getAttributeNode&lt;span style="color: rgb(255, 0, 0);"&gt;(&lt;/span&gt;name&lt;span style="color: rgb(255, 0, 0);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;    if&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;(&lt;/span&gt;att&lt;span style="color: rgb(255, 0, 0);"&gt;){&lt;/span&gt;&lt;br /&gt;       att.value = value;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    }&lt;/span&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;else&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;{&lt;/span&gt;&lt;br /&gt;       node.setAttribute&lt;span style="color: rgb(255, 0, 0);"&gt;(&lt;/span&gt;name,value&lt;span style="color: rgb(255, 0, 0);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Update, an even easier way to set the css class:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;function setCssClass&lt;span style="color: rgb(255, 0, 0);"&gt;(&lt;/span&gt;node,className&lt;span style="color: rgb(255, 0, 0);"&gt;){&lt;/span&gt;&lt;br /&gt;   node.setAttribute&lt;span style="color: rgb(255, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;"class"&lt;/span&gt;,className,0&lt;span style="color: rgb(255, 0, 0);"&gt;)&lt;/span&gt;;&lt;br /&gt;   node.setAttribute&lt;span style="color: rgb(255, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;"className"&lt;/span&gt;,className,0&lt;span style="color: rgb(255, 0, 0);"&gt;)&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;was posted by &lt;a href="http://www.alistapart.com/comments/jslogging?page=#1"&gt;Chris Gillis&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-114737448674260891?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/114737448674260891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=114737448674260891' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/114737448674260891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/114737448674260891'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2006/05/html-dom-attributes.html' title='HTML DOM Attributes'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-114402738836751451</id><published>2006-04-02T18:04:00.000-07:00</published><updated>2006-04-02T19:02:18.690-07:00</updated><title type='text'>Recent excursion into Tagland</title><content type='html'>Recently I was working on a project dealing with content items that could be rated by a user (think Netflix style ratings). The forward most portion is relatively simple JavaScript that handles the mouseovers and click actions. There is of course the JSP which will render the page. In this instance, we're using a custom tag to render the rating block so a new tag class and appropriate entries in our existing custom TLD are required.&lt;br /&gt;&lt;br /&gt;For this, we used a different approach than I am used to.&lt;br /&gt;&lt;br /&gt;In the past, we typically used our custom tags for utility purposes- things like finding out if a user is signed in or retrieving string values from IDs, etc. Basically anything that keeps scriptlets out of the JSP and maintains a "pure" markup state. Any presentation was handled in the JSP and never in the tag class.&lt;br /&gt;&lt;br /&gt;What we did this time still keeps out scriptlets and maintains the preferred seperation of presentation from the class. Just differently.&lt;br /&gt;&lt;br /&gt;First, all of the pages are built from many different JSPs that all do very specific things. With this project, many sections not only look the the same, but act the same as well. For these sections, we opted to use custom tags to render them, passing in just the object and additional parameters (iconsize, in my case) needed to return a fully rendered and ready to use block of code.&lt;br /&gt;&lt;br /&gt;To do this we start with the basic custom tag setup in our TLD and write a new class that will handle all the heavy lifting involved in retrieving the rating for a given object for a given user. Now, we also write a second JSP that will be included into the servlet request by the DoStartTag method and this is what will actually perform the render. That is then returned back to the calling JSP and ta-da!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7875/344/1600/flow1.0.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer;" src="http://photos1.blogger.com/blogger/7875/344/400/flow1.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm sure this is not novel, and is not new either. But I bring it up here, not just because it's new to me, but because this method of custom tag creation has it's benefits and drawbacks.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;First, the benefits.&lt;/span&gt; The obvious one being the presentation is still coupled to the tag class, but is separate from it and you can change the display at will without ever having to go back into the class. Simple sounding, yes, but if you have a team of mixed Java devs and front-end devs, this can make for strong symbiosis and promote sanity.&lt;br /&gt;&lt;br /&gt;Another benefit is that it makes your error handling a lot easier, if you choose to you can do all of your checks in the class and set attributes you can then check in your JSP rather than sending values in and checking to see if they're null or not before acting on them. This can get unwieldily, but in most cases may be better than having the huge, ungainly, choose/when/otherwise blocks in the JSP.&lt;br /&gt;&lt;br /&gt;Reusability! Yes! I am a huge proponent of reusable front-end code. If you have a site with a bunch of yellow boxes, and all the boxes look and behave the same, there's no reason to have every developer build a new box for his or her assigned deliverables in their own way. There should be one way to render the yellow box. This method achieves that, and that's my number one reason for doing it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The biggest downside&lt;/span&gt; comes straight out of the best reason to use this method- reusability. Using our yellow box example, what happens if on one instance of the page the box should be red? Or has a header? Or a border? Or different content? Sure, you add more attributes to the tag to handle these off cases. And you will also get bit in the rear doing this, because every time you add one more level of complexity, you're changing not just the tag def, but the JSP that renders it and maybe even the other pre-existing calling JSPs as well (although, if authored well, probably not).&lt;br /&gt;&lt;br /&gt;Another "against" is keeping track of what file does what and where it lives. You don't want your calling JPS living in the same directories as your rendering JSPs, so you're probably going to create a new file structure to keep the tag JSPs. It's also a learning curve to anyone else who comes into your group that might not be familiar with writing custom tags in this manner.&lt;br /&gt;&lt;br /&gt;So what about you? Done this before? What do you think?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-114402738836751451?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/114402738836751451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=114402738836751451' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/114402738836751451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/114402738836751451'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2006/04/recent-excursion-into-tagland.html' title='Recent excursion into Tagland'/><author><name>R(k)</name><uri>http://www.blogger.com/profile/10478999294152077322</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><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-113925610732919398</id><published>2006-02-06T11:08:00.000-08:00</published><updated>2006-02-06T12:45:32.223-08:00</updated><title type='text'>Parsing currency into a BigDecimal</title><content type='html'>This is only slightly related to a previous post.&lt;br /&gt;To start off, one would think that a &lt;code&gt;DecimalFormat&lt;/code&gt; object just &lt;span style="font-style: italic;"&gt;might&lt;/span&gt; be able to parse a string into a &lt;code&gt;BigDecimal&lt;/code&gt; object. &lt;span style="font-style: italic;"&gt;hahaha&lt;/span&gt;&lt;br /&gt;Well, what about doing an in between double conversion?&lt;br /&gt;ie...&lt;br /&gt;&lt;code&gt;Number nbr = fmt.parse(testVal);&lt;/code&gt;&lt;br /&gt;&lt;code&gt;BigDecimal bd = new BigDecimal(nbr.doubleValue())&lt;/code&gt;&lt;br /&gt;Ahh, but here is where you get into why not to use doubles (or floats) for money.&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;pre&gt;&lt;br /&gt;   NumberFormat fmt = new DecimalFormat("$0.00");&lt;br /&gt;   String testVal = "$5.35";&lt;br /&gt;   Number nbr = fmt.parse(testVal);&lt;br /&gt;   BigDecimal bd = new BigDecimal(nbr.doubleValue());&lt;br /&gt;   System.out.println("val: "+bd.toString());&lt;/pre&gt;&lt;br /&gt;This will put "val: 5.3499999999999996447286321199499070644378662109375" on the console. Not quite 5.35 anymore.&lt;br /&gt;Now to be clear, I created the &lt;code&gt;NumberFormat&lt;/code&gt; object incorrectly for the context. It should be done as:&lt;br /&gt;&lt;code&gt;    Locale loc = Locale.US;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;    NumberFormat fmt = NumberFormat.getCurrencyInstance(loc);&lt;/code&gt;&lt;br /&gt;Anyway, the results are the same.&lt;br /&gt;Now, by creating the &lt;code&gt;BigDecimal&lt;/code&gt; using the string constructor, as:&lt;br /&gt;&lt;code&gt;bd = new BigDecimal(nbr.toString());&lt;/code&gt;&lt;br /&gt;works. Also, the javadoc for &lt;code&gt;BigDecimal&lt;/code&gt; says that the string constructor should be preferred over the double constructor. However, converting by going &lt;tt&gt;String-&gt;Object-&gt;String-&gt;Object&lt;/tt&gt; is just wrong, on so many levels. Besides, there is this java convention that says never depend on the &lt;code&gt;toString()&lt;/code&gt; implementation.&lt;br /&gt;Now, one might be tempted into doing something like:&lt;br /&gt;&lt;code&gt;BigDecimal adjustedBD = bd.setScale(2,BigDecimal.ROUND_HALF_UP);&lt;/code&gt;&lt;br /&gt;Because, here in the US, the fractional part of a dollar (cents) should always be two digits. Truth is, I'm not sure what it may be in other locales.&lt;br /&gt;I've chosen a different variation on this.&lt;br /&gt;&lt;code&gt;bd.setScale(fmt.getMaximumFractionDigits(),BigDecimal.ROUND_HALF_UP);&lt;/code&gt;&lt;br /&gt;This ensures that the fraction is based on the currency for a given Locale.&lt;br /&gt;&lt;br /&gt;So, now my (JUnit test) code looks like:&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;pre&gt;import java.math.BigDecimal;&lt;br /&gt;import java.text.NumberFormat;&lt;br /&gt;import java.util.Locale;&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;public void testParseCurrency() throws Exception&lt;br /&gt;{&lt;br /&gt;   Locale loc = Locale.US;&lt;br /&gt;   NumberFormat fmt = NumberFormat.getCurrencyInstance(loc);&lt;br /&gt;   String testVal = "$5.35";&lt;br /&gt;   Number nbr = fmt.parse(testVal);&lt;br /&gt;   BigDecimal bd = new BigDecimal(nbr.doubleValue());&lt;br /&gt;   BigDecimal adjusted =&lt;br /&gt;       bd.setScale(&lt;br /&gt;           fmt.getMaximumFractionDigits(),&lt;br /&gt;           BigDecimal.ROUND_HALF_UP);  &lt;br /&gt;   assertEquals("5.35", adjusted.toString());&lt;br /&gt;}&lt;/pre&gt;The very astute will notice this test will fail if the currency symbol has been omitted. Fixing this is somewhat less than trivial. You can get the &lt;code&gt;Currency&lt;/code&gt; object from the &lt;code&gt;NumberFormat&lt;/code&gt; object, and, you can get the currency symbol from that. But, currencies differ as to whether the symbol should go before or after the amount. The joy never ends.&lt;br /&gt;&lt;br /&gt;Comments on this issue are appreciated.&lt;br /&gt;Also, a jUnit test for a locale with a very different currency would be great too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-113925610732919398?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/113925610732919398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=113925610732919398' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/113925610732919398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/113925610732919398'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2006/02/parsing-currency-into-bigdecimal.html' title='Parsing currency into a BigDecimal'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-113899309333953528</id><published>2006-02-03T10:58:00.000-08:00</published><updated>2006-02-03T10:58:13.356-08:00</updated><title type='text'>Formatting a BigDecimal</title><content type='html'>Ok, this one is just me being stupid.&lt;br /&gt;It took me slightly longer to figure out how to apply a format to a BigDecimal than it should have.&lt;br /&gt;&lt;br /&gt;solution:&lt;br /&gt;using &lt;code&gt;java.math.BigDecimal&lt;/code&gt; and &lt;code&gt;java.text.DecimalFormat&lt;/code&gt;.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;BigDecimal bd = getIt();&lt;br /&gt;DecimalFormat frmt = new DecimalFormat("$0.00");&lt;br /&gt;String formatted = frmt.format(bd.doubleValue());&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Feel free to make fun of me now.&lt;br /&gt;&lt;a href="http://wheelworkshop.blogspot.com/"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-113899309333953528?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/113899309333953528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=113899309333953528' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/113899309333953528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/113899309333953528'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2006/02/formatting-bigdecimal.html' title='Formatting a BigDecimal'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-112716224756898371</id><published>2005-09-19T12:36:00.000-07:00</published><updated>2005-09-19T13:37:27.596-07:00</updated><title type='text'>emulated by a synthetic accessor method</title><content type='html'>I stumbled across this warning while performing my regular cleansing the code base for wanings.&lt;br /&gt;Being the first time I've seen it I felt the need for a bit of research.&lt;br /&gt;This is generated by Eclipse and IBM WSAD when an nested class is trying to reference a private field in its containing class.&lt;br /&gt;For example:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;package demo;&lt;br /&gt;public class Foo {&lt;br /&gt; private String myFoo; &lt;br /&gt;&lt;br /&gt; private class Bar {&lt;br /&gt;    private String myString;&lt;br /&gt;&lt;br /&gt;    void changeVal() {&lt;br /&gt;       myFoo = "bar";&lt;br /&gt;    }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;To understand this, you have to remember that the inner class is compiled into a separate file. So, the compiler outputs two files: Foo.class and Foo$Bar.class into the same folder. Since a class cannot see the private member variables of another, the compiler generates an accessor method, and links to it.&lt;br /&gt;Running &lt;code&gt;javap -s -c -private demo.Foo&lt;/code&gt; yields:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;Compiled from "Foo.java"&lt;br /&gt;public class demo.Foo extends java.lang.Object{&lt;br /&gt;private java.lang.String myFoo;&lt;br /&gt;Signature: Ljava/lang/String;&lt;br /&gt;&lt;br /&gt;public demo.Foo();&lt;br /&gt;Signature: ()V&lt;br /&gt;Code:&lt;br /&gt;0: aload_0&lt;br /&gt;1: invokespecial #11; //Method java/lang/Object."&lt;init&gt;":()V&lt;br /&gt;4: return&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;static void access$0(demo.Foo,java.lang.String);&lt;/span&gt;&lt;br /&gt;Signature: (Ldemo/Foo;Ljava/lang/String;)V&lt;br /&gt;Code:&lt;br /&gt;0: aload_0&lt;br /&gt;1: aload_1&lt;br /&gt;2: putfield #19; //Field myFoo:Ljava/lang/String;&lt;br /&gt;5: return&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/init&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Here we can see the compiler generated the static method (with package level access) &lt;code&gt;access$0(Foo foo, String s)&lt;/code&gt;&lt;br /&gt;This is literally the equivalent of:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;static access$0(Foo foo, String s){&lt;br /&gt;  foo.myFoo = s;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Disassembling Foo$Bar (&lt;code&gt;javap -s -c -private demo.Foo&lt;/code&gt;) shows the method being called.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;void changeVal();&lt;br /&gt;Signature: ()V&lt;br /&gt;Code:&lt;br /&gt; 0: aload_0&lt;br /&gt; 1: getfield #17; //Field this$0:Ldemo/Foo;&lt;br /&gt; 4: ldc #24; //String bar&lt;br /&gt; 6: invokestatic #30; //Method demo/Foo.access$0:(Ldemo/Foo;Ljava/lang/String;)V&lt;br /&gt; 9: return&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This means the method &lt;code&gt;changeVal()&lt;/code&gt; was changed from its original form to:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;void changeVal(){&lt;br /&gt;   Foo.access$0(this$0,"bar");&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Where &lt;code&gt;this$0&lt;/code&gt; is the instance of Foo that was sent to the constructor of the nested class Foo$Bar.&lt;br /&gt;So, how do you make the original warning go away? Just change the access of the private variable to package level access (no access modifier).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-112716224756898371?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/112716224756898371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=112716224756898371' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/112716224756898371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/112716224756898371'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2005/09/emulated-by-synthetic-accessor-method.html' title='emulated by a synthetic accessor method'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-112196067722831034</id><published>2005-07-21T08:31:00.000-07:00</published><updated>2005-07-21T08:44:37.233-07:00</updated><title type='text'>Write once debug everywhere...</title><content type='html'>Oh, the joy of Websphere on HPUX.&lt;br /&gt;First, I discover that UTF-8 character encoding is not supported without some plugins to the appserver. How the hell is UTF-8 not supported? weak&lt;br /&gt;Next, I discover that url parameters are not decoded. So, if you have a param &lt;span style="color: rgb(51, 102, 255);font-family:courier new;" &gt;&amp;foo=this%20is%20cool&lt;/span&gt; and call &lt;span style="color: rgb(51, 102, 255);font-family:courier new;" &gt;String foo = request.getParameter("foo");&lt;/span&gt; you get &lt;span style="color: rgb(102, 51, 255);"&gt;foo.equals("this%20is%20cool");&lt;/span&gt; Seems every other appserver (J2EE or not) will decode url parameters automatically. So, now everything has to be wrapped in &lt;span style="color: rgb(102, 51, 255);font-family:courier new;" &gt;URLDecoder.decode(request.getParameter(&lt;/span&gt;...&lt;br /&gt;Struts forms, all sets need to be changed as well;&lt;br /&gt;instead of:&lt;br /&gt;&lt;span style="color: rgb(102, 51, 255);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;public void setFoo(String val){ this.foo=val; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;you need&lt;br /&gt;&lt;span style="color: rgb(102, 51, 255);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;public void setFoo(String val){ this.foo=URLDecoder.decode(val); }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;One might think, IBM would choose to have their app server behave the same on every OS. LOL&lt;br /&gt;This is the kind of crap I'd expect from oracle. HPUX sucks enough on its own.&lt;br /&gt;I really want these methods to not use the deprecated and actually say:&lt;br /&gt;URLDecoder.decode(param,"UTF-8")&lt;br /&gt;But, as mentioned, UTF-8 is not an option. As Cartman would say, "weeak".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-112196067722831034?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/112196067722831034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=112196067722831034' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/112196067722831034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/112196067722831034'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2005/07/write-once-debug-everywhere.html' title='Write once debug everywhere...'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-112172169602287247</id><published>2005-07-19T21:53:00.000-07:00</published><updated>2005-07-23T22:03:15.076-07:00</updated><title type='text'>Breaking into entry-level Web Development</title><content type='html'>Today I conducted an interview for a Web Development position on my team. The candidate should be a rockstar Web dev, knowledgeable and well versed in cross-platform/cross-browser XHTML, CSS 2, JavaScript plus one or more scripting languages and/or JSP.&lt;br /&gt;&lt;br /&gt;He had all but the JSP bit on his resume, but when interviewed he met none of those requirements and more. Less? Whatever, he wasn't right for the position.&lt;br /&gt;&lt;br /&gt;But why?&lt;br /&gt;&lt;br /&gt;Because he didn't have even a fundamental understanding of XHTML/HTML (on his resume) or CSS (also on his resume) and JavaScript seemed to be an amorphous entity to him. Despite building and managing Web sites, these things escaped him. Looking back over his resume, I think I've discovered why- DreamWeaver.&lt;br /&gt;&lt;br /&gt;WAIT! Before you flame me about the benefits of DreamWeaver, I am not debating its usefulness nor any other thing about it. The point here is that he didn't write any code- the editor did it for him.&lt;br /&gt;&lt;br /&gt;Clearly this is a bad way to get a job. If you have something on your resume, you probably should have more than just an idea of what it actually is- you should KNOW it, you should UNDERSTAND it.&lt;br /&gt;&lt;br /&gt;For anyone who is considering getting into Web Development or Web Programming (use your own definition for this) there are some tips I'd like to impart to you.&lt;br /&gt;&lt;br /&gt;Start early&lt;br /&gt;The Internet, believe it or not, is a great place to help you learn front end things like HTML and CSS. There are a few dozen odd books you can start reading as well. Reading is only part of it though, knowledge is power but unless you have the ability to use it you "ain't got nothing!" so to speak. While you're reading and learning, you should start building Web pages. Find a free site host like Yahoo or Tripod and BUILD. Explore HTML and XHTML, find out why they're different, challenge yourself by trying to find a good looking site and then make one of your own using only XHTML and CSS2 and running it through the W3C validator.&lt;br /&gt;&lt;br /&gt;Craft the sword, then learn how to wield it&lt;br /&gt;When you get to the point where you are comfortable with coding and can write nice, valid code. Volunteer to help someone build a Web site. Family, friend's band, your own startup- whatever. The idea here is to get some practice working in HTML. Learn JavaScript (and please note that it and Java are not the same) and play with XML if you can. Write a new template for your blog, if you have one. If you don't- make one for someone else. Get familiar with browsers other than the one you're using right now. If you have access to a Mac (or if you're a Mac user: a PC) look around at your favorite sites and see if they look any different. Look at your own, what's different? If you find some variance between the way your page looks and works in different browsers or computers, fix it. This single thing (aside from actually learning the languages) is going to be your most valuable asset- the ability to code cross browser/platform.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;It may be true that "anyone" can learn HTML, however few people are actually good at it.&lt;br /&gt;Fewer still are what I would consider expert, and these are the hardest to find.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;School&lt;br /&gt;Schooling is great, schooling is awesome. If you are in high school, take any classes having to do with the Internet that are available to you. Got a computer lab? Get familiar with it. Learn everything you can about HTTP and then start learning HTML and CSS.&lt;br /&gt;&lt;br /&gt;BUT once you get into college, take programming and computer fundamental courses. Maybe even get a CS degree. Why? Because having a good educational background in structured languages will only benefit you, even if you only want to work on the front end.&lt;br /&gt;&lt;br /&gt;I know, I know. "What about the Web stuff though? How do you gain any kind of experience in that?" See next paragraph.&lt;br /&gt;&lt;br /&gt;Volunteering&lt;br /&gt;While you're taking college courses and burning up some ones money trying to better yourself, give up a few nights a week and find a Web site to volunteer as a developer for. This is much easier than you think. Pick a topic you're interested in, Google it, view the resulting Web pages. Find one you think you can make better and contact the administrator. Tell them you're in school and are looking for a few sites to do some volunteer development on, no charge.&lt;br /&gt;&lt;br /&gt;What you're going to gain here are two things: Experience and work history.&lt;br /&gt;&lt;br /&gt;Wielding the sword&lt;br /&gt;Education versus experience is a double edged sword. Too much of one and not enough of the other might be ok for some jobs. For those companies that prefer to hire straight out of college, having more education is great, they often don't WANT you to have experience.&lt;br /&gt;&lt;br /&gt;The majority of the remaining companies would rather have the experience or experience and some formal education, even if it is only a few classes focused on programming languages or theory.&lt;br /&gt;&lt;br /&gt;When I am interviewing, the first thing I look at is wether or not the candidate actually knows the stuff he or she put on their resume. I'll ask simple questions first, because they often have simple answers that require knowledge of the subject. That's the point, actually. If you've told me you know XHTML, then none of the things I aske you should stump you.&lt;br /&gt;&lt;br /&gt;What's it worth?&lt;br /&gt;Many new Web devs don't know what they're worth. Sometimes this is a bad thing for more than just the obvious reason of getting underpaid. Thinking you should be paid more than what's reasonable is even worse. There's nothing wrong with wanting a little more. If you're coming into a company at an entry level, &lt;span style="font-style: italic;"&gt;especially &lt;/span&gt;I should say, &lt;span style="font-style: italic;"&gt;especially &lt;/span&gt;if you're coming into a company at an entry level, do a little research before your interview to find out what someone in the position you're applying for with your skills and experience gets paid.&lt;br /&gt;&lt;br /&gt;50k is honestly not too bad a salary for this kind of work at the entry level. 80k is bordering on unreasonable if you have less than 2 years of consistent work experience (even if most is voluntary) and no or little education. Everything is relative though, in some areas of the country these salaries may seem very high or really low, so hopefully this sheds some light. If you're in a city like Seattle, no way would I take less than 45k unless you really need the work. My friend and colleague here at Wheel Workshop has this advice:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;"If you are going into the field for the money, instead of love of the craft, find another career."&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Too true. We've seen too many people who just do the minimum because they are not really interested in their jobs. You can spot right away the person who does what they do because they love it. They know what they're talking about, their eyes blaze with new ideas about how to solve problems and they are good at what they do. The people who do it because it's a job usually have nothing to contribute. They come in, work their hours, go home and that's it.&lt;br /&gt;&lt;br /&gt;Hopefully I've managed to actually say something here. If I had to sum it up I guess it would come out something like this: Like it, learn it, love it, do it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-112172169602287247?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/112172169602287247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=112172169602287247' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/112172169602287247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/112172169602287247'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2005/07/breaking-into-entry-level-web.html' title='Breaking into entry-level Web Development'/><author><name>R(k)</name><uri>http://www.blogger.com/profile/10478999294152077322</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><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-111898422120156662</id><published>2005-06-18T15:45:00.000-07:00</published><updated>2005-06-18T15:50:30.290-07:00</updated><title type='text'>On the JSP atomic pattern</title><content type='html'>Last week I started a new project to bring a better music and radio experience to my company's customers. One of my tasks this time around was application setup and base configuration using our in-house application framework. This is the first time I have done the initial setup myself as all other projects I've worked on were ready to start building on.&lt;br /&gt;&lt;br /&gt;In the last few apps I've helped develop, the Atomic pattern has been the primary JSP pattern used. This pattern uses distinct code components responsible for individual "modules" in the view. These atomic modules can thus be shifted around in the view and still perform their functions because they are not tied to a "place" in the model in order to work.&lt;br /&gt;&lt;br /&gt;Before I go any further, let me drop some quick definitions for clarity. These words will be used in this manner for these meanings in the remainder of this post. The author makes no guarantee that anyone else uses these defs, but they are close to real-world and this is free after all.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;View &lt;/span&gt;- the visible rendering&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Module&lt;/span&gt; - an atomic portion of the view&lt;br /&gt;&lt;span style="font-style: italic;"&gt;JSP module&lt;/span&gt; - the code that represents a view module&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Module definition&lt;/span&gt; - the configuration (usually in XML) of the JSP module&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Decorations&lt;/span&gt; - Simplified here to mean parameters, attributes and flags that alter minor changes in the view. (Could be text transforms, toggles for list ordinals, etc)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sharing Pain&lt;/span&gt;&lt;br /&gt;Implementing this pattern in the past produced two extreme ends of the spectrum for me. On one end we have too few code components, basically JSP files, responsible for handling too much view. The components became massive switch cases of EL tags (we try to keep scriptlets out of the view-producing JSPs) that tried to cover, say, 3 or more ways a module could look. On the opposite end we took atomic units and made multiple levels of smaller code components responsible for the view. This produced an overwhelming number of files, mostly lower-level includes that rendered things like an artist name or image. The problem stemmed from creating JSPs that were trying to be reusable and extendable when they didn't really need to be either one of those things to meet the business requirements.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-style: italic;"&gt;Author's note - The second extreme mentioned just now? It got to the point where we actually exceed the number of included files at request time that the JVM could handle.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The happy medium&lt;/span&gt;&lt;br /&gt;Before starting to write any code and just after I set the app core up, I decided that this time we should take a new approach. On this project I wanted to not just follow the standards we had in place already, but look at how and why we write JSP code. An Atomic pattern again makes sense due to the modular nature of what we're building. I also chose to change some precepts of other devs on my team that it really is OK to build JSPs that did one thing or two rather than "everything" or breaking them up into tiny fragments. But how to convince them?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The epiphany&lt;/span&gt;&lt;br /&gt;I began to write a document outlining the project structure, conventions and why we should seek this happy medium. The hard part was how to find it. Thinking back on the previous projects and their SODs, it occurred to me that they were all missing one very important (and now obvious) thing: There were no guidelines for developing atomic units in JSP! No one had ever mentioned how to make the decision on how to write a JSP module, only what they would look like and where they fit into the app.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Clarity raises its hand&lt;/span&gt;&lt;br /&gt;I was excited! I wanted to build a clean app and now I had the vehicle to describe HOW that could be done. A quick yes/no test would help the developer to decide wether the JSP module they are working on should do more than just handle its view.&lt;br /&gt;&lt;br /&gt;It went a little something like this:&lt;br /&gt;During development, and even refactoring at a later time, if it naturally fits to reuse one JSP module for another, by all means do so if you can answer yes to these questions:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Does it make sense?&lt;/span&gt;&lt;br /&gt;For example, will the data will be represented in the same way excluding any decorations?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Will it happen quickly?&lt;/span&gt;&lt;br /&gt;Will the work to build one JSP module or merge two (or more) be faster than the work to build both individually?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Are the view modules able to coexist in a single JSP?&lt;/span&gt;&lt;br /&gt;If the views are drastically different, it may cause problems in implementation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Can the module definitions work with a single JSP?&lt;/span&gt;&lt;br /&gt;If modules are defined/configured differently and you need to use different methods or bean properties, you must answer no to this question.&lt;br /&gt;&lt;br /&gt;A&lt;span style="font-style: italic;"&gt;re view modules you want to merge context independent?&lt;/span&gt;&lt;br /&gt;That is, can this JSP module that contains logic for more than one view work on any page without each view having to know which page it is on?&lt;br /&gt;&lt;br /&gt;... and no to these:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Is this an attempt to make one module do "everything?"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Will it bloat the base code in the JSP you're starting with?&lt;/span&gt;&lt;br /&gt;Nobody likes bloat, but what is it? In this case, bloat is not the code the modules themselves require, it's the handling code that surrounds them, helping to live in a single JSP module. If it takes more code to make your modules "fit" in the same space, you've got bloat. Break them up and use them individually.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Can it survive changes that alters the view of any given module?&lt;/span&gt;&lt;br /&gt;Ah, so this one is key. If you are going to make one JSP module do the work of multiple views, keep in mind the requirements for the view modules can change on you. If the view requirements do change, read back through the list of questions and if your answers have changed- it's time to split it out into a new JSP.&lt;br /&gt;&lt;br /&gt;Similarly, you can use the opposite approach to determine wether or not a JSP should be split into more than one JSP module.&lt;br /&gt;&lt;br /&gt;With guidelines now in place, we'll see how development goes. I am &lt;span style="font-style: italic;"&gt;hoping &lt;/span&gt;smoothly. In any case, I'll update on this topic as we go along in the process.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-111898422120156662?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/111898422120156662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=111898422120156662' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111898422120156662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111898422120156662'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2005/06/on-jsp-atomic-pattern.html' title='On the JSP atomic pattern'/><author><name>R(k)</name><uri>http://www.blogger.com/profile/10478999294152077322</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><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-111903273172989362</id><published>2005-06-17T10:23:00.000-07:00</published><updated>2005-06-17T11:25:31.736-07:00</updated><title type='text'>Java turning into perl</title><content type='html'>I'm growing increasingly fustrated with the removal of some of the best features of Java. Namely type safety.&lt;br /&gt;More and more we are getting these configuration driven frameworks where objects are cast to their correct types willy nilly. The idea behind these systems is "a non developer can reconfigure the application without touching code". This is just dumb. There is no way a non-developer can edit a half-megabyte Spring configuration and know what they are doing. Even developers are having a hard time with it. Next, since its just a bunch of xml, typos can cause huge problems that are not discovered until runtime. And sometimes not till a certain piece of code is executed.&lt;br /&gt;&lt;br /&gt;We are creating defacto programming languages with these configurations that only the application developers can understand. We are losing the benefit of a compiler to tell us if the object we are pointing to exists. Even in the code, we are losing type safety as the objects handed from the framework are cast to the correct type.&lt;br /&gt;&lt;br /&gt;Worse of all, people keep saying "its more object oriented". This is just incorrect. It does make the code more abstract but, this is really a farse since objects must be cast before they can be used. About the only thing it is really good for is enforcing developers to code to interfaces instead of implementation classes.&lt;br /&gt;&lt;br /&gt;I got started on this rant in the process of migrating a rather large code base from Hibernate 2 to version 3. I must clarify that I was using a patched version of Hibernate 2. This patched allowed one to call count on a criteria object. So my pagination code basically called:&lt;br /&gt;&lt;span style="color: rgb(51, 51, 153);font-size:85%;" &gt;&lt;span style="font-family: courier new;"&gt;List results = criteria.list(); // get a page of results&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;long totalCount = criteria.count(); // get the toatl count&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The criteria had criterion added to it to restrict the results for a page of data.&lt;br /&gt;The Hibernate developers decided that its more convienent for me to get the count with:&lt;span class="postbody"&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 153);font-size:85%;" &gt;&lt;span style="font-family: courier new;"&gt;Integer count = (Integer)criteria.setProjection(Projections.rowCount()).uniqueResult();&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;int total = count.intValue();&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;So now instead of the safety of a method that returned a long. We have a method that returns an&lt;span style="font-family: courier new;"&gt; Object&lt;/span&gt;. We &lt;span style="font-weight: bold;"&gt;*know*&lt;/span&gt; the &lt;span style="font-family: courier new;"&gt;Object&lt;/span&gt; is an &lt;span style="font-family: courier new;"&gt;Integer&lt;/span&gt; because we passed &lt;/span&gt;&lt;span class="postbody"&gt;&lt;span style="font-family: courier new;"&gt;Projections.rowCount()&lt;/span&gt; to the object that we passed to the criteria, and we cast it. So instead of the criteria interface getting bloated, every consumer of the library gets to have their code bloated. If the Hibernate code ever changes, you won't know until you run the code because of the cast. Suppose one fine day they decide to return a &lt;span style="font-family: courier new;"&gt;Long&lt;/span&gt; instead of an &lt;span style="font-family: courier new;"&gt;Integer&lt;/span&gt;. You'll get no compile error because the interface returns an &lt;span style="font-family: courier new;"&gt;Object&lt;/span&gt;. Instead of using the compiler to find the code that needs to change, you'll have to grep for it (unless you use windows, then your life will suck).&lt;br /&gt;&lt;br /&gt;Any developer who has spent time using the Spring framework can tell you how much time they've wasted because they have to start the application to find errors in the configuration.&lt;br /&gt;&lt;br /&gt;How about we start writing configuration classes. Actual compilable code to configure the application. Return actual objects instead of strings. Return actual types and not just Object. Drop construction via reflection. Non developers are not going to be able to reliably configure your application anyway. Create a configuration package. All of the config classes can go in there. If anything is wrong, you get a compile error. No more spending an hour debugging just to find a typo in hte config (the config), hehe.&lt;br /&gt;&lt;br /&gt;Finally, a word regarding setter injection so loved by Spring aficionados. If the object passed in a setter to an object is required to make it function, then get rid of the setter method and pass it to the constructor. How else can anyone know that a required thing is missing?&lt;br /&gt;&lt;br /&gt;Final word, I am not finished with this subject.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-111903273172989362?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/111903273172989362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=111903273172989362' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111903273172989362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111903273172989362'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2005/06/java-turning-into-perl.html' title='Java turning into perl'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-111773665123027820</id><published>2005-06-02T11:14:00.000-07:00</published><updated>2005-06-02T11:32:15.676-07:00</updated><title type='text'>Problems with Hibernate Expression.not( criterion )</title><content type='html'>So, I'm building my hibernate queries dynamically with Criteria (that I love so much).&lt;br /&gt;Then I come accross a problem while trying to do a not:&lt;br /&gt;&lt;small&gt;&lt;tt&gt;&lt;br /&gt;Criteria criteria = session.createCriteria(MyValueObj.class);&lt;br /&gt;criteria.add(Expression.isNotNull(&lt;span style="color: rgb(0, 0, 153);"&gt;"dateCreated"&lt;/span&gt;));&lt;br /&gt;criteria.add(Expression.not(Expression.eq(&lt;span style="color: rgb(0, 0, 153);"&gt;"deleteCode"&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 153);"&gt;"D"&lt;/span&gt;)));&lt;br /&gt;&lt;/tt&gt;&lt;/small&gt;&lt;br /&gt;This yields no results, suck.&lt;br /&gt;It looks like it generating some bad SQL.&lt;br /&gt;&lt;br /&gt;I decide to try refactoring the statements into:&lt;br /&gt;&lt;small&gt;&lt;tt&gt;&lt;br /&gt;Criteria criteria = session.createCriteria(MyValueObj.class);&lt;br /&gt;criteria.add(&lt;br /&gt;&lt;span style="margin-left: 15px;"&gt;Expression.&lt;span style="font-weight: bold;"&gt;not&lt;/span&gt;(&lt;/span&gt;&lt;br /&gt;&lt;span style="margin-left: 30px;"&gt;Expression.&lt;span style="font-weight: bold;"&gt;and&lt;/span&gt;(&lt;/span&gt;&lt;br /&gt;&lt;span style="margin-left: 45px;"&gt;Expression.isNull(&lt;span style="color: rgb(0, 0, 153);"&gt;"dateCreated"&lt;/span&gt;),&lt;/span&gt;&lt;br /&gt;&lt;span style="margin-left: 45px;"&gt;Expression.eq(&lt;span style="color: rgb(0, 0, 153);"&gt;"deleteCode"&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 153);"&gt;"D"&lt;/span&gt;))));&lt;br /&gt;&lt;/tt&gt;&lt;/small&gt;&lt;br /&gt;And all is well and happy in the world. Perhaps there is some kind of bug in the implementation of the not expression. Investigation will have to wait until another time.&lt;br /&gt;When all else fails, find another way to skin the cat.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-111773665123027820?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/111773665123027820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=111773665123027820' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111773665123027820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111773665123027820'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2005/06/problems-with-hibernate-expressionnot.html' title='Problems with Hibernate Expression.not( criterion )'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-111651372594231874</id><published>2005-05-19T07:37:00.001-07:00</published><updated>2005-05-19T07:42:05.946-07:00</updated><title type='text'>thursday morning configuration woes</title><content type='html'>XML is like violence. If it doesn't solve the problem, use more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-111651372594231874?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/111651372594231874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=111651372594231874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111651372594231874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111651372594231874'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2005/05/thursday-morning-configuration-woes.html' title='thursday morning configuration woes'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-111626618902477865</id><published>2005-05-16T10:44:00.000-07:00</published><updated>2005-05-16T11:05:29.453-07:00</updated><title type='text'>Mondays</title><content type='html'>A new exception to start the day&lt;br /&gt;&lt;tt&gt;java.sql.SQLException: Fail to convert to internal representation&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;This morning after a CVS update my app starts giving this exception trying to get some data.&lt;br /&gt;FYI, my app is using &lt;tt&gt;Spring-&gt;Hibernate-&gt;Oracle&lt;/tt&gt;&lt;br /&gt;A google search (always the first thing with strange errors) shows a bunch of posts with replies telling people to use prepared statements instead of string hoodoo-voodoo. Well, I'm using hibernate, so this doesn't apply. suck.&lt;br /&gt;A quick check shows the hibernate config and the value object still match-up (woohoo, my co-workers aren't conspiring against me). Well, the next thing is to actually *read* the stack trace ;)&lt;br /&gt;So, I see some interesting lines:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:226)&lt;br /&gt;  at oracle.jdbc.driver.&lt;span style="font-weight: bold; color: rgb(51, 0, 153);"&gt;CharCommonAccessor.getBigDecimal&lt;/span&gt;(CharCommonAccessor.java:324)&lt;br /&gt;  at oracle.jdbc.driver.CharCommonAccessor.getBoolean(CharCommonAccessor.java:157)&lt;br /&gt;  at oracle.jdbc.driver.OracleResultSetImpl.getBoolean(OracleResultSetImpl.java:394)&lt;br /&gt;  at oracle.jdbc.driver.OracleResultSet.getBoolean(OracleResultSet.java:1570)&lt;br /&gt;  at com.ibm.ws.rsadapter.jdbc.WSJdbcResultSet.getBoolean(WSJdbcResultSet.java:686)&lt;br /&gt;  at net.sf.hibernate.&lt;span style="font-weight: bold; color: rgb(51, 0, 153);"&gt;type.BooleanType.get&lt;/span&gt;(BooleanType.java:19)&lt;/span&gt;&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;Well, I've only got a few fields that are booleans, this should be easy to trace down. The exception also points out that Oracle is expecting the booleans to really be BigDecimals. So, time to look at the database.&lt;br /&gt;Aha, they are consipring against me (jk), the columns have misteriously been changed to varchars. Gently abuse the dba, and all is well in the world again.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Now if I could only stop them from changing my checked exceptions to unchecked ones....&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-111626618902477865?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/111626618902477865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=111626618902477865' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111626618902477865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111626618902477865'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2005/05/mondays.html' title='Mondays'/><author><name>willCode4Beer</name><uri>http://www.blogger.com/profile/14121976149233329281</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><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-12766970.post-111595708851978499</id><published>2005-05-12T21:04:00.000-07:00</published><updated>2005-05-12T21:04:48.520-07:00</updated><title type='text'>First!</title><content type='html'>First post!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/12766970-111595708851978499?l=wheelworkshop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wheelworkshop.blogspot.com/feeds/111595708851978499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=12766970&amp;postID=111595708851978499' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111595708851978499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/12766970/posts/default/111595708851978499'/><link rel='alternate' type='text/html' href='http://wheelworkshop.blogspot.com/2005/05/first.html' title='First!'/><author><name>R(k)</name><uri>http://www.blogger.com/profile/10478999294152077322</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><thr:total>0</thr:total></entry></feed>
