Flex SDK is not open sourced until Adobe opens compiler’s templates and code generators

The fact that Adobe is open sourcing Flex is good but not good enough. The whole idea of open sourcing any software is to bring more brain power to the development process, which leads to a better quality product. But today my hands are tied.

I wasted a whole day on what should have been a trivial task – adding and ability to send some client context information alongside with an AMF request. Passing the request’s header information (i.e. information that is not passed with the RPC call but can be picked up by querying context mechanism) is quite common in Java programming.

I started by trying to pass the user name across the wire. With RTMP or HTTP requests you just add the objects you need to pass along to the HTTP header.

Setting up the Java side literally took 10 minutes – subclassing the FDS endpoints, creating the context class that would be used for keeping the information within thread execution:

package com.farata.remoting;
import java.util.Hashtable; import flex.messaging.endpoints.*;
import flex.messaging.MessageBroker;
import flex.messaging.config.ChannelSettings;
import flex.messaging.messages.Message;

public class CustomAMFEndpoint extends AMFEndpoint {

public CustomAMFEndpoint(MessageBroker broker, ChannelSettings cs) {super(broker, cs);}

public CustomAMFEndpoint(MessageBroker broker, ChannelSettings cs, boolean enableManagement) {super(broker, cs, enableManagement);}

public Message serviceMessage(Message message) {

Hashtable ht = new Hashtable();

ht.put(“context”, message.getHeaders());

MessageContext.setParams(ht);

return super.serviceMessage(message);
}
}

Here’s the “by the book” implementation of the Context object using Java’s ThreadLocal class:

package com.farata.remoting;
import java.util.Hashtable;

public class MessageContext {

public static void setParams(Hashtable session) { sessions.set(session); }

public static Hashtable getParams() { return (Hashtable)sessions.get(); }

private static ThreadLocal sessions = new ThreadLocal();

}

Let’s use a classical HelloWorld.java for testing:

package com.farata.test;

import java.util.HashMap;
import java.util.Hashtable;
import com.farata.remoting.MessageContext;
public class HelloWorld {

public String hello() {
Hashtable ht = MessageContext.getParams();
HashMap context = (HashMap)ht.get(“context”);
return “Hello “+ (String)context.get(“user”);
}
}

Done with Java, here comes the Flex turn. Now we need to subclass the ActionScript class Operation to update the message headers when the operation is being invoked:

package {

import mx.rpc.remoting.mxml.Operation;
import mx.core.mx_internal;
use namespace mx_internal;
import mx.rpc.AsyncToken;
import mx.messaging.messages.IMessage;
import mx.rpc.remoting.mxml.RemoteObject;

public class ContextOperation extends Operation {

public function ContextOperation(svc:RemoteObject = null, name:String = null):void {

super(svc, name);

}

mx_internal override function invoke(msg:IMessage, token:AsyncToken=null):AsyncToken {

msg.headers.context = {user : “Anatole”};

return super.invoke(msg, token);
}
}
}

Now the client’s test application:

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” xmlns:local=”*”> <mx:Button label=”hw” click=”ro.hello()”/>

<mx:RemoteObject id=”ro” operationClass=”{ContextOperation}” destination=”com.farata.test.HelloWorld” result=”Alert.show(event.result)” /> </mx:Application>

So far so good, we are getting back “Hello Anatole” as expected. Here comes trouble – you can not use mx:method with this solution – operationClass is not being used with the template used by Flex compiler, which generates the following ActionScript code (you can see it with the help of -keep compiler’s option):

private function _RemoteObject1_i() : mx.rpc.remoting.mxml.RemoteObject
{
var temp : mx.rpc.remoting.mxml.RemoteObject = new mx.rpc.remoting.mxml.RemoteObject();
ro = temp;
temp.destination = “com.farata.test.HelloWorld”;
temp.operations = {hello: _Operation1_c()};
temp.initialized(this, “ro”)return temp;
}

private function _Operation1_c() : mx.rpc.remoting.mxml.Operation{

var temp : mx.rpc.remoting.mxml.Operation = new mx.rpc.remoting.mxml.Operation();
temp.name = “hello”;temp.addEventListener(
“result”, ___Operation1_result);
temp.addEventListener(“fault”, ___Operation1_fault);

return temp; }

I did not expect to see “new mx.rpc.remoting.mxml.Operation()”, but rather new ContextOperation.  This is clearly a bug in the template used by the code generator, which I could have fixed myself and returned the fixed version back to Flex developer’s community. Unfortunately, the code of the templates is not available.

Frameworks that use code generators need to open templates so enterprise developers can extend them. Extension of the framework means symmetrical changes in templates, so if you allow one, you should allow the other. Also, in order to take an application framework to the next level, the preprocessor/code generation passes need to be extendable by developers as well .

Please open up AMF/RPC and Flex compiler or at least set up the community process to let us quickly fix such bugs.

Thank you,
Anatole

One thought on “Flex SDK is not open sourced until Adobe opens compiler’s templates and code generators

  1. hi
    i am working on this RemoteObject in flex . i just invoke a java object through this . i want to iterate return type ArrayList from java in flex . i want to get the data in ArrayList with the help of index .

    i.e i want to get the data of arrayList[0],arrayList[1],arrayList[2] like tat

    u can send the reply to my mail also

    thanks
    kandasami raja

    kandaraja@gmail.com

Comments are closed.