Archive for the ‘Java’ Category

LCDS, ManagedObjectProxy and some reserved keywords

Yesterday I struggled for several hours looking in the Livecycle Data Services code in order to investigate the following error message:TypeError: Error #1034: Type Coercion failed: cannot convert “ZGUID” to QName. It was not easy but in the end I understood that it is an issue related to property collision inside of the ManagedObjectProxy  class. The ManagedObjectProxy instance is adding all the properties from the serialized objects into it. However if the name of one of your properties already exists in the ManagedObjectProxy instance then this process will fail. The following properties already exist (inherited from ObjectProxy):

dispatcher : EventDispatcher
notifiers : Object
object : Object
propertyList : Array
proxyClass : Class
type : QName
uid:String

For the “type” property a fix was provided in Livecycle Data Services 3, but not for the others. So if you design your domain object and you plan to use Livecycle Data Services it’s a good idea to not use this reserved keywords as names for your properties.

The problem appears only if you like to use the proxy approach (not having the corresponding AS class included in the client SWF).

Flex Data Services, Hibernate and Eclipse – Mike Slinn book

A lot of books about Flash, Flex, ActionScript and Java are available on the market and some of them are really good. However there are still very few books related to Flex and Java integration – best practices, frameworks, performance issues, patterns and anti patterns. Mike’s book fills a gap here, in talking primarily about the two Adobe products: BlazeDS and LiveCycle Data Services. I’ve met few people who really know well these products well, and I think that this book can help people get a better understanding. Flex and the other RIA technologies should improve not only the user experience/interaction but also the developers life  – making it much easier with – increased productivity, no more hacks and no more stateless clients. For that you need a strong platform both on the client and server side and LiveCycle Data Services can fulfill that.

The book comes with a tool written in Flash that can help you edit configuration files visually. Personally I would like to see an Eclipse plugin also – but considering that the tools for integrating Flash Player with Eclipse already exist I guess it’s possible in future.

The book is in early release – it can be ordered here.

BlazeDS, AMF and read only properties

A common scenario when building domain objects is to have read only objects properties. The serialization algorithm from BlazeDS/LCDS does not know how to serialize the read only properties – it needs both get and set methods (with one exception – the java.lang.Throwable class). So you have two options in this scenario if you do not want to build adapters over your domain object:

a)Build your own serialization/deserialization mechanism

In order to do that you need to implement the java.lang.Externalizable interface for the Java classes and flash.utils.IExternalizable for the ActionScript ones. The Java example is here and the AS here.

When using this approach you have the following advantages/disadvantages:

Advantages: the serialization/deserialization is much faster
Disadvantages: greater development time, and you lose some optimizations related to data compression (like string references and writing numbers in fewer bytes). Of course, you can build your own optimizations but again this means more development time

b)Patch the code from BlazeDS. You either add the includeReadOnly = true line in the BeanProxy constructor (this flag is used for Throwable serialization), or, better yet, take the modifications from the current BlazeDS branch where this feature was implemented.

Logging in BlazeDS and LCDS with Java Util

I created a small class to allow integration between the logging mechanism from BlazeDS and java.util.logging. As an example it’s useful if you plan to use BlazeDS or Livecycle Data Services inside Google App Engine – the former one uses java.util.logging.

In order to use it you should modify services-config.xml to use the newly created class (I created my class in the package flex.messaging.log):
<target class=”flex.messaging.log.JavaUtilLogTarget” level=”Debug”>

The source code is below:

import java.util.logging.Level;

public class JavaUtilLogTarget extends AbstractTarget{
public void logEvent(LogEvent event) {

  java.util.logging.Logger log =
    java.util.logging.Logger.getLogger(event.logger.getCategory());
  Level level;

  if (event.level >= LogEvent.ERROR)
    level = Level.SEVERE;
  else if (event.level >= LogEvent.WARN)
    level = Level.WARNING;
  else if (event.level >= LogEvent.INFO)
    level = Level.INFO;
  else if (event.level >= LogEvent.DEBUG)
    level = Level.FINE;
  else
    level = Level.FINEST;

  log.log(level,event.message,event.throwable);

  }
}

Java serialization versus AMF/Hessian serialization

Update: I added also compression. The result is the same, Hessian is the clear winner. Not quite sure why deflate takes so much time when applied to AMF output, but I was able to reproduce this result with different inputs.

Two months ago I was asked by several guys from JUG Gothenburg to do a comparison between AMF and classic Java serialization. I was not able to answer at the moment, because I had never thought about it nor had I performed any tests. Now I extended my mini-benchmark from my previous post and I also serialized the objects using Java serialization. The results are below, and you can see from the results that the size of compressed data is much larger for Java serialization (I used Java 1.6). Without looking at the code from ObjectOutputStream I assume that there are no techniques like detecting duplicate values and writing references or writing small number on fewer bytes.

My suggestion is to use AMF/Hessian rather than Java serialization whenever you can – you will be able to save a lot of bandwidth.

The result table is below, and you can download the source code from here.

Avg Time (microseconds) Data size (kbytes)
AMF3 9945 28
Hessian 4675 29
Java serialization 6400 60
AMF3+Deflate 34479 14.5
Hessian+Deflate 6076 14
Java serialization+Deflate 19193 22
XML 22064 158
XML+Deflate 27336 18

Using AMF and Web Services

You can pack and send your data using AMF even if you don’t use the remoting services. In this post I will show several ways to do that using HTTP services. Why would you want to do that ? There are organizations or departments that expose only REST and SOAP services and it can be hard to persuade them to add the remoting services. In this case, when using web services, you have two solutions: you can create XML from your object graph (and for that you’ll have to write extra code) and apply a compression algorithm on it, or you can apply AMF serialization on the object graph, add the resulting byte code in the service body, and deserialize the AMF format on the client side.

Below is a sample how to do that. First, the Java code on the server:

    public void service(ServletRequest arg0, ServletResponse response)
            throws ServletException, IOException {

        Product product = new Product("name","description");        

        SerializationContext context = new SerializationContext();
        context.instantiateTypes = true;

        ByteArrayOutputStream baos = new ByteArrayOutputStream(64*1024);
        Amf3Output amf3Output = new Amf3Output(context);
        amf3Output.setOutputStream(baos);

        amf3Output.writeObject(product);
        amf3Output.flush();

        response.getOutputStream().write(baos.toByteArray());
    }

On the client you have two options. The easier one is to use an URLLoader.

        private function loaderCompleteHandler(event:Event):void {
            //rebuild the object                            
            var product:Product = loader.data.readObject();
        }

        function sendData(event:Event){
            var request:URLRequest = new URLRequest("/test/loaddata/");
            loader = new URLLoader();
            loader.dataFormat = URLLoaderDataFormat.BINARY;
            loader.load(request);
            loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
            loader.addEventListener(Event.COMPLETE, loaderCompleteHandler);
        }

If you want to use an HTTPService you have a problem, because by default it does not handle binary data. However it’s easy to extend the class and to add binary support.

    public class HTTPServiceExt extends HTTPService{
        protected static var binaryChannel:Channel;
        protected static var binaryChannelSet:ChannelSet;
        public var binaryData:Boolean;

        public function HTTPServiceExt(){
        }
        override public function send(parameters:Object = null):AsyncToken{
            if (( useProxy == false ) && (binaryData)){
                if ( binaryChannelSet == null ){
                    var dcs:ChannelSet = new ChannelSet();
                    binaryChannel =
                    new DirectHTTPBinaryChannel("directhttpbinarychannel");
                    dcs.addChannel(binaryChannel);
                    channelSet = dcs;
                    binaryChannelSet = dcs;
                }
                else if ( channelSet != binaryChannelSet ){
                    channelSet = binaryChannelSet;
                }
            }
            return super.send(parameters);
        }
    }

The class DirectHTTPBinaryChannel is taken from Anirudh Sasikumar’s blog. It extends DirectHTTPChannel and it configures the internal URLoader to work with binary data.

Now you have an HTTPService class that knows how to receive binary data also. In order to use it you have to add the binaryData parameter:

    function resultCall(event:ResultEvent):void{
       var product:Product = event.result.readObject();
    }
    <local:HTTPServiceExt binaryData="true" id="srv"
        url="/test/loaddata/"
        result="resultCall(event)"
        fault="faultCall(event)"/>

That’s all. You can refine the code; for example you may want to create only one URL for all the resources and to pass parameters, or you can use SOAP services and add the AMF binary format as an attachment.

I also uploaded a Flex/WTP project here containing all the source code.

BlazeDS bootcamp – resources

Adobe Developer Day is over and I made an archive containing a project with samples related to remoting and messaging (BlazeDS bootcamp). You can download it from this link.

Taking into account that we received good feedback will start again a new session of bootcamps.

Using Hessian and Flash player

I created my first application using Hessian last week and I thought I’d write about the main differences between using AMF and the Hessian protocol for remoting. You can also download my sample project here – it’s the same Hello World sample with PureMVC from a previous post modified to work with Hessian.

In comparing AMF and Hessian I’ll start with the server side.

a)Server side libraries and configuration

If you plan to use AMF you will need to use BlazeDS, LiveCycle Data Services  or another product (GraniteDS, WebOrb etc). If you only need remoting you can strip out most of the jars, but you will still need more than 800 kbytes. For Hessian you need only one jar – about 300 kbytes. Also for AMF you will need to declare a servlet (MessageBroker) in the web.xml file.

b)Exposing your Java methods

When using BlazeDS any object with a public constructor can be a remoting point, and you will have to write an entry in a configuration file:

<destination id=”HelloService”>
<channels>
<channel ref=”my-amf”/>
</channels>
<properties>
<source>
org.puremvc.server.java.helloworld.services.HelloService
</source>
<scope>application</scope>
</properties>
<adapter ref=”java-object” />
</destination>

You will also have to define the channel – to specify how you intend to communicate between the client and server. For remoting the AMF channel is the preferred solution

<channel-definition id=”my-amf” class=”mx.messaging.channels.AMFChannel”>
<endpoint url=

http://{server.name}:{server.port}/hellopuremvc_blaze/messagebroker/amf

class=”flex.messaging.endpoints.AMFEndpoint”/>
</channel-definition>

For Hessian you have to write a class extending HessianServlet containing all the methods which can be invoked. After that you add this servlet in web.xml

<servlet>
<servlet-name>model</servlet-name>
<servlet-class>HessianSerializeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>model</servlet-name>
<url-pattern>/model/*</url-pattern>
</servlet-mapping>

Another difference is that in the Hessian case all the Java objects used as value objects should implement the Serializable interface

c)Client side invocation

For AMF you do not need any external libraries because the serialization and deserialization is done natively in Flash Player. However for Hessian you will need a library and latest version (3.2) is about 500 kbytes.

From a programming point of view is the biggest difference is that for Hessian case you will need to have the AS class and the Java class in the same location (package +name) if you want to have automatic serialization/deserialization. You can use the “RemoteClass” tag also for Hessian, but it works only in one direction (from Flex to Java), at least this is what I noticed. Otherwise the call looks the same:

AMF:

service = new RemoteObject();
service.destination = “HelloService”;
service.requestTimeout = 3;
var call:Object = service.sayHello(name);

Hessian

service = new HessianService();
service.destination = “/hellopuremvc_hessian/services/”;
service.requestTimeout = 3;
var call:Object = service.sayHello(name);

The destination definition is a little bit tricky – for AMF it should be the same as the one defined in services.xml, for Hessian it should be the same as the servlet mapping from web.xml

<servlet>
<servlet-name>services</servlet-name>
<servlet-class>org.puremvc.server.java.helloworld.servlet.HelloServiceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>services</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

d)Performance and other considerations

As I wrote in a previous post Hessian serialization from the server side is faster than AMF one, and the compressed data almost has the same size. However on the client side the AMF is the clear winner because of the native support provided by Flash Player. Also the Hessian library for the client is quite big.

Below are the links describing the mapping between ActionScript and Java types:
AMF
Hessian

Remoting, XML, AMF, Hessian and Deflate algorithm

I’m a big fan of using remote calling whenever possible to bring the data from a Java server into a Flex application, not only for performance reasons but also because the code is much cleaner. Yesterday, I implemented a quick benchmark to test both approaches (remote versus a service returning xml) – results are bellow.  You can also download the project here (it’s created in Intellij, and you will also need Java persistence libraries). It’s a quick benchmark and not a benchmark framework so the code is no production quality. I’ve tried to eliminate the time spent by the garbage collector and the times for the benchmark are taken into consideration only after the Hotspot optimizations of the code.

Some details about my benchmark: I have three objects (Company objects havea bidirectional 1-n relation with an Employee objects and the Employee has a n-1 relation with a Town object). I read the data from a MySql database using Hibernate(I have about 3 Companies, 1000 Employees, and 5 Towns).

For the XML case I’m doing a conversion from the Java objects to XML, and optionally I have also included a ZIP compression. For the remote case I tested both AMF3 compression and Hessian. I tested only the algorithms (not the time spent the data from the application server) because I think that’s the most important thing.

The results are interesting, the most time is spent in XML conversion (using DOM4J). I will try to use also another XML library, maybe that time can be reduced a little . The results prove again that the binary formats (AMF3 and Hessian) are a very good option when sending data to the Flex client…note that even the compressed XML is not much smaller than the binary format.

Results table below. My system is a Lenovo laptop, CORE 2 Duo, 2.4Ghz

Avg Time (microseconds) Data size (kbytes)
AMF3 9945 28
Hessian 4675 29
XML 22064 158
XML+Deflate 27336 18

Note: the difference between AMF and Hessian depends a lot on the input data. For example if you have more repetitive data then AMF tends to be more efficient than Hessian on data size. I will try in the future to create a mini benchmark framework with different sets of data.

How to prevent memory leaks when reloading web applications

During my career as a software engineer I had to fix some nasty memory leaks that appeared only when trying to reload the current web application (one bug is described here). Most of the time the PermGen space was completely filled with class definition and the following error message was returned: “java.lang.OutOfMemoryError: PermGen space” (on older JVM it is possible to receive just “java.lang.OutOfMemoryError”)

PermGen is a region of memory allocated by the JVM for class definitions and for the constant pool. At first glance you might will be tempted to increase its size (the default value is 64MB) using the -XX:MaxPermSize parameter, however this solution will only allow you maybe just to reload your application perhaps several times more. The better solution is to identify the memory leak (and this post will describe several possible causes) and after that to fix it .

I will also write about the classloader architecture of an application server and what happens when the application server tries to unload a deployed application but I will not go into much detail, since there are better articles or books describing these things.

a)Classloader arhitecture for an applications server.

Classloaders are organized in parent child relationship, and a class can be visible only if it is visible from the current classloader or any of its parents – it cannot go down in hierarchy. Every classloader keeps a list of references to the loaded classes (take a look in java.lang.ClassLoader).

The following diagram (inspired from Tomcat documentation) describes the simplified classloader hierarchy used by an application server :

                       Bootstrap
                          |
                       System
                          |
                       Common
                      /      \
                 Webapp1   Webapp2 ...

If you are curious to see the whole hierarchy of classloaders for your class and server you can use the following code:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
while(classLoader != null) {
    System.out.println(classLoader);
    classLoader = classLoader.getParent();
}

The application server uses this hierarchy of classloaders in order to keep the applications isolated. For example if a class is loaded by the classloader Webapp1 it will be not visible from a class loaded by the classloader Webapp2. However a class loaded by the classloader Common is visible from the classloader Webapp2. As an analogy all the libraries from the Tomcat lib folder are visible for all deployed applications, but one application cannot see the libraries from the lib folder located inside another application.

b)Deploying and restarting your application

When you deploy and start your own application the server will a create a new classloader – let’s call it WEBCLOADER1, which will be used to load the classes from your application. When you redeploy your application it will set the reference of WEBCLOADER1 to null and it will create a new classloader used again to load your application. When you undeploy your application it will destroy WEBCLOADER1 and it will try to delete the application.

This process works well if the classes from your application are referenced only from WEBCLOADER1 or any other children classloaders created from WEBCLOADER1. If not, for example if one of your classes is referenced from the System classloader then your deployed application cannot be garbage collected and eventually you will receive the dreaded OutOfMemoryError.

How is it possible to have this situation? Is too simple unfortunately, just use something like this:

private static final ThreadLocal cache = new ThreadLocal();
cache.set(someObject);

In this case the current thread (one of the threads created by the application servers) has a reference to your object. The thread was created by the application server using a higher level classloader so it does not matter that WEBCLOADER1 is null, your application cannot be garbage collected.

The problem also arises when you use methods from the java.beans.Introspector class without calling flushCaches because it uses a static cache in order to make the introspection faster, so again your classes are going to be referenced from a classloader other than WEBCLOADER1.

c)How do I identify a memory leak related to the multiple classloader problem?

Use a good profiler. I was using YourKit profiler, it was one of the few able to help me two years ago (today there maybe be other choices). Using YourKit you can take a memory snapshot, undeploy your application, take another snapshot and use the compare snapshots features. If you will see objects belonging to your application it means that you have memory leaks. You can use the “Find paths from GC roots” option to see who’s keeping references to your class. That’s the easier part, after that you will have to locate the problem in your application – or in other third-party libraries used by your application. Bellow I will wrote some tips related to common problems.

Use a ServletContextListener to intercept when the context is destroyed; this is the place where you should have your clean up code. Or you can use the destroy() method from a dedicated servlet. Bellow are some tips for some common problems:

  • if you use commons-logging then call this method from the clean up method
  • LogFactory.release(Thread.currentThread().getContextClassLoader());
  • call Introspector.flushCaches() from the clean up method (or use a framework such as Spring which does that);
  • if you use any jdbc drivers you have two options: You can load them with a global classloader (for Tomcat copy the drivers in common/lib folder) or you can unregister them manually in the clean up method by calling
  • DriverManager.deregisterDriver(yourDriverClass);
  • the usage of static members does NOT prevent your application from being garbage collected
  • use ThreadLocal with caution and if you are using them be sure to clean the values. A safe practice is to use a filter or some kind of interceptor to do that.