Status
WIP
Description
In the family of servlet containers and application servers, GateIn only offers good support to Tomcat/JBoss and Jetty. Hence, providing full support to a popular application server like GlassFish is one of our high-priority tasks. Successful deployment of GateIn on GlassFish is the first step to complete that task.
This article describes how to deploy GateIn 3.2 on GlassFish 3.1.2, the latest release of GlassFish application server.
Install GlassFish 3.1.2
Dowload GlassFish 3.1.2 Open Source Edition at http://glassfish.java.net/ and extract it on your machine.
Open the terminal and browse to the directory GLASSFISH_DIR/glassfish/bin, then execute the command
./startserv
Open the browser and navigate to http://localhost:8080/ to see if GlassFish server is available.
New users of GlassFish server are suggested to make a tour on the administration console before going to next section of the article. It is worth to keep in mind that
any manipulation via admin console is reflected in the file GLASSFISH_DIR/glassfish/domains/domain1/config/domain.xml , and vice versa.
Prepare GateIn Artifacts.
We are using Maven artifacts, generated as GateIn is built with profile -Ppkg-tomcat, to deploy on GlassFish.
jar artifacts
Copy all .jar under tomcat/lib to GLASSFISH_DIR/glassfish/lib
war artifacts
For each war artifact under tomcat/webapps, remove the file META-INF/context.xml (if any) and add a file name sun-web.xml with following content
{code:xml}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD GlassFish Application Server 3.0 Servlet 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_3_0-0.dtd">
<sun-web-app>
<context-root>/war_file_name</context-root>
<security-role-mapping>
<role-name>administrators</role-name>
<group-name>administrators</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>users</role-name>
<group-name>users</group-name>
</security-role-mapping>
</sun-web-app>
For integration.war, we need to modify the content of WEB-INF/web.xml to
<web-app>
<listener>
<listener-class>org.gatein.wci.impl.generic.GenericServletContainerContext</listener-class>
</listener>
</web-app>
{code}
For integration.war, we need to modify the content of WEB-INF/web.xml to
{code:xml}
<web-app>
<listener>
<listener-class>org.gatein.wci.impl.generic.GenericServletContainerContext</listener-class>
</listener>
</web-app>
{code}
Copy those custom .war artifacts to GLASSFISH_DIR/glassfish/domains/domain1/autodeploy
GlassFish Configuration
Portal container configuration setting
From Tomcat6 packaging, copy the directory gatein to GLASSFISH_DIR/glassfish/domains/domain1, then declare the following JVM property via Admin Console or via domain.xml
{code:xml}
-Dexo.conf.dir.name=gatein/conf
{code}
Update the content of GLASSFISH_DIR/glassfish/domains/domain1/gatein/conf/configuration.properties so that we have
{code:xml}
gatein.conf.dir=${com.sun.aas.instanceRoot}/gatein/conf
gatein.data.dir=${com.sun.aas.instanceRoot}/gatein/data
{code}
Logger setting
Declare the JVM property org.exoplatform.container.configuration.debug=true and adjust the log level of exo.kernel.container.ConfigurationManagerImpl to FINEST.
The setting allows us to verify if any configuration file of portal container (especially configuration.properties) is omitted.
First Run
Start GlassFish and check the link http://localhost:8080/portal/ . At this point we must see the front of GateIn.
Authentication
GlassFish does not provide a default realm using JAAS. Hence, we need to build one working with below-enlisted login modules.
{code:xml}
gatein-domain {
org.gatein.wci.security.WCILoginModule optional;
org.exoplatform.services.security.jaas.SharedStateLoginModule required;
org.exoplatform.services.security.j2ee.TomcatLoginModule required;
};
{code}
Instructions on building a custom realm for GlassFish is documented at http://docs.oracle.com/cd/E18930_01/html/821-2418/beabo.html#beabs . According to the reference guide, we need:
- An implementation of AppservRealm like the GateInRealm below.
- Adaption of WCILoginModule/SharedStateLoginModule/TomcatLoginModule to AppservPasswordLoginModule.
{code:java}
public class GateInRealm extends AppservRealm
{
@Override
protected void init(Properties props) throws BadRealmException, NoSuchRealmException
{
super.init(props);
String jaasCtx = props.getProperty(AppservRealm.JAAS_CONTEXT_PARAM);
this.setProperty(AppservRealm.JAAS_CONTEXT_PARAM, jaasCtx);
}
@Override
public Enumeration<Object> getGroupNames(String user) throws InvalidOperationException, NoSuchUserException
{
return Collections.enumeration(new ArrayList<Object>());
}
@Override
public String getAuthType()
{
return "GateInRealm";
}
}
{code}
Declare default realm
Open the admin console and define a new realm with following parameters:
{code:xml}
name = GateInRealm
classname = Qualified name of GateInRealm class
property jaas-context = gatein-domain
{code}
Then, select this newly created realm as default realm of GlassFish
JAAS configuration
JAAS configuration file is defined in GlassFish as:
-Djava.security.auth.login.config=${com.sun.aas.instanceRoot}/config/login.conf
The final step is creating a login configuration entry named gatein-domain (the value matches the property jaas-context of GateInRealm realm) in GLASSFISH_DIR/glassfish/domains/domain1/config/login.conf which contains the three custom login modules.
Redirection problem
Implementation of redirection in GlassFish is quite specific, the server attempts to write content to client http://java.net/projects/glassfish/sources/svn/content/tags/3.1.2/web/web-core/src/main/java/org/apache/catalina/connector/Response.java . However, that would raise IllegalStateException in GateIn as both getWriter and getOutputStream methods are invoked on one response object.
As described in the JIRA https://issues.jboss.org/browse/GTNPORTAL-2418, solution to redirection problem is to add a try/catch block in PortalRequestHandler
{code:java}
Safe.close(context.getWriter());
{code}
becomes
{code:java}
try
{
Safe.close(context.getWriter());
}
catch(IllegalStateException ex)
{
Safe.close(context.getResponse().getOutputStream());
}
{code}
Comments