Although in this tutorial I am addressing BlazeDS, the steps in this tutorial should also apply to Adobe Flex LiveCycle Data Services. The only difference are the jars that you copy to your WEB-INF/lib directory. For those who want to integrate BlazeDS with Struts 2, the instructions in this tutorial should also be helpful.
In the Java Backend:
Step 1
Download blazeds.war from http://opensource.adobe.com/wiki/display/blazeds/Downloads
Step 2
Unzip blazeds.war. Copy the files in WEB-INF/lib and WEB-INF/flex to your web project under the same path in your web app.
Step 3
Edit web.xml and add the following lines:
<!-- 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>
Step 4
Create a simple java class with a simple method that we will invoke from Adobe Flex:
package uk.co.spltech.remote;
import java.util.ArrayList;
import java.util.List;
/**
* This remote service is called using BlazeDS/LiveCycle DS from Flex
*
* @author Armindo Cachada
*
*/
public class RemoteService {
/**
* I am not doing anything useful except to just show that I can be invoked remotely
* from Adobe Flex using RemoteObject.
*
*/
public List<String> callMe() {
System.out.println("I am being invoked!");
List<String> result = new ArrayList<String>();
result.add("Michael Jackson");
result.add("Beatles");
result.add("Tina Turner");
return result;
}
}
Step 5
Create a new destination in remoting-config.xml:
<destination id="remoteService" >
<properties>
<source>uk.co.spltech.remote.RemoteService</source>
<scope>application</scope>
</properties>
</destination>
The source of the destination can be a fully qualified class name, a jndi reference or a spring bean. We will discuss that in a later post. For this example we just specify a class name.
The scope of the destination can be one of:
- application - there is only one instance of the class for the entire application(i.e. global in atg, singleton in spring)
- session - there is one instance per user session
- request - for each http request a new instance of the class is created
In Adobe Flex:
Step 1
Create a new project in Adobe Flex. Please make sure that the Application Server type is set to none.
Why? Fair question to ask since most instructions say to do exactly the opposite. I found those instructions not really helpful in the case of JBOSS since they assume I can provide the directory containing the application after it is deployed to JBOSS. That works quite well for tomcat because it simply extracts the war file under webapps. The path is always the same. In the case of JBOSS the path to the application changes after each deployment...
Step 2
The only reason Adobe Flex asks you for the path to the root folder of your web application is so that it can provide two arguments to the flex compiler:
- services - The path to the Adobe flex data services configuration file
- context-root - The context root of your web application
After you create your web application add the following arguments to the flex compiler:
-services "/usr/java/eclipse/workspace/example6/resources/flex/services-config.xml" -context-root "/example6"
Step 3
Let's create a very simple flex application that invokes the callMe() method in uk.co.spltech.remote.RemoteService. This method returns an ArrayList with a list of items:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" >
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import flash.utils.getQualifiedClassName;
/**
* Populates the data list using the results returned by callMe()
*/
private function populateList(event:ResultEvent):void {
var result:ArrayCollection= ArrayCollection(event.result);
singerList.dataProvider= result;
}
]]>
</mx:Script>
<mx:RemoteObject id="myService" destination="remoteService" result="populateList(event)"/>
<mx:List id="singerList" >
</mx:List>
<mx:Button click="myService.callMe();" label="Call Remote Function" />
</mx:Application>
Step 4
Compile the flex app and copy all the generated swf/html/js to your jboss web app.
Step 5
Deploy the war file to JBOSS and test it under http://localhost:8080/example6
If you click in the "Call Remote Function" button you should see a list of results returned by the method callMe().
Download source code for JBOSS+Adobe Flex+BlazeDS project
Note that, in order to make the zip smaller, I didn't include the BlazeDS jar files. You need to manually copy them to the lib directory before generating the war file.
Click here to read Part II
20 comments:
Thanx!!! Work perfect!How I can debug my flex part of application?
Great to know that it worked for you. Are you using Flex Builder? It allows you to debug a flex application. Did you not try to use it?
Hello! Yes, I'm using FB3. When I try debug as flex appl I get exception "RPC Fault faultString="Send failed" faultCode="Client.Error.MessageSend" faultDetail="Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Failed: url: 'http://localhost/messagebroker/amf'".
After I defined Output Folder URL in Properties by my flex project. But this way I can debug only flex, which alredy deployed on server. I want try debug my flex appl before
If you are running the example I provided you with then your messagebroker should be located at http://localhost:8080/example6/messagebroker/amf
Have you checked if the flex compiler settings are correct?
You need to provide the path to services-config.xml and indicate the correct context root:
e.g.
-services "/usr/java/eclipse/workspace/example7/resources/flex/services-config.xml" -context-root "/example7" -locale en_US
Since your application server is running at port 8080, and flex tries to access port 80 by default, there are two ways around that:
1.Change the services-config.xml channel definition for "my-amf" and hardcode the port to 8080. That worked for me.
2. Another simple solution is to change your application server to run in port 80 or to run a web server.
Let me know if this works for you.
Thanx!!! First way works well!It will make my job easier! I try this way before, but something work wrong. Now all is right.Your blog is most correctly for jboss. I checked much blogs before your.
Glad it worked for you :)
Good luck with your flex+jboss integration.
Thank you for help! :)
Hello, Armindo! How I can use in BlazeDS java session what created when server start?When I use remoting I get object from new session
Don't worry! I fixed it! :)
Great to know. Java sessions are basically created for each new browser session. if you want components that are global you need to use the application scope I believe. Was that your problem?
I just have to use FlexContext in java to get session. Now I have problem: I dynamically created my .jsp and dynamically write html code for my flex object and in this way don't work all initialize method in mx:Application tag. When I run flex application in usual way it works well.
I fixed it again! :)
I have question about arguments to the flex compiler: we have to define
-services use the absolute path. Can we use relative path(inside j2ee project) ?
The answer seems to be no. I tried to provide a relative path and it didn't work.
That shouldn't be a problem though as the services-config.xml is only needed at compile time. So once you export your project into your war file, it should all just work.
P.S. Worked for me
You rigth, Armindo. I met this problem when one more man began work with me on my project. I had to adjust project for him apart.But it's only way.Thanx!
Good Afternoon!!! simplyolaf.blogspot.com is one of the most outstanding resourceful websites of its kind. I take advantage of reading it every day. Keep it that way.
Hello,
I am working on a project with ATG and Flex 3. Is there any way to use Flash remoting (AMF) rather than the REST services?
The client has LCDS and prefers that.
Thanks!
David LaTour
davidDOTlatourATthinkelevenDOTcom
Hi David. I definitely think it is possible to use BlazeDS/LCDS. But someone needs to create a factory for nucleus components. There are instructions on the internet on how to do this, however they are not specific to ATG.
Post a Comment