Friday, March 28, 2008

BlazeDS for Java-Flex communication

BlazeDS is a server-based Java remoting and web messaging technology that enables communication between back-end Java applications and Adobe Flex applications running in the browser. In this post, I describe a way (may not be the best) I was able to successfully to build a simple application using BlazeDS and Flex. The application is build using eclipse and ant, rather than using FlexBuilder. Following are the main steps that you have to follow to implement the example.
  1. Install tomcat
  2. Install Flex sdk
  3. Download BlazeDS web application.
  4. Create tomcat user with manager permisison
  5. Create dynamic web project in eclipse
  6. Create java file
  7. Create mxml file
  8. Update the config files in the WEB-INF/flex directory of the web application
  9. Copy flexTasks.tasks to the root directory.
  10. Create build file
  11. Copy catalina-ant.jar and flextasks.jar into ant lib directory, add them to ant runtime in eclipse.
  12. Build application using ant
Skip to Sample Code: Moving the mouse over the bolded code parts shows additional information
  1. Install tomcat: This example was implemented on Tomcat 6.0.16
  2. Install Flex sdk: You can download the flex sdk from here The example was implemented on Flex 3.0.0
  3. Download BlazeDS:Download the BlazeDS web application from here
  4. Create tomcat user with manager permisison: In the TOMCAT_HOME/tomcat-users.xml, add the following line
    <role rolename="manager"/>
    <user username="abhi" password="abhi" roles="manager"/>
  5. Create dynamic web project in eclipse by importing the BlazeDS Web application war file.
  6. Create java fileThe java class simply echoes the data input in the textbox shown in the browser.
    package hello;
    public class HelloWorld {

    public String sayHelloTo(String str) {
    System.out.println("Hello " + str);
    return "Hello " + str;
    }
    }
  7. Create mxml fileThe mxml file simply shows a text box and a submit button. A label will be displayed below the textbox with the word "Hello" appended to the input text.
    <?xml version="1.0" encoding="utf-8"?> 
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" viewSourceURL="srcview/index.html">
    <mx:Script>
    <![CDATA[

    import mx.rpc.events.FaultEvent;
    import mx.rpc.events.ResultEvent;


    [Bindable]
    private var helloResult:String;
    private function sayHelloTo():void {
    ro.sayHelloTo(inputText.text);
    }
    private function resultHandler(event:ResultEvent):void
    {

    helloResult = event.result as String;
    }

    ]]>
    </mx:Script>
    <mx:RemoteObject id="ro" destination="helloworld" result="resultHandler(event)" />
    <mx:HBox width="100%">
    <mx:TextInput id="inputText"/>
    <mx:Button label="Submit" click="sayHelloTo()"/>
    </mx:HBox>
    <mx:Label text="{helloResult}"/>
    </mx:Application>
    Note: Defining the remote object enables you to make calls to the remote Java classes as if they are local action script classes.
  8. Update the configuration files For this example, you only have to update one config file, WEB-INF/flex/remoting-config.xml, to add a new destination, the HelloWorld class.
    <?xml version="1.0" encoding="UTF-8"?>
    <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="helloworld">
    <properties>
    <source>hello.HelloWorld</source>
    </properties>
    </destination>



    </service>
  9. Copy flexTasks.tasks to the root directory.
  10. Create build fileThe ant build file uses two flex specific tasks, mxmlc to compile the mxml file and html-wrapper to create a html wrapper that contains the created swf file.
    <project name="helloWorldServer" default="build" basedir=".">

    <!-- ===================== Property Definitions =========================== -->

    <property file="build.properties" />
    <property file="${user.home}/build.properties" />


    <!-- ==================== File and Directory Names ======================== -->

    <property name="app.name" value="helloWorldServer" />
    <property name="app.path" value="/${app.name}" />
    <property name="app.version" value="0.1-dev" />
    <property name="build.home" value="${basedir}/build" />
    <property name="catalina.home" value="C:/unzipped/apache-tomcat-6.0.16" />
    <property name="dist.home" value="${basedir}/dist" />
    <property name="docs.home" value="${basedir}/docs" />
    <property name="manager.url" value="http://localhost:8080/manager" />
    <property name="src.home" value="${basedir}/src" />
    <property name="web.home" value="${basedir}/WebContent" />
    <property name="manager.username" value="abhi" />
    <property name="manager.password" value="abhi" />
    <property name="FLEX_HOME" value="C:/Adobe/Flex" />
    <property name="APP_ROOT" value="${basedir}/WebContent" />



    <!-- ==================== External Dependencies =========================== -->

    <!-- ==================== Compilation Classpath =========================== -->

    <path id="compile.classpath">
    <fileset dir="${catalina.home}/bin">
    <include name="*.jar" />
    </fileset>
    <pathelement location="${catalina.home}/lib" />
    <fileset dir="${catalina.home}/lib">
    <include name="*.jar" />
    </fileset>

    </path>

    <!-- ================== Custom Ant Task Definitions ======================= -->


    <taskdef resource="org/apache/catalina/ant/catalina.tasks" classpathref="compile.classpath" />
    <taskdef resource="flexTasks.tasks" classpath="c:/ant/lib/flexTasks.jar" />

    <!-- ==================== Compilation Control Options ==================== -->

    <property name="compile.debug" value="true" />
    <property name="compile.deprecation" value="false" />
    <property name="compile.optimize" value="true" />



    <!-- ==================== All Target ====================================== -->

    <target name="all" depends="clean,build" description="Clean build and dist directories, then compile" />



    <!-- ==================== Clean Target ==================================== -->

    <target name="clean" description="Delete old build and dist directories">
    <delete dir="${build.home}" />
    <delete dir="${dist.home}" />
    </target>



    <!-- ==================== Compile Target ================================== -->

    <target name="build" depends="prepare" description="Compile Java sources">

    <!-- Compile Java classes as necessary -->
    <mkdir dir="${build.home}/WEB-INF/classes" />
    <javac srcdir="${src.home}" destdir="${build.home}/WEB-INF/classes" debug="${compile.debug}" deprecation="${compile.deprecation}" optimize="${compile.optimize}">
    <classpath refid="compile.classpath" />
    </javac>

    <!-- Copy application resources -->
    <copy todir="${build.home}/WEB-INF/classes">
    <fileset dir="${src.home}" excludes="**/*.java" />
    </copy>

    </target>



    <!-- ==================== Dist Target ===================================== -->

    <target name="dist" depends="build,javadoc" description="Create binary distribution">

    <!-- Copy documentation subdirectories -->
    <mkdir dir="${dist.home}/docs" />
    <copy todir="${dist.home}/docs">
    <fileset dir="${docs.home}" />
    </copy>

    <!-- Create application JAR file -->
    <jar jarfile="${dist.home}/${app.name}-${app.version}.war" basedir="${build.home}" />

    <!-- Copy additional files to ${dist.home} as necessary -->

    </target>

    <!-- ==================== Flex targets ==================================== -->

    <target name="appcompile" depends="install">
    <mxmlc file="${APP_ROOT}/helloWorld.mxml" context-root="/helloWorldServer" keep-generated-actionscript="true" services="${web.home}/WEB-INF/flex/services-config.xml" output="${catalina.home}/webapps/${app.name}/helloWorld.swf">
    <compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
    <include name="${web.home}/WEB-INF/lib/" />
    </compiler.library-path>
    <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml" />
    <source-path path-element="${FLEX_HOME}/frameworks" />
    </mxmlc>

    </target>

    <target name="createHtmlWrapper" depends="appcompile">
    <html-wrapper application="${APP_ROOT}/helloWorld.mxml" output="${catalina.home}/webapps/${app.name}" swf="helloWorld" />
    </target>



    <!-- ==================== Install Target ================================== -->

    <target name="install" depends="build" description="Install application to servlet container">

    <deploy url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${app.path}" localWar="file://${build.home}" />

    </target>


    <!-- ==================== Javadoc Target ================================== -->

    <target name="javadoc" depends="build" description="Create Javadoc API documentation">

    <mkdir dir="${dist.home}/docs/api" />
    <javadoc sourcepath="${src.home}" destdir="${dist.home}/docs/api" packagenames="*">
    <classpath refid="compile.classpath" />
    </javadoc>

    </target>



    <!-- ====================== List Target =================================== -->

    <target name="list" description="List installed applications on servlet container">

    <list url="${manager.url}" username="${manager.username}" password="${manager.password}" />

    </target>


    <!-- ==================== Prepare Target ================================== -->

    <target name="prepare">

    <!-- Create build directories as needed -->
    <mkdir dir="${build.home}" />
    <mkdir dir="${build.home}/WEB-INF" />
    <mkdir dir="${build.home}/WEB-INF/classes" />


    <!-- Copy static content of this web application -->
    <copy todir="${build.home}">
    <fileset dir="${web.home}" />
    </copy>

    <!-- Copy external dependencies as required -->
    <mkdir dir="${build.home}/WEB-INF/lib" />

    <!-- Copy static files from external dependencies as needed -->
    <!-- *** CUSTOMIZE HERE AS REQUIRED BY YOUR APPLICATION *** -->

    </target>


    <!-- ==================== Reload Target =================================== -->

    <target name="reload" depends="build" description="Reload application on servlet container">

    <reload url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${app.path}" />

    </target>


    <!-- ==================== Remove Target =================================== -->

    <target name="remove" description="Remove application on servlet container">

    <undeploy url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${app.path}" />

    </target>
    </project>
  11. Addtional ant configuration: Copy catalina-ant.jar and flextasks.jar into ant lib directory, add them to ant runtime in eclipse.
  12. To build and install the file, simply run the createHtmlWrapper target in ant
References
  • The ant build file was created using the base build.xml file available on apache tomcat website.
  • The config files are used as is available with the BlazeDS service.

9 comments:

  1. hi Abhi
    you have good knowledge in java
    myself Ashish Patel I work on .net platform and starting to work on new platform flex and java where I get project on BlazeDS
    but my problem is that I work on Flex 3.0, I have flex build so complied project on flex and generated its output in Java project form where I deploy it but it did not work well so can you help in this how I integrate flex and java with blazeDS feature

    ReplyDelete
  2. I don't think this will work. You have not configured the channel at all. Actually that's the key point for the blazeDS remote object

    ReplyDelete
  3. BlazeDS offers a great mechanism to attach your flex application to backend services. In this brief overview we’ll configure flex to call a Java Class and return results. This overview assumes you’ve already setup your IDE with a basic Flex / BlazeDS project.

    vitamin a

    ReplyDelete
  4. Excellent work. Very usefull. Thank you very much

    ReplyDelete
  5. It is glad to see this blog, it is good and detailed fun to read this, nice informative blog, Thanks for share this article.

    College Research Papers

    ReplyDelete
  6. It is easy to see that you are passionate about your writing.

    Advantage Custom writing – We do it your way

    ReplyDelete