2009/04/15 - Apache HiveMind has been retired.

For more information, please explore the Attic.

Apache > HiveMind
Apache
 
Font size:      

Serializing Services

It is often useful, especially in a web-based application, to serialize services. In HiveMind 1.0, objects that had references to HiveMind services could not be serialized ... the services were not serializable. You could make your service implemention implement Serializable, but that's not what client code sees ... client code sees the service proxy, which did not implement Serializable. End of story.

Note
Service proxies are the objects that are obtained from the Registry, or injected into other services. The proxies implement the service interface, but are generated on the fly. These service proxies are part of how HiveMind handles just-in-time service instantiation.

Starting with HiveMind 1.1, service proxies are, themselves, serializable. If you create objects that have references to HiveMind services, those objects can be serialized. For example:

public class MyDataObject implements Serializable
{
  private MyService _myService;
  
  . . .
}    

Here, the MyDataObject class has a reference to a HiveMind service in its _myService instance variable. An instance of MyDataObject may be serialized in one JVM and de-serialized in another. In the new JVM, the _myService instance variable will point to an equivalent HiveMind service.

Note
Serialization involves a particular global static variable that stores the Registry. When a service proxy is serialized, the Registry manufactures a service token to take its place. It is this token that is actually serialized and deserialized -- not the service proxy itself. When the token is later deserialized, it accesses the Registry through the global variable to get the service proxy (in the new JVM) back. This causes a problem if you have multiple Registry instances ... they will try to overwrite each other. If you have multiple web applications that all use HiveMind, you need to ensure that the HiveMind framework JARs exist in each WAR's WEB-INF/lib folder ... that will ensure that each is loaded by a different class loader, and each will have its own static variable.

It is the service proxy that is serializable, not the service implementation. That means that a stateful service (one that uses the threaded or pooled service model) will likely not be in the same state in the new JVM. Again, the internal state of the service is not serialized ... just the service's id.

If your service acts as a factory (or otherwise provides access to itself), you must be careful to share the service proxy, not the implementation itself. For example:

public class MyServiceImpl implements MyService
{
  private void MyService _myProxy;
  
  public void setMyProxy(MyService myProxy)
  {
    _myProxy = myProxy;
  }
  
  // Service method
  
  public MyDataObject newDataObject()
  {
    return new MyDataObject(_myProxy);
  }
  
  . . .
}

Here, the implementation acts as a factory for MyDataObject instances. It connects each data object to the service proxy ( new MyDataObject(_myProxy) rather than new MyDataObject(this)). You will need to use the hivemind.BuilderFactory and include a <set-service> element to connect the implementation's myProxy property to the service proxy.

A final note: Services using the primitive service model do not have service proxies and therefore they are not serializable, even in release 1.1. The other service models (including the default service model, singleton), do use a proxy and are serializable, as discussed in this document.