Tips From The Masters
Adding Enum Support to Adobe Flex AMF Protocol
Advanced techniques for adding new data types to Flex/Java communication via AMF protocol
Sep. 17, 2007 01:15 PM
Introduction
Flex has short learning curve for Java developers, who will find that there are a lot of familiar language constructs and patterns. It also provides excellent remoting capabilities for Java programmers, allowing transparent data transfer between ActionScript and Java 1.4 data types. With Java version 5 and above you have a lot of Java data structures that use enum and need marshaling to/from the Flex applications. In this article I will provide a working example of the ActionScript language extension for the enum data type. We'll discuss the issues common for adding language extensions to the bytecode machines/compilers. We will also extend LiveCycle Data Services AMF3 protocol to support native translation of classes between Java 5 and ActionScript 3.
Problem Statement
One of the most discussed limitations of LiveCycle Data Services (LCDS) serialization mechanism is a lack of serialization support for Java 5 enumerations. It is partially due to the fact that the code is supposed to work against Java 1.4, which did not have enums. This problem is acknowledged by Adobe, so one of your choices is just waiting for the next release of LCDS. But, alternatively, with a moderate effort you can extend existing data service classes and get the necessary functionality right away.
Let us review some facts about Flex AMF serialization to understand better why LCDS fails to serialize enumeration values out of the box. Flex serialization does not mimic Java’s serialization, it has only some similarities. Here are restrictions for remoting imposed by the default behavior of serialization:
1. Remote Java objects must have a public no-arguments constructor to be successfully de-serialized. With Java serialization, even objects without such constructor can be de-serialized as long as they implement java.io.Serializable marker interface.
2. Flex populates all public non-final non-transient instance fields upon deserialization and sets the JavaBean properties (exposed as pair of get/set methods) of the instance. Java serialization mechanism populates all non-transient instance fields (even the final ones). By the way, FDS and LCDS use JavaBean introspection mechanism to find out the object’s properties, so in theory you may use any method names besides classic getSomething / setSomething pair as long as you provide necessary BeanInfo class.
3. Flex may use externalization instead of serialization. Your Flex class has to implement flash.utils.IExternalizable interface and the corresponding remote Java class must implement java.io.Externalizable.
As you can see, the items 1 and 2 from list above rule out Java 5 enumerations from Flex serialization process. We will need a custom serialization on the Java side to serialize/deserialize enumerations. But first, take a look at the following simple Java enumeration:
public enum Gender { MALE, FEMALE }
Under the hood, Java compiler generates something like this (decompile the generated class with one of the free Java decompilers available on Web):
final public class Gender extends Enum<Gender> {
private Gender(String name, int ordinal) { super(name, ordinal); }
public static final Gender MALE = new Gender(“MALE”, 0);
public static final Gender FEMALE = new Gender(“FEMALE”, 1);
/* rest is omitted */
}
First, there is no public no-arguments constructor. Second, inherited “properties” name and ordinal of custom enumeration type are read-only. So even any Java 5 enumeration is a valid type for Java serialization due to explicit built-in support, it can’t be used as Flex remote class. Actually, we may not use externalization mechanism either while it’s impossible to restore internal read-only fields of enumeration value in implementation of java.io.Externalizable.readExternal().
Solution
What we would like propose is a small extension that allows using custom Java 5 enumerations as remote classes with minimal effort. In short, this is a drop-in extension for standard Flex AMFEndpoint classes that augments LCDS functionality with special support for Java 5 enumeration types.
Adobe engineers take the extensibility aspect of LiveCycle Data Services 2.5 seriously. Besides numerous code-free configuration options available out-of-the-box, the API is very developer-friendly. The endpoints and AMF serialization framework have a lot of extensibility hooks and have nicely applied creational design patterns, so extending existing functionality is a joy.
The idea of our extension library is to intercept read/write operations with enumeration type as argument, substitute enumeration type with some wrapper that plays nicely with Flex serialization rules and pass this wrapper to super implementation. Please download and explore the source code at http://www.myflex.org/articles/downloads/farata-j5-messaging.src.zip.
About Valery SilaevValery Silaev has served as the lead architect for a number of J2EE solutions for a variety of industry sectors and was involved into several R&D projects for SAP NetWeaver platform. Having over 10 years of experience in software development, he is still extending his knowledgebase with new languages and frameworks like Scala and Flex.