GWT can be Magical

The person or people responsible for the following must either be much more knowledgeable than I about JavaScript if statements, or simply more sinister. While pretty compiling one of my GWT modules today, I decided to take a peek at the generated source. As I was scrolling through the the module, my coworker pointed something out. This is what I found:

    if (function(){
      return ua.indexOf('msie') != -1 && $doc_0.documentMode >= 8;
    }
    ())
      return 'ie8';
    if (function(){
      var result = /msie ([0-9]+)\.([0-9]+)/.exec(ua);
      if (result && result.length == 3)
        return makeVersion(result) >= 6000;
    }
    ())
      return 'ie6';

After a few moments with a baffled expression on my face, he made the announcement that he would henceforth be performing all conditional expression evaluations within anonymous functions. I couldn’t agree more. I mean, what better way to mess with the person who will be reviewing, or worse yet, supporting your code? Now, I see what they did there in the IE 6 test. Quite the cleaver hack. Kinda. But to use the same mechanism for the IE8 test is just plain strange. Does anyone have a reason why this pattern might be desirable? I’ve since taken an oath to refrain from examining the generated crap, no matter how pretty it may proclaim to be, until I’ve come a bit further in my GWT mastery.

Ditching JCL for SLF4J

When discussing these two logging API's it really comes down to dynamic discovery vs. statically bound bridging mechanisms. As Ceki Gülcü wrote in his 2009 article detailing the problems with JCL:

Class loading problems encountered when using JCL fall into three main categories:
  • Type-I: A java.lang.NoClassDefFoundError thrown when a class is inaccessible from a parent class loader even if the said class is available to a child class loader
  • Type-II: Assignment incompatibility of two classes loaded by distinct class loaders, even in case where the two classes are bit-wise identical.
  • Type-III: Holding references to a given class loader will prevent the resources loaded by that class loader from being garbage collected.
The article goes on to provide highly detailed descriptions of the problem while including code samples demonstrating the bugs in action.

Well, it turns out that on seeing these problems with the JCL, the good people on the log4j project decided to go another direction and create the Simple Logging Facade for Java (SLF4J) project. From the SLF4J site:

The Simple Logging Facade for Java or (SLF4J) serves as a simple facade or abstraction for various logging frameworks, e.g. java.util.logging, log4j and logback, allowing the end user to plug in the desired logging framework at deployment time.

What does it do?

SLF4J provides logging related interface to code against. By doing so, the resultant code is implementation agnostic and has only a single build-time dependency (the SLF4J library). Implementations are specified by runtime classpath configuration. The inclusion of a single library either bridging to a specific logging framework (log4j, JUL, or even JCL) or a direct implementation such as Logback will trigger the use of that implementation by SLF4J's static binding mechanism. Finally, this API provides parameterized logging which improve performance.

How does this work?

Well, I'm summarizing here but, the core of the static binding code works by discovering implementations of org.slf4j.impl.StaticLoggerBinder on the application classpath. This magic is done in the LoggerFactory. Specifically at:

private final static void bind() {
  try {
    // the next line does the binding
    StaticLoggerBinder.getSingleton();
    ...

StaticLoggerBinder classes provided by SLF4J bridges or implementations tie the API to the concrete frameworks. Here's an example in Logback.

Just Use It

Coding against SLF4J will make your life a bit easier. Bridges erode excuses based on inheriting logging frameworks from your dependencies. Projects can freely float between logging implementations as capability and configuration requirements change. To quote Ceki Gülcü, "In summary, statically bound discovery provides better functionality, with none of the painful bugs associated with JCL's dynamic discovery."

Spring's Alternative Configuration Features

A primary complaint about Spring is the heavy XML configuration traditionally required to use it in a non-trivial way. More and more recent releases have made significant strides away from this model. With the introduction of annotation-based container configuration, Component beans, component scanning, and finally configuration beans, that argument has been largely deflated. These tools move significant portions of configuration from XML into annotation based equivalents. Combined with highly configurable classpath scanning, many traditional component beans like services or repositories can be auto instantiated and auto wired. This is a miracle for larger projects with hundreds of these singleton beans. But some of you might just be saying, "Doesn't this just move configuration from one common place, outside of code, into the code itself?" For those of you who have spent years fighting to get configuration out of code, this might seem all kinds of wrong. Well, if you find yourself in either of these groups - you're not alone - you are both right and wrong.

The reason is simple. All of that configuration, really isn't application configuration at all is it? Think of it this way, if you were not using a dependency injection pattern, all of this bean wiring is something that you would be doing in code by passing dependencies along in method signatures, or some other mechanism. We've all been there, and none of us want to go back. It is Spring configuration, not application configuration. In many instances these tools provide more powerful means of accessing your actual application configuration, which is why we use these frameworks. These make our lives more simple.

Simple is nice. But powerful is awesome. Enter the Spring configuration bean. These are beans which, when loaded via XML or component scanning, define beans to be loaded into the context. With these tools you can finally debug and unit test Spring configuration at a granular level, as well as create configuration inheritance models. Boom. But maybe the best reason to use this stuff is that it makes your Spring configuration much more reusable. No more copying chunks of XML, no more massive efforts to upgrade code bases. So, before you dismiss this stuff too quickly, take a few moments and try to think about how you could use it without violating your personal coding ethics. It will pay out in spades.

Oh, and for those of you who are still a bit buried in your XML configuration bunkers, good luck with the Servlet 3 specification.