Tuesday, July 14, 2009

Porting RichFaces Portlets in WebSphere 6.1 Portal

This was painful week of trying to get the rich faces to get work in WebSphere Portal 6.1 running on the WebSphereAS 6.1. I used fully functional RichFaces 3.3.0.GA enabled Portlets (JSR 286) which work fine in JBoss Portal 2.7.1 with JBoss Bridge 1.0.0.CR2, JSF 1.2_12.

When deploying this Portlets on WPS, they got started, but running the Portlets always failed. The problem was closely related to RichFaces and it's filter and how the Mapping of the Resources URL was built.

The following Exception was trhrown:


Rendering View[/myportlet/view.xhtml]
javax.faces.FacesException: Resources framework is not initialised, check web.xml for Filter configuration
at org.ajax4jsf.resource.ResourceBuilderImpl.getWebXml(ResourceBuilderImpl.java:116)
at org.ajax4jsf.resource.ResourceBuilderImpl.getUri(ResourceBuilderImpl.java:323)
at org.jboss.portletbridge.richfaces.PortalResourceBuilder.getUri(PortalResourceBuilder.java:29)

In short it tells that the Filter resources are not properly installed in the web.xml.

I traced the org.ajax4jsf.resource.ResourceBuilderImpl.getWebXm method and on the place where this exception is thrown, it appears that the WebXml Object is null.

I read here that the Ajax4Jsf Filter is not running in WebSphere.

I started playing with the filter mapping in the web.xml. Depending on the Filter Mapping I used in the web.xml, I either get the Portlet to render the Standart JSF with out RichFaces components or I get the above message.

When the Portlet renders the Standard JSF, I looked in to the source code of the page and I see the rich faces panels etc. printed out to XML/JS but the components are not loaded or rendered.
I noticed that the Java Script links are possibly not loading, cause they look in my opinion not correct.
For example, in the Source code I could see:

which I tried to download this way:
http:// localhost:8080/wps/myappcontextpath/rfResorg/richfaces/renderkit/html/scripts/utils.js which always returned:

Error 404: SRVE0190E: File not found: /myappcontextpath/rfResorg/richfaces/renderkit/html/scripts/utils.js


I initially thought that the part:/rfResorg/ should be more like: /rfRes/org/ and the following bug in the jboss jira gave me additional thoughts on the URLs.

I still ain't clear if this was the root cause of the problem, but with additional configuration games, I actually got it to work.

This is how the AJAX4JSF Filter Configuration in the web.xml now looks:


richfaces
org.ajax4jsf.Filter


richfaces
/*
REQUEST
FORWARD
INCLUDE
ERROR


richfaces
/faces/rfRes/*
REQUEST
FORWARD
INCLUDE
ERROR




I added one General mapping for every URL and one to get the Resources through the Faces Servlet. Don't ask me why this works, to me it looks weird enough.

This is not the whole pie. Additionally to this, I had to add the following factory in the faces-config.xml:



org.jboss.portletbridge.context.FacesContextFactoryImpl



So that was it all about. I don't know if this might work on another configuration or even WebSphere Portal, but for now it works on mine.

One more important issue: set the Classloading policy as application classes loaded first. This will make sure that your classes in your WEB-INF/lib/* Directory will be loaded first.

This way, you can run JSF 1.2_12 on your WPS 6.1

Update:

It appears that this issue is caused due to a Class loading problems in WPS. According to some sources, WPS loads the Filters and Servlets with different class loaders. This results in an Exception when the Filter Mapping is configured as followed



Faces Servlet



In this case, only the ULR based mapping as shown above will do, since the Servlet instance is not known to the Filter instance.