View Javadoc

1   package org.codehaus.mojo.jboss;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.rmi.RMISecurityManager;
6   
7   import javax.management.InstanceNotFoundException;
8   import javax.management.MBeanServerConnection;
9   import javax.management.ObjectName;
10  import javax.naming.InitialContext;
11  import javax.naming.NamingException;
12  
13  import org.apache.maven.plugin.MojoExecutionException;
14  
15  /**
16   * Waits until an app is started.
17   * 
18   * @author <a href="mailto:viniciusfk@hotmail.com">Vinicius Kopcheski</a>
19   * @goal wait-app-start
20   * @requiresProject false
21   * @since 1.5.0
22   */
23  public class WaitAppStartMojo
24      extends StartAndWaitMojo
25  {
26      /**
27       * @parameter default-value="" expression="${jboss.earName}"
28       */
29      protected String earName;
30  
31      private static String command = null;
32  
33      public void execute()
34          throws MojoExecutionException
35      {
36          // Set up the security manager to allow remote code to execute.
37          try
38          {
39              File policyFile = File.createTempFile( "jboss-client", ".policy" );
40              policyFile.deleteOnExit();
41              JBossServerUtil.writeSecurityPolicy( policyFile );
42              // Get the canonical file which expands the shortened directory names in Windows
43              policyFile = policyFile.getCanonicalFile();
44              System.setProperty( "java.security.policy", policyFile.toURI().toString() );
45              System.setSecurityManager( new RMISecurityManager() );
46          }
47          catch ( IOException e )
48          {
49              this.getLog().info( "Unable to create security policy file for loading remote classes: " + e.getMessage(),
50                                  e );
51              this.getLog().info( "Will try to load required classes from local classpath." );
52          }
53          catch ( SecurityException e )
54          {
55              this.getLog().info( "Unable to set security manager for loading remote classes: " + e.getMessage(), e );
56              this.getLog().info( "Will try to load required classes from local classpath." );
57          }
58          InitialContext ctx = this.getInitialContext();
59  
60          // Try to get JBoss jmx MBean connection
61          MBeanServerConnection server = null;
62          NamingException ne = null;
63          for ( int i = 0; i < this.retry; ++i )
64          {
65              try
66              {
67                  Thread.sleep( this.retryWait );
68                  server = (MBeanServerConnection) ctx.lookup( "jmx/invoker/RMIAdaptor" );
69                  break;
70              }
71              catch ( NamingException e )
72              {
73                  ne = e;
74                  this.getLog().info( "Waiting to retrieve JBoss JMX MBean connection... " );
75              }
76              catch ( InterruptedException e )
77              {
78                  this.getLog().warn( "Thread interrupted while waiting for MBean connection: " + e.getMessage() );
79                  e.printStackTrace();
80              }
81          }
82  
83          if ( server == null )
84          {
85              throw new MojoExecutionException( "Unable to get JBoss JMX MBean connection: " + ne.getMessage(), ne );
86          }
87  
88          this.getLog().info( "JBoss JMX MBean connection successful!" );
89  
90          // Wait until server startup is complete
91          boolean started = false;
92          for ( int i = 0; i < this.retry; ++i )
93          {
94              this.getLog().info( "Trying " + ( i + 1 ) + " of " + this.retry );
95              try
96              {
97                  started = this.isAppStarted( server );
98                  if ( started )
99                  {
100                     break;
101                 }
102                 this.getLog().info( "App not started yet" );
103                 Thread.sleep( this.retryWait );
104             }
105             catch ( Exception e )
106             {
107                 this.getLog().error( e );
108                 throw new MojoExecutionException( "Unable to wait: " + e.getMessage(), e );
109             }
110         }
111         if ( !started )
112         {
113             throw new MojoExecutionException( "App is not stared before timeout has expired! " );
114         }
115         this.getLog().info( "App started!" );
116     }
117 
118     /**
119      * Check if the server has finished starting the app. Will throw one of several exceptions if the server connection
120      * fails.
121      * 
122      * @param server The connection to the server
123      * @return true if the app is started
124      * @throws Exception
125      */
126     protected boolean isAppStarted( MBeanServerConnection server )
127         throws Exception
128     {
129 
130         ObjectName serverMBeanName = new ObjectName( this.getAttribute() );
131         try
132         {
133             this.getLog().info( "Checking if " + this.earName + " is already started..." );
134             return server.getAttribute( serverMBeanName, "StateString" ).equals( "Started" );
135         }
136         catch ( InstanceNotFoundException infe )
137         {
138             return false;
139         }
140     }
141 
142     private String getAttribute()
143     {
144         if ( WaitAppStartMojo.command == null )
145         {
146             StringBuilder commandSB = new StringBuilder( "jboss.j2ee:service=EARDeployment,url='" );
147             commandSB.append( this.earName );
148             commandSB.append( "'" );
149             WaitAppStartMojo.command = commandSB.toString();
150         }
151         return WaitAppStartMojo.command;
152     }
153 
154 }