/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.catalina.startup; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.apache.catalina.Container; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; import org.apache.catalina.Server; import org.apache.catalina.core.StandardServer; import org.apache.tomcat.util.digester.Digester; import org.apache.tomcat.util.digester.Rule; import org.xml.sax.Attributes; import org.xml.sax.InputSource; /** * Startup/Shutdown shell program for Catalina. The following command line * options are recognized: *
true
if we should continue processing; otherwise
* return false
.
*
* @param args Command line arguments to process
*/
protected boolean arguments(String args[]) {
boolean isConfig = false;
if (args.length < 1) {
usage();
return (false);
}
for (int i = 0; i < args.length; i++) {
if (isConfig) {
configFile = args[i];
isConfig = false;
} else if (args[i].equals("-config")) {
isConfig = true;
} else if (args[i].equals("-nonaming")) {
setUseNaming( false );
} else if (args[i].equals("-help")) {
usage();
return (false);
} else if (args[i].equals("start")) {
starting = true;
stopping = false;
} else if (args[i].equals("stop")) {
starting = false;
stopping = true;
} else {
usage();
return (false);
}
}
return (true);
}
/**
* Return a File object representing our configuration file.
*/
protected File configFile() {
File file = new File(configFile);
if (!file.isAbsolute())
file = new File(System.getProperty("catalina.base"), configFile);
return (file);
}
/**
* Create and configure the Digester we will be using for startup.
*/
protected Digester createStartDigester() {
long t1=System.currentTimeMillis();
// Initialize the digester
Digester digester = new Digester();
digester.setValidating(false);
digester.setRulesValidation(true);
HashMapcatalina.base
System property to the current
* working directory if it has not been set.
* @deprecated Use initDirs()
*/
public void setCatalinaBase() {
initDirs();
}
/**
* Set the catalina.home
System property to the current
* working directory if it has not been set.
* @deprecated Use initDirs()
*/
public void setCatalinaHome() {
initDirs();
}
/**
* Start a new server instance.
*/
public void load() {
long t1 = System.nanoTime();
initDirs();
// Before digester - it may be needed
initNaming();
// Create and execute our Digester
Digester digester = createStartDigester();
InputSource inputSource = null;
InputStream inputStream = null;
File file = null;
try {
file = configFile();
inputStream = new FileInputStream(file);
inputSource = new InputSource("file://" + file.getAbsolutePath());
} catch (Exception e) {
;
}
if (inputStream == null) {
try {
inputStream = getClass().getClassLoader()
.getResourceAsStream(getConfigFile());
inputSource = new InputSource
(getClass().getClassLoader()
.getResource(getConfigFile()).toString());
} catch (Exception e) {
;
}
}
// This should be included in catalina.jar
// Alternative: don't bother with xml, just create it manually.
if( inputStream==null ) {
try {
inputStream = getClass().getClassLoader()
.getResourceAsStream("server-embed.xml");
inputSource = new InputSource
(getClass().getClassLoader()
.getResource("server-embed.xml").toString());
} catch (Exception e) {
;
}
}
if ((inputStream == null) && (file != null)) {
log.warn("Can't load server.xml from " + file.getAbsolutePath());
return;
}
try {
inputSource.setByteStream(inputStream);
digester.push(this);
digester.parse(inputSource);
inputStream.close();
} catch (Exception e) {
log.warn("Catalina.start using "
+ getConfigFile() + ": " , e);
return;
}
// Stream redirection
initStreams();
// Start the new server
if (server instanceof Lifecycle) {
try {
server.initialize();
} catch (LifecycleException e) {
log.error("Catalina.start", e);
}
}
long t2 = System.nanoTime();
if(log.isInfoEnabled())
log.info("Initialization processed in " + ((t2 - t1) / 1000000) + " ms");
}
/*
* Load using arguments
*/
public void load(String args[]) {
try {
if (arguments(args))
load();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
public void create() {
}
public void destroy() {
}
/**
* Start a new server instance.
*/
public void start() {
if (server == null) {
load();
}
long t1 = System.nanoTime();
// Start the new server
if (server instanceof Lifecycle) {
try {
((Lifecycle) server).start();
} catch (LifecycleException e) {
log.error("Catalina.start: ", e);
}
}
long t2 = System.nanoTime();
if(log.isInfoEnabled())
log.info("Server startup in " + ((t2 - t1) / 1000000) + " ms");
try {
// Register shutdown hook
if (useShutdownHook) {
if (shutdownHook == null) {
shutdownHook = new CatalinaShutdownHook();
}
Runtime.getRuntime().addShutdownHook(shutdownHook);
}
} catch (Throwable t) {
// This will fail on JDK 1.2. Ignoring, as Tomcat can run
// fine without the shutdown hook.
}
if (await) {
await();
stop();
}
}
/**
* Stop an existing server instance.
*/
public void stop() {
try {
// Remove the ShutdownHook first so that server.stop()
// doesn't get invoked twice
if (useShutdownHook) {
Runtime.getRuntime().removeShutdownHook(shutdownHook);
}
} catch (Throwable t) {
// This will fail on JDK 1.2. Ignoring, as Tomcat can run
// fine without the shutdown hook.
}
// Shut down the server
if (server instanceof Lifecycle) {
try {
((Lifecycle) server).stop();
} catch (LifecycleException e) {
log.error("Catalina.stop", e);
}
}
}
/**
* Await and shutdown.
*/
public void await() {
server.await();
}
/**
* Print usage information for this application.
*/
protected void usage() {
System.out.println
("usage: java org.apache.catalina.startup.Catalina"
+ " [ -config {pathname} ]"
+ " [ -nonaming ] { start | stop }");
}
// --------------------------------------- CatalinaShutdownHook Inner Class
// XXX Should be moved to embedded !
/**
* Shutdown hook which will perform a clean shutdown of Catalina if needed.
*/
protected class CatalinaShutdownHook extends Thread {
public void run() {
if (server != null) {
Catalina.this.stop();
}
}
}
private static org.jboss.logging.Logger log=
org.jboss.logging.Logger.getLogger( Catalina.class );
}
// ------------------------------------------------------------ Private Classes
/**
* Rule that sets the parent class loader for the top object on the stack,
* which must be a Container
.
*/
final class SetParentClassLoaderRule extends Rule {
public SetParentClassLoaderRule(ClassLoader parentClassLoader) {
this.parentClassLoader = parentClassLoader;
}
ClassLoader parentClassLoader = null;
public void begin(String namespace, String name, Attributes attributes)
throws Exception {
if (digester.getLogger().isDebugEnabled())
digester.getLogger().debug("Setting parent class loader");
Container top = (Container) digester.peek();
top.setParentClassLoader(parentClassLoader);
}
}