AnsweredAssumed Answered

How-To: Installing Alfresco 2.0 on GlassFish v2

Question asked by nickmalthus on Mar 8, 2007
Latest reply on Oct 5, 2008 by chndu6ue
Alfresco deployment to GlassFish

I noticed that the Alfresco forums and documentation did not mention many references to deploying Alfresco to Sun’s open source application server GlassFish. I wanted to run Alfresco on GlassFish so I spent a considerable amount of time the past couple of days attempting to do so. I wanted to share what I discovered during the process for future reference and to assist with making Alfresco more portable across application servers.

My first attempt at running Alfresco 2.0 on GlassFish v2 B37 with JDK 1.6 involved removing the myfaces implementation and letting Alfresco use the JSF 1.2 implementation included with GlassFish. After all, the JSF 1.2 spec claims to be 1.1 backwards compatible in most cases.

The first issue I encountered was that when I attempted to deploy alfresco to GlassFish I got an OutOfMemory genPerm error. I was able to quickly fix it by running the asadmin command

asadmin create-jvm-options – "-XX\\:MaxPermSize=128m"

I also placed the cryptix-jce-provider.jar in the GlassFish Domain’s lib directory to fix a security issue I encountered.

The Alfresco 2.0 WCM web UI is based on Java Server Faces 1.1. However, it is not completely portable across JSF implementations. There are several dependencies on the MyFaces implementation classes, most notably org.alfresco.web.ui.common.Utils and the call from generateFormSubmit to the myfaces HtmlFormRendererBase.addHiddenCommandParameter(). This utility method generated many of the links in Alfresco and without it working correctly none of the links in the WCM application would function properly (one can’t generate myfaces links that the Sun RI understands). According to the myfaces comments in the HtmlFormRendererBase  code the need for this method was addressed in JSF 1.2 but I did not know enough about JSF 1.2 and how JSF was used by Alfresco to generate the links in order to update it. I also found out that the <h: form acceptCharset referenced in over a hundred Alfresco JSP files was cited as being incorrect by the JSP 2.1 compiler and should have been acceptcharset according to the JSF 1.2 TLD. After discovering other additional dependencies on the myfaces implementation classes, I decided that modifying Alfresco to be JSF implementation agnostic would be too difficult and be too much of a maintenance headache to pursue any further.

My next attempt was to deploy Alfresco to GlassFish and to configure the web app so the bundled myfaces implementation would override the default Sun JSF 1.2 RI implementation. This was no small feat because GlassFish implements JavaEE 5 which is the first EE release that has JSF baked in. Because of this, it is next to impossible to override the bundled JavaEE classes. First, if during application initialization GlassFish sees the Faces Servlet registered in the application’s web.xml it will then initialize it’s own Faces implementation automatically. Fortunately, even though the Faces Servlet is final, myfaces has it’s own Faces Servlet that wraps the JSF Faces Servlet and can be used instead.

<servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>org.apache.myfaces.webapp.MyFacesServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>


Secondly, after some research, I found out I could add an additional Sun deployment descriptor /WEB-INF/sun-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
<sun-web-app>
  <class-loader delegate="false"/>
</sun-web-app>
To the Alfresco web application. This tells the GlassFish web container to load classes from the web application first and then from the container. However, since javax.faces is now included with JavaEE those classes were protected and the JSF 1.2 API was still being loaded. Editing the <GF_HOME>/lib/processLauncher.xml file and modifying the as9-server configuration to have

<sysproperty key="com.sun.enterprise.overrideablejavaxpackages"
            value="javax.help,javax.portlet,javax.faces"/>

fixed that issue so that the JSF 1.1 API classes were loaded from the myfaces web application. However, the JSP compiler, according to the JSP 2.1 spec, still included the Sun RI taglib classes instead of the myfaces taglib implementation from the web app. Ignoring TLD declarations for the JSF taglib namespace is hard coded in the GlassFish JSP compiler so there is no way around it. To get around this, I extracted the myfaces_core.tld and myfaces_html.tld from the myfaces_impl.jar in the Alfresco WEB-INF/lib directory to the WEB-INF directory. I then created a script to search and replace the following values

http://java.sun.com/jsf/core -> http://myfaces.apache.org/jsf/core
http://java.sun.com/jsf/html-> http://myfaces.apache.org/jsf/html


in all of the jsp and tld files located in the Alfresco war file.

After redeploying, Alfresco WCM was running!!!!! I made it half way through the tutorial without any exceptions in the logs so I am pretty sure it is solid.

To make Alfresco more JavaEE compliant I would suggest the following to the Alfresco developers:

Do a recursive search for “myfaces” in all of the alfresco Java source files. There are not that many actually. See if the dependencies on the myfaces implementation classes can be easily re-implemented in a standard way. MyFaces JSF 1.2 support is still in development but all JSP 2.1 containers must support it to be JavaEE compliant so sooner or later the move the JSF 1.2 will be required to run on JavaEE version of JBoss and Tomcat.

As a side note, the method signature of sun.text.Normalizer has changed in JDK 1.6 and the same functionality is now included in java.text.Normalizer. Please consider modifying the way the Normalizer is included so Alfresco 2.0 WCM can be compiled without modification using JDK 1.6

Outcomes