Tuesday, March 31, 2009

Romans, Calendars, Java, and Bad Bugs

Well, I learned today that Java is not smart enough to figure out that if there aren't 31 days in a month, just to go to the last day. Now I may be the last self-respecting Java developer on the planet to figure this out, but if not, here's a tip:

1) use the roll() method to push an element of the date forward, without affecting the other days.
2) Don't instantiate your GregorianCalendar and then just add a month, because if you move to April 31, it automatically becomes May 1. Instead, you can also just create a new Calendar with the day set to 1, and then new month set correctly.

Java, you vex me so. What a terrible bug by me. And without the benefits of unit tests, not something I ever would have found out until we hit a 31st day of a month, or until we reached January and went into February with it's 28 days. Sigh.

Been A While

Well, it's been a few days since I've written, so here goes:

It's SPRING! One of the best things about working in this old dump of a subleased office is the fact that back in the 40s and 50s, the people who built these things used windows that open. So today, as I sit here, my yearly allergies kicking in, I eagerly await Opening Day, the removal of all warm-weather clothing from my closet, and the ability to go for nice runs in the mornings, and long walks in the evenings with Jena. Other things of note that are good about Spring: grilling, drinking beer outside, longer days, and wearing flip-flops.

Not much to note. I had a pretty great weekend, including walks through Georgetown and Eastern Market/Capitol Hill. I got some nerding in, furthering my beliefs that Grails is just too easy. I feel like I am stealing something when it takes me 45 minutes to write a slick messaging tool using a nice jQuery thickbox and a slick ajax post. It's good. In a couple weeks we are heading to our nephew's birthday party. That will be very exciting for us, as we wish we could see them a lot more often.

I finished the second Baldacci book that I was reading, Divine Justice, which was good as usual, and have moved on to Next, by Michael Crichton. I always enjoy his stuff - even if it is a little odd and overblown sometimes, the pages really turn.

In a great piece of news, bad baseball player and all around jerk Gary Sheffield was waived by the Detroit Tigers today. He can take his lack of production, bad baserunning, terrible attitude, and gimpy shoulders elsewhere. Ahh, hopefully now that the Tigers aren't saddled with expectations, they can pull some 2006 magic out of their hats and give me something good to watch.

Friday, March 20, 2009

Struts 2 Error Reporting Tips

As I wrote before, Struts 2 isn't the best framework for error handling or notification. I think for the most part the entire framework is an incredible improvement over Struts 1, which had so many silly moving parts that just made it a genuine pain in the ass to work with. Struts 2 is simple, and I take well to the Action-As-Bean pattern used here. Moreover, it's what we use, so I had to learn to deal with the oddness of it. Since I wrote that post, I have come up with/implemented a couple handy tricks:

1) Display the Error Details on the Error Page

Obviously I didn't invent this, but we weren't doing it yet, so here's what I did:

You will likely create a global error mapping. In the action that you map to, add this code that will trap the error details:

Throwable error = (Throwable) request.getAttribute("javax.servlet.error.exception");

request.setAttribute( "errorCause", error.getCause().toString() );
request.setAttribute( "errorMessage", error.getMessage() );
request.setAttribute( "errorStackTrace", error.getStackTrace() );
Now you can insert a little line into your error page that shows the error, instead of having struts swallow it up forever.

<%= if ( request.getAttribute( "errorMessage" ) != null { %>

-- print out the data --

<% } %>

2) Debug Better

If you get the source code for Struts 2, you can add it to your Eclipse project, and insert a breakpoint in the following piece of code in com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept():

public String intercept(ActionInvocation invocation) throws Exception {
String result;

try {
result = invocation.invoke();
} catch (Exception e) {

/* BREAKPOINT HERE */

if (logEnabled) {
handleLogging(e);
}
List exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
String mappedResult = this.findResultFromExceptions(exceptionMappings, e);
if (mappedResult != null) {
result = mappedResult;
publishException(invocation, new ExceptionHolder(e));
} else {
throw e;
}
}

return result;
}
This way you can see if something weird happened inside struts that didn't get reported in the logs. Boom, you can see if there is some mysterious internal error getting thrown, rather than trying to divine it using rain dances and crossed fingers. These two things have really improved my experience with Struts. If I were a better person, I would upgrade to see if it's fixed, and if not, I'd probably add some decent logging.

Bonus Tip

If your application starts up, but you are getting invalid results from your struts action, like the "no result defined for action" message, make sure your source control tool didn't merge incorrectly and add a double mapping for the action. We ran across this recently, where an old mapping was included, and was picked up first. Perhaps there should be a way to tell Struts2 to error out and fail if it finds the same mapping twice in a file? Just something to watch for.

Happy Strutting!

Thursday, March 19, 2009

What's Up!

Some ramblings from my personal life and current affairs:

1) Books

Been reading a lot again lately. I went through a bit of a lull there after our trip to Aruba where I wasn't reading much at all, but now I am back on it. This week I finished a David Baldacci book, Stone Cold. Those are always entertaining, if a bit light on substance. I dove right into the next one in the series, Divine Justice, which is as good as all the others so far, though it's mostly set outside of DC, which is a big part of the reason that I enjoy some of his other books.

I also finished Alive, the story of the survivors of the Andes plane crash in the early 70s, where the survivors were able to last 10 weeks in the mountains by eating the dead passengers. Wow. If you ever think your life is tough, just think to yourself "Well this current work assignment sucks, and I hate traffic, but at least I didn't eat my cousin to stay alive today". Just an amazing story of persistence and togetherness, but at the same time a fair account of personal weakness, and how people can behave (or not) in the face of hopelessness. This book was written quite a while ago, and was made into a movie starring Ethan Hawke, but like most other adaptations, the movie doesn't capture the real spirit of the struggle like the book.

My new metro book is The Wealth and Poverty of Nations, by David Landes. I've had this book on my bookshelf for ten years, but just never got around to reading it. It has been staring at me in its familiar position next to its unread compatriot, Guns, Germs, and Steel, calling out to be read, and I am finally obliging. It is an interesting tale of geography, history, and anthropology, and how they combine to make some societies rich, and some poor. I hope it's as good as it has started out.

2) AIG Bonuses

Lots of talk about AIG bonuses. I would say that any sort of 90% tax is silly. The government has bought up most of the company. Now they are doing all they can to ensure that no competent people will go work there. This means the taxpayers will never recoup their bonuses. If some of the employees there will accept revised bonuses, then good, if not, let them go on their way, but let's not make working for AIG such a poisonous experience that the story will end badly. It doesn't have to - there are still important and viable portions of the company. Everyone just needs to chill out and let this play out without trying to tar and feather a bunch of people who in most cases had nothing to do with the irresponsible financial practices that have killed the company.

3) Where is Spring?

Where is it? It's 50 and cloudy every day. I am ready to go for a run outside and a bike ride, and for leaves on trees. Come on Spring, get your ass in gear!

4) World Baseball Classic

Why is this played? Does it matter? Does anyone really care? I guess it's marginally better than watching your players play in Spring Training, but isn't it basically like watching 23 AAA all star games? I just don't feel it. Side note: my new HD TV makes baseball look sweet, so WBC has that going for it, at least. I just think that all this is doing is penalizing the teams that have lots of good players who play in the classic (see the Tigers, whose 4-5-6 is playing for Venezuela). Bah. Bring on opening day.

5) Travel

We haven't done any. Boo. We are off to Massachusetts next month for our nephew's 2nd birthday, which we are definitely looking forward to! We love our nephew (and Mindy and Jayson too)!

6) Rush Limbaugh

Keep in mind that I am not a 'registered' anything. I vote on the issues, and that generally leaves me squarely in the middle. That said, Rush Limbaugh is just terrible. Is there anything he does that is constructive? It really doesn't seem like it. Seems like he's just a terrible windbag who wants to tear down, tear down, tear down everything that he doesn't think is okay. Easy to snipe when you aren't actually responsible for anything. He should really reconsider wanting to be the leader of the RNC, because then he will be accountable, and that will be new for him.

7) NCAA Championships

God I love college basketball. I love this tournament. I love that Michigan finally made it back in the dance, and I love that Syracuse made a great run in the tournament (6 OTs! WTF!?!) to nab a three seed in a relatively easy region. All I was thinking was "well Syracuse hasn't been announced yet, and we know they are in - what if this ends up as Syracuse-Michigan in a 5-12 matchup?" Could be tough on my marriage! Fortunately nothing came of it. Phew!

Tuesday, March 10, 2009

Consuming RSS Feeds with Groovy/Grails

Building off of my recent post about RSS Feed parsing using the ROME Library, I had an idea for a fun application to build using Grails. The first part of this application, which I'll share when I am done, is the part where we read the feed. Now, the last time I did this in Java, it was pretty easy to do, but man, this is just a little bit better:
    def readFeed( url )
{
def xmlFeed = new XmlParser().parse(url);

def feedList = []

(0..< xmlFeed.channel.item.size()).each {

def item = xmlFeed.channel.item.get(it);
RSSFeed feed = new RSSFeed( item.title.text(), item.link.text(),
item.description.text(), item.pubDate.text() )
feedList << feed
}

feedList
}
Yep, that's it. One line to pull back the feeds. The iterator, and one line to create my RSSFeed object. Then add the feed to a list, and return the list to your controller. In 25 minutes, I have a feed reader application that's basically functional, taking a feed as an input, and returning a page that displays the post title linked to the post, and the posts contents and date. All of life should be this easy.

Monday, March 9, 2009

Read These Now!

My friend Ramsey is a true renaissance man. He is an extremely talented and creative software designer and developer at Blackboard. In addition to having the best sense of humor I have ever seen out of a software engineer, he is also a fine writer - a legitimate writer who gets things published - not to be confused with this blog writer, who just spits out a bunch of junk on a blog periodically and hopes something sticks.

Check out his stories here:

Jimmy's Roadside Cafe
Creature

They are both extremely entertaining and well-written. If you enjoy those, check out Ramsey's blog, Glass Maze. It's full of interesting posts and hilarious takes on everyday stuff.

Congrats Ramsey! Don't forget me when you are famous.

Saturday, March 7, 2009

Garbage Collection, Tomcat, Hibernate, and You

java.lang.OutOfMemoryError: PermGen space

If you are using Sun's Hotspot JVM, maybe you've seen this in your log file, and you don't know what to do. Maybe this will help.

Ever since we upgraded at work from Hibernate 2.1 to 3.2, we have been fighting memory management issues. Some of those can probably be traced back to increased traffic, some probably to odd legacy code that can be refactored pretty easily, and much of it relates to Hibernate and cgLib. There are endless blog posts about this, so if you want to read about the way cgLib, Hibernate, and the Perm region of the JVM heap interact, google away.

To break it down, here's how to know you may run across a problem:
/bin/jps
This will give you a listing of running JVM instances on your machine. Tomcat presents as:
xxxx Bootstrap
this is the JVM pid that you can use to check out memory utilization. Now run the garbage collection util to see what's going on in your heap:
jstat -gcutil
You will be presented with the following:












S0S1EOPYGCYGCTFGCFGCT GCT
0.0031.5860.1357.7699.6626475.19262.1147.306

The measures above give you space utilization in percentage of the regions of the JVM memory space. For a detailed explanation of this, check out the official Sun paper on the topic. For our purposes, we will do a quick overview:

S0 and S1 are both survivor spaces.
E is Eden space.
O is Old space.
P is Perm space.

When an object is created, it lives in Eden space. If it makes it past a garbage collection while still containing an active reference to it, it will move on to Survivor space. From there, if it's still actively referenced, it moves on to Old space. Garbage Collections of Eden and Survivor spaces are not the big garbage collections - the are the Young Garbage Collections (YGC). Once something gets into the Old space, it can only be removed by a Full Garbage Collection (FGC). You can see from the above table that a YGC is not expensive - 2647 of them were performed in a total of 5.192 seconds, while just six full collections take 2.114 seconds. Finally, there is the Perm space. This is where the JVM structures and class objects are put. The classloader sticks stuff here to help you so it doesn't have to constantly load and reload these structures. The problem is that if you have a lot of these things, it's going to just keep sticking things in there until it's full.

There are a couple of ways to combat this issue:
  1. Maybe you haven't increased the default size of the Perm space. You can do that by adding this JVM flag to your startup script: -XX:MaxPermSize=m. To give some perspective, the default is 32m.
  2. Look at your classpath. Are you loading a LOT of libraries in? Do you need them all? Perhaps you can remove some of those libraries.
If you still have problems with Perm space after making the above changes, try these JVM arguments and see if you have any more issues.

-XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled
Whereas we were constantly hovering around 99.88% perm space utilization prior to these changes, now we are usually back down around 60%, so an extraordinary event in the system won't trigger an outofmemory situation. Hope this helps.

Why Grails is Sweet

Grails is sweet because you do things that are relatively complex, like upload a photo, resize it, save it, and persist the metadata using this code in a controller class, and nothing more:
        def photo = new Photo(params)
Member m = authenticatedMember()
def myFile = request.getFile( "file" )
def imageTool = new ImageTool()
photo.path = "";
photo.member = m

if(myFile && photo.save())
{
String imagepath = grailsApplication.config.imagePath +
File.separatorChar + "${photo.id}.jpg"
myFile.transferTo(new File(imagepath))

imageTool.load(imagepath)
imageTool.thumbnail(640)

String fixedImagePath = grailsApplication.config.imagePath + File.separatorChar + "${photo.id}-fixed.jpg"
imageTool.writeResult(fixedImagePath, "JPEG")
imageTool.square()
imageTool.swapSource()
photo.path = fixedImagePath
}
Oh by the way, when you define a domain class with a byte array to store a file, then generate the edit/create view, it automatically does all the multipart form submission stuff in the .gsp file. It NEVER gets this easy with Java/JSP. Hmm. Awesome. This is made possible by the innate goodness of grails and a plugin called ImageTools. It makes me dread going back to work and using Java sometimes. Sigh. It's amazing how much you can get done in a short time with this framework, and the more I have a-ha moments with it, the more I think I won't be going back to just Java when I make the switch full time, especially in the knowledge that whether it's Groovy/Grails or JRuby/Rails, I can still fall back on familiar Java libraries. Yessir, this is a good time to be a nerd...

Friday, March 6, 2009

jQuery Goodness

This week I did a lot of client-side development.  Usually, this would be reason to cry and/or drink heavily, but this week, it was one of the more pleasant parts of my week.  I thought that I'd go ahead and share a one of the goodies that I experienced.

Thickbox

Thickbox is an awesome library that pops up a page that you defined as a dialog that can be modal if you specify that option.  It's pretty peppy, and looks sharp.  Thickbox uses decoration of links on a page (set up by specifying a class of 'thickbox').  Anchor tags are set up to register an onclick event that pops up a page that you specified, be it a static page, or the result of a server-side call.  Anything can be displayed in a thickbox.  It can be information, or a form that you submit back to the server.  It's been pretty simple for us, but I did run across an issue today.  I am loading some pre-rendered html into another div that displays as a floating popup on the page.  One of the links there needs to call an overlay that is loaded via thickbox.  The button was defined as an input, which should work, but all the documentation refers to anchor tags, so I figured that we could get around it by doing this:

<script type="text/javascript">

function showOverlay {

jQuery( '#floatingDiv' ).hide();
jQuery( '#hiddenTbLink' ).click();

</script>
<input type="button" id="id" onclick="javascript:showOverlay();" value="showIt">
<a id="hiddenTbLink" style="display: none;" class="thickbox" href="http://www.blogger.com/path/to/action"></a>
This hides the floating div and invokes the click action on the anchor tag that contains the thickbox element.  This should work, right?  Wrong.  The html is dynamically inserted into the DOM after the document.ready code is called.  That is where you perform the thickbox initialize call.  So, what we had to do is add call to tb_init() in the code that loads the floating div, thus doing the jQuery DOM manipulation and allowing the thickbox-enabled link.  Much better now.  I sat back with glee, realizing that in a few hours, I had enabled this floating div and figured out how, from that floating div, I could make a call to load a beautiful thickbox element.  It was all too easy.

Tuesday, March 3, 2009

Are You Doing The Right Things?

Are you doing the right things with your time? How would you know either way?!?

Let me preface this by saying that this will not be one of those posts where I tell you what the right things are. I don't have any clue. I am don't even know if I am doing the right things! Much of this post is me trying to justify the way I spend my time, because if there is one thing I do know, it is that you get 24 hours in a day, and you have to spend it right to achieve true success and happiness.

What does that mean? To me, it could mean that I spend more time with my wife. It could mean that I spend more time working on my guitar practice. It could mean more time at the gym, or running, or cycling. It could be more time spent on my entrepreneurial pastime. It could be just more time relaxing, reading books and listening to music. For some people, it could be working at their 'day job' for long hours, to be the absolute best they can be at their job.

In the end, what I don't want to do is regret the way I spend my time. I am pretty happy guy. Things are good. Great, really. I feel like an awfully lucky guy. I just don't want to look back and think that if I just done this, I could have done that, and so on. I suppose some would say that you know whether or not you are happy, because at the moment when you are doing something, you woudln't want to be doing something else. There must be something to the bliss of not having anything to do when you get home, but I remember in the years after college, just coming home and veg-ing out and feeling somewhat unfulfilled. I think what I've figured out is that the 'grass is greener' theory definitely seems to apply.

The biggest things you have to make sure of, in my opinion, are:

  1. You are always learning something, whether it be a barre chord on the guitar, a new programming language, or a new recipe
  2. You aren't doing things you hate to do just because "it seems like the right thing to do"
  3. You aren't neglecting the really important things in life (family, health)
  4. You are ALWAYS investing in yourself and your future

Even if you STILL don't know what you want to do when you grow up, as long as you are moving in the right direction it's okay. This can be achieved (in my experience) in three ways:

  1. Set attainable goals and attack them
  2. Check back on goals you have already set to measure progress and to decide if they are still applicable
  3. Once you have attained a goal, see how it actually affects your overall plan
By taking these steps, you can know if you are getting closer to your destination in life, and more importantly if your destination is actually somewhere you want to get to. I am still figuring it out, and if anyone knows of ways to keep all this mess straight and still sleep, I am all ears.