Monday, October 27, 2014

How to burn your weekend, with jackson-mapper

TL;DR - version 1.5.3 in pom.xml was wrong; changing to 1.9.10 fixed it.

We are still knee-deep past our project deadlines. There we were, generating the EAR file to be deployed on to our HSM-laden servers in office. Introduce my version. I'd been mucking around happily developing my own stuff. Now comes my turn to deploy my version merged from CVS into the JBoss. I'll just cut it short to say that, other than my version, nobody else could get a specific ajax function to operate properly.

The team became stuck for a day or two. Washing my hands off of it, "it was working when I left", and several hours later, they still couldn't get the clean CVS copy to do the job. None of their EAR files could. Then Saturday late night comes, and a colleague decides to head back to office after dinner. I joined her remotely from home. She mucked around for a good 2 hours. Still no dice. Then she decided to drop my webapp WAR into her EAR. It works! She diff'd the archive contents in BeyondCompare, and found several differences. We tested out several theories, but to no avail. It was around 2.30am when we pretty much decided to give it a rest.

Before she left, she noted one difference for me to investigate, since I was planning to head down this morning. The /lib files contained 2 different pairs of JAR files. Both jackson-mapper and jackson-core JARs represented themselves differently in her WAR and mine.

After researching, it turns out jackson-mapper has a dependency on jackson-core, meaning they should always come in pairs. I had both pairs of version 1.5.3 and 1.9.10 in my WAR.

Come morning, I was in the office testing out this newfound theory. In order not to let my miraculous EAR interfere, I only meddled with a copy of the EAR left behind for me by my colleague.
  1. Control test - deploy her original, untainted EAR; true to form, the ajax call is broken.
  2. Replace both jackson-mapper and jackson-core with v1.9.10 inside WAR; hurray, it works!
  3. Additionally, due to extra instructions with another colleague, remove jackson-core and leaving solely jackson-mapper v1.9.10 within; expectedly, it doesn't work. His impression was our pom only indicating the use of the mapper JAR and not the core JAR, so maven truly did its job behind the scenes by including the required dependency without us even realising.
After some hemming and hawing because this guy is reluctant to upgrade from 1.5.3 to 1.9.10, in case it breaks anything else, I barely persuaded him to go ahead with it anyway or it'd remain a showstopper.

Our pom was indicating 1.5.3 all this while, because nobody wants to rock the boat with a new version since it works. Even though v1.5.3 is 4 years old and 1.9.10 is 2 years old at best. The version number in our pom for jackson-mapper was updated, so that the maven on everybody's machines would know to use the newer version instead.

Was it that hard to identify the problem? The server never provided any feedback in our logs. The ajax function obviously did its job, since the database was updated because of it. But with v1.5.3, the result never returned to the browser. The culprit could either be due to the @ResponseBody implementation being unavailable in 1.5.3 (unlikely), or the fact that the ajax call was using the jQuery implementation on a POST method instead of GET. We don't have time to point any more fingers.

The problem with the multitudes of libraries and frameworks available, is that through such obfuscation, identifying problems like this can become increasing difficult. And not forgetting the convenience of the Spring framework that performs autowiring with annotations. Those files compile fine and are happily packaged into WARs, JARs and EARs. Except they'd quietly fail at runtime.

Our project continues on its way with our testers picking out the bugs.

No comments:

Post a Comment