1 /* 2 * The Apache Software License, Version 1.1 3 * 4 * Copyright (c) 1999 The Apache Software Foundation. All rights 5 * reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * 3. The end-user documentation included with the redistribution, if 20 * any, must include the following acknowlegement: 21 * "This product includes software developed by the 22 * Apache Software Foundation (http://www.apache.org/)." 23 * Alternately, this acknowlegement may appear in the software itself, 24 * if and wherever such third-party acknowlegements normally appear. 25 * 26 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software 27 * Foundation" must not be used to endorse or promote products derived 28 * from this software without prior written permission. For written 29 * permission, please contact apache@apache.org. 30 * 31 * 5. Products derived from this software may not be called "Apache" 32 * nor may "Apache" appear in their names without prior written 33 * permission of the Apache Group. 34 * 35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * SUCH DAMAGE. 47 * ==================================================================== 48 * 49 * This software consists of voluntary contributions made by many 50 * individuals on behalf of the Apache Software Foundation. For more 51 * information on the Apache Software Foundation, please see 52 * <http://www.apache.org/>. 53 * 54 * [Additional notices, if required by prior licensing conditions] 55 * 56 */ 57 58 59 package org.apache.tomcat.shell; 60 61 import org.apache.tomcat.shell.deployment; 62 import org.apache.tomcat.core; 63 import org.apache.tomcat.server; 64 import org.apache.tomcat.util.StringManager; 65 import java.io; 66 import java.net; 67 import java.util; 68 import java.rmi; 69 import java.rmi.registry; 70 71 /** 72 * Command line entry point to start up tomcat. 73 * 74 * @author James Duncan Davidson [duncan@eng.sun.com] 75 * @author James Todd [gonzo@eng.sun.com] 76 */ 77 78 public class Startup { 79 80 protected StringManager sm = 81 StringManager.getManager(Constants.Package); 82 83 // add war protocol handler to system properties 84 85 static { 86 String warPackage = Constants.Protocol.WAR.PACKAGE; 87 String protocolKey = Constants.Protocol.WAR.SYSTEM_PROPERTY; 88 String protocolHandlers = 89 System.getProperties().getProperty(protocolKey); 90 System.getProperties().put(protocolKey, 91 (protocolHandlers == null) ? 92 warPackage : protocolHandlers + "|" + warPackage); 93 }; 94 95 /** 96 * 97 */ 98 99 public Startup() { 100 } 101 102 public void configure(String[] args) 103 throws StartupException { 104 Config config = getConfig(args); 105 106 if (config == null) { 107 return; 108 } 109 110 checkClassDependencies(); 111 112 ServerConfig serverConfig = config.getServerConfig(); 113 114 Registry registry= createRegistry(serverConfig.getAdminPort()); 115 Enumeration contextManagers = serverConfig.getContextManagers(); 116 117 while (contextManagers.hasMoreElements()) { 118 ContextManagerConfig contextManagerConfig = 119 (ContextManagerConfig)contextManagers.nextElement(); 120 ContextManager contextManager = new ContextManager(); 121 Enumeration contexts = contextManagerConfig.getContextConfigs(); 122 123 while (contexts.hasMoreElements()) { 124 ContextConfig contextConfig = 125 (ContextConfig)contexts.nextElement(); 126 Context context = contextManager.addContext( 127 contextConfig.getPath(), 128 contextConfig.getDocumentBase()); 129 String contextWorkDirPath = 130 getContextWorkDirPath(serverConfig, 131 contextManagerConfig, 132 contextConfig.getPath()); 133 134 context.setSessionTimeOut( 135 contextConfig.getDefaultSessionTimeOut()); 136 context.setInvokerEnabled(contextConfig.isInvokerEnabled()); 137 context.setIsWARExpanded(contextConfig.isWARExpanded()); 138 context.setIsWARValidated(contextConfig.isWARValidated()); 139 context.setWorkDir(contextWorkDirPath, 140 contextConfig.isWorkDirPersistent()); 141 context.setIsWARValidated(contextConfig.isWARValidated()); 142 143 if (contextConfig.getPath().equals( 144 org.apache.tomcat.core.Constants.Context.Default.Path)) { 145 contextManager.setDefaultContext(context); 146 contextManager.setServerInfo( 147 contextManager.getDefaultContext().getEngineHeader()); 148 } 149 } 150 151 InetAddress inetAddress = null; 152 153 try { 154 inetAddress = InetAddress.getByName( 155 contextManagerConfig.getINet()); 156 } catch (java.net.UnknownHostException uhe) { 157 String msg = sm.getString("startup.setinit.uhe1", 158 contextManagerConfig.getINet()); 159 160 System.out.println(msg); 161 } 162 163 try { 164 HttpServer server = new HttpServer( 165 contextManagerConfig.getPort(), inetAddress, 166 contextManagerConfig.getHostName(), contextManager); 167 168 Enumeration conE=contextManagerConfig.getConnectorConfigs(); 169 while( conE.hasMoreElements() ) { 170 ConnectorConfig conC=(ConnectorConfig) conE.nextElement(); 171 String cn=conC.getClassName(); 172 ServerConnector conn=null; 173 174 try { 175 Class c=Class.forName( cn ); 176 conn=(ServerConnector)c.newInstance(); 177 } catch(Exception ex) { 178 ex.printStackTrace(); 179 // XXX 180 } 181 Enumeration props=conC.getParameterKeys(); 182 while( props.hasMoreElements() ) { 183 String k=(String)props.nextElement(); 184 String v=(String)conC.getParameter( k ); 185 conn.setProperty( k, v ); 186 } 187 188 server.addConnector( conn ); 189 } 190 191 // XXX 192 // instead of HTTPServer it should be EndpointManager, 193 // ContextManager, Handler, etc 194 if( registry != null ) 195 registry.bind(Constants.Registry.Service + ":" + 196 server.getPort(), new AdminImpl(server)); 197 198 // XXX 199 // start/stop individual components 200 server.start(); 201 } catch (HttpServerException hse) { 202 String msg = sm.getString("startup.server.hse"); 203 204 System.out.println(msg); 205 hse.printStackTrace(); 206 throw new StartupException(); 207 // "problem starting server" can't help 208 // the user detect that the port is taken. 209 // ( or another tcp-related problem ) 210 // Please, let the stack trace until we have a better 211 // message ( that shows what failed) 212 } catch (RemoteException re) { 213 String msg = sm.getString("startup.server.re"); 214 215 System.out.println(msg); 216 re.printStackTrace(); 217 throw new StartupException(); 218 // The original message is useless, 219 // I had no idea what to do - if we can't figure a better 220 // message, please let the stack trace in 221 222 // in my case - I had no eth card, and it couldn't find the hostname 223 } catch (AlreadyBoundException abe) { 224 String msg = sm.getString("startup.server.abe"); 225 System.out.println(msg); 226 abe.printStackTrace(); 227 throw new StartupException(); 228 } 229 } 230 } 231 232 /** 233 * class dependencies 234 */ 235 236 public void checkClassDependencies() { 237 for (int i = 0; i < Constants.REQUIRED_CLASSES.length; i++) { 238 String clazz = (String)Constants.REQUIRED_CLASSES[i]; 239 240 try { 241 Class.forName(clazz); 242 } catch (ClassNotFoundException cnfe) { 243 String msg = sm.getString("startup.classes.cnfe", clazz); 244 245 System.out.println("warning: " + msg); 246 } 247 } 248 } 249 250 /** 251 * 252 */ 253 254 protected Registry createRegistry(int port) 255 throws StartupException { 256 Registry registry = null; 257 int numberAttempts = 0; 258 259 if (port==0) return null; 260 261 if (port < 0) { 262 port = newPort(); 263 } 264 265 while (true) { 266 String msg = null; 267 268 try { 269 registry = LocateRegistry.createRegistry(port); 270 createLog(port); 271 } catch (Exception e) { 272 msg = sm.getString("startup.registry.e"); 273 } 274 275 if (registry == null && 276 numberAttempts++ < Constants.RMI.MAX_ADMIN_PORT_ATTEMPTS) { 277 port = newPort(); 278 } else if (registry != null) { 279 break; 280 } else { 281 throw new StartupException(msg); 282 } 283 } 284 285 return registry; 286 } 287 288 /** 289 * 290 */ 291 292 protected int newPort() { 293 Random r = new Random(); 294 double mul = r.nextDouble(); 295 int min = Constants.RMI.MIN_ADMIN_PORT; 296 int max = Constants.RMI.MAX_ADMIN_PORT; 297 298 return (int)Math.round(min + mul * (max - min)); 299 } 300 301 /** 302 * 303 */ 304 305 protected void createLog(int port) { 306 File f = null; 307 308 try { 309 f = new File(Constants.Server.LogFile); 310 } catch (NullPointerException npe) { 311 System.out.println(sm.getString("startup.log.npe", 312 Constants.Server.ConfigFile)); 313 } 314 315 if (f != null) { 316 try { 317 if (f.exists() && 318 f.isFile()) { 319 f.delete(); 320 } 321 } catch (SecurityException se) { 322 System.out.println(sm.getString("startup.log.se", 323 Constants.Server.ConfigFile)); 324 } 325 326 try { 327 BufferedWriter bw = 328 new BufferedWriter(new FileWriter(f)); 329 330 bw.write(Constants.Property.AdminPort + ":" + port); 331 bw.newLine(); 332 333 bw.close(); 334 } catch (IOException ioe) { 335 System.out.println(sm.getString("startup.log.ioe", 336 Constants.Server.ConfigFile)); 337 } 338 } 339 } 340 341 /** 342 * 343 */ 344 345 public static void main(String[] args) { 346 try { 347 Startup start = new Startup(); 348 349 start.configure(args); 350 } catch (StartupException e) { 351 // System.out.println(e.getMessage()); 352 System.exit(1); 353 } 354 } 355 356 /** 357 * file and command line configuration processing 358 */ 359 360 private Config getConfig(String args[]) 361 throws StartupException { 362 Config config = new Config(args); 363 364 System.out.println(sm.getString("startup.banner")); 365 366 if (config.isArg(Constants.Arg.Help)) { 367 368 System.out.println(sm.getString("startup.help")); 369 System.out.println(); 370 371 return null; 372 } 373 374 String configFile = Constants.Server.ConfigFile; 375 376 if (config.isArg(Constants.Arg.Config)) { 377 configFile = config.getArg(Constants.Arg.Config); 378 } 379 380 config.loadConfig(configFile); 381 382 return config; 383 } 384 385 private String getContextWorkDirPath(ServerConfig serverConfig, 386 ContextManagerConfig contextManagerConfig, String path) { 387 String s = ""; 388 String baseDir = serverConfig.getWorkDir(); 389 String hostName = contextManagerConfig.getHostName(); 390 String iNet = contextManagerConfig.getINet(); 391 int port = contextManagerConfig.getPort(); 392 393 if (hostName.trim().length() > 0) { 394 s += hostName; 395 } else if (iNet.trim().length() > 0) { 396 s += iNet; 397 } 398 399 if (s.length() != 0) { 400 s += ":"; 401 } 402 403 if (port > -1) { 404 s += Integer.toString(port); 405 } 406 407 return baseDir + File.separator + URLEncoder.encode(s + path); 408 } 409 }