Adobe AIR and Adobe FLex 3 released

February 25, 2008

Adobe AIR 1.0 and Flex 3 are released. Check out the below URLs for more details.

Adobe AIR

http://www.adobe.com/products/air/

http://labs.adobe.com/technologies/air/

http://www.nytimes.com/2008/02/25/technology/25adobe.html

Adobe Flex 

http://www.adobe.com/products/flex/

Advertisements

Handling Java Exceptions in Flex application

February 12, 2008

We can invoke Java objects using BlazeDS. For details on how to invoke Java objects from flex visit this URL Invoking Java methods from Flex

It’s a common practice in Java methods to throw Exceptions to indicate that something has failed. These exceptions can be either custom exceptions or inbuilt exceptions. It is also common that we include some message in that exception, which describes the problem caused. Now how do we get that message and display it in Flex applications? What if you want to add some other information to the Exception you are throwing and you want to access that information too?

You can do this 🙂

BlazeDS will by default serialize any Throwable type object. All you need to do is to access the objects.

Accessing the Throwable object in Flex

RemoteObject component invokes the fault event when an error occurs while remote method invocation. The fault event handler is provided with the FaultEvent object. This FaultEvent object has property named message of type mx.messaging.messages.ErrorMessage. The message property holds the Throwable object from the Java method in the rootCause property. We need to use this rootCause property to retrieve the properties which are set to the Throwable object in Java. All the public properties from the Throwable object are available.

We will see a sample application. In this application I am creating a custom Exception and adding a getter method to that, which will return my custom data. From the Flex application I will access both the error message and the custom data.

MyException.java

public class MyException extends Exception {

public MyException(String message) {

super(message);

}

public String getMyName(){

return “Sujit Reddy G”;

}

}

Method throwing exception

This method will throw the custom exception created above, add this method to a Java class. Invoke the below method using RemoteObject component in Flex.

public void throwCheckedException() throws Exception{

throw new MyException(“This is a checked exception”);

}

Reading values in Flex application

We add the method below as the fault event handler to the RemoteObject component in the Flex application. You can see that we accessed the rootCause object to retrieve the properties of the custom Exception object returned from the Java method.

private function handleException(event:FaultEvent):void{

var errorMessage:ErrorMessage = event.message as ErrorMessage;

Alert.show(errorMessage.rootCause.message);

Alert.show(errorMessage.rootCause.myName);

}

We are adding the above method as fault event handler to the RemoteObject component.

<mx:RemoteObject id=”exceptionObj” destination=”CreatingRpc” result=”handleRPC(event)”

fault=”handleException(event)”/>

Invoking the method in the Java class on button click

<mx:Button label=”Invoke Exception” click=”exceptionObj.throwCheckedException()”/>

You can also use the flex.messaging.MessageException. This class is packaged in the flex-messaging-core.jar. You should throw MessagException instead of MyException or any custom exception created. MessageException provides a property named extendedData, which is a HashMap. You can add any data to this property and access it from the Flex application using ErrorMessage(event.message).extendedData.

That’s it 🙂 let me know if you have problem implementing this 🙂


Splitting Flex application into modules

February 5, 2008

There are many scenarios in which you might want a part of the code in Adobe Flex application to be loaded only when required, that is you might not want a piece of code to be compiled into main application SWF, instead load it when required. Scenarios can include screens which user accesses very rarely or a set of libraries which you want to load when required. This can achieved using Modules in Flex.

There might be many screens in Adobe Flex application, which user access very rarely. Examples can include screens where users give suggestions, complaints etc. if all such screens are included in your application, your application size might be huge, affecting the initial loading experience.

Similarly you might have a library code which might be used rarely. Examples can include library for creating reports, which is required only when the user wants the reports to be generated.

All such code which you think will be used very rarely can be included in modules and load them dynamically when required.

About modules

Modules are SWF files which can be loaded dynamically by an application. They cannot run independently, they have to be invoked by application. Any number of applications can share the same module.

Modules allow you to interact with the parent application and also interact with other modules. Modules can be loaded either using ModuleLoader or ModuleManager.

Click here for more details on Modules

Sample application

This application shows how to load a module dynamically. The module loaded dynamically will display a window in which we can capture user’s suggestions. The module accepts input from the parent application and also invokes properties of the parent application.

Application includes three files.

Modules.mxml – this will invoke the module

SuggestionModule.mxml – this is the module

IUserInput.as – this interface is implemented by the module. This is for module-application communication. (Optional)

Screen shot

Modules Sample Application

Modules.mxml

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; layout=”vertical”>

<mx:Script>

<![CDATA[

import mx.controls.Alert;

import mx.managers.PopUpManager;

import mx.events.ModuleEvent;

import mx.modules.ModuleManager;

import mx.modules.IModuleInfo;

private var moduleInfo:IModuleInfo;

private var suggestion:SuggestionModule;

private function loadSuggestionModule():void

{

moduleInfo = ModuleManager.getModule(“SuggestionModule.swf”);

moduleInfo.addEventListener(ModuleEvent.READY, renderSuggestionModule);

moduleInfo.addEventListener(ModuleEvent.ERROR, handleError);

moduleInfo.addEventListener(ModuleEvent.PROGRESS, showProgress);

moduleInfo.load();

suggestionProgress.visible = true;

}

private function renderSuggestionModule(event:ModuleEvent):void

{

suggestion = moduleInfo.factory.create() as SuggestionModule;

suggestion.setHeaderMessage(“Suggestion – Home Page”);

PopUpManager.addPopUp(suggestion, this, true);

PopUpManager.centerPopUp(suggestion);

suggestionProgress.visible = false;

}

public function closeSuggestion():void

{

PopUpManager.removePopUp(suggestion);

moduleInfo.unload();

}

private function showProgress(event:ModuleEvent):void

{

suggestionProgress.text = “Loaded ” + Math.round((event.bytesLoaded / event.bytesTotal)* 100) + “%”;

}

private function handleError(event:ModuleEvent):void

{

Alert.show(event.errorText,”Error”);

suggestionProgress.visible = false;

}

]]>

</mx:Script>

<mx:Button id=”chartModuleBtn” label=”Suggest” click=”loadSuggestionModule();”/>

<mx:Label id=”suggestionProgress” text=”Loaded 0%” visible=”false”/>

</mx:Application>

SuggestionModule.mxml

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Module xmlns:mx=”http://www.adobe.com/2006/mxml&#8221;

layout=”vertical” width=”366″

height=”200″ borderStyle=”solid” cornerRadius=”11″

borderColor=”#000305″ borderThickness=”2″

implements=”com.adobe.IUserInput”>

<mx:Script>

<![CDATA[

import mx.controls.Alert;

[Bindable]

private var heading:String = “Your suggestion please”;

private function submitSuggestion():void

{

parentApplication.suggestionProgress.text = “We will consider your suggestion”;

parentApplication.suggestionProgress.visible = true;

parentApplication.closeSuggestion();

}

public function setHeaderMessage(message:String):void

{

this.heading = message;

}

]]>

</mx:Script>

<mx:Form width=”100%” height=”100%”>

<mx:FormHeading label=”{heading}”/>

<mx:FormItem label=”Your Name”>

<mx:TextInput id=”userName” width=”233″/>

</mx:FormItem>

<mx:FormItem label=”Suggestion”>

<mx:TextArea id=”description” width=”234″/>

</mx:FormItem>

<mx:ControlBar width=”100%” horizontalAlign=”center”>

<mx:Button label=”Submit” click=”submitSuggestion();”/>

<mx:Button label=”Cancel” click=”parentApplication.closeSuggestion();”/>

</mx:ControlBar>

</mx:Form>

</mx:Module>

IUserInput.as

package com.adobe

{

public interface IUserInput

{

function setHeaderMessage(message:String):void;

}

}


BlazeDS and LCDS Performace difference

February 4, 2008

Is there a difference in performance between BlazeDS or LCDS? The answer for this is – Depends on what features you are using. 🙂

PS: Thanks to Seth Hodgson from Adobe for posting these details in the pre-release forums 🙂

Scenarios in which BlazeDS and LCDS provide same performance

If you’re just using RPC services (RemoteObject, HTTPService, WebService) over an AMFChannel from the client to the server, there’s no difference in performance between BlazeDS and LCDS. That’s just traditional HTTP requests/responses between the clients and servers. So you’re limited by OS/hardware specs to some max request per second processing capacity for your box (this limit would also depend on what your RemoteObjects are doing, etc.)

If you application is using messaging (or auto-sync data management), that requires a channel that can get messages from the server down to the client. There’s simple polling, and that behaves the same in BlazeDS and LCDS.

Scenarios in which LCDS performance is better than BlazeDS performance

If your application is using data push, this is where the performance differs. BlazeDS supports long-polling and streaming over HTTP to push data to the client but it manages this through the Servlet API, which has the restriction right now of mandating blocking IO.

Why LCDS performs better

LCDS provides support for the RTMPChannel (direct duplex socket connection between the client and server) as well as non-blocking long-polling and streaming support over HTTP that bypasses the Servlet API and its blocking IO limitation. All of these options in LCDS are built on top of the Java NIO APIs.

Non-blocking IO doesn’t require a thread per connection sitting blocked in a read() call on the underlying socket. So you can have many connections without the expense of a having a thread per connection.

In terms of the total number of connections a BlazeDS or LCDS server will support, back of the envelope estimates are in the hundreds for BlazeDS (because of Servlet blocking IO and the fact that Servlet containers generally don’t have more than hundreds of threads in their request handler thread pool) and in the thousands for LCDS thanks to Java NIO. Whether you’re talking about 5K or 10K depends on your OS, hardware and application. At some point, depending on the number of messages you’re sending and the amount of processing and IO you’re doing you’ll saturate your box.

Conclusion

For traditional request/response style interaction between the client and server, blocking IO is reasonable, but for server data push and messaging, it’s not so good. That is BlazeDS and LCDS performance differs when it comes to server data push and messaging, where you are using Blocking IO, LCDS performs better in these scenarios, because of Java NIO. 🙂