1. Configuration for Seam
General Web Configuration (web.xml)
In order to initialize GDS/Tide for Seam and Hibernate, you must add granite-tide.jar, granite-tide-hibernate.jar and granite-tide-seam.jar to your WEB-INF/lib or in the lib directory of an ear.
In the case of ear packaging, jboss-seam.jar should be added at the root of the ear and referenced in application.xml:
<module><ejb>jboss-seam.jar</ejb></module>
With ear again, it is necessary to put all libs in ear/lib and to make sure that no jar concerning JPA persistence is left in WEB-INF/lib.
Then you have to add the following configuration to your web.xml:
<web-app version="2.4" ...> ... <!-- Seam --> <listener> <listener-class>org.jboss.seam.servlet.SeamListener</listener-class> </listener> <!-- GDS AMF message filter --> <filter> <filter-name>AMFMessageFilter</filter-name> <filter-class>org.granite.messaging.webapp.AMFMessageFilter</filter-class> <!-- Uncomment (part of) this block if configs are not present at default locations. <init-param> <param-name>servicesConfigPath</param-name> <param-value>/WEB-INF/flex/services-config.xml</param-value> </init-param> <init-param> <param-name>graniteConfigPath</param-name> <param-value>/WEB-INF/granite/granite-config.xml</param-value> </init-param--> </filter> <filter-mapping> <filter-name>AMFMessageFilter</filter-name> <url-pattern>/graniteamf/*</url-pattern> </filter-mapping> <!-- JSF Servlet --> <context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.xhtml</param-value> </context-param> <context-param> <param-name>facelets.DEVELOPMENT</param-name> <param-value>true</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <!-- GDS AMF Servlet --> <servlet> <servlet-name>AMFMessageServlet</servlet-name> <servlet-class>org.granite.messaging.webapp.AMFMessageServlet</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> <servlet-mapping> <servlet-name>AMFMessageServlet</servlet-name> <url-pattern>/graniteamf/*</url-pattern> </servlet-mapping> ... </web-app>
| You must not use the standard SeamFilter together with the Tide/Seam interceptor. If you need a dual Flex/HTML front-end, you have to configure the standard SeamFilter only for the HTML URLs. |
Flex/GDS Configuration
To use Tide+Seam services in your Flex application, you must configure a specific destination and service factory in services-config.xml:
<services-config> <services> <service id="granite-service" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage"> <!-- ! Use "tideSeamFactory" and "my-graniteamf" for "seam" destination (see below). ! The destination must be "seam" when using Tide with default configuration. !--> <destination id="seam"> <channels> <channel ref="my-graniteamf"/> </channels> <properties> <factory>tideSeamFactory</factory> </properties> </destination> </service> </services> <!-- ! Declare seamFactory service factory. !--> <factories> <factory id="tideSeamFactory" class="org.granite.tide.seam.SeamServiceFactory" /> </factories> <!-- ! Declare my-graniteamf channel. !--> <channels> <channel-definition id="my-graniteamf" class="mx.messaging.channels.AMFChannel"> <endpoint uri="http://{server.name}:{server.port}/{context.root}/graniteamf/amf" class="flex.messaging.endpoints.AMFEndpoint"/> </channel-definition> </channels> </services-config>
Note that this is the one and only destination configuration needed for all remote component calls.
There is then a little more configuration in granite-config.xml for Tide and security integration:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE granite-config PUBLIC "-//Granite Data Services//DTD granite-config internal//EN" "http://www.graniteds.org/public/dtd/1.2.0/granite-config.dtd"> <granite-config> <amf3messageinterceptor type="org.granite.seam.SeamInterceptor"/> <externalizers> <externalizer type="org.granite.hibernate.HibernateExternalizer"> <include annotatedwith="javax.persistence.Entity"/> <include annotatedwith="javax.persistence.MappedSuperclass"/> <include annotatedwith="javax.persistence.Embeddable"/> </externalizer> ... </externalizers> ... <security type="org.granite.seam.security.SeamSecurityService"/> <tide-components> <!-- List of component matchers, see 'Enabling components' section --> </tide-components> </granite-config>
Note that this part is much simpler if you use the automatic scanning of GraniteDS 1.1+:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE granite-config PUBLIC "-//Granite Data Services//DTD granite-config internal//EN" "http://www.graniteds.org/public/dtd/1.2.0/granite-config.dtd"> <granite-config scan="true"> <security type="org.granite.seam.security.SeamSecurityService"/> <tide-components> <!-- List of component matchers, see 'Enabling components' section --> </tide-components> </granite-config>
Configuration for Seam 2.1 (only GDS 1.2.0 RC1+)
Due to some changes in the Seam API, the configuration of GDS/Tide for use with Seam 2.1 is a little different.
First, the granite-tide-seam21.jar specific Tide library for Seam 2.1 must be used instead of the normal jar. The ActionScript SWC library is exactly the same: granite-tide-seam.swc.
Second, the FacesServlet is no longer needed in web.xml, but you can still keep it if you need to use JSF side-by-side with Tide. A typical web.xml with Tide/Seam21 will look like:
<web-app version="2.4" ...> ... <!-- Seam --> <listener> <listener-class>org.jboss.seam.servlet.SeamListener</listener-class> </listener> <!-- GDS AMF message filter --> <filter> <filter-name>AMFMessageFilter</filter-name> <filter-class>org.granite.messaging.webapp.AMFMessageFilter</filter-class> <!-- Uncomment (part of) this block if configs are not present at default locations. <init-param> <param-name>servicesConfigPath</param-name> <param-value>/WEB-INF/flex/services-config.xml</param-value> </init-param> <init-param> <param-name>graniteConfigPath</param-name> <param-value>/WEB-INF/granite/granite-config.xml</param-value> </init-param--> </filter> <filter-mapping> <filter-name>AMFMessageFilter</filter-name> <url-pattern>/graniteamf/*</url-pattern> </filter-mapping> <!-- No more JSF Servlet configuration --> <!-- GDS AMF Servlet --> <servlet> <servlet-name>AMFMessageServlet</servlet-name> <servlet-class>org.granite.messaging.webapp.AMFMessageServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AMFMessageServlet</servlet-name> <url-pattern>/graniteamf/*</url-pattern> </servlet-mapping> ... </web-app>
The security service is also different, so the granite-config.xml would look like:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE granite-config PUBLIC "-//Granite Data Services//DTD granite-config internal//EN" "http://www.graniteds.org/public/dtd/1.2.0/granite-config.dtd"> <granite-config> <amf3messageinterceptor type="org.granite.seam21.Seam21Interceptor"/> <converters> <converter type="org.granite.seam21.ValueExpressionConverter"/> </converters> <externalizers> <externalizer type="org.granite.hibernate.HibernateExternalizer"> <include annotatedwith="javax.persistence.Entity"/> <include annotatedwith="javax.persistence.MappedSuperclass"/> <include annotatedwith="javax.persistence.Embeddable"/> </externalizer> ... </externalizers> ... <security type="org.granite.seam21.security.Seam21SecurityService"/> <tide-components> <!-- List of component matchers, see 'Enabling components' section --> </tide-components> </granite-config>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE granite-config PUBLIC "-//Granite Data Services//DTD granite-config internal//EN" "http://www.graniteds.org/public/dtd/1.2.0/granite-config.dtd"> <granite-config scan="true"> <security type="org.granite.seam21.security.Seam21SecurityService"/> <tide-components> <!-- List of component matchers, see 'Enabling components' section --> </tide-components> </granite-config>
