GraniteDS release 3.0.0.M2 introduced a new serialization format for Java clients which is largely inspired by (Action Message Format version 3). It is called JMF, which stands for Java Messaging Format, and it is now used, starting with GraniteDS 3.0.0.M3, as the standard serialization format between Java / JavaFX / Android client applications and GraniteDS servers.
Basically because we love AMF but AMF isn’t good for Java client applications: with AMF, for example, all Java numeric types (byte, short, int, long, float, double, etc.) are serialized either as ActionScript int or Number, which leads to useless conversions in the context of a Java to Java data exchange and can even lead to a loss of precision (large long values cannot be represented as Numbers without truncation). Furthermore, all collections (java.util.*) are normalized to a single ArrayCollection type, BigDecimals are converted to Numbers, enum values to nothing standard (ActionScript has no enum types), etc.
Using AMF with Java clients is certainly possible, and we do have AMF support for Java clients in GraniteDS, but it is pointlessly complicated and, as a result, requires a full bunch of ugly workarounds.
That said, JMF is largely inspired by AMF and designed with the following goals in mind:
You basically need to do nothing to use JMF: HTTP headers of serialized data, unless you have configured your Java client application to do otherwise, use a specific mime-type which tells the GraniteDS backend to switch to JMF instead of AMF serialization for the incoming request and corresponding response.
The JMF mime-type is currently “application/x-jmf+amf�?, the “+amf�? part stating that the messages inside the request are instances of flex.messaging.messages.Message (possibly enclosed in an AMF0 envelop). We are considering to use our own message envelops when using JMF and the mime-type is likely going to be “application/x-jmf�? only in later versions.
The good thing with this mime-type switch mechanism is that you can have Java (or even JavaFX / Android) client applications using the exact same backend used by Flex client applications: there is nothing specific to configure on the server-side.
With small messages such as a ping message (which purpose is to make sure that the server is alive and to negotiate serialization options), JMF vs. AMF vs. Standard Java Serialization (ie. java.io.ObjectOutputStream) gives these results:
With bigger messages (a list of person with collections of contacts), you can typically get these results:
As a general result, but without conducting an extensive benchmark, we have found that:
AMF serialization doesn’t state anything about what is (de)serializable or not: this lack of control can lead to a security breach that was discovered by Wouter Coekaerts and reported . Granite Data Services fixed this issue by adding a AMF3DeserializerSecurizer that controls which class can be instantiated at deserialization time (see this post about GraniteDS 2.2.1.GA).
Unlike AMF but just like the standard Java serialization, JMF only encodes primitive types and classes that implement java.io.Serializable. As a result, the above vulnerability doesn’t affect JMF, unless classes that shouldn’t be serialized implement (which is a design bug) java.io.Serializable.
Not yet. However, you are free to have look at the implementation, it’s fully open-source, just like the rest of the GraniteDS platform.
1 Comment