You are on page 1of 27

9/29/2010 The architecture of Flex and Java appli…

Adobe
Products Industries Learning Help Downloads Company
Store
Adobe Store for home or home office
Education Store for students, educators, or staff
Business Store for small and medium business
Other ways to buy

Search Search
Info Sign in
My cart My shipments My support
Adobe Developer Connection /Flex Developer Center /

The architecture of Flex and Java applications


by Jeanette Stallons

stallons.com

Content
1. Client/server architecture
2. Flash Remoting
3. Security
4. Flex application architecture
5. Messaging
6. Data managed applications
7. Model driven development
8. Portal integration

Created
Mar 22, 2010

Comments (0)
adobe.com/…/flex_java_architecture.html 1/27
9/29/2010Comments (0) The architecture of Flex and Java appli…

(0 Ratings)

Requirements
User level
All

The Java EE Platform is the leading enterprise web server. The Adobe Flash Platform is the leader in the rich
Internet application space. Using both, developers can deliver compelling, data-centric applications that leverage
the benefits of an enterprise back-end solution and a great user experience.

In this article, you learn about the architecture of applications built using Flex and Java including:

An overview of the client/server architecture.


The different ways the client and server can communicate.
An introduction to Flash Remoting and why and how you use it.
How to integrate a Flex application with your security framework.
An overview of how to build Flex applications using events, states, MXML components, and modules.
An introduction to developing a Flex application with real-time server data push.
How to boost productivity developing data-intensive applications using the Data Management service in
LiveCycle Data Services.
An overview of model driven development using Flash Builder and LiveCycle Data Services to generate
client and server-side code.
How to deploy a Flex application on a portal server.

Be sure to also watch the video Introduction to Flex 4 and Java integration.

To learn more about the technologies used to build these applications, read The technologies for building Flex
and Java applications article.

1. Client/server architecture
Flex and Java applications use a multi-tier architecture where the presentation tier is the Flex application, the
business or application tier is the Java EE server and code, and the data tier is the database. You can write the
back-end code just as you normally would for a Java application, modeling your objects, defining your database,
using an object-relational framework such as Hibernate or EJB 3, and writing the business logic to query and
manipulate these objects. The business tier must be exposed for access via HTTP from the Flex application and
will be used to move the data between the presentation and data tiers.

Typical HTML applications consist of multiple pages and as a user navigates between them, the application data
must be passed along so the application itself (the collection of pages and functionality it consists of) can maintain
state. In contrast, Flex applications, by nature, are stateful. A Flex application is embedded in a single HTML
page that the user does not leave and is rendered by Flash Player. The Flex application can dynamically change
views and send and retrieve data asynchronously to the server in the background, updating but never leaving the

adobe.com/…/flex_java_architecture.html 2/27
9/29/2010 The architecture of Flex and Java appli…
single application interface (see Figure 1) (similar to the functionality provided by the XMLHttpRequest API with
JavaScript.)

Figure 1. The client/server architecture.

Client/server communication

Flex applications can communicate with back-end servers using either direct socket connections or more
commonly, through HTTP. The Flex framework has three remote procedure call APIs that communicate with a
server over HTTP: HTTPService, WebService, and RemoteObject. All three wrap Flash Player's HTTP
connectivity, which in turn, uses the browser's HTTP library. Flex applications cannot connect directly to a
remote database.

You use HTTPService to make HTTP requests to JSP or XML files, to RESTful web services, or to other
server files that return text over HTTP. You specify the endpoint URL, listener functions (the callback functions
to be invoked when the HTTPService request returns a successful or unsuccessful response), and a data type for
the returned data (what type of data structure it should be translated into once received in the Flex application).
You can specify the data to be handled as raw text and assigned to a String variable or converted to XML, E4X,
or plain old ActionScript objects. If you get back JSON, you can use the Adobe Flex corelib package of classes
to deserialize the JSON objects into ActionScript objects. To make calls to SOAP based web services, you can
use the HTTPService API or the more specialized WebService API, which automatically handles the serialization
and deserialization of SOAP formatted text to ActionScript data types and vice versa.

The third option for making remote procedure calls is to use the RemoteObject API. It makes a Flash Remoting
request to a method of a server-side Java class that returns binary Action Message Format over HTTP. When
possible, use Flash Remoting whose binary data transfer format enables applications to load data up to 10 times
faster than with the more verbose, text-based formats such as XML, JSON, or SOAP (see Figure 2). To see a
comparison of AMF to other text-based serialization technologies, see James Ward's Census RIA Benchmark
application.

Figure 2. Methods for connecting Flex and Java.


adobe.com/…/flex_java_architecture.html 3/27
9/29/2010 The architecture of Flex and Java appli…

2. Flash Remoting

Flash Remoting is a combination of client and server-side functionality that together provides a call-and-response
model for accessing server-side objects from Flash Platform applications as if they were local objects. It
provides transparent data transfer between ActionScript and server-side data types, handling the serialization into
Action Message Format (AMF), deserialization, and data marshaling between the client and the server.

Flash Remoting uses client-side functionality built in to Flash Player and server-side functionality that is built in to
some servers (like ColdFusion and Zend) but must be installed on other servers (as BlazeDS or LiveCycle Data
Services on Java EE servers, WebORB or FluorineFX on .NET servers, the Zend framework or amfphp on
PHP servers, and more). See the technologies for building Flex and Java applications article for more details
about BlazeDS and LiveCycle Data Services.

BlazeDS and LiveCycle Data Services use a message-based framework to send data back and forth between
the client and server. They provide Remoting, Proxying, and Messaging services, and for LiveCycle, an
additional Data Management service. The Flex application sends a request to the server and the request is routed
to an endpoint on the server. From the endpoint, the request is passed to the MessageBroker, the BlazeDS and
LiveCycle Data Services engine that handles all the requests and routes them through a chain of Java objects to
the destination, the Java class with the method to invoke (see Figure 3).

Figure 3. Flash Remoting architecture.

AMF

AMF is a binary format used to serialize ActionScript objects and facilitate data exchange between Flash
Platform applications and remote services over the Internet. Adobe publishes this protocol; the latest is AMF 3
Specification for ActionScript 3. You can find tables listing the data type mappings when converting from
ActionScript to Java and Java to ActionScript here.

For custom or strongly typed objects, public properties (including those defined with get and set methods) are
serialized and sent from the Flex application to the server or from the server to the Flex application as properties
of a general 0bject. To enable mapping between the corresponding client and server-side objects, you use the
same property names in the Java and ActionScript classes and then in the ActionScript class, you use the
[RemoteClass] metadata tag to create an ActionScript object that maps directly to the Java object.

adobe.com/…/flex_java_architecture.html 4/27
9/29/2010 The architecture of Flex and Java appli…

Here is an example Employee ActionScript class that maps to a server-side Employee Java DTO located in the
services package on the server.

package valueobjects.Employee{ [Bindable] [RemoteClass(alias="services.Employee")]


public class Employee { public var id:int; public var firstName:String; public var
lastName:String; (...) } }

Installing BlazeDS or LiveCycle Data Services

To use Flash Remoting with BlazeDS or LiveCycle Data Services, you need to install and configure the
necessary server-side files. For BlazeDS, you can download it as a WAR file which you deploy as a web
application or as a turnkey solution. The turnkey download contains a ready-to-use version of Tomcat in which
the the BlazeDS WAR file has already been deployed and configured along with a variety of sample applications.
Similarly, for LiveCycle Data Services, the installer lets you choose to install LiveCycle with an integrated
Tomcat server or as a LiveCycle Data Services web application.

In either scenario a web application called blazeds or lcds (usually appended by a version number) is created.
You can modify and build out this application with your Java code, or more typically, you can copy the JAR files
and configuration files the blazeds or lcds web application contains and add them to an existing Java web
application on the server (see Figure 4).

Figure 4. The required BlazeDS or LiveCycle Data Services files.

Modifying web.xml

adobe.com/…/flex_java_architecture.html 5/27
9/29/2010 The architecture of Flex and Java appli…

If copying the files to a different web application, you also need to modify the web.xml file to define a session
listener for HttpFlexSession and a servlet mapping for MessageBroker, which handles all the requests and passes
them off to the correct server-side Java endpoints. You can copy and paste these from the original blazeds or
lcds web application web.xml file.

<!-- Http Flex Session attribute and binding listener support --> <listener>
<listener-class>flex.messaging.HttpFlexSession</listener-class> </listener> <!--
MessageBroker Servlet --> <servlet> <servlet-name>MessageBrokerServlet</servlet-
name> <display-name>MessageBrokerServlet</display-name> <servlet-
class>flex.messaging.MessageBrokerServlet</servlet-class> <init-param> <param-
name>services.configuration.file</param-name> <param-value>/WEB-INF/flex/services-
config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping> <servlet-name>MessageBrokerServlet</servlet-name> <url-
pattern>/messagebroker/*</url-pattern> </servlet-mapping>

Optionally, you may also want to copy and paste (and uncomment) the mapping for RDSDispatchServlet, which
is used for RDS (Remote Data Service) access with the data service creation feature in Flash Builder 4 that
introspects a server-side service and generates corresponding client-side code. See the model driven
development section for more details.

<servlet> <servlet-name>RDSDispatchServlet</servlet-name> <display-


name>RDSDispatchServlet</display-name> <servlet-
class>flex.rds.server.servlet.FrontEndServlet</servlet-class> <init-param> <param-
name>useAppserverSecurity</param-name> <param-value>false</param-value> </init-
param> <load-on-startup>10</load-on-startup> </servlet> <servlet-mapping
id="RDS_DISPATCH_MAPPING"> <servlet-name>RDSDispatchServlet</servlet-name> <url-
pattern>/CFIDE/main/ide.cfm</url-pattern> </servlet-mapping>

Reviewing services-config.xml

For Flash Remoting, the client sends a request to the server to be processed and the server returns a response to
the client containing the results. You configure these requests by modifying the services-config.xml and remoting-
config.xml files located in the /WEB-INF/flex/ folder for the web application.

The services-config.xml file defines different channels that can be used when making a request. Each channel
definition specifies the network protocol and the message format to be used for a request and the endpoint to
deliver the messages to on the server. The Java-based endpoints unmarshal the messages in a protocol-specific
manner and then pass the messages in Java form to the MessageBroker which sends them to the appropriate
service destination (you'll see how to define these next).

<channels> <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">


<endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
class="flex.messaging.endpoints.AMFEndpoint"/> </channel-definition> <channel-
definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel">
<endpoint
url="https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure"
class="flex.messaging.endpoints.SecureAMFEndpoint"/> </channel-definition> (...)
</channels>

Defining destinations

adobe.com/…/flex_java_architecture.html 6/27
9/29/2010 The architecture of Flex and Java appli…
In the remoting-config.xml file, you define the destinations (named mappings to Java classes) to which the
MessageBroker passes the messages. You set the source property to the fully qualified class name of a Java
POJO with a no argument constructor that is located in a source path, usually achieved by placing it in the web
application's /WEBINF/classes/ directory or in a JAR file in the /WEBINF/lib/ directory. You can access EJBs
and other objects stored in the Java Naming and Directory Interface (JNDI) by calling methods on a destination
that is a service facade class that looks up an object in JNDI and calls its methods.

You can access stateless or stateful Java objects by setting the scope property to application, session, or
request (the default). The instantiation and management of the server-side objects referenced is handled by
BlazeDS or LiveCycle Data Services.

<service id="remoting-service" class="flex.messaging.services.RemotingService">


<adapters> <adapter-definition id="java-object"
class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/>
</adapters> <default-channels> <channel ref="my-amf"/> </default-channels>
<destination id="employeeService"> <properties>
<source>services.EmployeeService</source> <scope>application</scope> </properties>
</destination> </service>

You can also specify channels for individual destinations.

<destination id="employeeService " channels="my-secure-amf">

Lastly, you use these destinations when defining RemoteObject instances in a Flex application.

<s:RemoteObject id="employeeSvc" destination="employeeService"/>

3. Security
In many applications, access to some or all server-side resources must be restricted to certain users. Many Java
EE applications use container managed security in which user authentication (validating a user) and user
authorization (determining what the user has access to—which is often role based) are performed against the
Realm, an existing store of usernames, passwords, and user roles. The Realm is configured on your Java EE
server to be a relational database, an LDAP directory server, an XML document, or to use a specific
authentication and authorization framework.

To integrate a Flex application with the Java EE security framework so that access to server-side resources is
appropriately restricted, you add security information to the BlazeDS or LiveCycle Data Services configuration
files (details follow below) and then typically in the Flex application, create a form to obtain login credentials from
the user which are passed to the server to be authenticated. The user credentials are then passed to the server
automatically with all subsequent requests.

Modifying services-config.xml

In the BlazeDS or LiveCycle Data Services services-config.xml file, you need to specify the "login command" for
your application server in the <security> tag. BlazeDS and LiveCycle Data Services supply the following login
commands: TomcatLoginCommand (for both Tomcat and JBoss), JRunLoginCommand,
WeblogicLoginCommand, WebSphereLoginCommand, OracleLoginCommand. These are all defined in the
XML file and you just need to uncomment the appropriate one.
adobe.com/…/flex_java_architecture.html 7/27
9/29/2010 The architecture of Flex and Java appli…

You also need to define a security constraint that you specify to use either basic or custom authentication and if
desired, one or more roles. To do custom authentication with Tomat or JBoss, you also need to add some extra
classes to the web application for integrating with the security framework used by the Jave EE application server
and modify a couple of configuration files. Mode details can be found here.

<services-config> <security> <login-command


class="flex.messaging.security.TomcatLoginCommand" server="Tomcat"> <per-client-
authentication>false</per-client-authentication> </login-command> <security-
constraint id="trusted"> <auth-method>Custom</auth-method> <roles>
<role>employees</role> <role>managers</role> </roles> </security-constraint>
</security> ... </services-config>

Modifying remoting-config.xml

Next, in your destination definition, you need to reference the security constraint:

<destination id="employeeService"> <properties>


<source>services.EmployeeService</source> </properties> <security> <security-
constraint ref="trusted"/> </security> </destination>

You can also define default security constraints for all destinations and/or restrict access to only specific methods
that can use different security constraints.

The default channel, my-amf, uses HTTP. You can change one or more of the destinations to use the my-secure-
amf channel that uses HTTPS:

<destination id="employeeService"> <channels> <channel ref="my-secure-amf"/>


</channels> ... </destination>

where my-secure-amf is defined in the services-config.xml file:

<!-- Non-polling secure AMF --> <channel-definition id="my-secure-amf"


class="mx.messaging.channels.SecureAMFChannel"> <endpoint
url="https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure"
class="flex.messaging.endpoints.SecureAMFEndpoint"/> </channel-definition>

Adding code to the Flex application

That covers the server-side setup. Now, if you are using custom authentication, you need to create a form in the
Flex application to retrieve a username and password from the user and then pass these credentials to the server
by calling the ChannelSet.login() method and then listening for its result and fault events. A result
event indicates that the login (the authentication) occurred successfully, and a fault event indicates the login
failed. The credentials are applied to all services connected over the same ChannelSet. For basic authentication,
you don’t have to add anything to your Flex application. The browser opens a login dialog box when the
application first attempts to connect to a destination.

Your application can now make Flash Remoting requests to server destinations just as before, but now the user
credentials are automatically sent with every request (for both custom and basic authentication). If the destination
or methods of the destination have authorization roles specified which are not met by the logged in user, the call

adobe.com/…/flex_java_architecture.html 8/27
9/29/2010 The architecture of Flex and Java appli…
will return a fault event. To remove the credentials and log out the user, you use the ChannelSet.logout()
method.

4. Flex application architecture


Now that you've learned to set up Flash Remoting on the server-side and define a RemoteObject instance in
Flex, let's take a look at how you build an application to use this object.

Using events

A typical Flex application consists of MXML code to define the user interface and ActionScript code for the
logic. Just as for JavaScript and the browser DOM objects, the two are wired together using events and event
handlers. To use a RemoteObject in an application, you define the instance, invoke a method of the server-side
remoting destination, specify callback functions for the result and fault events, and inside those, do
something with the data returned from the server.

Here is a simple application where employee data is retrieved from a database and displayed in a Flex DataGrid
component. After the application is initialized, the getEmployees() method of the employeeService destination
defined in the remoting-config.xml file on the server is called, and if data is successfully returned from the server,
the variable employees is populated and if the request fails for any reason, a message is displayed in an Alert
box. Data binding is used to bind the employees variable to the dataProvider property of the DataGrid.

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" initialize="employeeSvc.getEmployees()">
<fx:Script> <![CDATA[ import mx.collections.ArrayCollection; import
mx.controls.Alert; import mx.rpc.events.FaultEvent; import
mx.rpc.events.ResultEvent; [Bindable]private var employees:ArrayCollection; private
function onResult(e:ResultEvent):void{ employees=e.result as ArrayCollection; }
private function onFault(e:FaultEvent):void{ Alert.show("Error retrieving
data.","Error"); } ]]> </fx:Script> <fx:Declarations> <s:RemoteObject
id="employeeSvc" destination="employeeService" result="onResult(event)"
fault="onFault(event)" /> </fx:Declarations> <mx:DataGrid
dataProvider="{employees}"/> </s:Application>

When using a RemoteObject, you can define result and fault handlers on the service level:

<s:RemoteObject id="employeeSvc" destination="employeeService"


result="onResult(event)" fault="onFault(event)"/>

on the method level:

<s:RemoteObject id="employeeSvc" destination="employeeService"> <s:method


name="getEmployees" result="onResult(event)" fault="onFault(event)"/> <s:method
name="getDepartments" result="onResult2(event)" fault="onFault2(event)"/>
</RemoteObject>

or on a per-call basis:

<s:Application xmlns:fx=http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"

adobe.com/…/flex_java_architecture.html 9/27
9/29/2010 The architecture of Flex and Java appli…
xmlns:mx="library://ns.adobe.com/flex/mx"
initialize="getEmployeesResult.token=employeeSvc.getEmployees()"> <fx:Declarations>
<s:RemoteObject id="employeeSvc" destination="employeeService"/> <s:CallResponder
id="getEmployeesResult" result="onResult(event)" fault="onFault(event)"/>
</fx:Declarations>

Using data binding

Data binding is a powerful part of the Flex framework that lets you update the user interface when data changes
without you having to explicitly register and write the event listeners to do this. In the previous application code,
the [Bindable] tag in front of the the employees variable definition is a compiler directive; when the file is
compiled, ActionScript code is automatically generated so that an event is broadcast whenever the employees
variable changes.

[Bindable]private var employees:ArrayCollection;

The curly braces in the assignment of the DataGrid's dataProvider property actually generates the code to
listen for changes to the employees variable and when it changes, to update the DataGrid view accordingly.

<mx:DataGrid dataProvider="{employees}"/>

In this application, employees is initially null and no data is displayed in the DataGrid but as soon as the data is
successfully retrieved form the server and employees is populated, the DataGrid is updated to display the
employee data.

Using view states

To make more extreme changes to the user interface dynamically at runtime, for instance to add, remove, move,
or modify components, you use Flex view states. For every Flex view or component, you can define multiple
states and then for every object in that view, you can define what state(s) it should be included in and what it
should look like and how it should behave in that state. You switch between states by setting the component's
currentState property to the name of one of the defined states.

<s:states> <s:State name="employees"/> <s:State name="departments"/> </s:states>


<mx:DataGrid dataProvider="{employees}" includeIn="employees"/> <s:Button
label.employees="Switch to departments" label.departments="Switch to employees"
click.employees="currentState='departments'"
click.departments="currentState='employees'"/>

Using MXML components

As your application gets larger, you need to break up your logic into packages of ActionScript classes and your
views into separate MXML files (called MXML components). Each MXML component extends an existing
component and can only be included in an application, but not run on its own. To use a component in MXML,
you instantiate an instance of that component (its class name is the same as its file name) and include the proper
namespace so the compiler can locate it.

Here is the code for a MXML component, Masterview, saved as MasterView.mxml in the
com.adobe.samples.views package.
adobe.com/…/flex_java_architecture.html 10/27
9/29/2010 The architecture of Flex and Java appli…

<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" > <fx:Metadata>
[Event(name="masterDataChange",type="flash.events.Event")] </fx:Metadata>
<fx:Script> <![CDATA[ import mx.collections.ArrayList; [Bindable]private var
masterData:ArrayList=new ArrayList(["data1", "data2", "data3"]); public var
selectedData:String; private function onChange(e:Event):void{
selectedData=dataList.selectedItem; this.dispatchEvent(new
Event("masterDataChange")); } ]]> </fx:Script> <s:DropDownList id="dataList"
dataProvider="{masterData}" change="onChange(event)"/> </s:Group>

Here is the code for an application that instantiates and uses that custom MasterView component.

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" xmlns:views="com.adobe.samples.views.*">
<fx:Script> <![CDATA[ import mx.controls.Alert; private function
onMasterDataChange(e:Event):void{ Alert.show(e.currentTarget.selectedData,"Master
data changed"); } ]]> </fx:Script> <views:MasterView
masterDataChange="onMasterDataChange(event)"/> </s:Application>

Broadcasting events

In order to build loosely-coupled components, you need to define a public API for the component (its public
members) and/or define and broadcast custom events as shown in the MasterView code example above. The
[Event] metadata tag is used to define the event as part of the component's API and specify what type of event
object it broadcasts.

<fx:Metadata> [Event(name="masterDataChange",type="flash.events.Event")]
</fx:Metadata>

When some event occurs in the component (in this example, a DropDownList change event), the component
creates an instance of the type of event object specified in the metadata and broadcasts it.

this.dispatchEvent(new Event("masterDataChange"));

The code that instantiates this custom component can now register to listen for this custom event and register and
event handler.

<views:MasterView masterDataChange="onMasterDataChange(event)"/>

Loosely-coupled components like this that define and broadcast custom events are the core building blocks for
Flex applications. In fact, this is how the components in the Flex framework itself are built. For more information
on broadcasting custom events, watch the video, Learn how to define and broadcast events.

Creating modules

By default, all your code gets compiled into one SWF file. If your SWF file gets very large or contains
functionality that only specific users may use, you can use modules to break your application into multiple SWF
files that can be loaded and unloaded dynamically by the main application at runtime. To create a module, you
create a class (ActionScript of MXML) extending the Module class and then compile it. To load the module
dynamically at runtime into an application, you use the <mx:ModuleLoader> tag or methods of the

adobe.com/…/flex_java_architecture.html 11/27
9/29/2010 The architecture of Flex and Java appli…
ModuleLoader class.

Using a microarchitecture

That covers the basics for building an application, but as your application gets larger, you are going to want to
use some methodology to organize its files, centralize the application data and data services, and handle
communication between all the components. To do this, you can build your Flex application using all the design
patterns that have proven useful over the years in enterprise application development. In fact, many Flex specific
microarchitectures have been and continue to be developed. The oldest and most established is Cairngorm, an
open source microarchitecture that uses commands and delegates, front controllers, a singleton data model, a
singleton service store, and an event dispatcher. Other popular frameworks include Pure MVC, Mate, Parsley,
Swiz, and Spring ActionScript. For more information about these and other frameworks, see Flex Architecture
on the Adobe Developer Center.

5. Messaging
To this point, the article has focused on creating applications that use a call-response model to make
asynchronous calls to Java classes on the server. Using BlazeDS or LiveCycle Data Services, you can also build
applications that use a publish-subscribe model to send messages between multiple Flex clients (through the
server), push messages from the server to clients, and/or send messages to other JMS enabled messaging clients.
A Flex application can send messages to a destination on the server and any other clients subscribed to that same
destination will receive those messages.

A simple application using messaging is instant messaging where text is exchanged between clients. Messaging
can also be used to create rich collaborative data applications where data changes made in one client are
"instantly" seen by other clients viewing the same data. Server sending notifications to clients, clients receiving
sport score updates, auction sites having access to real-time bids, applications for trading stocks, foreign
exchange etc. are all examples of applications that can be developed using the messaging infrastructure.

Defining destinations

Similar to how you configure remoting, you configure messaging by defining destinations in a server-side
configuration file, in this case, messaging-config.xml. A messaging destination can be as simple as this:

<destination id="chat">

in which case it uses the default adapter and channel defined in the messaging-config.xml file:

<adapters> <adapter-definition id="actionscript"


class="flex.messaging.services.messaging.adapters.ActionScriptAdapter"
default="true" /> <adapter-definition id="jms"
class="flex.messaging.services.messaging.adapters.JMSAdapter"/> </adapters>
<default-channels> <channel ref="my-rtmp"/> <channel ref="my-streaming-amf"/>
</default-channels>

The first adapter defined, actionscript, is the default adapter and is used to exchange messages between Flex
clients. The jms adapter can be used instead to bridge to JMS destinations. The default channel is my-rtmp, a
real-time streaming channel with failover to a streaming AMF channel (both defined in the services-config.xml
adobe.com/…/flex_java_architecture.html 12/27
9/29/2010 The architecture of Flex and Java appli…
file). Channels are discussed in more detail in the next section, Selecting a channel.

You can also specify additional properties when defining a destination, including network and server properties.
In the following destination, the chat destination is configured to use the my-polling-amf channel, users are
never unsubscribed even with no activity, messages are kept on the server indefinitely until there are 1000
messages at which time the oldest is replaced, and only clients that have been authenticated and authorized
against the trusted security constraint defined in the services-config.xml file (see the Security section) can
publish or receive messages.

<destination id="chat"> <properties> <channels> <channel ref="my-polling-amf"/>


</channels> <network> <session-timeout>0</session-timeout> </network> <server> <max-
cache-size>1000</max-cache-size> <message-time-to-live>0</message-time-to-live>
<durable>false</durable> <send-security-constraint ref="trusted"/> <subscribe-
security-constraint ref="trusted"/> </server> </properties> </destination>

Selecting a channel

When defining a destination, you specify the channel to be used for the communication between the client and
server including the protocol, the port, and the endpoint. Channels are defined in the services-config.xml file. For
remoting, you usually use the my-amf or my-secure-amf channel. For messaging, there is larger number of
channels to select from, including those that use polling or streaming, servlets or sockets, and HTTP or RTMP.

Polling channels support polling the server on some interval or on some event. The my-polling-amf channel
polls the server every 8 seconds for new messages.

<channel-definition id="my-polling-amf" class="mx.messaging.channels.AMFChannel">


<endpoint
url="http://{server.name}:{server.port}/{context.root}/messagebroker/amfpolling"
class="flex.messaging.endpoints.AMFEndpoint"/> <properties> <polling-
enabled>true</polling-enabled> <polling-interval-seconds>8</polling-interval-
seconds> </properties> </channel-definition>

To more closely mimic a real-time connection, you can use long polling. The my-amf-longpoll channel is
configured for long polling.

<channel-definition id="my-amf-longpoll" class="mx.messaging.channels.AMFChannel">


<endpoint
url="http://{server.name}:{server.port}/{context.root}/messagebroker/myamflongpoll"
class="flex.messaging.endpoints.AMFEndpoint"/> <properties> <polling-
enabled>true</polling-enabled> <polling-interval-seconds>0</polling-interval-
seconds> <wait-interval-seconds>60</wait-interval-seconds> <client-wait-interval-
seconds>3</client-wait-interval-seconds> <max-waiting-poll-requests>100</max-
waiting-poll-requests > </properties> </channel-definition>

When this channel is used, the client polls the server; the server poll response thread waits 60 seconds for new
messages to arrive if there are no new messages on the server and then returns to the client; after receiving the
poll response, the client polls again after 3 seconds; the process is repeated. The server is set to allow 100
simultaneous server poll response threads in a wait state; if exceeded, the server does not wait for new messages
before returning a response. Typical application servers might have around 200 HTTP request threads available,
so you need to make sure you set the maximum allowable number of polling threads to a smaller number and still
leave enough threads to handle other HTTP requests.
adobe.com/…/flex_java_architecture.html 13/27
9/29/2010 The architecture of Flex and Java appli…

With servers and proxy servers that support HTTP 1.1, an HTTP streaming channel can be used. A persistent
connection is established between the client and the server over which server messages are pushed to the client.
HTTP connections can't handle traffic in both directions, so separate, short-lived threads must be used for any
other server requests. Network latency is minimized compared to long-polling because connections don’t have to
be continually closed and reopened.

<channel-definition id="my-streaming-amf"
class="mx.messaging.channels.StreamingAMFChannel"> <endpoint
url="http://{server.name}:{server.port}/{context.root}/messagebroker/streamingamf"
class="flex.messaging.endpoints.StreamingAMFEndpoint"/> </channel-definition>

Using HTTP long-polling and streaming the number of simultaneous users that can be connected to a destination
is limited by the available number of server HTTP threads. For applications that will have larger numbers of
simultaneous users, messages can be pushed using sockets instead of HTTP threads. LiveCycle Data Services
includes a NIO-based socket server and has additional channels available for messaging that are not available
with BlazeDS. These channels, defined in the services-config.xml file, all contain "nio" in their names. NIO stands
for Java New Input/Output and is a collection of Java APIs for I/O operations.

If you are using LiveCycle Data Services you should use the NIO channels over the servlet based channels
because they scale better, handling thousands of simultaneous users instead of around a hundred. There are NIO
equivalents for each of the AMF polling, long polling, and streaming channels just discussed (my-nio-amf-
poll, my-nio-amf-longpoll, my-nioamf-stream). These channels are still using HTTP so in the latter two
cases, separate threads are still required for client-server requests and the persistent (or waiting) threads used for
the server-to-client updates.

<channel-definition id="my-nio-amf-longpoll"
class="mx.messaging.channels.AMFChannel"> <endpoint
url="http://{server.name}:2080/nioamflongpoll"
class="flex.messaging.endpoints.NIOAMFEndpoint"/> <server ref="my-nio-server"/>
<properties> <polling-enabled>true</polling-enabled> <polling-interval-
millis>0</polling-interval-millis> <wait-interval-millis>-1</wait-interval-millis>
</properties> </channel-definition>

With LiveCycle Data Services you can choose channels that use the RTMP protocol instead of HTTP.

<channel-definition id="my-rtmp" class="mx.messaging.channels.RTMPChannel">


<endpoint url="rtmp://{server.name}:2037"
class="flex.messaging.endpoints.RTMPEndpoint"/> <properties> <idle-timeout-
minutes>20</idle-timeout-minutes> </properties> </channel-definition>

RTMP, the Real-Time Messaging Protocol, was developed by Adobe for high-performance transmission of
audio, video, and data between Adobe Flash Platform technologies (like Adobe Flash Player and Adobe AIR)
and is now available as an open specification. RTMP provides a full duplex socket connection so that a single
connection can be used for all communication between the client and the server, including all RPC and
messaging. Another benefit of RTMP is that when a client connection is closed, the endpoint is immediately
notified (so the application can instantly respond) unlike when using the HTTP protocol where endpoints do not
receive notification until the HTTP session on the server times out. Because RTMP generally uses a non-standard
port, though, it is often blocked by client firewalls. In this case, the channel automatically attempts to tunnel over
HTTP.

adobe.com/…/flex_java_architecture.html 14/27
9/29/2010 The architecture of Flex and Java appli…

As a general recommendation, if you are using LiveCycle Data Services, use RTMP with failover to NIO-based
long-polling. If using BlazeDS, use AMF long-polling or AMF streaming with failover to long-polling.

Sending and receiving messages

To send messages from a Flex application you use the Producer API and to receive messages, the Consumer
API. A basic application sends, receives, and displays messages is shown here.

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="application1_creationCompleteHandler()"> <fx:Script> <![CDATA[
import mx.messaging.events.MessageEvent; import mx.messaging.messages.AsyncMessage;
protected function application1_creationCompleteHandler():void{
consumer.subscribe(); } protected function
button1_clickHandler(event:MouseEvent):void{ var message:AsyncMessage=new
AsyncMessage(); message.headers.username=username.text; message.body=msg.text;
producer.send(message); msg.text=""; } protected function
consumer_messageHandler(event:MessageEvent):void{
messageDisplay.text+=event.message.headers.username+": "+event.message.body+"\n"; }
]]> </fx:Script> <fx:Declarations> <s:Producer id="producer" destination="chat"/>
<s:Consumer id="consumer" destination="chat"
message="consumer_messageHandler(event)"/> </fx:Declarations> <s:TextArea
id="messageDisplay" width="400"/> <s:TextInput id="username" x="0" y="160"/>
<s:TextInput id="msg" x="136" y="160"/> <s:Button label="Send"
click="button1_clickHandler(event)" x="272" y="160"/> </s:Application>

For more information about using the messaging service, see the BlazeDS and LCDS documentation.

6. Data managed applications


You can build real-time data applications, applications for which data changes made in one client are "instantly"
seen by other clients viewing the same data, using a combination of remoting and messaging. This entails writing a
lot of client-side code to keep track of the changes made to the data on the client (additions, updates, and
deletions), to make calls to retrieve and persist data on the server, to send messages to other clients when the
data has changed, to make calls to retrieve and display this new data, to recognize and handle data conflicts, and
to resolve these conflicts on the client and server. To help you more quickly and easily build these types of data-
intensive, transaction-oriented applications without having to write so much code. LiveCycle Data Services (and
not BlazeDS) provides the Data Management service.

The Data Management service provides client and server-side code to help you build applications that provide
real-time data synchronization between client, server, and other clients; data replication; on-demand data paging;
and for AIR applications, local data synchronization for occasionally connected applications.

To build a managed data application you define a Data Management service destination in a configuration file on
the server and then use the Flex DataService component in the application to call methods of a server-side
service specified by that destination. The DataService API provides methods for filling client-side data collections
with data from the server and batching and sending data changes to the server. The Data Management service on
the server handles checking for conflicts, committing the changes, and pushing the data changes to simultaneously
connected clients.
adobe.com/…/flex_java_architecture.html 15/27
9/29/2010 The architecture of Flex and Java appli…

Defining destinations

Similar to how you configure remoting and messaging, you typically configure data management by defining
destinations in a server-side configuration file, in this case, data-management-config.xml. The default
configuration file defines a default channel, the RTMP channel discussed in Selecting a channelin the Messaging
section of this article, and a default adapter, actionscript.

<service id="data-service" class="flex.data.DataService"> <adapters> <adapter-


definition id="actionscript" class="flex.data.adapters.ASObjectAdapter"
default="true"/> <adapter-definition id="java-dao"
class="flex.data.adapters.JavaAdapter"/> </adapters> <default-channels> <channel
ref="my-rtmp"/> </default-channels> </service>

The adapter is responsible for updating the server-side data. The actionscript adapter is used for services
that have no persistent data store on the server but instead manage data in the server's memory. The java-dao
adapter passes the data changes to appropriate methods of a Java assembler class, which typically calls methods
of a data access object (DAO) to persist data in a database.

When defining a destination using the java-dao adapter, you specify the assembler class that handles the data
persistence and the property of the data objects that uniquely identifies an object. Below is a data management
destination called employeeService that uses a Java class called EmployeeAssembler to persist data in a
database table with a unique field employeeId. The Java assembler class must extend an AbstractAssembler
class provided with LiveCycle Data Services that has methods including fill(), createItem(),
deleteItem(), and updateItem().

<destination id="employeeService"> <adapter ref="java-dao"/> <properties>


<source>adobe.samples.EmployeeAssembler</source> <metadata> <identity
property="employeeId"/> </metadata> </properties> </destination>

You can add additional properties to the destination definition to specify the scope the assembler is available in
(request, session, or application), to configure paging, to specify security-constraints, and more.

LiveCycle Data Services also provides some standard assembler classes that you can use so you don’t have to
write your own. The SQLAssembler provides a bridge to a SQL database without requiring you to write the
Java assembler code. Instead, you specify database info (url, driver, username, password, etc.) and SQL
statements (the SQL to execute when data is sent from the Flex application to be added, updated, or deleted)
right in the destination definition. This assembler can be used for simple database models that do not have any
nested relationships. If you are using Hibernate, you can use the HibernateAssembler, which provides a bridge to
the Hibernate object/relational persistence and query service. It uses the Hibernate mapping files to at runtime to
execute the necessary SQL to persist data changes to the database.

Creating a managed data application

To create a Flex managed data application that uses the LCDS Data Management service, you create a
DataService object with its destination property set to a destination defined in the data-management-
config.xml file. You use the DataService fill() method to fetch data from the server and populate an
ArrrayCollection with the data. By default, the DataService commit() method is called whenever data changes

adobe.com/…/flex_java_architecture.html 16/27
9/29/2010 The architecture of Flex and Java appli…
in the ArrayCollection it manages. To avoid excessive calls, you can batch the calls by setting the DataService
object's autoCommit property to false and then explicitly calling its commit() method.

Here is a simple application that uses the employeeService Data Management destination to retrieve employee
data from the database on the server and populate a DataGrid with that data. When changes are made to the
data in the DataGrid, the changes are automatically persisted on the server and synchonized with any other
instances of the client application.

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:valueObjects="valueObjects.*"
creationComplete="employeeDS.fill(employees)"> <fx:Declarations> <s:DataService
id="employeeDS" destination="employeeService"/> <s:ArrayCollection id="employees"/>
<valueObjects:Employee id="employee"/> </fx:Declarations> <mx:DataGrid
dataProvider="{employees}" editable="true"/> </s:Application>

For more information about using the Data Management service, see the Live Cycle Data Services
documentation.

7. Model driven development


In previous sections of this article, you learned to use the Remoting and Messaging services of BlazeDS and
LCDS and the Data Management service of LCDS to build data-centric applications. You can build these types
of applications even faster using the Adobe application modeling technology (code named Fiber), a set of
technologies that together enable model driven development for Flex applications, which can be used to generate
both client and server-side code.

Generating client-side code using Flash Builder

Instead of using the RemoteObject class (or other RPC classes) to make calls to server-side classes, you can
use Flash Builder to create ActionScript service wrapper classes and use these classes. The RPC service
wrapper classes have public methods with the same names as the corresponding server-side classes making
development and debugging much simpler.

In order to generate client-side code, RDS access must be enabled on the server so Flash Builder can introspect
server-side Java classes and configuration files. To enable RDS access, you need to add and/or uncomment a
mapping for the BlazeDS 4 or LiveCycle Data Services 3 RDSDispatchServlet in the web application's web.xml
file and disable security by setting the useAppserverSecurity parameter to false (or alternatively, set up and
enable security).

<servlet> <servlet-name>RDSDispatchServlet</servlet-name> <display-


name>RDSDispatchServlet</display-name> <servlet-
class>flex.rds.server.servlet.FrontEndServlet</servlet-class> <init-param> <param-
name>useAppserverSecurity</param-name> <param-value>false</param-value> </init-
param> <load-on-startup>10</load-on-startup> </servlet> <servlet-mapping
id="RDS_DISPATCH_MAPPING"> <servlet-name>RDSDispatchServlet</servlet-name> <url-
pattern>/CFIDE/main/ide.cfm</url-pattern> </servlet-mapping>

Once RDS is enabled for the server, you can generate ActionScript service wrappers in Flash Builder using the
Data menu (see Figure 5).
adobe.com/…/flex_java_architecture.html 17/27
9/29/2010
Data menu (see Figure 5). The architecture of Flex and Java appli…

Figure 5. The Flash Builder Data menu for creating client-side code.

When selecting Connect to BlazeDS or Connect to LCDS, you will get a dialog box displaying all the server-side
destinations defined in the configuration files (see Figure 6).

adobe.com/…/flex_java_architecture.html 18/27
9/29/2010 The architecture of Flex and Java appli…

Figure 6. The dialog box for selecting service destinations.

Flash Builder generates ActionScript wrapper classes for the selected services and classes for the corresponding
data transfer objects (also called value objects) manipulated by these classes (which often correspond to records
in database tables) (see Figure 7). You can then manipulate the same types of objects on the client and on the
server and pass instances of them back and forth between the two. If you are using LCDS, the generated service
classes use LiveCycle specific classes to also provide the additional data management features discussed
previously. The use of these generated client-side service wrapper and valueObject classes that map to the
server-side classes greatly facilitates application development.

adobe.com/…/flex_java_architecture.html 19/27
9/29/2010 The architecture of Flex and Java appli…

Figure 7. The generated client-side classes.

In the services package, the _Super_ServiceName.as class extends the RemoteObject or DataService class it
is wrapping and defines the service methods. In the case of RemoteObject, the service class will have public
methods with the same names as the corresponding server-side class methods. The ServiceName.as class
extends the super class and is intitially empty. This is the class you use in your code. You can modify this class to
customize the wrapper. This file is not overwritten if you refresh the service to recreate the client-side code after
changes have been made to the server-side service code.

In the valueObjects package, the _EntityNameEntityMetadata.as class contains information about an entity
(an object manipulated by the service class) and its relationship with other entities. The
_Super_EntityName.as class contains getters and setters for the data properties of an entity. The
EntityName.as class extends the super class and is initially empty. This is the class you use in your code. You
modify this class to customize the generated value object class.

Generating server-side code using LCDS and the Modeler plug-in

If you are using LiveCycle Data Services, you can use Flash Builder in conjunction with an additional Modeler
plug-in to generate server-side code in addition to client-side code. The Adobe application modeling plug-in for
Adobe Flash Builder (the Modeler) is a graphical modeling editor for defining data models and generating client
and server-side code to manipulate these data models. You can use the Modeler to define a model based on an
existing database and then have it generate and deploy the client-side code, the server-side code, and the server-
side configuration files needed to manipulate this data. Or if you are starting from scratch and the database tables
don't exist yet, you can use the Modeler to define a model and then have it generate the database tables in
addition to generating the client and server-side code to manipulate this data.

In order to use the Modeler, you need to define your data source as a resource in your webapp.xml file, install

adobe.com/…/flex_java_architecture.html 20/27
9/29/2010 The architecture of Flex and Java appli…
the Modeler in Flash Builder, and configure RDS in Flash Builder. For detailed steps, see the tutorial Setting up
model-driven development with LiveCycle Data Services ES2. You can then use the Modeler and its RDS
Dataview view to create data models and generate client and server-side code.

The RDS Dataview view displays SQL databases configured as JDBC datasources on the server (see Figure 8).

Figure 8. The RDS Dataview view.

You can drag database tables from the RDS Dataview view to the Modeler Design view to define corresponding
entities in your data model (see Figure 9). You can also use the Modeler Design mode tools to define entities and
relationships if there are no corresponding database tables. The Modeler Design view uses standard UML
notation in its diagrams.

adobe.com/…/flex_java_architecture.html 21/27
9/29/2010 The architecture of Flex and Java appli…

Figure 9. The Modeler Design view.

The data model is stored as XML in a file with an FML extension. You can switch to the source mode of the
Modeler view to look at the generated model XML code.

Figure 10. Generated model code in the Modeler source mode.

To create code to manipulate the entities, you click the Modeler Generate Code button in the Modeler Design
view. By default, no server-side code is generated. To customize the generated code, select Window >
Preferences, select Adobe > Data Model > Code Generation, and modify the settings. You can specify whether
only server-side value objects corresponding to the entities in the data model are created or value objects and
assembler classes to manipulate the value objects and persist them in the database are generated (see Figure 11).

adobe.com/…/flex_java_architecture.html 22/27
9/29/2010 The architecture of Flex and Java appli…

Figure 11. The dialog box for configuring the Modeler's generated code.

Example generated value object and assembler classes are show in Figure 12.

adobe.com/…/flex_java_architecture.html 23/27
9/29/2010 The architecture of Flex and Java appli…

Figure 12. The generated server-side Java classes.

For more information about using moel driven development, see the LiveCycle Data Services documentation.

8. Portal integration

Using LiveCycle Data Services, you can deploy Flex applications as local portlets on portal servers that
implement the JSR 168 portlet specification or that support Web Services for Remote Portlets (WSRP); this
includes JBoss Portal, BEA WebLogic Portal, and IBM WebSphere Portal. The Flex application can be part of
a LiveCycle Data Services application (for example, using the Remoting, Messaging, and/or Data Management
services) but it does not have to be.

To enable a Flex application to be deployed as a portlet, you need to copy and customize some files included in
the LiveCycle Data Services /lcds/resources/wsrp/ directory and then follow the portal server's specific steps to
set up the portlet.

adobe.com/…/flex_java_architecture.html 24/27
9/29/2010 The architecture of Flex and Java appli…
Figure 13. The required LiveCycle Data Services files for deployment on portals.

You need to copy the flex-portal.jar file to your web application's /WEB-INF/lib/ directory. (If LiveCycle Data
Services is not being used on the server, the flex-messaging-common jar file must also be copied to there. ) The
flex-portal.jar file contains a GenericFlexPortlet class that handles all WSRP requests and returns appropriate
HTML depending upon whether the view, edit, or portlet mode is requested. The LiveCycle Data Services
wsrp-jsp folder contains three JSP pages used for the view, edit, and help portlet view modes. You need to
copy this wsrp-jsp folder to the root of your web application and customize these pages for your application.
When a specific view of the portlet is requested, the GenericFlexPortlet class delivers one of these JSP pages.
The portlet-view.jsp contains HTML and JavaScript for loading the application SWF and checking for the
necessary version of Flash Player.

Requests for a portlet specify whether the portlet should be maximized, minimized, or normal. The value for this
requested window state is passed to the Flex application as a flashvar, and can be accessed as
FlexGlobals.topLevelApplication.parameters.PORTLET_WS allowing you to customize the application for the
specific window state requested. If a minimized portlet is requested, the GenericFlexPortlet does not return a
SWF because the user would not be able to interact with it anyways.

Where to go from here


This article discussed the architecture of Flex and Java applications. For additional information, use the links
contained in the article and the following resources:

Adobe Flex Developer Center


Flex and Java on the Adobe Developer Center
Flex Architecture on the Adobe Developer Center
Adobe Data Services Developer Center
BlazeDS on Adobe Open Source
BlazeDS documentation
Adobe LiveCycle Data Services ES2 documentation
Adobe Flex 4 documentation

More Like This


flex_hibernate
Integrating a simple Flex search application with Grails
Choosing a Flex framework
A survey of Inversion of Control frameworks for Flex
The Flex, Spring and BlazeDS full stack – Part 2: Writing the to-do list server
The Flex, Spring and BlazeDS full stack – Part 3: Putting the application together
Flex, BlazeDS, and Hibernate JPA on Tomcat and MySQL – Part 2: Extending the demo to use linked
database relations
Developing Flex RIAs with Cairngorm microarchitecture - Part 6: Rapid and consistent development with
Cairngorm and Flex
The Flex, Spring, and BlazeDS full stack – Part 1: Creating a Flex module
Object-oriented programming: Using inheritance wisely
adobe.com/…/flex_java_architecture.html 25/27
9/29/2010 The architecture of Flex and Java appli…

Tutorials & Samples


Tutorials

Transitioning an application from Flex 3 to Flex 4


Flex, PHP, and mobile
Configuring Flash Builder 4 and Eclipse PHP development tools

Samples
DigiPri Widgets Sales Dashboard – Part 3: Understanding the dashboard application
DigiPri Widgets Sales Dashboard – Part 4: Exploring the code in Flash Builder
DigiPri Widgets Sales Dashboard – Part 1: Overview

Flex User Forum


More
09/2010 dataGrid itemEditor instances stay in memory. How to remove them?
09/2010 Load content problem (address)
09/2010 Help:java.lang.StackOverflowError
09/2010 Check Box in Datagrid

Flex Cookbook
More
09/2010 Handling database in Flash? (@everythingFLA)
09/2010 Adobe AIR and (Ext)GWT : Building for the Web and the Desktop using the same code and Java
09/2010 Selecting multiple dates in DateChooser just by clicking dates
09/2010 Combo box doesn't navigate entries with keyboard when first letter have diacritic.
Comments (0)
Comments

There are no reviews yet. Be the first to rate and comment on this article.
adobe.com/…/flex_java_architecture.html 26/27
9/29/2010 The architecture of Flex and Java appli…
Please sign in to improve or rate the content.
Choose your region
Security Contact Adobe Report piracy EULAs Permissions and trademarks Careers

Copyright © 2010 Adobe Systems Incorporated. All rights reserved.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy (updated 07-14-
2009).

adobe.com/…/flex_java_architecture.html 27/27

You might also like