Tuesday, July 28, 2009

Tapestry 5.1 on JBoss 5.1

Well, today I tried this configuration and guess what... it didn't work! We all know who to blame (and this is not the Tapestry guys)! Now, what can we do about it?

The information on Tapestry wiki states that there is a workaround required for Tapestry to work on JBoss 5.0.x. The wiki says also that the workaround wouldn't work with JBoss 5.1. Hmmm... to bad, but why wouldn't it work?

I've decided to debug the code I got from the wiki and take a look at the behavior differences on both versions of JBoss. After an hour of debugging I found out that the URLs to the resources are build differently for jars which are packed inside of wars. There is however easy way to make them look the same.

Here's my patch for the original workaround at Tapestry Wiki.


...
public URL convert(URL url) {
if (url != null && url.getProtocol().startsWith("vfs")) {
// supports virtual filesystem used by JBoss 5.x
try {
URLConnection connection = url.openConnection();
Object virtualFile = invokerGetter(connection, "getContent");
Object zipEntryHandler = invokerGetter(virtualFile, "getHandler");
Object realUrl = invokerGetter(zipEntryHandler, "getRealURL");

// start of the patch (small fix for JBoss 5.1)
if (realUrl.toString().endsWith("jar")) {
Object localPath = invokerGetter(zipEntryHandler, "getLocalPathName");
Object context = invokerGetter(zipEntryHandler, "getZipEntryContext");
Object tempUrl = invokerGetter(context, "getRealURL");
realUrl = new URL(tempUrl + "" + localPath);
}
// end of the patch
return (URL) realUrl;
} catch (Exception e) {
log.info(e.getCause());
}
}
return url;
}
...


Now, you may enjoy having Tapestry on your favorite application server... and wait for a more professional workaround from Apache guys.

No comments: