1. Configuration for Seam
General Web Configuration (web.xml)
In order to initialize GDS/Tide for Seam 2.1 and Hibernate, you must add granite.jar, granite-hibernate.jar and granite-seam21.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> <!-- 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>
| 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 have to 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/2.0.0/granite-config.dtd"> <granite-config> <amf3-message-interceptor type="org.granite.seam21.Seam21Interceptor"/> <converters> <converter type="org.granite.seam21.ValueExpressionConverter"/> <converter type="org.granite.seam21.ConversationEntryConverter"/> </converters> <externalizers> <externalizer type="org.granite.hibernate.HibernateExternalizer"> <include annotated-with="javax.persistence.Entity"/> <include annotated-with="javax.persistence.MappedSuperclass"/> <include annotated-with="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>
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/2.0.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>
Configuration for Seam 2.0
It is highly recommend to use Seam 2.1 with Flex because the removal of the dependency on JSF. If you absolutely need to use Seam 2.0, the configuration of GDS/Tide is a little different.
First, the granite-seam.jar must be used instead of granite-seam21.jar.
Second, the FacesServlet must be added in web.xml. A typical web.xml with Tide/Seam 2.0 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> <!-- 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>
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/2.0.0/granite-config.dtd"> <granite-config> <amf3-message-interceptor type="org.granite.seam.SeamInterceptor"/> <externalizers> <externalizer type="org.granite.hibernate.HibernateExternalizer"> <include annotated-with="javax.persistence.Entity"/> <include annotated-with="javax.persistence.MappedSuperclass"/> <include annotated-with="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/2.0.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>
