Sunday, July 19, 2009

Q: What is the warranty of Open Source?

A: Here, you figure it out.


This posting is rated
PG
[Pretty Geeky]
Knowing about code is helpful,
but not required
.

After seven years of enterprise programming in .NET/C#, over the past year I've been relearning the hardcore aspects of enterprise level Java. Maven, Spring, Jetty, Jersey and Eclipse have become my new and free-for-download best friends.

It was hard breaking away from the Redmondians. But after the bait and switch tactic of ASP.NET MVC, I decided to take a rest from the lemming like culture of Visual Studio's "Productivity Out of the Box". I mean, couldn't those guys on Lake Washington figure out that ViewState was a bad idea from the get go?

Anyway, all aspirations come with a price and a story. This is mine:

A few weeks ago I got this bright idea to exercise my Java coding prowess by making a Java library that provides a randomization service against often used data, in this case the city, state, longitude, latitude information associated with a given United States Postal Service zip code.

It was a simple idea. The library publishes a method, getAddress(). Behind the call to getAddress() is code that gets a random Address object from a list of Address objects. The list of Address objects is composed of data that resides in an XML file that contains all the address information for zipcodes in the United States.

The XML file is embedded as a resource in the Java project to allow the library to be transportable. I got the zipcode XML file from the Internet. The effort seemed like a no brainer.

So I make the library code as a Maven project under Eclipse and write my unit tests every step of the way using TestNG. (I am obnoxiously loyal to Test Drive Development.)

I run the unit tests under Eclipse and also from the command line, just to be extra special sure. No problem. All works as planned. At the end of it all I have a nice JAR file which I can share with my coding brethren and qualified family members.

Then I get another bright idea, "Say, wouldn't it be great to expose my Random Address library as a REST service". After all, I am just as susceptible to coding trends as the next guy. So getting a handle on writing a Java based REST service using that new fangled OpenSource project, Jersey, seems a nice way to kill two birds with one stone.

(This is the part in story where the skies beginning to blacken. Evil things are about to happen.)

That night I go home from the day job and begin to read up on Jersey. It seems that all the code examples on the Internet are referencing beta versions of the Jersey artifact, which is weird because I know for a fact that there is a 1.0 version in play. All the coders at work doing REST under Jersey are using the 1.0. Anyway, I figure to myself, what the hell, just get the Jersey code examples to work and take care of upgrading to 1.0 later.

So I do. I use Jersey to get a simple REST site up and running under a Jetty web server.

Then I fiddle with the code to my Jersey REST site to make calls to the API in my Address Randomizer JAR/Library.

You know what? THE ADDRESSS RANDOMIZER LIBRARY DOES NOT WORK!

I figure, OK, I'll work around the Jersey enabled web code; after all maybe the beta version really is a dog. I write a unit test within the REST Web project that accesses the Address Randomizer directly, straight call to the JAR file.

THE UNIT TEST FAILS TOO!

I ask a colleague for guidance. He says to debug the unit test in the Web Project as a remote server. So, I fire up the Surefire debugger from the command line and bind in the unit test under Eclipse.

(Now for those of you common folks that are looking for breathing apparatus by which to survive this descent into the perilous depths of Java coding, please know this: if all this geekiness is causing you to lose interest, take heart! Read on knowing that in 5 years all of this technology will be replaced with a whole new set of gizmos that will be just as hard to learn and equally exasperating to use.)

Back to the coding.

So I look at the code under the remote debugger. It turns out that the XML file is not loading under the REST Web Project. I don't know why. All I know is that there is a null value where the file based InputStream transformed by getResourceAsStream() is supposed to be.

The wheels begin to spin and the self-doubt sets in. What am I doing wrong? What don't I understand? Am I loading the resource properly? Is there something about the Jetty web server that I do not understand? Is the Jersey beta code that wacky? Is there something more about the XML file format that I need to learn?

I go to lunch with a coding friend. We talk about the problem. He says that I might want to check the XML to make sure that the prolog is correct. And, he goes on to say, that it's a real craps shoot coding to XML in Java because all the XML parsers seem to work differently.

So, I fiddle with the encoding. Still, the XML file won't load.

I do some new coding in the original Address Randomizer library using the Xerces parser directly. I get a new error: Content is not allowed in prolog. I track down the error message on the Internet.

At one point I am taken to a Java bug report, UTF-8 encoding does not recognize initial BOM.

I think, can it be this deep that I have to start looking at bytes in the XML file? But, I figure, what the hell? At this point I'll do anything. I am that frazzled.

So I download the workaround code. The code is literally doing byte inspection, not my favorite topic in the world of computer programming. Turns out that the code had portions commented out. Can I trust this code? I go through it line by line trying to follow the logic. It seems that some of the comments were left in by error. I start uncommenting code. Then recommenting code.

Three hours later I am still at a standstill. I go to sleep quivering in my bed completely obsessed about the error of my ways. I just can't get it. The code is working running the unit tests under Eclipse. But, when I try to use the code in the REST Web Project, running against Maven from the command line, it fails.

It's a new day. It's the weekend. I can hit the code really hard.

So I start fresh, getting ready to completely rewrite the whole Random Address library. Then I notice something.

I try to follow good coding practice. Thus, I put the name of the XML file in the resource as a constant value like so:

/** The Constant ZIPCODES_FILESPEC. */
private static final String ZIPCODES_FILESPEC = "zipCodes.xml";

Just for giggles, I look at the name of the resource file in the file system.

The name of the XML, zipcodes.xml.

Again, the name of the XML file in the file system is, zipcodes.xml. The value assigned to the constant in my code is, zipCodes.xml. One little 'c'!

So I go back and change the constant value to:

private static final String ZIPCODES_FILESPEC = "zipcodes.xml";

The code works everywhere!

So what do we have? I spent at least three evenings trying to find the bug and fix it. I took the time of at least two of my friends trying to leverage their expertise to solve my problem. All for what?

Here's for what: Learning that the libraries under Eclipse will load a resource file, case insensitive against a filename:


/**
* This is a helper method that fetches an Xml file that is embedded as a
* resources as an InputStream and converts that input stream into a string
* that represents an in memory representation of that Xml file
*
* @param resourceFilename
* the name of the xml file. You do NOT need to prepend a '/'
* symbol to the file name. This method make the prepend for you.
* @return the xml file as a string
*
@throws IOException Signals that an I/O exception has occurred.
*/
String getXmlFileString(String resourceFilename) throws IOException {
InputStream is = this.getClass().getResourceAsStream(
String.format("/%s", resourceFilename));
return convertStreamToString(is);
}



While the libraries in my Web Project will not!

Had Eclipse failed from the get go, I might have noticed that one little 'c' a whole lot earlier and avoided many a night of fitful sleep.

I love to code, always have, and always will. Coding is an enormously demanding, yet intensely satisfying creative experience that's hard to describe to anybody but another programmer. Still, when I signed up to work with code as a way of life, I don't remember reading the paragraph that said to be suspicious of all that you see and never to expect anything to really work, particularly if you follow the Way of the OpenSource.

It's like this: most painter's don't have to know about the in's and out's of each type of paint in order to make a portrait. Paint making is mostly a third party affair. An artist gets some paint and executes the intention.

I really wish that the same could be said of OpenSource programming. I do. I really, really do.


Muse Alert!

I need to thank my wife for her patience on this one. I spent the whole weekend getting the code to run and then writing up on it.

She didn't give me any trouble at all; no "You are spending too much time in your geekiness."

Most guys would have been sleeping on the couch for lesser offenses.

Sunday, July 05, 2009

Q: What happens when work goes away?

A: Society goes insane

No doubt about it, the bubble's blown and payment is due. Without a moment's thought I can come up with three friends that are out of work.

It seems as if every Saturday the number of people trying to resell old clothes, VHS players and tattered furniture along that stretch of block on Venice Blvd, just west of Sawtelle is getting bigger. The sellers are people that used to work in kitchens, haul lumber at job sites, trim trees and do light assembly in local plants. The work that they did was provided by an economy that was based on funny money. And that money is long gone and it ain't never coming back; neither are those jobs.

So this where we ended up. It's like some scene out of Metropolis where the cream of society dress in white and live far up high in the clouds. The laborers dress in black and everyday march into the bowels of the earth in a eerie lockstep to man the gears of industry. Sort of like working on the line in what used to be GM. Only now they march in lockstep to the unemployment line, food stamp office or, if INS status is wanting, the nearest border.

The sad fact is that, for a variety of reasons, more and more people will be unable to participate as wage earners in the modern economy. We've moved way beyond the value of labor being the brawn of one's body. And, that taking advantage of entrepreneurial opportunities in most situations comes with a need for significant amounts of capital means that you can kiss goodbye the notion of starting an empire by selling oranges on the side of the road and reinvesting the profits. Fact is, the only viable side of the road to be had has 4 lanes in each direction with a name that starts with the letter "I", as in I95 and I80. Mickey D, Pizza Hut and Burger King tied those locations up a while ago.

Besides the important aspect of providing money to put food on the table, work organizes one's self and one's society. Ever since being ejected into the world, we've had agents that have organized our sense of self. When we were infants our parents held us and talked to us, even before we could figure out what they were saying. The subliminal message was,"You exist, you exist". We needed the ongoing message for our identity to emerge.

Then as we got older, regularity set in. Most of us had a specific meal time and bedtime. Then it was time to go to school. Our week became organized. School was soooo boring. But, as much as we hated it, the structuring of time further enhanced our sense of self and brought predictability to our world.

After school, we went to work. For some of us who were lucky enough, our life had meaning. But no matter what, just about all of us had structure. The notion of being without ego was kept far away. If we had no internal sense of existence, then that was easily provided by the alarm clock going off each morning.

But what about those of us that didn't have the parent telling us that we existed, the predictable meal and bed time and all the external structures that take a blob of undefined identity and evolve it into a mature human being? What's happens to these people?

Well, if the world won't on its own provide the structure required to differentiate, then these type of people force the world's hand. They injure themselves in public view. They'll get caught for a grand or petty crime that ends up having time structured for them: jail. In some cases they'll just join the military.

The human psyche needs structure.

Which brings us to work. Here's the deal. All the talking heads are saying that we are going to have significant unemployment for a long time, maybe forever. It takes a lot of smarts to participate in the modern economy. After a while the UPS packages will figure out how to deliver themselves and all the movie theaters will be in your house, even the 3D ones. We won't need drivers or ushers.

The birth rate might go down. But, without birth control in the water supply that's debatable. So there is a good possibility that we'll have a lot of people sitting around with no place to go, without need of an alarm clock. The external structures that reinforce ones sense of self will diminish. An ego without identity is an ego in panic.

Then as far fetched as it might sound, if the unemployment rate is high enough, for long enough, society just might go insane.