Comments? Feedback?

This wiki does not yet support public comments (a limitation of Google Sites), so we encourage you to post your comments on Twitter by responding to @orbeon.

Recent site activity

Deployment - Portlet (JSR-168/JSR-268)


Introduction

Servlet and Portlet Deployment

Orbeon Forms is typically used to create Web applications. In this case, Orbeon Forms relies on standard Java Servlet technology, and the Web application's web.xml file is configured to use the OrbeonForms Servlet or Orbeon Forms Servlet Filter. Orbeon Forms conforms to the Java Servlet API and handles a Web client's entire real estate on the browser.

Orbeon Forms also provides the Orbeon Forms Portlet, which supports the implementation of standard Java portlets that can be deployed within any portal or portlet container compatible with the Java Portlet specification version 1 or 2. These specifications are also known as JSR-168 and JSR-268.

What is a Portal?

A portal is a Web application that provides several features such as:
  • Content Aggregation -  A single Web page within the application aggregates the output or user interface of several data sources or applications.
  • Personalization - Users or administrators of the portal can customize the user interface. This often means not only customizing the look and feel, but also selecting a certain set of available functionalities within the application.
  • Single Sign-On - The user logs in only once to access several applications in the portal.

What Is a Portlet?


According to the Java Portlet Specification, a portlet is a "Java technology based Web component, managed by a portlet container that processes requests and generates dynamic content. Portlets are used by portals as pluggable user interface components that provide a presentation layer to Information Systems". An implementation agnostic definition can be found in the Web Services for Remote Portals (WSRP) White Paper of 22 September 2002 "Portlets are user-facing, interactive Web application components rendering markup fragments to be aggregated and displayed by the portal."

In other words, a portlet is usually a Web application that can be embedded within a portal, and shares Web page real estate with other portlets. Traditionally portlets available in public portals have provided simple features such as stock quotes, news feeds, weather reports, etc. In particular thanks to the Java Portlet specification, there is no limit to the extent of the features provided by a portlet, and it is expected that complex interactive portlets will become more and more widespread.

Orbeon Forms and Portlets

Orbeon Forms hides the complexity of the Portlet API to allow most Orbeon Forms applications to work unmodified within portlet containers and to follow best practices allowed by the Web Application Controller. In particular, the Portlet API requires:
  • Separation of faceless actions from rendering - Orbeon Forms allows actions to generate output while still adhering to the Java Portlet specification. Developers are obviously free to only write faceless actions. In the Page Flow Controller, such actions end with a <result page="some-page-id"> directive.
  • Getting rid of the familiar concept of URL path - Orbeon Forms abstracts this behavior and provides Orbeon Forms Portlet developers with the notion of a path, implicitly in the Web Application Controller, or explicitly with the Request Generator, while still adhering to the Java Portlet specification.
  • Getting rid of the familiar concept of URL redirection - Instead, portlet actions can set parameters to use in subsequent portlet rendering. Orbeon Forms abstracts this behavior and provides, indirectly in the Page Flow Controller, or explicitly with the Redirect Processor, the notion of redirecting to another page within the portlet.
  • Calling APIs to generate URLs - Orbeon Forms handles this by providing automatic URL rewriting.
  • Generating Markup Fragments - The default Orbeon Forms epilogue automatically extracts a fragment from a Orbeon Forms <d:document>. This allows pages to remain unmodified for both servlet and portlet deployment. The default epilogue also makes sure that no HTML or XML DOCTYPE is generated at the beginning of a fragment. The default epilogue can easily be modified.

Portal Servers

Liferay

The Orbeon Forms WAR can be directly deployed into the Liferay portal. Follow the following steps:
  1. Only for Liferay 5 [NOTE: For Orbeon Forms builds before  February 4, 2009] (skip this step if you are using Liferay 4 or Orbeon Forms builds after February 4, 2009)

    1. Uncompress the orbeon.war in a temporary directory.
    2. Open WEB-INF/web.xml in an editor.
    3. Uncomment the code between "Uncomment this for the context listener processors" and "End context listener processors".
    4. Uncomment the <listener> which references org.orbeon.oxf.webapp.OPSServletContextListenerDelegate.
    5. Compress back the data you have extracted to recreate the orbeon.war with this modified web.xml.

    For information on why this is needed on Liferay 5, see note 1 below.

  2. Set larger MaxPermSize (optional) - Depending on your system, you might get an error when starting Liferay, or later one when using Liferay, telling you that the Java VM ran out of PermGen space. You can prevent this error by setting the value of MaxPermSize to a value larger than the default value, for instance by declaring the JAVA_OPTS environment variable in a way similar what is is done below. The declaration of JAVA_OPTS can be done at the beginning of bin/setclasspath.sh (or if on Windows, the equivalent line at the beginning of bin/setclasspath.bat):

        JAVA_OPTS="-server -verbosegc -Xms386m -Xmx386m -Djava.awt.headless=true -XX:MaxPermSize=128m"

  3. Deploy orbeon.war - Start Liferay. When it is fully started move the orbeon.war into the Liferay deploy directory (e.g. ~/liferay/deploy). At this point, you should see message indicating that Orbeon is being deployed. Monitor the Liferay output as well as the logs/orbeon.log for possible errors.

  4. Enable dynamic resource reloading (optional) - Remove the file webapps/orbeon/META-INF/context.xml and restart Liferay. For more information on what this does, see note 2 below.

  5. Configuration for Form Runner and Form Builder (optional) - You can skip this step if you do not intend to use Form Runner or Form Builder in a portlet. Otherwise, create a file WEB-INF/resources/config/properties-local.xml which declares the following property:

        <properties xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    xmlns:oxf="http://www.orbeon.com/oxf/processors">
            <property as="xs:anyURI"  name="oxf.fr.appserver.uri" value="http://localhost:8080/orbeon"/>
        </properties>


  6. Add the Orbeon Forms portlet - Log into the portal, go to Add Application, and if the deployment of Orbeon Forms was successful you will see:



    Click the Add link or drag and drop Orbeon Forms Portlet where you want the portlet to be inserted into the page. Those links are defined in WEB-INF/resources/apps/portlet-welcome/view.xhtml.


Notes:
  1. While Liferay 4 lazy loads portlets, but, because of performance related issues, Liferay 5 is aggressively loading portlets when the web application is being deployed. So with Liferay 5, the initialization order is as follows:

    1. Servlet context listeners are initialized.
    2. Portlets are initialized.
    3. Servlets are initialized.

    For the Orbeon Forms portlet to be able to run, code which is executed by either the Orbeon Forms servlet context listener, or the Orbeon Forms servlet needs to run first. Since servlets are initialized after portlets, the only option is to have this code executed from the servlet context listener.

    NOTE: By default, the Orbeon Forms servlet context listener is enabled for Orbeon Forms builds after Febuary 4, 2009.

  2. When Liferay deploys Orbeon Forms, it changes some of the descriptors and adds a META-INF/context.xml which is not present in the distribution of Orbeon Forms. This file contains:

        <Context antiJARLocking="true" antiResourceLocking="true"/>

    which causes Tomcat to, on startup, make a copy of the Orbeon web application into its temp directory and use that copy instead of the files under webapps/orbeon. That copy is removed when the server shuts down, and will be done again the next time the server is started. This makes starting Liferay slower, but more importantly this means that changes you make to files under webapps/orbeon after the server started will never be picked up. So any modification to the resources (WEB-INF/resources) of your application will require a restart of Liferay. This  can be quite very time consuming and annoying, hence our recommendation to remove the META-INF/context.xml generated by Liferay..

Jetspeed 2 based portals

Orbeon's war distribution can easily be deployed on any Jetspeed-2 based portal. If you don't have a Jetspeed portal yet, you may want to get started with the Jetspeed 2 installer, see http://portals.apache.org/jetspeed-2/getting-started-installer.html. Note: Orbeon's version 3.7 later than the nightly build from january 15th 2009 has to be used.

Deployment:
  1. Deploy Orbeon.war

    a) On Tomcat - If your Jetspeed portal runs on Tomcat (like when having used the installer), the easiest way is to let Jetspeed deploy Orbeon by copying orbeon.war to Jetspeed's deploy directory  webapps/jetspeed/WEB-INF/deploy.  Auto-deployment will take place directly if the portal is running, otherwise at startup.

    b) Other - On application servers other than Tomcat, use your application server's own deployment mechanism to deploy Orbeon as web application.

    The following servlet is to be inserted into Orbeon's web.xml

    <servlet>
       <servlet-name>JetspeedContainer</servlet-name>
       <display-name>Jetspeed Container</display-name>
       <description>MVC Servlet for Jetspeed Portlet Applications</description>
       <servlet-class>org.apache.jetspeed.container.JetspeedContainerServlet</servlet-class>
       <init-param>
         <param-name>contextName</param-name>
         <param-value>orbeon</param-value>
       </init-param>
       <load-on-startup>[your-value]</load-on-startup>
    </servlet>
    <servlet-mapping>
       <servlet-name>JetspeedContainer</servlet-name>
       <url-pattern>/container/*</url-pattern>
    </servlet-mapping>

    With this setup Orbeon will register itself as portlet application to Jetspeed.

  2. Add Orbeon's portlet on your page

    To add Orbeon's portlet called OrbeonFormsPortlet to a page, adjust the desired .psml page to incorporate this portlet in a fragment, e.g. 
    <fragment id="yourId" type="portlet" name="orbeon::OrbeonFormsPortlet">


    This can also be accomplished using a UI with the Edit page functionality when logged in as admin.
More information on Jetspeed 2 available at http://portals.apache.org/jetspeed-2/guides.

IBM WebSphere Portal 6

It has been reported that Orbeon Forms deploys into IBM WebSphere Portal 6.

[TODO: Exact configuration steps.]

JBoss Portal

This instructions have been reported to work with JBoss Portal 2.6.5-SP1.
  1. First setup and run the portal normally and check that you get the portal first page OK at http://localhost:8080/portal.
  2. Download a nightly build of Orbeon Forms, and add the following files inside the WEB-INF directory:

    portlet-instances.xml:

    <?xml version="1.0" standalone="yes"?>
    <!DOCTYPE deployments PUBLIC
      "-//JBoss Portal//DTD Portlet Instances 2.6//EN"
      "
    http://www.jboss.org/portal/dtd/portlet-instances_2_6.dtd">
    <deployments>
      <deployment>
         <instance>
            <instance-id>OrbeonPortletInstance</instance-id>
            <portlet-ref>OrbeonFormsPortlet</portlet-ref>
         </instance>
      </deployment>
    </deployments>


    orbeon-object.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE deployments PUBLIC
      "-//JBoss Portal//DTD Portal Object 2.6//EN"
      "
    http://www.jboss.org/portal/dtd/portal-object_2_6.dtd">
    <deployments>
      <deployment>
         <parent-ref>default.default</parent-ref>
         <if-exists>overwrite</if-exists>
         <window>
            <window-name>Orbeon Forms</window-name>
            <content>
            
    <content-type>portlet</content-type>
            
    <content-uri>OrbeonPortletInstance</content-uri>
            </content>
            <region>center</region>
            <height>1</height>
         </window>
      </deployment>
    </deployments>

  3. Uncomment the following in the web.xml, since resource is present in jboss-web.xml file:

       <!-- Uncomment this for the SQL examples -->
       <resource-ref>
           <description>DataSource</description>
           <res-ref-name>jdbc/db</res-ref-name>
           <res-type>javax.sql.DataSource</res-type>
           <res-auth>Container</res-auth>
       </resource-ref>

  4. Deploy modified WAR to $JBOSS_PORTAL_DIR/server/default/deploy
  5. The deployer should automatically deploy the WAR and if you refresh the first page on the portal, you will see that the orbeon portlet view has appeared on the page. Check the terminal or logs for issues during deployment if you have some problems.

Portlet Configuration File

Configuration of portlets is done in a standard file called portlet.xml that sits in the same directory (WEB-INF) as your web.xml. The portlet-class element must always be:
  •  org.orbeon.oxf.portlet.OrbeonPortletDelegate for Portlet 1 (JSR-168) Orbeon Forms Portlets 
  •  org.orbeon.oxf.portlet.OrbeonPortlet2Delegate for Portlet 2 (JSR-268) Orbeon Forms Portlets
You can also configure non-Orbeon Forms Portlets within the same portlet.xml.The main processor URI and optional inputs are specified with the oxf.main-processor.uri and oxf.main-processor.input.* initialization parameters. For example:

<portlet-app>
    <portlet>
        <portlet-name>OrbeonFormsPortlet</portlet-name>
        <portlet-class>org.orbeon.oxf.portlet.OrbeonPortlet2Delegate</portlet-class>
        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>edit</portlet-mode>
        </supports>
        <init-param>
            <name>oxf.main-processor.name</name>
            <value>{http://www.orbeon.com/oxf/processors}pipeline</value>
        </init-param>
        <init-param>
            <name>oxf.main-processor.input.config</name>
            <value>oxf:/config/prologue-portlet.xpl</value>
        </init-param>
        <init-param>
            <name>oxf.error-processor.name</name>
            <value>{http://www.orbeon.com/oxf/processors}pipeline</value>
        </init-param>
        <init-param>
            <name>oxf.error-processor.input.config</name>
            <value>oxf:/config/error.xpl</value>
        </init-param>
        <supports>
            <mime-type>text/html</mime-type>
            <mime-type>application/xml</mime-type>
        </supports>
        <portlet-info>
            <title>Orbeon Forms Portlet</title>
        </portlet-info>
        <portlet-preferences>
            <preference>
                <name>web-site</name>
                <value>http://www.orbeon.com/</value>
            </preference>
            <preference>
                <name>favorite-animals</name>
                <value>cat, dog</value>
            </preference>
        </portlet-preferences>
    </portlet>
</portlet-app>

It is possible to configure several Orbeon Forms Portlets within the same portlet.xml, with the same or a different configuration. The portlet-name element however must be different for each portlet, as per the Java Portlet specification.

Portlet Output

The type of the portlet output is determined by the serializer. With the default Orbeon Forms epilogue in config/epilogue-portlet.xpl, the HTML serializer is used.

Preferences

Portlet preferences can be retrieved with the oxf:portlet-preferences-generator processor.

To retrieve the preferences of your current portlet, use the following code:

<p:processor name="oxf:portlet-preferences">
    <p:output name="data" id="portlet-preferences"/>
</p:processor>

The generator outputs a document containing name / values in the following format:

<portlet-preferences>
    <preference>
        <name>name1</name>
        <value>value1</value>
    </preference>
    <preference>
        <name>name2</name>
        <value>value1</value>
        <value>value2</value>
        <value>value3</value>
    </preference>
</portlet-preferences>

For example:

<portlet-preferences>
    <preference>
        <name>max-items</name>
        <value>10</value>
    </preference>
    <preference>
        <name>url</name>
        <value>http://xml.newsisfree.com/feeds/42/1842.xml</value>
    </preference>
</portlet-preferences>

Portlet preferences can be saved with the oxf:portlet-preferences-serializer processor. [TODO]

Security

Portlet security can be configured in portlet.xml as per the Portlet specification. The Request Security processor provides security information like in the case of Servlets.

Deployment

A Orbeon Forms portlet application is deployed like a regular Web application. You have to make sure that, in addition to the web.xml, you have a valid portlet.xml configuration file as well.

You can deploy the application in any portlet container supporting the version of the specification mentioned above.

It is possible to deploy Orbeon Forms Servlets, Servlet Filters, Servlet Context Listeners, and Portlets within the same application:



For more information, see Packaging and Deployment. Note that the use of the Page Flow Controller is optional but its use is typical.

Limitations of Orbeon Forms Portlets

The Orbeon Forms Portlet developer should be aware of the following limitations:
  • Redirection - In the Page Flow Controller, pages that are the target of a portlet render URL cannot end with a redirection. This in particular applies to the default portlet page ("/"). Developers have to make sure that a page exists for "/" that produces content and does not end in a redirect. Other pages can end with redirects by making sure that they are targeted by action URLs (by default, only the target of HTML or XHTML form submissions generate action URLs).
  • Portlet Mode and Window State hints - It is currently not possible to set a portlet mode or window state hint in a URL. 
  • Content Type Hints - It is not possible for an Orbeon Forms Portlet to know which content types are supported by the portal.
  • Preferences - It is currently not possible to modify portlet preferences or store them from within a portlet.
  • XML Fragments - The Orbeon Forms Portlet currently must generate XML fragments containing a root node. This is rarely an issue, as a fragment can for example be embedded within an XHTML <div> element.
  • Struts integration - Currently, Struts does not natively support operations within a Java portlet.
In addition, and this is by design of the API, Java portlets cannot directly serve resources such as images, CSS stylesheets, standalone JavaScript files, etc. Those resources have to be served by a Servlet. Portlets therefore cannot directly serve resources using:
  • The Chart processor
  • The Image server
  • The Resource server
  • The PDF serializer
  • The Excel serializer
  • Or any processor serving resources
Orbeon Forms Portlets can however refer to resources served by the Orbeon Forms Servlet.