Tuesday, September 29, 2009

NESS 2009: multithreading and the Java memory model

At the New England Software Symposium, I attended Brian Goetz's session called "The Java Memory Model". When I saw the phrase "memory model" in the title I thought it would be about garbage collection, memory allocation and memory types. Instead, it is really about multithreading. The difference is that this presentation focuses on visibility, not locking or atomicity. This is my attempt to summarize his talk.

Thursday, September 24, 2009

On the lightness of Spring

Shortly after I blogged about the direction of Spring, I came across a blog entry asking "Is Spring still lightweight?" The resulting DZone discussion is spirited, but last I checked it nobody actually defined what it means to be lightweight. That seems unfortunate. If the Spring folks are no longer right in their claim to be lightweight, we should at least have a falsifiable proposition. Way back in 2004, Rod Johnson in his book "J2EE Development without EJB" defined the characteristics of a lightweight container (summary of chapter 6):
  • Non-invasiveness: imposing minimal special requirements on application objects run within it
  • Quick start up
  • Lack of any special deployment steps
  • Light footprint, enabling it to run in any architectural tier
  • Ability to manage objects of any granularity, including fine-grained objects that cannot be modelled as EJBs.
Now when we look at SpringSource's mission statement today concerning the Spring framework, we see pretty much the same ideas. They no longer talk about a light footprint, though the spring.jar super-bundle in the 2.5.6 release is still under 3 MB. While you can get the footprint much smaller by using the individual Spring modules (spring-core.jar, spring-context.jar etc), I don't think the footprint is an issue.

What Spring really stands for is the non-invasiveness: the framework helped make POJO development trendy. We have Spring to thank for the new status quo in enterprise Java, where we don't have to inherit from mandatory classes, write unnecessary boilerplate or otherwise deal with much accidental complexity. Spring's idea of lightweight containers --along with Hibernate -- gave us dependency injection, AOP, declarative transactions and POJO object persistence. When we think of Spring as being lightweight, we really mean its adherence to the principles I quoted above.

There are some aspects of Spring that I find unnecessarily tedious, verbose and complex. Sometimes, I am tempted to apply the word "heavyweight" to Spring. And it is true that SpringSource has become a big company with a confusing proliferation of commercial products. But I would not deny the title of "lightweight" to the core Spring framework according to principles defined by Spring, nor would I begrudge a measure of gratitude to a programming paradigm that transformed an industry.

Wednesday, September 23, 2009

KBLauncher for BlackBerry has launched

I released my latest BlackBerry app, KBLauncher, last week. So far, the major BlackBerry blogs that have mentioned KBLauncher are CrackBerryBerryReview and BlackBerryItalia. I also partnered with BerryReview for a giveaway program. All 50 copies of KBLauncher were snapped up within the half hour. People do love their freebies.

KBLauncher is an app that I have been wanting to write for a long time. I have a personal policy of writing only apps that I would want on my own BlackBerry. KBLauncher is an app launcher/switcher that gets its inspiration from a number of familiar desktop applications, such as Bash, ENSO and the IDEA/Eclipse class name lookup. It addresses the too-many-apps problem in a way that I find both efficient and intuitive.

Tuesday, September 22, 2009

NESS 2009: The Coming Spring

One of the sessions I attended at the recent New England Software Symposium is the one on new features in Spring 3. This covers Spring Core functionality. This session got my attention because the presenter was Craig Walls, who wrote Spring in Action. The main features he covered were:
  • Spring Expression Language (SpEL)
  • Spring MVC annotations (@PathVariable, @RequestHeader, @CookieValue, @RequestParam defaults), some to support REST.
  • jsp tag to generate context-sensitive URL
  • Declarative validation of some sort that may or may not make it
  • Etag support
  • HiddenHttpMethodFilter (more Spring MVC REST support)
  • ContentNegotiatingViewResolver
  • RestTemplate
  • JavaConfig (Java-based alternative to XML wiring). This has been around for a while, but is being bundled in Spring 3. 
  • Object-to-XML mapping from Spring-WS
  • Java 5 support

Friday, September 11, 2009

New BlackBerry app in beta: KBLauncher

My latest BlackBerry app KBLauncher is finally undergoing beta testing. KBLauncher is an application launcher and switcher. My idea is that a keyboard-intensive device like a BlackBerry would have users that prefer to use the keyboard rather than scroll endlessly with the trackball to find an app to launch. Oh, and I think the UI is pretty slick too.

This has taken longer than I expected. Part of this of course is the nature of a hobby: I can -- and did -- put the project aside when more important issues came up. But the problem is also technical: the vast BlackBerry installed base comes at a cost, and that cost is the large number of models and operating system releases out in the field. The API for launching apps does not behave consistently across releases. Something that was possible in OS 4.2 stopped working in 4.5, and the workaround in 4.5 does not work in OS 4.6. And a bug in 4.6.0 was fixed in 4.6.1. You get the idea. I spent a lot of quality time with various simulators, and while they are a great development tool, they have their limits. Unfortunately, as a hobbyist I don't have full time QA staff nor a stockpile of test equipment.

This is why this beta period is critical for me. It's not a marketing exercise. I am hoping to find a sufficient number of beta testers who care enough that KBLauncher works to report bugs and collaborate with me.  KBLauncher will likely not be perfect, but I hope to make it work fine in the most common cases.

Thursday, September 10, 2009

Going to the New England Software Symposium

I will be attending the New England Software Symposium this weekend, and I am really looking forward to it. Unlike most tech conferences I've been to, this one is actually held over a weekend. The advantage to this is that it allows participants -- both attendees and speakers -- to participate without sacrificing productive time. I suspect this made it easier for me to get approval from my boss. I sacrifice family and personal time, but the sessions look really valuable. I hope to blog a bit about the topics discussed there.

The App World torture continues

I have a handful of BlackBerry apps published on RIM's BlackBerry App World, the "official" app store for BlackBerry phones. Recently, I have been getting emails daily from users who have trouble downloading my applications. The problem is actually with the on-phone App World application, which can get stuck trying to download an application. App World does not make it easy to figure out who to contact for help with the store, so its users click on the tech support link for the individual apps instead. Those tech support requests, of course, go to the app publishers such as myself, who are in no position to fix App World problems.

It has been a rough ride for many publishers of apps on RIM's store. In their rush to match Apple's App Store, RIM released App World store software that remains buggy and immature. When it first opened in April, App World 1.0 had a glaring bug: for software that sold as try&buy, the store would either deliver paid versions to people who downloaded the free trial version, or delivered the free trial version to people who paid for the full version. This bug was only fixed in App World 1.1, released months later at the end of July.

App World is not the only option for publishers of BlackBerry software. Stores like Mobihand and Handango have been around for years, and you can publish for free. It is a bit of a shame, really: these older stores are in many ways more mature. For example, Mobihand's vendor portal lets you issue coupon codes, set promotional pricing, set prices as low as $0.99 and issue refunds. None of this is possible with App World. So why do I publish on App World? The reality is that for all its problems, App World still has the highest sales volume among the 3 BlackBerry app stores I am publishing on. It probably works fine for most people most of the time. Unfortunately, I have to deal with the exceptions.

Friday, September 4, 2009

Logging: should I wrap?

Once upon a time, there was a de facto logging standard, log4j. Then Sun decided to confuse matters by introducing another -- and many say inferior -- logging API in JDK 1.4. Some people responded with Jakarta Commons Logging (JCL), a wrapper that abstracts away these two APIs. Some other people decided that JCL was awful, and wrote SLF4J, a wrapper that abstracts away the first two APIs and JCL. There are also other logging implementations like Logback and x4juli, but fortunately these natively implement the existing APIs so they don't multiply the confusion.

If you start work on an existing project, I suppose you'd use whatever logging API is already in use. If on the other hand you are lucky enough to start a brand new project, you have to choose from a number of logging APIs:
  • log4j
  • JDK Logging
  • JCL
  • SLF4J
The conventional wisdom is that if you are writing a component or library, you'd likely choose one of the wrapper APIs (JCL or SLF4J) since you won't have control over what logging implementation the actual app will use. On the other hand, the conventional wisdom continues, if you are working on a standalone application you might as well code directly to the native APIs since you can pick the logging engine and are unlikely to switch. Even SLF4J's docs say that you needn't bother with SLF4J for standalone applications.

I have joined projects that build J2EE applications almost from scratch, so we got to pick the logging API. My initial inclination was the direct approach: we'd code directly to log4j. After all, why add an unnecessary abstraction? In one project, we ended up using SLF4J, even though we had no intention of switching logging engines. Why? Well, it turns out that SLF4J has a useful feature that log4j does not: parameterized logging. Ordinary logging messages incur the overhead of building the log message even if the message will not be logged at the current log level:

logger.debug("Value of obj#" + i + " = " + obj.toString());

All that work will be wasted if you are logging at the INFO level. The performance penalty could be significant if obj.toString() is particularly heavy. You could wrap that line in an "if (logger.isDebugEnabled()) {...}" block, but that adds clutter. SLF4J lets you defer evaluation of any String conversions until the line is actually written:

logger.debug("Value of obj#{} = {}", i, obj);

Does this minor convenience justify throwing in yet another 3rd party library? We did not need to answer that question. In a substantial app, there is no extra overhead. Quite likely, as in our case, the third party libraries you use will require JCL (e.g., Spring) and SLF4J (e.g., Hibernate) anyway. It's up to you to choose the API for your own logging. For us, SLF4J came along for the ride, gave us the parameterized expressions and still exposed powerful features like Mapped Diagnostic Context (MDC). Where is the downside?

In another project, we coded straight to the log4j API. This project was coded almost entirely in Groovy. In Groovy, we get lazy evaluation for free, so SLF4J offered no API benefits. The Groovy logging code below lazily evaluates its parameters regardless of logging implementation, and more concisely than SLF4J:

logger.debug "Value of obj#${i} = ${obj}"