<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">

<chapter id="configuration">
    <title>Configuring Seam and packaging Seam applications</title>
    <para> Configuration is a very boring topic and an extremely tedious pastime. Unfortunately, several lines of XML
        are required to integrate Seam into your JSF implementation and servlet container. There's no need to be too put
        off by the following sections; you'll never need to type any of this stuff yourself, since you can just copy and
        paste from the example applications! </para>

    <sect1>
        <title>Basic Seam configuration</title>

        <para> First, let's look at the basic configuration that is needed whenever we use Seam with JSF. </para>

        <sect2>
            <title>Integrating Seam with JSF and your servlet container</title>

            <para> Of course, you need a faces servlet! </para>

            <programlisting role="XML"><![CDATA[<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.seam</url-pattern>
</servlet-mapping>]]></programlisting>

            <para> (You can adjust the URL pattern to suit your taste.) </para>

            <para> In addition, Seam requires the following entry in your <literal>web.xml</literal> file: </para>

            <programlisting role="XML"><![CDATA[<listener>
    <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>]]></programlisting>

            <para> This listener is responsible for bootstrapping Seam, and for destroying session and application
                contexts. </para>

            <para> Some JSF implementations have a broken implementation of server-side state saving that interferes
                with Seam's conversation propagation. If you have problems with conversation propagation during form
                submissions, try switching to client-side state saving. You'll need this in <literal>web.xml</literal>: </para>

            <programlisting role="XML"><![CDATA[<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>]]></programlisting>	

            <para>
                    There is a minor gray area in the JSF specification regarding the mutability of view state values. Since
                    Seam uses the JSF view state to back its PAGE scope this can become an issue in some cases. If you're
                    using server side state saving with the JSF-RI and you want a PAGE scoped bean to keep its exact value
                    for a given view of a page you will need to specify the following context-param. Otherwise if a user
                    uses the "back" button a PAGE scoped component will have the latest value if it has changed not the
                    value of the "back" page. (see
                    <ulink url="https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=295">
                            Spec Issue
                    </ulink>
                    ). This setting is not enabled by default because of the performance hit of serializing the JSF view
                    with every request.
            </para>
                        <programlisting role="XML"><![CDATA[<context-param>
        <param-name>com.sun.faces.serializeServerState</param-name>
        <param-value>true</param-value>
</context-param>]]></programlisting>

        </sect2>

        <sect2>
            <title>Using facelets</title>

            <para> If you want follow our advice and use facelets instead of JSP, add the following lines to
                    <literal>faces-config.xml</literal>: </para>

            <programlisting role="XML"><![CDATA[<application>
    <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>]]></programlisting>

            <para> And the following lines to <literal>web.xml</literal>: </para>

            <programlisting role="XML"><![CDATA[<context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.xhtml</param-value>
</context-param>]]></programlisting>

        </sect2>

        <sect2>
            <title>Seam Resource Servlet</title>

            <para> The Seam Resource Servlet provides resources used by Seam Remoting, captchas (see the security
                chapter) and some JSF UI controls. Configuring the Seam Resource Servlet requires the following entry in
                    <literal>web.xml</literal>: </para>

            <programlisting role="XML"><![CDATA[<servlet>
  <servlet-name>Seam Resource Servlet</servlet-name>
  <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>
    
<servlet-mapping>
  <servlet-name>Seam Resource Servlet</servlet-name>
  <url-pattern>/seam/resource/*</url-pattern>
</servlet-mapping>]]></programlisting>
        </sect2>

        <sect2>
            <title>Seam servlet filters</title>

            <para> Seam doesn't need any servlet filters for basic operation. However, there are several features which
                depend upon the use of filters. To make things easier, Seam lets you add and configure
                servlet filters just like you would configure other built-in Seam components. To take advantage of this
                feature, we must first install a master filter in <literal>web.xml</literal>: </para>

            <programlisting role="XML"><![CDATA[<filter>
    <filter-name>Seam Filter</filter-name>
    <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>Seam Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>]]></programlisting>

            <para>The Seam master filter <emphasis>must</emphasis> be the first filter specified in
                <literal>web.xml</literal>. This ensures it is run first. </para>
            
            <para>
               The Seam filters share a number of common attributes, you can set these in 
               <literal>components.xml</literal> in addition to any parameters discussed
               below:
            </para>
            
            <itemizedlist>
               <listitem>
                  <para>
                     <literal>url-pattern</literal> &#8212; Used to specify which requests are filtered, the
                         default is all requests. <literal>url-pattern</literal> is a Tomcat style pattern
                         which allows a wildcard suffix.
                  </para>
               </listitem>
               <listitem>
                  <para>
                     <literal>regex-url-pattern</literal> &#8212; Used to specify which requests are filtered, the
                     default is all requests. <literal>regex-url-pattern</literal> is a true regular expression
                     match for request path. It's worth noting when composing the regular expression that the request path does not contain
                     the server or request context path. 
                  </para>
               </listitem>
               <listitem>
                  <para>
                     <literal>disabled</literal> &#8212; Used to disable a built in filter.
                  </para>
               </listitem>
           </itemizedlist>

            <para> Adding the master filter enables the following built-in filters. </para>

            <sect3>
                <title>Exception handling</title>
                <para> This filter provides the exception mapping functionality in <literal>pages.xml</literal> (almost
                    all applications will need this). It also takes care of rolling back uncommitted transactions when
                    uncaught exceptions occur. (According to the Java EE specification, the web container should do this
                    automatically, but we've found that this behavior cannot be relied upon in all application servers.
                    And it is certainly not required of plain servlet engines like Tomcat.) </para>

                <para> By default, the exception handling filter will process all requests, however this behavior may be
                    adjusted by adding a <literal>&lt;web:exception-filter&gt;</literal> entry to
                        <literal>components.xml</literal>, as shown in this example: </para>

                <programlisting role="XML"><![CDATA[<components xmlns="http://jboss.com/products/seam/components"
            xmlns:web="http://jboss.com/products/seam/web">

    <web:exception-filter url-pattern="*.seam"/>

</components>]]></programlisting>

                
            </sect3>

            <sect3>
                <title>Conversation propagation with redirects</title>
                <para> This filter allows Seam to propagate the conversation context across browser redirects. It
                    intercepts any browser redirects and adds a request parameter that specifies the Seam conversation
                    identifier. </para>

                <para> The redirect filter will process all requests by default, but this behavior can also be adjusted
                    in <literal>components.xml</literal>: </para>

                <programlisting role="XML"><![CDATA[<web:redirect-filter url-pattern="*.seam"/>]]></programlisting>
            </sect3>

            <sect3>
                <title>Multipart form submissions</title>
                <para> This feature is necessary when using the Seam file upload JSF control. It detects multipart form
                    requests and processes them according to the multipart/form-data specification (RFC-2388). To
                    override the default settings, add the following entry to <literal>components.xml</literal>: </para>

                <programlisting role="XML"><![CDATA[<web:multipart-filter create-temp-files="true" 
                      max-request-size="1000000" 
                      url-pattern="*.seam"/>]]></programlisting>

                <itemizedlist>
                    <listitem>
                        <para>
                            <literal>create-temp-files</literal> &#8212; If set to <literal>true</literal>, uploaded
                            files are written to a temporary file (instead of held in memory). This may be an important
                            consideration if large file uploads are expected. The default setting is
                            <literal>false</literal>. </para>
                    </listitem>
                    <listitem>
                        <para>
                            <literal>max-request-size</literal> &#8212; If the size of a file upload request
                            (determined by reading the <literal>Content-Length</literal> header in the request) exceeds
                            this value, the request will be aborted. The default setting is 0 (no size limit). </para>
                    </listitem>
                </itemizedlist>
            </sect3>

            <sect3>
                <title>Character encoding</title>
                <para> Sets the character encoding of submitted form data. </para>

                <para> This filter is not installed by default and requires an entry in
                    <literal>components.xml</literal> to enable it: </para>

                <programlisting role="XML"><![CDATA[<web:character-encoding-filter encoding="UTF-16" 
                               override-client="true" 
                               url-pattern="*.seam"/>]]></programlisting>

                <itemizedlist>
                    <listitem>
                        <para>
                            <literal>encoding</literal> &#8212; The encoding to use. </para>
                    </listitem>
                    <listitem>
                        <para>
                            <literal>override-client</literal> &#8212; If this is set to <literal>true</literal>,
                            the request encoding will be set to whatever is specified by <literal>encoding</literal> no
                            matter whether the request already specifies an encoding or not. If set to
                            <literal>false</literal>, the request encoding will only be set if the request doesn't
                            already specify an encoding. The default setting is <literal>false</literal>. </para>
                    </listitem>
                </itemizedlist>
            </sect3>

            <sect3>
                <title>RichFaces</title>

                <para> 
                  If RichFaces is used in your project, Seam will install the
                  RichFaces Ajax filter for you, making sure to install it
                  before all other built-in filters. You don't need to install
                  the RichFaces Ajax filter in <literal>web.xml</literal>
                  yourself.
                </para>
                
                <para>
                  The RichFaces Ajax filter is only installed if the RichFaces
                  jars are present in your project.
                </para>

                <para> To override the default settings, add the following entry to <literal>components.xml</literal>.
                    The options are the same as those specified in the RichFaces Developer Guide: </para>

                <programlisting role="XML"><![CDATA[<web:ajax4jsf-filter force-parser="true" 
                     enable-cache="true" 
                     log4j-init-file="custom-log4j.xml"
                     url-pattern="*.seam"/>]]></programlisting>
                <itemizedlist>
                    <listitem>
                        <para>
                            <literal>force-parser</literal> &#8212; forces all JSF pages to be validated by
                            Richfaces's XML syntax checker. If <literal>false</literal>, only AJAX responses are
                            validated and converted to well-formed XML. Setting <literal>force-parser</literal> to
                                <literal>false</literal> improves performance, but can provide visual artifacts on AJAX
                            updates. </para>
                    </listitem>
                    <listitem>
                        <para>
                            <literal>enable-cache</literal> &#8212; enables caching of framework-generated resources
                            (e.g. javascript, CSS, images, etc). When developing custom javascript or CSS, setting to
                            true prevents the browser from caching the resource. </para>
                    </listitem>
                    <listitem>
                        <para>
                            <literal>log4j-init-file</literal> &#8212; is used to setup per-application logging. A
                            path, relative to web application context, to the log4j.xml configuration file should be
                            provided. </para>
                    </listitem>
                </itemizedlist>

            </sect3>

             <sect3>
                <title>Identity Logging</title>

                <para> 
                    This filter adds the authenticated user name to the log4j mapped diagnostic context so that it 
                    can be included in formatted log output if desired, by adding %X{username} to the pattern.                       
                </para>

                 
                 <para> By default, the logging filter will process all requests, however this behavior may be
                     adjusted by adding a <literal>&lt;web:logging-filter&gt;</literal> entry to
                     <literal>components.xml</literal>, as shown in this example: </para>
                 
                <programlisting role="XML"><![CDATA[<components xmlns="http://jboss.com/products/seam/components"
            xmlns:web="http://jboss.com/products/seam/web">
    <web:logging-filter url-pattern="*.seam"/>
</components>]]></programlisting>

            </sect3>
       
            <sect3>
                <title>Context management for custom servlets</title>
                <para> Requests sent direct to some servlet other than the JSF servlet are not processed through the JSF
                    lifecycle, so Seam provides a servlet filter that can be applied to any other servlet that needs
                    access to Seam components. </para>

                <para> This filter allows custom servlets to interact with the Seam contexts. It sets up the Seam
                    contexts at the beginning of each request, and tears them down at the end of the request. You should
                    make sure that this filter is <emphasis>never</emphasis> applied to the JSF
                    <literal>FacesServlet</literal>. Seam uses the phase listener for context management in a JSF
                    request. </para>

                <para> This filter is not installed by default and requires an entry in
                    <literal>components.xml</literal> to enable it: </para>

                <programlisting role="XML"><![CDATA[<web:context-filter url-pattern="/media/*"/>]]></programlisting>

                <para> The context filter expects to find the conversation id of any conversation context in a request
                    parameter named <literal>conversationId</literal>. You are responsible for ensuring that it gets
                    sent in the request. </para>

                <para> You are also responsible for ensuring propagation of any new conversation id back to the client.
                    Seam exposes the conversation id as a property of the built in component
                    <literal>conversation</literal>. </para>

            </sect3>

            <sect3>
                <title>Adding custom filters</title>
                <para> Seam can install your filters for you, allowing you to specify <emphasis>where</emphasis> in the
                    chain your filter is placed (the servlet specification doesn't provide a well defined order if you
                    specify your filters in a <literal>web.xml</literal>). Just add the <literal>@Filter</literal>
                    annotation to your Seam component (which must implement <literal>javax.servlet.Filter</literal>): </para>

                <programlisting role="JAVA"><![CDATA[@Startup
@Scope(APPLICATION)
@Name("org.jboss.seam.web.multipartFilter")
@BypassInterceptors
@Filter(within="org.jboss.seam.web.ajax4jsfFilter")
public class MultipartFilter extends AbstractFilter {]]></programlisting>

                <para> Adding the <literal>@Startup</literal> annotation means thar the component is available during
                    Seam startup; bijection isn't available here (<literal>@BypassInterceptors</literal>); and the filter
                    should be further down the chain than the RichFaces filter
                        (<literal>@Filter(within="org.jboss.seam.web.ajax4jsfFilter")</literal>). </para>

            </sect3>
        </sect2>

        <sect2>
            <title>Integrating Seam with your EJB container</title>

            <para> We need to apply the <literal>SeamInterceptor</literal> to our Seam components. The simplest way to
                do this across an entire application is to add the following interceptor configuration in
                    <literal>ejb-jar.xml</literal>: </para>

            <programlisting role="XML"><![CDATA[<interceptors>
    <interceptor>
        <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
    </interceptor>
</interceptors>
   
<assembly-descriptor>
    <interceptor-binding>
        <ejb-name>*</ejb-name>
        <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
    </interceptor-binding>
</assembly-descriptor>
]]></programlisting>

            <para> Seam needs to know where to go to find session beans in JNDI. One way to do this is specify the
                    <literal>@JndiName</literal> annotation on every session bean Seam component. However, this is quite
                tedious. A better approach is to specify a pattern that Seam can use to calculate the JNDI name from the
                EJB name. Unfortunately, there is no standard mapping to global JNDI defined in the EJB3 specification,
                so this mapping is vendor-specific. We usually specify this option in <literal>components.xml</literal>. </para>

            <para> For JBoss AS, the following pattern is correct: </para>

            <programlisting role="XML"><![CDATA[<core:init jndi-name="myEarName/#{ejbName}/local" />]]></programlisting>

            <para> Where <literal>myEarName</literal> is the name of the EAR in which the bean is deployed. </para>

            <para> Outside the context of an EAR (when using the JBoss Embeddable EJB3 container), the following pattern
                is the one to use: </para>

            <programlisting role="XML"><![CDATA[<core:init jndi-name="#{ejbName}/local" />]]></programlisting>

            <para> You'll have to experiment to find the right setting for other application servers. Note that some
                servers (such as GlassFish) require you to specify JNDI names for all EJB components explicitly (and
                tediously). In this case, you can pick your own pattern ;-) </para>
                
            <para>
                In an EJB3 environment, we recommend the use of a special built-in component for transaction management,
                that is fully aware of container transactions, and can correctly process transaction success events
                registered with the <literal>Events</literal> component. If you don't add this line to your 
                <literal>components.xml</literal> file, Seam won't know when container-managed transactions end:
            </para>
            
            <programlisting role="XML"><![CDATA[<transaction:ejb-transaction/>]]></programlisting>

        </sect2>

        <sect2>
            <title>Don't forget!</title>

            <para> There is one final item you need to know about. You must place a <literal>seam.properties</literal>,
                    <literal>META-INF/seam.properties</literal> or <literal>META-INF/components.xml</literal> file in
                any archive in which your Seam components are deployed (even an empty properties file will do). At
                startup, Seam will scan any archives with <literal>seam.properties</literal> files for seam components. </para>

            <para> In a web archive (WAR) file, you must place a <literal>seam.properties</literal> file in the
                    <literal>WEB-INF/classes</literal> directory if you have any Seam components included here. </para>

            <para> That's why all the Seam examples have an empty <literal>seam.properties</literal> file. You can't
                just delete this file and expect everything to still work! </para>

            <para> You might think this is silly and what kind of idiot framework designers would make an empty file
                affect the behavior of their software?? Well, this is a workaround for a limitation of the
                JVM&#8212;if we didn't use this mechanism, our next best option would be to force you to list every
                component explicitly in <literal>components.xml</literal>, just like some other competing frameworks do!
                I think you'll like our way better. </para>

        </sect2>

    </sect1>
    
    <sect1 id="alt-jpa-providers">
        <title>Using Alternate JPA Providers</title>
        
        <para> Seam comes packaged and configured with Hibernate as the default JPA provider.
        If you require using a different JPA provider you must tell <literal>seam</literal>
        about it.  
        </para>
        
        <note>
            <title>This is a workaround</title>
            <para>
            Configuration of the JPA provider will be easier in the future and will
            not require configuration changes, unless you are adding a custom persistence provider
            implementation.
            </para> 
        </note>
        
        <para>Telling seam about a different JPA provider can be be done in one of two ways:</para>
        <para>Update your application's <literal>components.xml</literal>
              so that the generic <literal>PersistenceProvider</literal> takes
              precedence over the hibernate version.  Simply add the following
              to the file:                    
        </para>
        <programlisting role="XML"><![CDATA[<component name="org.jboss.seam.persistence.persistenceProvider" 
           class="org.jboss.seam.persistence.PersistenceProvider"
           scope="stateless">
</component>]]></programlisting>
        <para>If you want to take advantage of your JPA provider's 
        non-standard features you will need to write you own implementation of
        the <literal>PersistenceProvider</literal>.  Use 
        <literal>HibernatePersistenceProvider</literal> as a starting 
        point (don't forget to give back to the community :).  Then you
        will need to tell <literal>seam</literal> to use it as before.
        </para>
        <programlisting role="XML"><![CDATA[<component name="org.jboss.seam.persistence.persistenceProvider" 
           class="org.your.package.YourPersistenceProvider">
</component>]]></programlisting> 
        <para>All that is left is updating the <literal>persistence.xml</literal>
            file with the correct provider class, and what ever properties your
            provider needs.  Don't forget to package your new provider's jar files in the 
            application if they are needed.
        </para>
    </sect1>

    <sect1>
        <title>Configuring Seam in Java EE 5</title>

        <mediaobject>
            <imageobject role="fo">
                <imagedata fileref="images/ee5.png" align="center"/>
            </imageobject>
            <imageobject role="html">
                <imagedata fileref="images/ee5.png" align="center"/>
            </imageobject>
        </mediaobject>

        <para> If you're running in a Java EE 5 environment, this is all the configuration required to start using Seam! </para>

        <sect2>
            <title>Packaging</title>

            <para> Once you've packaged all this stuff together into an EAR, the archive structure will look something
                like this: </para>

            <programlisting><![CDATA[my-application.ear/
    jboss-seam.jar
    lib/
        jboss-el.jar
    META-INF/
        MANIFEST.MF
        application.xml
    my-application.war/
        META-INF/
            MANIFEST.MF
        WEB-INF/
            web.xml
            components.xml
            faces-config.xml
            lib/
                jsf-facelets.jar
                jboss-seam-ui.jar
        login.jsp
        register.jsp
        ...
    my-application.jar/
        META-INF/
            MANIFEST.MF
            persistence.xml
        seam.properties
        org/
            jboss/
                myapplication/
                    User.class
                    Login.class
                    LoginBean.class
                    Register.class
                    RegisterBean.class
                    ...]]></programlisting>

            <para>
                You should declare <literal>jboss-seam.jar</literal> as an ejb module in <literal>META-INF/application.xml</literal>; 
               <literal>jboss-el.jar</literal> should be placed in the EAR's lib directory (putting it in the EAR classpath.
            </para>

            <para> If you want to use jBPM or Drools, you must include the needed jars in the EAR's lib directory.</para>

            <para> If you want to use facelets (our recommendation), you must include
                <literal>jsf-facelets.jar</literal> in the <literal>WEB-INF/lib</literal> directory of the WAR. </para>

            <para> If you want to use the Seam tag library (most Seam applications do), you must include
                    <literal>jboss-seam-ui.jar</literal> in the <literal>WEB-INF/lib</literal> directory of the WAR. If
                you want to use the PDF or email tag libraries, you need to put <literal>jboss-seam-pdf.jar</literal> or
                    <literal>jboss-seam-mail.jar</literal> in <literal>WEB-INF/lib</literal>. </para>

            <para> If you want to use the Seam debug page (only works for applications using facelets), you must include
                    <literal>jboss-seam-debug.jar</literal> in the <literal>WEB-INF/lib</literal> directory of the WAR. </para>

            <para> Seam ships with several example applications that are deployable in any Java EE container that
                supports EJB 3.0. </para>

            <para> I really wish that was all there was to say on the topic of configuration but unfortunately we're
                only about a third of the way there. If you're too overwhelmed by all this tedious configuration stuff,
                feel free to skip over the rest of this section and come back to it later. </para>

        </sect2>

    </sect1>

    <sect1>
        <title>Configuring Seam in J2EE</title>

        <para> Seam is useful even if you're not yet ready to take the plunge into EJB 3.0. In this case you would use
            Hibernate3 or JPA instead of EJB 3.0 persistence, and plain JavaBeans instead of session beans. You'll miss
            out on some of the nice features of session beans but it will be very easy to migrate to EJB 3.0 when you're
            ready and, in the meantime, you'll be able to take advantage of Seam's unique declarative state management
            architecture. </para>

        <mediaobject>
            <imageobject role="fo">
                <imagedata fileref="images/hibernate-ee.png" align="center"/>
            </imageobject>
            <imageobject role="html">
                <imagedata fileref="images/hibernate-ee.png" align="center"/>
            </imageobject>
        </mediaobject>

        <para> Seam JavaBean components do not provide declarative transaction demarcation like session beans do. You
                <emphasis>could</emphasis> manage your transactions manually using the JTA
            <literal>UserTransaction</literal> or declaratively using Seam's <literal>@Transactional</literal>
            annotation. But most applications will just use Seam managed transactions when using Hibernate with
            JavaBeans. </para>

        <para> The Seam distribution includes a version of the booking example application that uses Hibernate3 and
            JavaBeans instead of EJB3, and another version that uses JPA and JavaBeans. These example applications are
            ready to deploy into any J2EE application server. </para>

        <sect2>
            <title>Boostrapping Hibernate in Seam</title>

            <para> Seam will bootstrap a Hibernate <literal>SessionFactory</literal> from your
                    <literal>hibernate.cfg.xml</literal> file if you install a built-in component: </para>

            <programlisting role="XML"><![CDATA[<persistence:hibernate-session-factory name="hibernateSessionFactory"/>]]></programlisting>

            <para> You will also need to configure a <emphasis>managed session</emphasis> if you want a Seam managed
                Hibernate <literal>Session</literal> to be available via injection. </para>

            <programlisting role="XML"><![CDATA[<persistence:managed-hibernate-session name="hibernateSession"
                            session-factory="#{hibernateSessionFactory}"/>]]></programlisting>

        </sect2>

        <sect2>
            <title>Boostrapping JPA in Seam</title>

            <para> Seam will bootstrap a JPA <literal>EntityManagerFactory</literal> from your
                <literal>persistence.xml</literal> file if you install this built-in component: </para>

            <programlisting role="XML"><![CDATA[<persistence:entity-manager-factory name="entityManagerFactory"/>]]></programlisting>

            <para> You will also need to configure a <emphasis>managed persistence context</emphasis> if you want a
                Seam managed JPA <literal>EntityManager</literal> to be available via injection. </para>

            <programlisting role="XML"><![CDATA[<persistence:managed-persistence-context name="entityManager"
                            entity-manager-factory="#{entityManagerFactory}"/>]]></programlisting>

        </sect2>

        <sect2>
            <title>Packaging</title>

            <para> We can package our application as a WAR, in the following structure: </para>

            <programlisting><![CDATA[my-application.war/
    META-INF/
        MANIFEST.MF
    WEB-INF/
        web.xml
        components.xml
        faces-config.xml
        lib/
            jboss-seam.jar
            jboss-seam-ui.jar
            jboss-el.jar
            jsf-facelets.jar
            hibernate3.jar
            hibernate-annotations.jar
            hibernate-validator.jar
            ...
            my-application.jar/
                META-INF/
                   MANIFEST.MF
                seam.properties
                hibernate.cfg.xml
                org/
                    jboss/
                        myapplication/
                            User.class
                            Login.class
                            Register.class
                            ...
    login.jsp
    register.jsp
    ...]]></programlisting>

            <para> If we want to deploy Hibernate in a non-EE environment like Tomcat or TestNG, we need to do a little
                bit more work. </para>

        </sect2>
    </sect1>

    <sect1>
        <title>Configuring Seam in Java SE, without JBoss Embedded</title>

        <para> It is possible to use Seam completely outside of an EE environment. In this case, you need to tell Seam
            how to manage transactions, since there will be no JTA available. If you're using JPA, you can tell
            Seam to use JPA resource-local transactions, ie. <literal>EntityTransaction</literal>, like so: </para>
            
        <programlisting role="XML"><![CDATA[<transaction:entity-transaction entity-manager="#{entityManager}"/>]]></programlisting>
        
        <para> If you're using Hibernate, you can tell Seam to use the Hibernate transaction API like this: </para>
            
        <programlisting role="XML"><![CDATA[<transaction:hibernate-transaction session="#{session}"/>]]></programlisting>
        
        <para> Of course, you'll also need to define a datasource.</para>
        
        <para> A better alternative is to use JBoss Embedded to get access to the EE APIs. </para>
                
    </sect1>

    <sect1>
        <title>Configuring Seam in Java SE, with JBoss Embedded</title>

        <para> JBoss Embedded lets you run EJB3 components outside the context of the Java EE 5 application server. This
            is especially, but not only, useful for testing. </para>

        <para> The Seam booking example application includes a TestNG integration test suite that runs on JBoss Embedded
            via <literal>SeamTest</literal>. </para>

        <mediaobject>
            <imageobject role="fo">
                <imagedata fileref="images/testng.png" align="center"/>
            </imageobject>
            <imageobject role="html">
                <imagedata fileref="images/testng.png" align="center"/>
            </imageobject>
        </mediaobject>

        <para> The booking example application may even be deployed to Tomcat. </para>

        <mediaobject>
            <imageobject role="fo">
                <imagedata fileref="images/e-ejb3.png" align="center"/>
            </imageobject>
            <imageobject role="html">
                <imagedata fileref="images/e-ejb3.png" align="center"/>
            </imageobject>
        </mediaobject>

        <sect2 id="config.install.embedded">
            <title>Installing Embedded JBoss</title>


            <para>
              Embedded JBoss must by installed into Tomcat for Seam applications
              to run correctly on it. Embedded JBoss only runs on JDK 1.5 (not JDK 1.6). 
              Embedded JBoss can be downloaded 
              <ulink url="http://sourceforge.net/project/showfiles.php?group_id=22866&amp;package_id=228977">here</ulink>.
              The process for installing Embedded JBoss into Tomcat 6 is quite 
              simple. First, you should copy the Embedded JBoss JARs and 
              configuration files into Tomcat. 
            </para>

            <itemizedlist>

                <listitem>
                    <para> Copy all files and directories under the Embedded JBoss <literal>bootstrap</literal> and
                            <literal>lib</literal> directories, except for the <literal>jndi.properties</literal> file,
                        into the Tomcat <literal>lib</literal> directory. </para>
                </listitem>


                <listitem>
                    <para>Remove the <literal>annotations-api.jar</literal> file from the Tomcat <literal>lib</literal>
                        directory. </para>
                </listitem>
            </itemizedlist>


            <para>Next, two configuration files need to be updated to add Embedded JBoss-specific functionality.</para>

            <itemizedlist>


                <listitem>
                    <para> Add the Embedded JBoss listener to <literal>conf/server.xml</literal>. It should appear after
                        all other listeners in the file.</para>

                    <programlisting role="XML"><![CDATA[<Listener className="org.jboss.embedded.tomcat.EmbeddedJBossBootstrapListener"/>]]></programlisting>
                </listitem>

                <listitem>
                    <para>WAR file scanning should be enabled by adding a listener to
                            <literal>conf/context.xml</literal>. </para>

                    <programlisting role="XML"><![CDATA[<Listener className="org.jboss.embedded.tomcat.WebinfScanner"/>]]></programlisting>
                </listitem>
            </itemizedlist>

            <para>For more configuration options, please see the Embedded JBoss Tomcat integration 
                <ulink url="http://wiki.jboss.org/wiki/Wiki.jsp?page=EmbeddedAndTomcat">wiki entry</ulink>.</para>

        </sect2>

        <sect2>
            <title>Packaging</title>

            <para> The archive structure of a WAR-based deployment on an servlet engine like Tomcat will look something
                like this: </para>

            <programlisting><![CDATA[my-application.war/
    META-INF/
        MANIFEST.MF
    WEB-INF/
        web.xml
        components.xml
        faces-config.xml
        lib/
            jboss-seam.jar
            jboss-seam-ui.jar
            jboss-el.jar
            jsf-facelets.jar
            jsf-api.jar
            jsf-impl.jar
            ...
            my-application.jar/
                META-INF/
                    MANIFEST.MF
                    persistence.xml
                seam.properties
                org/
                    jboss/
                        myapplication/
                            User.class
                            Login.class
                            LoginBean.class
                            Register.class
                            RegisterBean.class
                            ...
    login.jsp
    register.jsp
    ...]]></programlisting>

            <para> Most of the Seam example applications may be deployed to Tomcat by running <literal>ant
                deploy.tomcat</literal>. </para>

        </sect2>

    </sect1>

    <sect1>
        <title>Configuring jBPM in Seam</title>
        <para> Seam's jBPM integration is not installed by default, so you'll need to enable jBPM by installing a
            built-in component. You'll also need to explicitly list your process and pageflow definitions. In
                <literal>components.xml</literal>: </para>

        <programlisting role="XML"><![CDATA[<bpm:jbpm>
    <bpm:pageflow-definitions>
        <value>createDocument.jpdl.xml</value>
        <value>editDocument.jpdl.xml</value>
        <value>approveDocument.jpdl.xml</value>
    </bpm:pageflow-definitions>
    <bpm:process-definitions>
        <value>documentLifecycle.jpdl.xml</value>
    </bpm:process-definitions>
</bpm:jbpm>]]></programlisting>

        <para> No further special configuration is needed if you only have pageflows. If you do have business process
            definitions, you need to provide a jBPM configuration, and a Hibernate configuration for jBPM. The Seam DVD
            Store demo includes example <literal>jbpm.cfg.xml</literal> and <literal>hibernate.cfg.xml</literal> files
            that will work with Seam: </para>

        <programlisting role="XML"><![CDATA[<jbpm-configuration>

  <jbpm-context>
    <service name="persistence">
       <factory>
          <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory">
             <field name="isTransactionEnabled"><false/></field>
          </bean>
       </factory>
    </service>
    <service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
    <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
    <service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
    <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
    <service name="authentication" 
             factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
  </jbpm-context>

</jbpm-configuration>]]></programlisting>

        <para> The most important thing to notice here is that jBPM transaction control is disabled. Seam or EJB3 should
            control the JTA transactions. </para>

        <sect2>
            <title>Packaging</title>

            <para> There is not yet any well-defined packaging format for jBPM configuration and process/pageflow
                definition files. In the Seam examples we've decided to simply package all these files into the root of
                the EAR. In future, we will probably design some other standard packaging format. So the EAR looks
                something like this: </para>

            <programlisting><![CDATA[my-application.ear/
    jboss-seam.jar
    lib/
       jboss-el.jar
       jbpm-3.1.jar
    META-INF/
        MANIFEST.MF
        application.xml
    my-application.war/
        META-INF/
            MANIFEST.MF
        WEB-INF/
            web.xml
            components.xml
            faces-config.xml
            lib/
                jsf-facelets.jar
                jboss-seam-ui.jar
        login.jsp
        register.jsp
        ...
    my-application.jar/
        META-INF/
            MANIFEST.MF
            persistence.xml
        seam.properties
        org/
            jboss/
                myapplication/
                    User.class
                    Login.class
                    LoginBean.class
                    Register.class
                    RegisterBean.class
                    ...
    jbpm.cfg.xml
    hibernate.cfg.xml
    createDocument.jpdl.xml
    editDocument.jpdl.xml
    approveDocument.jpdl.xml
    documentLifecycle.jpdl.xml]]></programlisting>

        </sect2>

    </sect1>

    <sect1>
        <title>Configuring SFSB and Session Timeouts in JBoss AS</title>

        <para> It is very important that the timeout for Stateful Session Beans is set higher than the timeout for HTTP
            Sessions, otherwise SFSB's may time out before the user's HTTP session has ended. JBoss Application Server
            has a default session bean timeout of 30 minutes, which is configured in
                <literal>server/default/conf/standardjboss.xml</literal> (replace <emphasis>default</emphasis> with your
            own configuration). </para>

        <para> The default SFSB timeout can be adjusted by modifying the value of <literal>max-bean-life</literal> in
            the <literal>LRUStatefulContextCachePolicy</literal> cache configuration: </para>

        <programlisting role="XML"><![CDATA[<container-cache-conf>
    <cache-policy>org.jboss.ejb.plugins.LRUStatefulContextCachePolicy</cache-policy>
    <cache-policy-conf>
        <min-capacity>50</min-capacity>
        <max-capacity>1000000</max-capacity>
        <remover-period>1800</remover-period>

        <!-- SFSB timeout in seconds; 1800 seconds == 30 minutes -->
        <max-bean-life>1800</max-bean-life>  

        <overager-period>300</overager-period>
        <max-bean-age>600</max-bean-age>
        <resizer-period>400</resizer-period>
        <max-cache-miss-period>60</max-cache-miss-period>
        <min-cache-miss-period>1</min-cache-miss-period>
        <cache-load-factor>0.75</cache-load-factor>
    </cache-policy-conf>
</container-cache-conf>]]></programlisting>

        <para> The default HTTP session timeout can be modified in
                <literal>server/&lt;profile&gt;/deploy/jboss-web.deployer/conf/web.xml</literal> for JBoss EAP 4.3. The following
            entry in this file controls the default session timeout for all web applications: </para>

        <programlisting role="XML"><![CDATA[<session-config>
    <!-- HTTP Session timeout, in minutes -->
    <session-timeout>30</session-timeout>
</session-config>]]></programlisting>

        <para> To override this value for your own application, simply include this entry in your application's own
                <literal>web.xml</literal>. </para>

    </sect1>
    
    <sect1>
        <title>Running Seam in a Portlet</title>

        <para>
           If you want to run your Seam application in a portlet, take a look at
           the JBoss Portlet Bridge, an implementation of JSR-301 that supports
           JSF within a portlet, with extensions for Seam and RichFaces. See
           <ulink url="http://labs.jboss.com/portletbridge">http://labs.jboss.com/portletbridge</ulink>
           for more.
        </para>
        
        <note>
        	<title>Technology preview </title>    
    		<para>Seam Integration with JBoss Portlet Bridge is marked as technology preview, so standard support is not guaranteed.</para>     
    	</note>

    </sect1>

</chapter>
