JBoss.org Community Documentation

4.3. Direct access

If no parameter is given to the run.sh script when the client is started then a reference to the HRService bean is looked up using the microcontainer controller once the service is deployed:


private HRManager manager;
...
private final static String HRSERVICE = "HRService";

...

void deploy() {
    bootstrap.deploy(url);
    if (!useBus && manager == null) {
        ControllerContext context = controller.getInstalledContext(HRSERVICE);
        if (context != null) { manager = (HRManager) context.getTarget(); }
    }
}

Rather than immediately looking up a reference to the bean instance we first lookup a reference to a ControllerContext. We then obtain a reference to the bean instance from the context using the getTarget() method. The reason for this is because the bean can exist in many states within the microcontainer e.g. NOT_INSTALLED, DESCRIBED, INSTANTIATED, CONFIGURED, INSTALLED. In order to keep track of which state the bean is in we need to wrap it in another object called a context that describes the current state. The name of the context is the same as the bean name. Once a context reaches the INSTALLED state then the bean it represents is considered to be deployed.

Now that we have a reference to the bean instance representing our service entry point we can call methods on it to perform work:


@SuppressWarnings("unchecked")
Set<Employee> listEmployees() {
    if (useBus)
        ...
    else
        return manager.getEmployees();
}

The client is said to be accessing the service directly since it's using a reference to the actual bean instance. Performance is good as each method call goes directly to the bean but what happens if we want to reconfigure the service and redeploy it whilst the application is running?

Reconfiguration as we know is achieved by making changes to the XML deployment descriptor and saving the file but in order to redeploy the service we must first undeploy the current one. During undeployment the microcontainer controller releases its reference to the bean instance together with any beans that depend on it. The intention is that these beans will subsequently become available for garbage collection as they are no longer required by the application. Deploying the service again creates new bean instances representing the new configuration. Any subsequent lookups from clients will then retrieve references to these new instances and they will be able to access the reconfigured service.

The problem is that we cache the reference to the bean instance representing our service entry point in our client when we deploy the service for the first time. Undeploying the service therefore has no affect as the bean instance can still be accessed using the cached reference and it will not be garbage collected until the client releases it. Similarly deploying the service again will not cause another lookup as the client already has a cached reference. It will therefore continue to use the bean instance representing the initial service configuration.

Note

You can test this behaviour for yourself by typing 'u' followed by return to undeploy the current service. You should still be able to access the service from the client even though it is 'undeployed'. Now make some changes to the configuration using the jboss-beans.xml file and deploy it again using the 'd' option (remember to save any changes you make to jboss-beans.xml first). Printing out the status of the service using the 'p' option should allow you to see that the client is still accessing the initial instance of the service that was deployed.

Warning

Even if we change our client so that we lookup a new reference each time the service is redeployed there is nothing to prevent new developers from coming along and mistakedly handing out copies of this reference to other objects. If all of these references are not cleaned up during redeployment then this then puts us in the same situation as before with access to older instances of the service still possible.

To reliably redeploy the reconfigured service you must therefore shutdown the application completely using the 'q' option and restart it again using the run.sh script. For enterprise services such as transactions, messaging and persistance this is perfectly acceptable since they are generally always in use. As such they cannot be redeployed at runtime and benefit from the high performance given by using direct access. If your service falls into this category then you too should consider using direct access via the microcontainer controller.