Dashboard > CruiseControl > Managing CruiseControl With JMX > Example RMI Controller
Example RMI Controller Log In View a printable version of the current page.

Added by Josh Micich , last edited by jacques couzteau on Feb 13, 2007  (view change) show comment
Labels: 

Here is a some simple code which demonstrates the basics of accessing CruiseControl by RMI/JMX.

To compile/run the class, add two jars to the classpath: mx4j.jar and mx4j-remote.jar. These can be found in the cruise control /lib folder.

It is assumed that CruiseControl is running on the specified host, with the '-rmiport' option (and default port 1099).

This code demonstrates how to:

  • Specify the JMX URL
  • Configure JNDI for the lookup of the JMX connector
  • Get a JMX connection
  • Locate an MBean (for a CruiseControl project)
  • Get a property ('status') and invoke an operation ('build') on the project MBean
  • Get a property ('status') and invoke an operation ('buildWithTarget') on the project MBean (Caution! the target is sticky. The next regular build will invoke the same target)

For more information on the jmx APIs see http://java.sun.com/j2se/1.5.0/docs/api/javax/management/package-summary.html

'BuildTriggerer.java'
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;

import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;

import com.sun.jndi.rmi.registry.RegistryContextFactory;
/**
 *
 */
public final class BuildTriggerer {

	
	private static final class BuildStatus {
		
		public static final String IN_QUEUE = "in build queue"; 
		public static final String WAITING = "waiting for next time to build";
		public static final String BOOTSTRAPPING = "bootstrapping";
		public static final String CHECKING_FOR_MODS = "checking for modifications";
		public static final String NOW_BUILDING = "now building";
		public static final String MERGING_LOGS = "merging accumulated log files";
		public static final String PUBLISHING  = "publishing build results";
	}	


	public static void main(String[] args) {

		forceBuild("localhost", "commons-math");
	}

	public static void forceBuild(String jmxRmiHost, String projectName) {
		MBeanServerConnection connection = getConnection(jmxRmiHost);

		ObjectName mbeanObj;
		try {
			mbeanObj = ObjectName.getInstance("CruiseControl Project:name=" + projectName);
		} catch (MalformedObjectNameException e) {
			throw new RuntimeException(e);
		}

		String status;
		
		try {
			status = (String)connection.getAttribute(mbeanObj, "Status");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

		
		if(!BuildStatus.WAITING.equals(status) && !BuildStatus.IN_QUEUE.equals(status)) {
			System.out.println("Not forcing build because current status is '" + status + "'");
			return;
		}
		System.out.println("Forcing build...");
		try {
			connection.invoke(mbeanObj, "build", new Object[0], new String[0]);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		System.out.println("sent 'build' msg successfully");
	}

    public static void forceBuildWithTarget(String jmxRmiHost, String projectName, String remoteTarget) {
		MBeanServerConnection connection = getConnection(jmxRmiHost);

		ObjectName mbeanObj;
		try {
			mbeanObj = ObjectName.getInstance("CruiseControl Project:name=" + projectName);
		} catch (MalformedObjectNameException e) {
			throw new RuntimeException(e);
		}

		String status;
		
		try {
			status = (String)connection.getAttribute(mbeanObj, "Status");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

		
		if(!BuildStatus.WAITING.equals(status) && !BuildStatus.IN_QUEUE.equals(status)) {
			System.out.println("Not forcing build because current status is '" + status + "'");
			return;
		}
		System.out.println("Forcing build with target " + remoteTarget + "...");
		try {
			connection.invoke(mbeanObj, "buildWithTarget", new Object[]  {remoteTarget},  new String[] {String.class.getName()});
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		System.out.println("sent 'build' msg successfully");
	}

	private static MBeanServerConnection getConnection(String jmxRmiHost) {

		final int rmiPort = 1099;
		
		JMXServiceURL url;

		try {
			url = new JMXServiceURL("service:jmx:rmi://" + jmxRmiHost + ":" + rmiPort + "/jndi/jrmp");
		} catch (MalformedURLException e) {
			throw new RuntimeException(e);
		}
		System.setProperty(Context.INITIAL_CONTEXT_FACTORY, RegistryContextFactory.class.getName());

//		System.setProperty(Context.PROVIDER_URL, "rmi://" + jmxRmiHost + ":" + rmiPort);

		// add the security attributes if they are there
		HashMap theEnvironment = new HashMap();

		// Connect to the JMXRMI Adapter and get the MBeanServerConnection
		try {
			return JMXConnectorFactory.connect(url, theEnvironment).getMBeanServerConnection();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
}
Powered by a free Atlassian Confluence Open Source Project / Non-profit License granted to ThoughtWorks, Inc.. Evaluate Confluence today.
Powered by Atlassian Confluence 2.7.1, the Enterprise Wiki. Bug/feature request - Atlassian news - Contact administrators