cancel
Showing results for 
Search instead for 
Did you mean: 

How-To: Installing Alfresco 2.0 on GlassFish v2

nickmalthus
Champ in-the-making
Champ in-the-making
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
25 REPLIES 25

pcheipe
Champ in-the-making
Champ in-the-making
I found a similar issue on the iceFaces forum:

http://www.icefaces.org/JForum/posts/list/3859.page

pcheipe
Champ in-the-making
Champ in-the-making
Oups ! I also have a "null pointer" just before:

[#|2007-03-14T20:51:45.892+0100|SEVERE|sun-appserver-pe9.0|javax.enterprise.system.container.web|_ThreadID=11;_ThreadName=httpWorkerThread-8080-0;_RequestID=2704bb7f-1c3b-46d6-ab59-8f5b1af45660;|StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
   at com.sun.faces.lifecycle.ELResolverInitPhaseListener.populateFacesELResolverForJsp(ELResolverInitPhaseListener.java:135)
   at com.sun.faces.lifecycle.ELResolverInitPhaseListener.beforePhase(ELResolverInitPhaseListener.java:100)
   at org.apache.myfaces.lifecycle.LifecycleImpl.informPhaseListenersBefore(LifecycleImpl.java:520)

pcheipe
Champ in-the-making
Champ in-the-making
OK, I solved the nullPointer simply by redeploying the war.

It seems that Glassfish does not take into account the sun-web.xml without redeploying.

It's now the myFaces implementation that is used.

It now crashes on an "UnsupportedException" on "AccessContext.getELContext" of the myFaces implementation.

I Do not understand. This method effectively does noty exist in the myFaces API (see myFaces Javadoc).

Does anybody know when will the 2.1 be available ?

kevinr
Star Contributor
Star Contributor
In 2.0 we are using MyFaces 1.1.1 (recently HEAD has been upgraded to 1.1.5 which is a noticable improvement). It may be something to do with any faces impl included in GlassFish by default?

Thanks,

Kevin

nickmalthus
Champ in-the-making
Champ in-the-making
Sorry for the late response, I have been away from the forums a bit.

Not only must the myfaces implementation be used in the Servlets and custom tags but also in the JSP's. With JSP 2.1 JSF is built into the spec and the JSP compiler treats the JSF tags differently, i.e. the JSF URL is hard coded in the JSP compiler and it will ignore any mapping you make to an alternative implementation.

The only way to get around this is to edit all the JSP's and myfaces TLDs and replace the standard JSF core and html taglib URL's with a custom one, i.e

"http://java.sun.com/jsf/core'-> "http://myfaces.apache.org/jsf/core"
"http://java.sun.com/jsf/html'-> "http://myfaces.apache.org/jsf/html"
 
I created a JDK 1.6 javascript function to do this for me in the myfaces TLDs extracted to WEB-INF and in all the JSP's.

This is a pain but it is non trivial to replace all the myfaces references in the alfresco code base. I am not a JSF expert so I could to fix the common.Utils generateFormSubmit code that generates all the Alfreso links. If this were fixed to use standard JSF code instead of relying on the HtmlFormRendererBase from the myfaces implmentation, it would go a long way to making Alfresco more portable between JSF implementations. JSF 1.2 is suppose to me mostly backwards compatible so theoretically if Alfresco was modifed to strictly adhere to the JSF 1.1 stanard it *should* work unmodified on glassfish and all these workarounds to support myfaces on GlassFish could go away.

pcheipe
Champ in-the-making
Champ in-the-making
Many thanks Nick.

I did that change. I certainly missed something.

I'm going to check my config.

naramski
Champ in-the-making
Champ in-the-making
I've just created an ant build.xml for building Alfresco V2.0 with "Glassfish support".

The script contains a "patch" to the web.xml for using MyFaces and do the tedious process of changing

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

You have only to change the processLauncher.xml and to copy the cryptix library to glassfish/domains/domain/lib/ext

On my system, Alfresco deploy now without problem. The final process is detailled on http://www.naramski.info/roller/david/entry/deploy_alfresco_in_glassfish_v2

The build and all the files is in the archive at the bottom of the article.

I hope it helps

amerigo5
Champ in-the-making
Champ in-the-making
Tried this on GlassFish v1 and it didn't work.  Does this only work on GlassFish v2? 

Also, does your Ant script also work on Alfresco 2.1? Just wondering if you tried.

Thanks.


I've just created an ant build.xml for building Alfresco V2.0 with "Glassfish support".

The script contains a "patch" to the web.xml for using MyFaces and do the tedious process of changing

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

You have only to change the processLauncher.xml and to copy the cryptix library to glassfish/domains/domain/lib/ext

On my system, Alfresco deploy now without problem. The final process is detailled on http://www.naramski.info/roller/david/entry/deploy_alfresco_in_glassfish_v2

The build and all the files is in the archive at the bottom of the article.

I hope it helps

offtopic
Champ in-the-making
Champ in-the-making
I followed David Naramski's instructions to the letter. It didn't work neither in 2.0 or 2.1RC  :cry:

naramski
Champ in-the-making
Champ in-the-making
Actually, this method works has been tested only with Alfresco 2.0 CE. I will try an upgrade on Alfresco 2.1 ASAP.

If you send me the version of glassfish you wanted to used, I can test it.