Sunday 20 December 2009

Exception hell

All Java programmers have certainly encountered their fare share of excessively long, incomprehensible or just plain stupid stacktraces, but this one got me stumped when I saw it:

08:34:55,989 ERROR [jsp:165] java.lang.ClassCastException: com.icesoft.faces.context.ElementController cannot be cast to com.icesoft.faces.context.ElementController
at com.icesoft.faces.context.ElementController.from(ElementController.java:22)
at com.icesoft.faces.context.DOMResponseWriter.enhanceBody(DOMResponseWriter.java:294)
at com.icesoft.faces.context.DOMResponseWriter.enhanceAndFixDocument(DOMResponseWriter.java:239)
at com.icesoft.faces.context.DOMResponseWriter.endDocument(DOMResponseWriter.java:144)
at com.icesoft.faces.facelets.D2DFaceletViewHandler.renderResponse(D2DFaceletViewHandler.java:283)
at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:161)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:107)
at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:268)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:137)
at com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:18)
at com.icesoft.faces.webapp.http.core.PageServer$1.respond(PageServer.java:25)
at com.icesoft.faces.webapp.http.servlet.ServletRequestResponse.respondWith(ServletRequestResponse.java:161)
at com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet$ThreadBlockingRequestResponse.respondWith(ThreadBlockingAdaptingServlet.java:36)
at com.icesoft.faces.webapp.http.core.PageServer.service(PageServer.java:30)
at com.icesoft.faces.webapp.http.core.MultiViewServer.service(MultiViewServer.java:56)
at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer$Matcher.serviceOnMatch(PathDispatcherServer.java:50)
at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:19)
at com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet.service(ThreadBlockingAdaptingServlet.java:19)
at com.icesoft.faces.webapp.http.servlet.EnvironmentAdaptingServlet.service(EnvironmentAdaptingServlet.java:29)
at com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet.service(MainSessionBoundServlet.java:106)
Unless my eyesight has really gone, this exception is saying it can't cast ElementController to ElementController? Same name, same package, as per usual it's just a big bag of fail again. Why can't I just get a normal comprehensible exception and stacktrace for once?

This one is bad, but there is one that is much worse, the dreaded NoClassDefFoundError, but that one deserves its own post somewhere after new year.

Monday 7 December 2009

Liferay installation problem: Could not find the main class: . Program will exit.

A few weeks ago I was installing Liferay at a client and ran into a very weird installation problem. I was under the impression that I'd done everything correctly, but when I tried to start Liferay I got a baffling error message almost immediatly:

"Could not find the main class: . Program will exit."

As Eddie Izzard would say: Quod The Fuck! How can a simple Liferay install go this wrong? I followed some simple steps to install it:
  • download Liferay
  • transfer ZIP file to server
  • unzip the downloaded file
  • check installed Java version
  • check DB connection
  • configure DB connection in portal-ext.properties
  • start Liferay
By now I've done this simple procedure more than a few times and it never failed, ... until now. So I was kinda gobsmacked. I started digging around, but couldn't find an obvious cause. Also Googling didn't turn up any leads. So I was on my own and decided to start from the beginning and check every line in the Tomcat start script and quickly found that strange things were happening with the startup classpath, hence the empty main class name. A JAR file seemed to be missing: bootstrap.jar.

How could that be possible. I downloaded a fresh Liferay ZIP that unzipped without problems. Then I remembered a long pause during the download around the same time the datacenter people were fiddling with the firewall. A second fresh download later, this time without hickups, I was able to run a file size check against the old download and what do you think: the first download was 20Mb smaller.

How it was able to unzip with throwing obvious errors I still don't know, but after deleting the previous install, unzipping the new one, Liferay started without any problem.

Email containing cid

Did you ever receive an email containing a line that looks like this:

[cid:163091419@01122009-2514]

This probably means that something, in my case an image, is attached to the mail or embedded in it, but the email client, isn't able to process it correctly. There's an easy way to still visualize it.

Just open the email source and find the correct mail part, this should look something like this:
------=_Part_42520_1491296619.1259746973647
Content-Type: image/png; name="Picture 9.png"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="Picture 9.png"
Once you've found this you'll know what the type and encoding of the missing attachment is. Now you'll just need to select the block of encoded text, drop it in a suitable decoder, save the result as a binary file and hey presto!