Additional Requirements

BlazeDS Turnkey Server

Java Development Kit (1.5 or later)

Eclipse

BlazeDS is a set of data services that significantly simplify the development of data-driven Rich Internet Applications, and dramatically improve the performance of their data access operations. In addition, BlazeDS enables the creation of a new breed of real-time data push and collaborative applications. BlazeDS is deployed as a set of JAR files as part of your Web application running in your Java EE application server or servlet container.

BlazeDS consists of three key services:

  • The Remoting Service allows your Flex application to directly invoke methods of Java objects deployed in your application server.
  • The Message Service provides a publish/subscribe infrastructure that allows your Flex application to publish messages and subscribe to a messaging destination, enabling the development of real-time data push and collaborative applications.
  • The Proxy Service allows your Flex application to make cross-domain service requests in a secure and controlled manner. In other words, it allows your Flex application to access a service available on a different domain than the domain from where the application was downloaded (without having to deploy a crossdomain.xml policy file on the target domain).

In this Getting Started tutorial, you will learn how to:

  • Set up your BlazeDS environment
  • Build a messaging application
  • Build a remoting application.

Setting up your BlazeDS environment

Step 1: Install and start the BlazeDS Turnkey Server

The BlazeDS turnkey server is a ready-to-use version of Tomcat (currently version 6.0.14) in which the BlazeDS data services have already been deployed along with sample applications.

Note: The goal of the turnkey server is to give developers an easy way to run samples out-of-the-box. In your real-life development or production environment, you would typically integrate BlazeDS in your own web application on your own application server.

To install the BlazeDS turnkey server:

  1. Make sure that you have the JDK 1.5 or higher installed, and that you have a JAVA_HOME environment variable pointing to your Java Development Kit installation.
  2. Download blazeds-turnkey-<version>.zip
  3. Expand blazeds-turnkey-<version>.zip

    Note: The instructions in this tutorial assume that you expand blazeds-turnkey-<version>.zip in /blazeds. If you expand the zip file anywhere else make sure you adjust the path provided in these instructions accordingly.

  4. Start Tomcat
    1. Open a command prompt window
    2. Navigate to /blazeds/tomcat/bin
    3. Execute the following command:

      catalina run

Step 2: Install Eclipse and the Flex Builder 3 plug-in

Note: You can skip this step if Eclipse and the Flex Builder 3 plug-in are already installed on your system.

Because you will work on both the client side and the server side of the applications built in this tutorial, you need to use Flex Builder plug-in configuration and install Flex Builder 3 on top of Eclipse. You cannot use the Flex Builder standalone configuration because it is built on top of a minimal version of Eclipse that does not include the Java development environment. As a result it does not allow you to work on the Java-based server side of your applications.

To install the Flex Builder 3 plug-in:

  1. Install Eclipse. You can download Eclipse at: http://www.eclipse.org/downloads/. If you are not sure which version to download, choose the “Eclipse IDE for Java Developers”, or the “Eclipse Classic” version.
  2. Install the Flex Builder 3 plug-in.

Step 3: Create a Java project

You will need a Java project to work on the server side of the applications built in this tutorial. There are several ways you can set up Eclipse to work on the Java classes of a Web application. You can use a simple Java project, work with the Web Tools Platform (WTP), or use other plug-ins such as MyEclipse. In this tutorial, to avoid dependencies on a specific plug-in, we use a simple Java project.

  1. In the Eclipse menu, choose File > New > Project.
  2. Select Java Project in the project type tree and click Next.
  3. On the “Create a Java Project” page of the wizard:
    • Enter “blazeds-server” as the project name.
    • Select Create project from existing source, and enter “C:\blazeds\tomcat\webapps\samples\WEB-INF”.
    • Click Next.
  4. On the Java Settings page, make sure that the Default output folder is “blazeds-server/classes”, and click Finish.

This project configuration allows you to store the source code for your Java classes in the WEB-INF/src directory. These classes will automatically be compiled in the WEB-INF/classes directory.

Building a messaging application

The BlazeDS Message Service provides a publish/subscribe infrastructure that allows your Flex application to publish messages and subscribe to a set of messaging destinations, enabling the development of real-time data push and collaborative applications.

Follow these steps to build a simple chat application that demonstrates the BlazeDS Message Service.

Step 1: Create the messaging destination

A messaging destination represents a topic of real time conversation that interested parties can subscribe (listen) to or contribute to by posting their own messages.

To define the simple chat destination for this application:

  1. In the blazeds-server project, open messaging-config.xml located in the Flex folder.
  2. Add a destination called tutorial-chat defined as follows:

    <destination id="tutorial-chat"/>

  3. Restart Tomcat.

A key element of a destination is the channel used to exchange data between the client and the server. Using BlazeDS, a messaging destination typically uses either a streaming or a polling channel.

  • Using a streaming channel, the server response is left open until the channel connection is closed, allowing the server to send incremental chunks of data to the client. Because HTTP connections are not duplex, a single streaming Action Message Format (AMF) or HTTP channel actually requires two browser HTTP connections in order to send data in both directions. One is needed for the streamed response from the server to the client that the channel hangs on to. A second transient connection, drawn from the browser pool, is needed only when data is sent to the server. This second transient connection is immediately released back to the browser’s connection pool after the data is sent.
  • A polling channel can be configured with a polling interval, or it can be set up to wait for data at the server-side if data is not immediately available (this approach is generally referred to as long polling). In either case, each poll response completes the request. Browser HTTP 1.1 connections are persistent by default, so the browser will likely recycle existing HTTP connections to send subsequent poll requests, which lowers the overhead for polling.

Notice that there is no need to explicitly define a channel for the tutorial-chat destination. When you do not specify channels at the destination level, the destination uses the default channels defined at the top of the messaging-config.xml file. In this case, the client will first try to connect to the message service using the “my-streaming-amf” channel. If a connection to the server cannot be established using that channel, the client will fall back to the “my-polling-amf” channel. Channels themselves are configured in services-config.xml.

Step 2: Create a Flex project

  1. In Eclipse, select File > New > Project…
  2. Expand the Flex Builder node, select Flex Project, and click Next.
  3. Enter “tutorial-chat” as the project name.
  4. Ensure Use default location is selected.
  5. Select Web Application as the application type.
  6. Select J2EE as the application server type.
  7. Select Use remote object access service.
  8. Deselect Create combined Java/Flex project using WTP.
  9. Click Next.
  10. Ensure the root folder for LiveCycle Data Services matches the root folder of your BlazeDS web application. The settings should look similar to these (you may need to adjust the exact folder name based on your own settings):

    Root Folder: C:\blazeds\tomcat\webapps\samples
    Root URL: http://localhost:8400/samples/
    Context Root: /samples

  11. Click Validate Configuration, and then Finish.

Step 3: Create the client application

In the newly created tutorial-chat project, open the main.mxml file located in the src folder, and implement the application as follows:

<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="consumer.subscribe()"> <mx:Script> <![CDATA[import mx.messaging.events.MessageEvent; import mx.messaging.messages.AsyncMessage; private function send():void { var message:AsyncMessage = new AsyncMessage(); message.body.chatMessage = msg.text; producer.send(message); msg.text = ""; } private function messageHandler(event:MessageEvent):void { log.text += event.message.body.chatMessage + "\n"; } ]]> </mx:Script> <mx:Producer id="producer" destination="tutorial-chat"/> <mx:Consumer id="consumer" destination="tutorial-chat" message="messageHandler(event)"/> <mx:Panel title="Chat" width="100%" height="100%"> <mx:TextArea id="log" width="100%" height="100%"/> <mx:ControlBar> <mx:TextInput id="msg" width="100%" enter="send()"/> <mx:Button label="Send" click="send()"/> </mx:ControlBar> </mx:Panel> </mx:Application>

Code highlights:

  • On the client side, the BlazeDS Message Service API provides two classes, Producer and Consumer, which you use to publish and subscribe to a destination, respectively.
  • To subscribe to a destination, you use the subscribe() method of the Consumer class.
  • When a message is published to a destination you subscribed to, the message event is triggered on the Consumer.

In this example, messages are published by Flex clients. The BlazeDS Message Service also provides a Java API that allows a server-side component to publish messages to a BlazeDS destination. A third option for exchanging messages between Flex and Java applications is to map destinations to Java Message Service (JMS) topics, enabling Flex clients to publish and subscribe to JMS topics.

Step 4: Run the application

  1. Click the Run icon in the Eclipse toolbar to start the application
  2. Open the same URL in another browser window to start a second instance of the chat application
  3. Type a message in one of the chat clients and click "Send": the message appears in the two chat clients

Building a remoting application

Using the Remoting Service, your application can directly invoke methods of Java objects deployed in your application server, and consume the return value. The method can return a value of a primitive data type, an object, a collection of objects, an object graph, and more. Java objects returned by server-side methods are deserialized into either dynamic or typed ActionScript objects.

This section describes how to build a simple inventory management application that demonstrates the BlazeDS Remoting Service.

Note: The turnkey server includes an HSQLDB database, which allows you to run the samples “out-of-the-box” without setting up a database. HSQLDB is a lightweight Java RDBMS that is particularly well-suited to run samples.

To start the sample database:

  1. Open a command prompt window
  2. Navigate to /blazeds/sampledb
  3. Execute the following command:

    startdb

Step 1: Create the Java components

The server-side of this application uses the simple Data Access Object (DAO) and Value Object patterns:

  • The ProductDAO class provides the data access logic to retrieve and update products
  • Products are transferred between the client and the server using Product objects (value objects).

To create Product.java:

  1. Make sure Eclipse is in the Java perspective
  2. In the blazeds-server project, right-click the src folder, and select New > Class. Enter “tutorial” as the package name and “Product” as the class name; then click Finish. Implement the Product class as follows:
package tutorial; public class Product { private int productId; private String name; private double price; private int qty; public int getProductId() { return productId; } public void setProductId(int productId) { this.productId = productId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getQty() { return qty; } public void setQty(int qty) { this.qty = qty; } }

To create ProductDAO.java:

  1. Make sure Eclipse is in the Java perspective
  2. In the blazeds-server project, right-click the src folder, and select New > Class. Enter “tutorial” as the package name and “ProductDAO” as the class name; then click Finish. Define the ProductDAO class as follows:
package tutorial; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import flex.samples.ConnectionHelper; import tutorial.Product; public class ProductDAO { public List getProducts() throws SQLException { List list = new ArrayList(); Connection c = null; try { c = ConnectionHelper.getConnection(); Statement s = c.createStatement(); ResultSet rs = s.executeQuery("SELECT * FROM product ORDER BY name"); while (rs.next()) { Product product = new Product(); product.setProductId(rs.getInt("product_id")); product.setName(rs.getString("name")); product.setPrice(rs.getDouble("price")); product.setQty(rs.getInt("qty_in_stock")); list.add(product); } } finally { c.close(); } return list; } public void update(Product product) throws SQLException { Connection c = null; try { c = ConnectionHelper.getConnection(); PreparedStatement ps = c.prepareStatement( "UPDATE product SET name=?, price=?, qty_in_stock=? WHERE product_id=?"); ps.setString(1, product.getName()); ps.setDouble(2, product.getPrice()); ps.setInt(3, product.getQty()); ps.setInt(4, product.getProductId()); } finally { ConnectionHelper.close(c); } } }

Step 2: Create the remoting destination

A Remoting destination exposes a Java class that your Flex application can invoke remotely. The destination id is a logical name that your Flex application uses to refer to the remote class, which eliminates the need to hardcode a reference to the fully qualified Java class name. This logical name is mapped to the Java class name as part of the destination configuration in remoting-config.xml.

To create a remoting destination for the ProductDAO class:

  1. In the blazeds-server project, open remoting-config.xml located in the flex folder.
  2. Add a destination called tutorial-product defined as follows:
<destination id="tutorial-product"> <properties> <source>tutorial.ProductDAO</source> </properties> </destination>

Step 3: Create a Flex project

  1. Select File > New > Project… in the Eclipse menu.
  2. Expand the Flex Builder node, select Flex Project, and click Next.
  3. Enter “tutorial-product” as the project name.
  4. Ensure Use default location is selected.
  5. Select Web Application as the application type.
  6. Select J2EE as the application server type.
  7. Select Use remote object access service.
  8. Deselect Create combined Java/Flex project using WTP.
  9. Click Next.
  10. Make sure the root folder for LiveCycle Data Services matches the root folder of your BlazeDS web application. The settings should look similar to these (you may need to adjust the exact folder based on your own settings):

    Root Folder: C:\blazeds\tomcat\webapps\samples
    Root URL: http://localhost:8400/samples/
    Context Root: /samples

  11. Click Validate Configuration, then Finish.

Step 4: Retrieve the list of products

  1. In the newly created tutorial-product project, open the tutorial-product.mxml file located in the src folder, and implement the application as follows:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:RemoteObject id="ro" destination="tutorial-product"/> <mx:DataGrid dataProvider="{ro.getProducts.lastResult}" width="100%" height="100%"/> <mx:Button label="Get Data" click="ro.getProducts()"/> </mx:Application>
  1. Run and test the application.

Step 5: Add event handlers to improve the application

RemoteObject calls are asynchronous. You use the result and fault events of the RemoteObject component to handle results and errors. To make the application more robust and better partitioned, modify the code as follows:

<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.controls.Alert; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.collections.ArrayCollection; [Bindable] private var products:ArrayCollection; private function resultHandler(event:ResultEvent):void { products = event.result as ArrayCollection; } private function faultHandler(event:FaultEvent):void { Alert.show(event.fault.faultString); } ]]> </mx:Script> <mx:RemoteObject id="ro" destination="tutorial-product" result="resultHandler(event)" fault="faultHandler(event)"/> <mx:DataGrid id="dg" dataProvider="{products}" width="100%" height="100%"/> <mx:Button label="Get Data" click="ro.getProducts()"/> </mx:Application>

Step 6: Create the value object

In the application so far, the list of products returned by the getProducts() method is deserialized into dynamic objects. Sometimes, you may want to work with strongly typed objects. To work with typed objects in this application, first create the ActionScript version of the Product class created in step 1:

  1. Right-click the src folder in the tutorial-product project and select New > ActionScript Class. Specify “Product” as the class name and click Finish.
  2. Implement the Product class as follows:
package { [Bindable] [RemoteClass(alias="tutorial.Product")] public class Product { public var productId:int; public var name:String; public var price:Number; public var qty:int; } }

Notice that the code uses the [RemoteClass(alias="tutorial.Product")] annotation to map the ActionScript version of the Product class (Product.as) to the Java version (Product.java). As a result, Product objects returned by the getProducts() method of ProductDAO are deserialized into instances of the ActionScript Product class. Similarly, in the next step, the instance of the ActionScript Product class passed as an argument to the update method of the RemoteObject is deserialized into an instance of the Java version of the Product class at the server-side.

Step 7: Update products

  1. Modify the tutorial-product.mxml application as follows to allow the user to update products:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ [Bindable] private var product:Product; private function update():void { product.name = productName.text; product.price = Number(price.text); product.qty = parseInt(qty.text); ro.update(product); } ]]> </mx:Script> <mx:RemoteObject id="ro" destination="tutorial-product"/> <mx:DataGrid id="dg" dataProvider="{ro.getProducts.lastResult}" width="100%" height="100%" change="product = Product(dg.selectedItem)"/> <mx:Button label="Get Data" click="ro.getProducts()"/> <mx:Form> <mx:FormItem label="Name"> <mx:TextInput id="productName" text="{product.name}"/> </mx:FormItem> <mx:FormItem label="Price"> <mx:TextInput id="price" text="{product.price}"/> </mx:FormItem> <mx:FormItem label="Qty In Stock"> <mx:TextInput id="qty" text="{product.qty}"/> </mx:FormItem> <mx:FormItem> <mx:Button label="Update" click="update()"/> </mx:FormItem> </mx:Form> </mx:Application>
  1. Run and test the application