View Javadoc

1   package org.codehaus.mojo.jboss;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file 
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   * 
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing, 
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
17   * KIND, either express or implied.  See the License for the 
18   * specific language governing permissions and limitations 
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.FileWriter;
24  import java.io.IOException;
25  import java.io.PrintWriter;
26  import java.rmi.RMISecurityManager;
27  import java.util.Properties;
28  
29  import javax.management.MBeanServerConnection;
30  import javax.management.ObjectName;
31  import javax.naming.Context;
32  import javax.naming.InitialContext;
33  import javax.naming.NamingException;
34  
35  import org.apache.maven.plugin.MojoExecutionException;
36  import org.jboss.security.SecurityAssociation;
37  import org.jboss.security.SimplePrincipal;
38  
39  /**
40   * Starts JBoss and waits until the server is started.
41   * 
42   * @author <a href="mailto:jc7442@yahoo.fr">J-C</a>
43   * @author <a href="mailto:fuzail@fingerprintsoft.org">Fuzail Sarang</a>
44   * @goal start-and-wait
45   * @requiresProject false
46   * @since 1.4
47   */
48  public class StartAndWaitMojo
49      extends StartMojo
50  {
51  
52      /**
53       * One second in millis.
54       */
55      public static final long ONE_SECOND = 1000;
56  
57      /**
58       * Maximum number of retries to get JBoss JMX MBean connection.
59       * 
60       * @parameter default-value="4" expression="${jboss.retry}"
61       */
62      protected int retry;
63  
64      /**
65       * Wait in ms before each retry of the JBoss JMX MBean connection.
66       * 
67       * @parameter default-value="5000" expression="${jboss.retryWait}"
68       */
69      protected int retryWait;
70  
71      /**
72       * Time in ms to start the application server (once JMX MBean connection has been reached).
73       * 
74       * @parameter default-value="20000" expression="${jboss.timeout}"
75       */
76      protected int timeout;
77  
78      /**
79       * The port for the naming service.
80       * 
81       * @parameter default-value="1099" expression="${jboss.namingPort}"
82       */
83      protected String namingPort;
84  
85      /**
86       * The host JBoss is running on.
87       * 
88       * @parameter default-value="localhost" expression="${jboss.hostname}"
89       */
90      protected String hostName;
91  
92      /**
93       * Main plugin execution.
94       * 
95       * @throws MojoExecutionException
96       */
97      public void execute()
98          throws MojoExecutionException
99      {
100         // Start JBoss
101         super.execute();
102 
103         // Set up the security manager to allow remote code to execute.
104         try
105         {
106             File policyFile = File.createTempFile( "jboss-client", ".policy" );
107             policyFile.deleteOnExit();
108             JBossServerUtil.writeSecurityPolicy( policyFile );
109             // Get the canonical file which expands the shortened directory names in Windows
110             policyFile = policyFile.getCanonicalFile();
111             System.setProperty( "java.security.policy", policyFile.toURI().toString() );
112             System.setSecurityManager( new RMISecurityManager() );
113         }
114         catch ( IOException e )
115         {
116             getLog().info( "Unable to create security policy file for loading remote classes: " + e.getMessage(), e );
117             getLog().info( "Will try to load required classes from local classpath." );
118         }
119         catch ( SecurityException e )
120         {
121             getLog().info( "Unable to set security manager for loading remote classes: " + e.getMessage(), e );
122             getLog().info( "Will try to load required classes from local classpath." );
123         }
124         InitialContext ctx = getInitialContext();
125 
126         // Try to get JBoss jmx MBean connection
127         MBeanServerConnection server = null;
128         NamingException ne = null;
129         for ( int i = 0; i < retry; ++i )
130         {
131             try
132             {
133                 Thread.sleep( retryWait );
134                 server = (MBeanServerConnection) ctx.lookup( "jmx/invoker/RMIAdaptor" );
135                 break;
136             }
137             catch ( NamingException e )
138             {
139                 ne = e;
140                 getLog().info( "Waiting to retrieve JBoss JMX MBean connection... " );
141             }
142             catch ( InterruptedException e )
143             {
144                 getLog().warn( "Thread interrupted while waiting for MBean connection: " + e.getMessage() );
145                 e.printStackTrace();
146             }
147         }
148 
149         if ( server == null )
150         {
151             throw new MojoExecutionException( "Unable to get JBoss JMX MBean connection: " + ne.getMessage(), ne );
152         }
153 
154         getLog().info( "JBoss JMX MBean connection successful!" );
155 
156         // Wait until server startup is complete
157         boolean started = false;
158         long startTime = System.currentTimeMillis();
159         while ( !started && System.currentTimeMillis() - startTime < timeout )
160         {
161             try
162             {
163                 Thread.sleep( ONE_SECOND );
164                 started = isStarted( server );
165             }
166             catch ( Exception e )
167             {
168                 throw new MojoExecutionException( "Unable to wait: " + e.getMessage(), e );
169             }
170         }
171         if ( !started )
172         {
173             throw new MojoExecutionException( "JBoss AS is not stared before timeout has expired! " );
174         }
175         getLog().info( "JBoss AS started!" );
176     }
177 
178     /**
179      * Check if the server has finished startup. Will throw one of several exceptions if the server connection fails.
180      * 
181      * @param s
182      * @return
183      * @throws Exception
184      */
185     protected boolean isStarted( MBeanServerConnection server )
186         throws Exception
187     {
188         ObjectName serverMBeanName = new ObjectName( "jboss.system:type=Server" );
189         return ( (Boolean) server.getAttribute( serverMBeanName, "Started" ) ).booleanValue();
190     }
191 
192     /**
193      * Set up the context information for connecting the the jboss server.
194      * 
195      * @return
196      * @throws MojoExecutionException
197      */
198     protected InitialContext getInitialContext()
199         throws MojoExecutionException
200     {
201         Properties env = new Properties();
202         env.put( Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory" );
203         env.put( Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces" );
204         env.put( Context.PROVIDER_URL, hostName + ":" + namingPort );
205 
206         String username = getUsername();
207         if ( username != null )
208         {
209             SecurityAssociation.setPrincipal( new SimplePrincipal( username ) );
210             SecurityAssociation.setCredential( getPassword() );
211         }
212                 
213         try
214         {
215             return new InitialContext( env );
216         }
217         catch ( NamingException e )
218         {
219             throw new MojoExecutionException( "Unable to instantiate naming context: " + e.getMessage(), e );
220         }
221     }
222 
223 }