package org.codehaus.mojo.jboss; import java.io.File; import java.io.IOException; import java.rmi.RMISecurityManager; import javax.management.InstanceNotFoundException; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.naming.InitialContext; import javax.naming.NamingException; import org.apache.maven.plugin.MojoExecutionException; /** * Waits until an app is started. * * @author <a href="mailto:viniciusfk@hotmail.com">Vinicius Kopcheski</a> * @goal wait-app-start * @requiresProject false * @since 1.5.0 */ public class WaitAppStartMojo extends StartAndWaitMojo { /** * @parameter default-value="" expression="${jboss.earName}" */ protected String earName; private static String command = null; public void execute() throws MojoExecutionException { // Set up the security manager to allow remote code to execute. try { File policyFile = File.createTempFile( "jboss-client", ".policy" ); policyFile.deleteOnExit(); JBossServerUtil.writeSecurityPolicy( policyFile ); // Get the canonical file which expands the shortened directory names in Windows policyFile = policyFile.getCanonicalFile(); System.setProperty( "java.security.policy", policyFile.toURI().toString() ); System.setSecurityManager( new RMISecurityManager() ); } catch ( IOException e ) { this.getLog().info( "Unable to create security policy file for loading remote classes: " + e.getMessage(), e ); this.getLog().info( "Will try to load required classes from local classpath." ); } catch ( SecurityException e ) { this.getLog().info( "Unable to set security manager for loading remote classes: " + e.getMessage(), e ); this.getLog().info( "Will try to load required classes from local classpath." ); } InitialContext ctx = this.getInitialContext(); // Try to get JBoss jmx MBean connection MBeanServerConnection server = null; NamingException ne = null; for ( int i = 0; i < this.retry; ++i ) { try { Thread.sleep( this.retryWait ); server = (MBeanServerConnection) ctx.lookup( "jmx/invoker/RMIAdaptor" ); break; } catch ( NamingException e ) { ne = e; this.getLog().info( "Waiting to retrieve JBoss JMX MBean connection... " ); } catch ( InterruptedException e ) { this.getLog().warn( "Thread interrupted while waiting for MBean connection: " + e.getMessage() ); e.printStackTrace(); } } if ( server == null ) { throw new MojoExecutionException( "Unable to get JBoss JMX MBean connection: " + ne.getMessage(), ne ); } this.getLog().info( "JBoss JMX MBean connection successful!" ); // Wait until server startup is complete boolean started = false; for ( int i = 0; i < this.retry; ++i ) { this.getLog().info( "Trying " + ( i + 1 ) + " of " + this.retry ); try { started = this.isAppStarted( server ); if ( started ) { break; } this.getLog().info( "App not started yet" ); Thread.sleep( this.retryWait ); } catch ( Exception e ) { this.getLog().error( e ); throw new MojoExecutionException( "Unable to wait: " + e.getMessage(), e ); } } if ( !started ) { throw new MojoExecutionException( "App is not stared before timeout has expired! " ); } this.getLog().info( "App started!" ); } /** * Check if the server has finished starting the app. Will throw one of several exceptions if the server connection * fails. * * @param server The connection to the server * @return true if the app is started * @throws Exception */ protected boolean isAppStarted( MBeanServerConnection server ) throws Exception { ObjectName serverMBeanName = new ObjectName( this.getAttribute() ); try { this.getLog().info( "Checking if " + this.earName + " is already started..." ); return server.getAttribute( serverMBeanName, "StateString" ).equals( "Started" ); } catch ( InstanceNotFoundException infe ) { return false; } } private String getAttribute() { if ( WaitAppStartMojo.command == null ) { StringBuilder commandSB = new StringBuilder( "jboss.j2ee:service=EARDeployment,url='" ); commandSB.append( this.earName ); commandSB.append( "'" ); WaitAppStartMojo.command = commandSB.toString(); } return WaitAppStartMojo.command; } }