java.lang.UnsatisfiedLinkError: no ocijdbc9 in java.library.path

So I’m trying to configure a servlet running on Tomcat to connect to IBM’s DB2 Content Management system (via II4C). I can get it to run under WebSphere using Rational Application Developer but seeing as I want to buy a MacBook Pro for my development, I figure I need to start using a more vanilla toolset. Martin Fowler‘s Ravine post served as part of the inspiration. I actually believe it’s a good idea to build J2EE apps using a variety of tools…proves the openstandardiness of my work. The fact that I’m calling a client app from a server (II4C is a windows installed app) disproves that a little but whatever…the next stage will be abstracting that beastie behind some enterprise service layer and that’s that

The error comes from the driver’s need for the presence of ocijdbc9 in the container’s library path.  Yeah, I know the use of Oracle’s thin driver eliminates the need to this coupling but in this case, I’m working with someone else’s project…they’re using this driver.

So add <<oraclehomedirectory>>/bin to the container’s Libary path and you’re back in the game…

Words collide

I think one of the most important virtues of a software professional is being fearless. Someone can lack fear for many reasons:

1) They’re naive

2) They’re stupid

3) They’re experienced

A naive or stupid person is either naturally or consciously ignorant of the risk involved with the activity they’re about to embark on. The first can be forgiven until becomes a trend (in which case they’re starting to become the second).

J.B. Rainsberger once wrote (in JUnit Recipes):

Test until fear turns to boredom.

Taken up a level, it means do the little things that help you become fearless. Don’t just act without fear.

File Upload, Portal, JSF and not being surprised…

I’m writing a portlet that allows a user to modify certain LDAP attributes.  It’s a nice little solution (if I do say so myself), wrapping IBM’s PUMA framework with something a little more durable, a little more generic and a lot less IBM.

The customer would like the user to upload their own picture.

“Yeah, shouldn’t be a problem…” I say, recalling the File Upload control on Rational Application Developer’s JSF palette…famous last thoughts.

IBM, in their wisdom and glory, have shipped some JSF components that don’t work with their Portal solution.  They’re available for use in a Portal project, they just don’t work… (bonus points to me for looking it up in the documentation rather than bugging the local IBM on-site consultant).  I guess that makes sense…

This means a trip to Apache and a chance to try the Commons File Upload component (apparently it works with Portal…I won’t get into why I find this entire thing so hilarious).

EJPPG0003E: ServletContext lookup for /.CreditCounterPartyReviewLog returned the portal context. It has to be a different one.

I’m working on a Portlet project right now. It helps a group over at TransAlta keep their financial obligations and exposures in check. I like the application…it has great business value, terrific customer participation…a great project.

A second developer was introduced to the project recently. He brought the portlets down from CVS and tried running them on his workstation. The received the following error:

2006.08.23 13:37:49.064 E com.ibm.wps.pe.om.definition.impl.WebApplicationDefinitionImpl getServletContext
EJPPG0003E: ServletContext lookup for /.CreditCounterPartyReviewLog returned the portal context. It has to be a different one.

hmmm, what does that mean? He created an EAR file to associate the project with…ahh, but wait! When Rational Application Developer associates Web Modules with an EAR, it doesn’t give it a context root. It tries using the context root for the Portal itself (uh oh) and then throws the exception found above. Fixing it, as my good friend from IBM Thomas Young discovered, is quite simple. Open the EAR, find the module reference and click ‘Refesh’ located beside the Context Root field.

ReDeploy and run…Right Side, not cropped

Refactoring

My wife and I took the kids out to Nipika for a four day weekend. It’s a wonderful place, I’d highly recommend it to anyone looking to get away from the hustle and bustle of city life for a while.

The last thing I did before leaving was export a .war file for release to my client’s Test Environment. I’m starting to learn the last thing you do prior to holidays is rarely the thing that causes the biggest upset while you’re gone. The second last thing you do prior to holidays…now that’s a different story.

As I prepared to export the .war and send it through the deployment process, I noticed something. I noticed a package within the code base with the following name: “org.transalta.creditservices.managedbeantests”.

I like to maintain two projects for every stream of production code, one for the code and one for the tests. That should explain why a package in my deployment release with ‘managedbeantests’ in its name seemed out of place. It’s not uncommon, it usually means I forgot to change the package name at the time of the classes creation. Since I typically create a class from within the context of my ‘Test’ project, it stands to reason why this happened.

No big deal.

So just before exporting, I refactor the package by changing its name to match the other managedbeans, “org.transalta.creditservices.managedbeans”…done. Export .war, send to Tommy and it’s a 4 day weekend.

I return Monday morning to find a note from Tommy, the deployment administrator. To summarize the content of the note, “Jamie, your deployment didn’t work”.

What?!?! Impossible. It worked when I left, I remember deploying it to my development environment right before packaging it up and sending it to Tommy, he must be mistaken. A thread of emails later, he’s right. It’s not working in either Project Dev or Test. I fire up my development environment to prove that I’m not nuts, that it worked just before I left.

It didn’t work.

again, What?!?!?

I spend 5 minutes thinking about the deployment and what may have gone wrong. I focus on the last thing I did before leaving (packaging the .war). A quick look at the code and I find an empty package, “”org.transalta.creditservices.managedbeantests”. Ahhhhh…a clue.
I moved the class but didn’t delete the package (lucky much?). That was enough to trigger my memory, a path to what may have happened lay ahead…. The class I moved is a JSF managed bean. These are beans used within JSF and registered with the JSF context. That means, you guessed it, an explicit reference to it within the faces-config.xml file (bloody xml!?!?!).
Oh, and by the way, nice exception logging JSF, “cannot instantiate ReviewLogManagedBean” (not even the bean in question, just the first referenced bean in the faces-config.xml file.  Almost as useful as Portal’s ‘AssertionFailed’ exception in the log…thanks guys.

I pop open faces-config.xml and there it is, a reference to the old package location. How foolish could I have been? I changed the reference to the new locations, ran it in Dev (it worked), deployed it to Tommy (it worked) and informed the customer (it worked).

So rather than learn a lesson over and over, I thought I’d jot down my lessons learned on this little adventure.

1) Never make a change between final test and deployment, no matter how trivial you think it is. Make the change, rerun your local tests and deploy (Comp. Sci 101, I know, I know)

2) Refactoring tools within Eclipse 3.02 are good, just not good enough to know about references within an XML file. 3.02, I know, is old but it’s what IBM use for Rational Application Developer (tool of choice here).

3) When a container driven exception is thrown and you’re working with JSF, take a look at the faces-config.xml file. It’s worth a shot and really, that’s the heart of the framework.

4) Never make a change between final test and deployment, no matter how trivial you think it is. Make the change, rerun your local tests and deploy (Comp. Sci 101, I know, I know) [worth a second mention]

5) Don’t release anything within 2 hours of a vacation and leave yourself a note.

6) Don’t fry bacon in a cast iron frying pan over a bbq in the mountains if you don’t want to smell like  bacon for the rest of the day.