Skip to content
June 3, 2010 / edeustace

Externalizing JGroups configuration file from a BlazeDS or LCDS application

A customer I am working with wanted to know if it was possible to externalize the JGroups clustering configuration file from their LCDS application. The reason that they want to do this is to make it easier for them to reconfigure the cluster without having to deploy a new war or by programmatic means.

Now all they’ll have to do is take down a server in the cluster, update the distributed jgroups config file, then boot it up again.

For more information on configuring clustering see here

However Blaze DS nor Lcds allow this to happen. If you add the following to you services-config.xml file:

<clusters>
     <cluster id="default-cluster" default="true" url-load-balancing="false" properties="C:/jgroups/jgroups-tcp.xml"/>
</clusters>

You’ll get the following error:

SEVERE: Servlet /externalize threw load() exception
javax.servlet.UnavailableException: The cluster properties file ‘C:/jgroups/jgroups-tcp.xml’ does not exist.
at flex.messaging.MessageBrokerServlet.init(MessageBrokerServlet.java:170)

I started looking into this by checking out Blaze DS 3.0.1 (thats what the customer is using) and saw this:
In flex.messaging.cluster.ClusterManager they have:

 public void prepareCluster(ClusterSettings settings)
    {
        if (settings.getPropsFileName() == null)
        {
            ClusterException cx = new ClusterException();
            cx.setMessage(10201, new Object[] { settings.getClusterName(), settings.getPropsFileName() });
            throw cx;
        }

        InputStream propsFile;

        try
        {	
            propsFile = broker.resolveInternalPath(settings.getPropsFileName());
        }
        catch (Throwable t)
        {
            ClusterException cx = new ClusterException();
            cx.setMessage(10208, new Object[] { settings.getPropsFileName() });
            cx.setRootCause(t);
            throw cx;
        }
        //...
}

Where the implementation is defined in MessageBrokerServlet like so:

 private void setupInternalPathResolver()
    {
        broker.setInternalPathResolver(
            new MessageBroker.InternalPathResolver()
            {
                public InputStream resolve(String filename)
                {
                    InputStream is = getServletContext().getResourceAsStream(FLEXDIR + filename);
                    return is;
                }
            }
        );
    }

This is always going to cause problems. I created a patch for this that does the following:
– Tries to load the config from within the .war.
– If the file is null, then tries to load it externally.

To achieve this I added the following to ClusterManager.prepareCluster:

 if( propsFile == null )
        {
        	//[Patch] Try to load external properties file for cluster configuration
	        try
	        {	
	            propsFile = broker.resolveExternalPath(settings.getPropsFileName());
	        }
	        catch (Throwable t)
	        {
	            ClusterException cx = new ClusterException();
	            cx.setMessage(10208, new Object[] { settings.getPropsFileName() });
	            cx.setRootCause(t);
	            throw cx;
	        }
        }

Then I added a path resolver:

 private void setupExternalPathResolver()
    {
    	broker.setExternalPathResolver(
    			new MessageBroker.ExternalPathResolver()
    			{
    				public InputStream resolve(String filename) throws FileNotFoundException
    				{
    					return new FileInputStream( new File(filename) );
    				}
    			}
    	);
    }

Then built blazeDS and it all worked.

However the customer was using LCDS, so I had to inject some of the patched classes in to the LCDS compiled jar.

I’ve created a feature request for this in bugs.adobe.com: BLZ-545

The patched java classes are attached in the bugs.adobe.com bug.

Advertisements

2 Comments

Leave a Comment
  1. shardul / Jan 6 2011 11:13 pm

    This solution is not working. This still throws an exception. It is no going in the if( propsFile == null ) statement. Please check again.

    Thanks

    Shardul

  2. edeustace / Jan 7 2011 9:00 am

    Hi Shardul,
    I’ll try and have a look today. I’ll run the blaze trunk which should have the fix in it.

    Best,
    Ed

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: