For the most part, this blog will be designated as a place to discuss and explore the various aspects of metadata. However, in order to break up the monotony of having a continuous theme, I plan to occasionally break out of that pattern and write about something else on my mind. In this case, I’d like to take a moment to both admire and complain about the nature of Java development. Since I’ve been an enterprise Java developer on and off over the last couple of decades, I’ve gotten to know it fairly well. However, my last Java project at work was an Android app for the Nook platform, so it had been some time since my last foray into Gosling’s world of managed memory (especially in the case of enterprise programming).
So, I was enthusiastic about getting back into the Java saddle when a new project arose for our new web site. It was a modest project for me, being a standalone server that would handle REST-style requests; these requests would consequently spawn threads with intense I/O activity. In the past, most of my Java projects had used a proprietary mechanism for logging, but in this case, I wanted to update my familiarity with the thriving Java community. So, I incorporated log4J into my Maven project, and yet again, I remembered what is so wonderful about the Java ecosystem. This free and open source library provided so much functionality, with only minimal effort on my part. When I admitted such to a fellow Java developer at work, he deflated my joy when he told me that log4j was old news; he recommended slf4j as the new popular option instead, for a number of reasons. Interesting enough, one of those reasons was its ability to wrap around log4j, leaving your code preserved and without needing to be altered. Eager to be as contemporary as possible and to be as hip as the cool kids, I switched from using log4j to slf4j within my project, and in the course of doing so, I remembered what also vexed me about developing with Java.
My project had used the “fatal()” method in order to record failures of a systemic nature (i.e., an inability to establish a database connection), and when my project failed to build with the inclusion of the slf4j library, I assumed that the fault was a product of my own shortcomings. However, as I digged down into its documentation, it suddenly became apparent that the author of slf4j had decided a FATAL error was outdated and should be rendered obsolete. Instead, it recommended creating your own error lexicon with its supplied MarkerFactory class, into which you could then create a FATAL error. (The “error()” method itself, though, would still be available.) Immediately, I had questions. First (and foremost), shouldn’t it be imperative that any library wrapper NOT exclude the functionality of its underlying library? Two, why did this fellow decide to arbitrarily designate errors as something which required a more complicated schema? Why not do the same with non-errors, keeping the “info()” method but requiring the creation of a non-error lexicon for everything else (like WARNING and DEBUG)? When I looked online and found no voices questioning such a decision, I was reminded again of what can be annoying with Java and the open source movement at large. As with this example, open source software is a wonderful origin for free and powerful tools, but if you’re looking for backward compatibility and the clarity of design decisions, it’s not uncommon to encounter disappointment instead.