GateIn on GlassFish 3.1.2

    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

     

    <?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>
    

     

     

    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>
    

     

     

    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

     

    -Dexo.conf.dir.name=gatein/conf
    

     

     

    Update the content of GLASSFISH_DIR/glassfish/domains/domain1/gatein/conf/configuration.properties so that we have

     

    gatein.conf.dir=${com.sun.aas.instanceRoot}/gatein/conf
    gatein.data.dir=${com.sun.aas.instanceRoot}/gatein/data
    

     

     

    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.

     

    gatein-domain {
      org.gatein.wci.security.WCILoginModule optional;
      org.exoplatform.services.security.jaas.SharedStateLoginModule required;
      org.exoplatform.services.security.j2ee.TomcatLoginModule required; 
    };
    

     

     

    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:

     

    1. An implementation of AppservRealm like the GateInRealm below.
    2. Adaption of WCILoginModule/SharedStateLoginModule/TomcatLoginModule to AppservPasswordLoginModule.

     

    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";
       }
    }
    

     

     

     

    Declare default realm

     

    Open the admin console and define a new realm with following parameters:

     

    name = GateInRealm
    classname = Qualified name of GateInRealm class
    property jaas-context = gatein-domain
    

     

     

    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

     

     

    Safe.close(context.getWriter());
    

     

     

    becomes

     

     

    try
    {
      Safe.close(context.getWriter());
    }
    catch(IllegalStateException ex)
    {
      Safe.close(context.getResponse().getOutputStream());
    }