catalina.bat 在最后启动了bootstrap.jar, 传递了start作为参数(如果多个参数的话,start在尾部)。 然后org.apache.catalina.startup.Bootstrap的main方法初始化了一个bootstrap守护进程,通过调用了catalina.java对应方法。

 /*
* 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.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer; import org.apache.catalina.Globals;
import org.apache.catalina.security.SecurityClassLoad;
import org.apache.catalina.startup.ClassLoaderFactory.Repository;
import org.apache.catalina.startup.ClassLoaderFactory.RepositoryType;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory; /**
* Bootstrap loader for Catalina. This application constructs a class loader
* for use in loading the Catalina internal classes (by accumulating all of the
* JAR files found in the "server" directory under "catalina.home"), and
* starts the regular execution of the container. The purpose of this
* roundabout approach is to keep the Catalina internal classes (and any
* other classes they depend on, such as an XML parser) out of the system
* class path and therefore not visible to application level classes.
*
* @author Craig R. McClanahan
* @author Remy Maucherat
*/
public final class Bootstrap { private static final Log log = LogFactory.getLog(Bootstrap.class); // ------------------------------------------------------- Static Variables /**
* Daemon object used by main.
*/
private static Bootstrap daemon = null; // -------------------------------------------------------------- Variables /**
* Daemon reference.
*/
private Object catalinaDaemon = null; ClassLoader commonLoader = null;
ClassLoader catalinaLoader = null;
ClassLoader sharedLoader = null; // -------------------------------------------------------- Private Methods private void initClassLoaders() {
try {
commonLoader = createClassLoader("common", null);
if( commonLoader == null ) {
// no config file, default to this loader - we might be in a 'single' env.
commonLoader=this.getClass().getClassLoader();
}
catalinaLoader = createClassLoader("server", commonLoader);
sharedLoader = createClassLoader("shared", commonLoader);
} catch (Throwable t) {
handleThrowable(t);
log.error("Class loader creation threw exception", t);
System.exit();
}
} private ClassLoader createClassLoader(String name, ClassLoader parent)
throws Exception { String value = CatalinaProperties.getProperty(name + ".loader");
if ((value == null) || (value.equals("")))
return parent; value = replace(value); List<Repository> repositories = new ArrayList<Repository>(); StringTokenizer tokenizer = new StringTokenizer(value, ",");
while (tokenizer.hasMoreElements()) {
String repository = tokenizer.nextToken().trim();
if (repository.length() == ) {
continue;
} // Check for a JAR URL repository
try {
@SuppressWarnings("unused")
URL url = new URL(repository);
repositories.add(
new Repository(repository, RepositoryType.URL));
continue;
} catch (MalformedURLException e) {
// Ignore
} // Local repository
if (repository.endsWith("*.jar")) {
repository = repository.substring
(, repository.length() - "*.jar".length());
repositories.add(
new Repository(repository, RepositoryType.GLOB));
} else if (repository.endsWith(".jar")) {
repositories.add(
new Repository(repository, RepositoryType.JAR));
} else {
repositories.add(
new Repository(repository, RepositoryType.DIR));
}
} return ClassLoaderFactory.createClassLoader(repositories, parent);
} /**
* System property replacement in the given string.
*
* @param str The original string
* @return the modified string
*/
protected String replace(String str) {
// Implementation is copied from ClassLoaderLogManager.replace(),
// but added special processing for catalina.home and catalina.base.
String result = str;
int pos_start = str.indexOf("${");
if (pos_start >= ) {
StringBuilder builder = new StringBuilder();
int pos_end = -;
while (pos_start >= ) {
builder.append(str, pos_end + , pos_start);
pos_end = str.indexOf('}', pos_start + );
if (pos_end < ) {
pos_end = pos_start - ;
break;
}
String propName = str.substring(pos_start + , pos_end);
String replacement;
if (propName.length() == ) {
replacement = null;
} else if (Globals.CATALINA_HOME_PROP.equals(propName)) {
replacement = getCatalinaHome();
} else if (Globals.CATALINA_BASE_PROP.equals(propName)) {
replacement = getCatalinaBase();
} else {
replacement = System.getProperty(propName);
}
if (replacement != null) {
builder.append(replacement);
} else {
builder.append(str, pos_start, pos_end + );
}
pos_start = str.indexOf("${", pos_end + );
}
builder.append(str, pos_end + , str.length());
result = builder.toString();
}
return result;
} /**
* Initialize daemon.
*/
public void init()
throws Exception
{ // Set Catalina path
setCatalinaHome();
setCatalinaBase(); initClassLoaders(); Thread.currentThread().setContextClassLoader(catalinaLoader); SecurityClassLoad.securityClassLoad(catalinaLoader); // Load our startup class and call its process() method
if (log.isDebugEnabled())
log.debug("Loading startup class");
Class<?> startupClass =
catalinaLoader.loadClass
("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.newInstance(); // Set the shared extensions class loader
if (log.isDebugEnabled())
log.debug("Setting startup class properties");
String methodName = "setParentClassLoader";
Class<?> paramTypes[] = new Class[];
paramTypes[] = Class.forName("java.lang.ClassLoader");
Object paramValues[] = new Object[];
paramValues[] = sharedLoader;
Method method =
startupInstance.getClass().getMethod(methodName, paramTypes);
method.invoke(startupInstance, paramValues); catalinaDaemon = startupInstance; } /**
* Load daemon.
*/
private void load(String[] arguments)
throws Exception { // Call the load() method
String methodName = "load";
Object param[];
Class<?> paramTypes[];
if (arguments==null || arguments.length==) {
paramTypes = null;
param = null;
} else {
paramTypes = new Class[];
paramTypes[] = arguments.getClass();
param = new Object[];
param[] = arguments;
}
Method method =
catalinaDaemon.getClass().getMethod(methodName, paramTypes);
if (log.isDebugEnabled())
log.debug("Calling startup class " + method);
method.invoke(catalinaDaemon, param); } /**
* getServer() for configtest
*/
private Object getServer() throws Exception { String methodName = "getServer";
Method method =
catalinaDaemon.getClass().getMethod(methodName);
return method.invoke(catalinaDaemon); } // ----------------------------------------------------------- Main Program /**
* Load the Catalina daemon.
*/
public void init(String[] arguments)
throws Exception { init();
load(arguments); } /**
* Start the Catalina daemon.
*/
public void start()
throws Exception {
if( catalinaDaemon==null ) init(); Method method = catalinaDaemon.getClass().getMethod("start", (Class [] )null);
method.invoke(catalinaDaemon, (Object [])null); } /**
* Stop the Catalina Daemon.
*/
public void stop()
throws Exception { Method method = catalinaDaemon.getClass().getMethod("stop", (Class [] ) null);
method.invoke(catalinaDaemon, (Object [] ) null); } /**
* Stop the standalone server.
*/
public void stopServer()
throws Exception { Method method =
catalinaDaemon.getClass().getMethod("stopServer", (Class []) null);
method.invoke(catalinaDaemon, (Object []) null); } /**
* Stop the standalone server.
*/
public void stopServer(String[] arguments)
throws Exception { Object param[];
Class<?> paramTypes[];
if (arguments==null || arguments.length==) {
paramTypes = null;
param = null;
} else {
paramTypes = new Class[];
paramTypes[] = arguments.getClass();
param = new Object[];
param[] = arguments;
}
Method method =
catalinaDaemon.getClass().getMethod("stopServer", paramTypes);
method.invoke(catalinaDaemon, param); } /**
* Set flag.
*/
public void setAwait(boolean await)
throws Exception { Class<?> paramTypes[] = new Class[];
paramTypes[] = Boolean.TYPE;
Object paramValues[] = new Object[];
paramValues[] = Boolean.valueOf(await);
Method method =
catalinaDaemon.getClass().getMethod("setAwait", paramTypes);
method.invoke(catalinaDaemon, paramValues); } public boolean getAwait()
throws Exception
{
Class<?> paramTypes[] = new Class[];
Object paramValues[] = new Object[];
Method method =
catalinaDaemon.getClass().getMethod("getAwait", paramTypes);
Boolean b=(Boolean)method.invoke(catalinaDaemon, paramValues);
return b.booleanValue();
} /**
* Destroy the Catalina Daemon.
*/
public void destroy() { // FIXME } /**
* Main method and entry point when starting Tomcat via the provided
* scripts.
*
* @param args Command line arguments to be processed
*/
public static void main(String args[]) { if (daemon == null) {
// Don't set daemon until init() has completed
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.init();
} catch (Throwable t) {
handleThrowable(t);
t.printStackTrace();
return;
}
daemon = bootstrap;
} else {
// When running as a service the call to stop will be on a new
// thread so make sure the correct class loader is used to prevent
// a range of class not found exceptions.
Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
} try {
String command = "start";
if (args.length > ) {
command = args[args.length - ];
} if (command.equals("startd")) {
args[args.length - ] = "start";
daemon.load(args);
daemon.start();
} else if (command.equals("stopd")) {
args[args.length - ] = "stop";
daemon.stop();
} else if (command.equals("start")) {
daemon.setAwait(true);
daemon.load(args);
daemon.start();
} else if (command.equals("stop")) {
daemon.stopServer(args);
} else if (command.equals("configtest")) {
daemon.load(args);
if (null==daemon.getServer()) {
System.exit();
}
System.exit();
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
// Unwrap the Exception for clearer error reporting
if (t instanceof InvocationTargetException &&
t.getCause() != null) {
t = t.getCause();
}
handleThrowable(t);
t.printStackTrace();
System.exit();
} } public void setCatalinaHome(String s) {
System.setProperty(Globals.CATALINA_HOME_PROP, s);
} public void setCatalinaBase(String s) {
System.setProperty(Globals.CATALINA_BASE_PROP, s);
} /**
* Set the <code>catalina.base</code> System property to the current
* working directory if it has not been set.
*/
private void setCatalinaBase() { if (System.getProperty(Globals.CATALINA_BASE_PROP) != null)
return;
if (System.getProperty(Globals.CATALINA_HOME_PROP) != null)
System.setProperty(Globals.CATALINA_BASE_PROP,
System.getProperty(Globals.CATALINA_HOME_PROP));
else
System.setProperty(Globals.CATALINA_BASE_PROP,
System.getProperty("user.dir")); } /**
* Set the <code>catalina.home</code> System property to the current
* working directory if it has not been set.
*/
private void setCatalinaHome() { if (System.getProperty(Globals.CATALINA_HOME_PROP) != null)
return;
File bootstrapJar =
new File(System.getProperty("user.dir"), "bootstrap.jar");
if (bootstrapJar.exists()) {
try {
System.setProperty
(Globals.CATALINA_HOME_PROP,
(new File(System.getProperty("user.dir"), ".."))
.getCanonicalPath());
} catch (Exception e) {
// Ignore
System.setProperty(Globals.CATALINA_HOME_PROP,
System.getProperty("user.dir"));
}
} else {
System.setProperty(Globals.CATALINA_HOME_PROP,
System.getProperty("user.dir"));
} } /**
* Get the value of the catalina.home environment variable.
*/
public static String getCatalinaHome() {
return System.getProperty(Globals.CATALINA_HOME_PROP,
System.getProperty("user.dir"));
} /**
* Get the value of the catalina.base environment variable.
*/
public static String getCatalinaBase() {
return System.getProperty(Globals.CATALINA_BASE_PROP, getCatalinaHome());
} // Copied from ExceptionUtils since that class is not visible during start
private static void handleThrowable(Throwable t) {
if (t instanceof ThreadDeath) {
throw (ThreadDeath) t;
}
if (t instanceof VirtualMachineError) {
throw (VirtualMachineError) t;
}
// All other instances of Throwable will be silently swallowed
}
}

Bootstrap

/*

* 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.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.ArrayList;

import java.util.List;

import java.util.StringTokenizer;

import org.apache.catalina.Globals;

import org.apache.catalina.security.SecurityClassLoad;

import org.apache.catalina.startup.ClassLoaderFactory.Repository;

import org.apache.catalina.startup.ClassLoaderFactory.RepositoryType;

import org.apache.juli.logging.Log;

import org.apache.juli.logging.LogFactory;

/**

* Bootstrap loader for Catalina.  This application constructs a class loader

* for use in loading the Catalina internal classes (by accumulating all of the

* JAR files found in the "server" directory under "catalina.home"), and

* starts the regular execution of the container.  The purpose of this

* roundabout approach is to keep the Catalina internal classes (and any

* other classes they depend on, such as an XML parser) out of the system

* class path and therefore not visible to application level classes.

*

* @author Craig R. McClanahan

* @author Remy Maucherat

*/

// Catalina的Bootstrap加载器。这个应用为加载Catalina的内部类(通过累加“catalina.home”下的jar文件)构造了一个类加载器,并启动了容器。

// 这种间接做法的目的是使catalina的内部类(和它依赖的其他类,必须Xml转化器)与系统的class path分离,与应用级别的类互相不能访问。

public final class Bootstrap {

private static final Log log = LogFactory.getLog(Bootstrap.class);

// ------------------------------------------------------- Static Variables

/**

* Daemon object used by main.

*/

private static Bootstrap daemon = null;

// -------------------------------------------------------------- Variables

/**

* Daemon reference.

*/

private Object catalinaDaemon = null;

ClassLoader commonLoader = null;

ClassLoader catalinaLoader = null;

ClassLoader sharedLoader = null;

// -------------------------------------------------------- Private Methods

private void initClassLoaders() {

try {

commonLoader = createClassLoader("common", null);

if( commonLoader == null ) {

// no config file, default to this loader - we might be in a 'single' env.

commonLoader=this.getClass().getClassLoader();

}

catalinaLoader = createClassLoader("server", commonLoader); // 在tomcat 7x的catalina.properties中server.loader为空

sharedLoader = createClassLoader("shared", commonLoader); // 在tomcat 7x的catalina.properties中shared.loader为空

} catch (Throwable t) {

handleThrowable(t);

log.error("Class loader creation threw exception", t);

System.exit(1);

}

}

  // 如果配置文件中没有name+".loader"属性, 返回parent

private ClassLoader createClassLoader(String name, ClassLoader parent)

throws Exception {

String value = CatalinaProperties.getProperty(name + ".loader");

if ((value == null) || (value.equals("")))

return parent;

value = replace(value); // 替换catalina.home和catalina.base

List<Repository> repositories = new ArrayList<Repository>();

StringTokenizer tokenizer = new StringTokenizer(value, ","); // 处理value把结尾不同的值放进不同的Repository

while (tokenizer.hasMoreElements()) {

String repository = tokenizer.nextToken().trim();

if (repository.length() == 0) {

continue;

}

// Check for a JAR URL repository

try {

@SuppressWarnings("unused")

URL url = new URL(repository);

repositories.add(

new Repository(repository, RepositoryType.URL));

continue;

} catch (MalformedURLException e) {

// Ignore

}

// Local repository

if (repository.endsWith("*.jar")) {

repository = repository.substring

(0, repository.length() - "*.jar".length());

repositories.add(

new Repository(repository, RepositoryType.GLOB));

} else if (repository.endsWith(".jar")) {

repositories.add(

new Repository(repository, RepositoryType.JAR));

} else {

repositories.add(

new Repository(repository, RepositoryType.DIR));

}

}

return ClassLoaderFactory.createClassLoader(repositories, parent); // 特权化

}

/**

* System property replacement in the given string.

*

* @param str The original string

* @return the modified string

*/

protected String replace(String str) {

// Implementation is copied from ClassLoaderLogManager.replace(),

// but added special processing for catalina.home and catalina.base.

String result = str;

int pos_start = str.indexOf("${");

if (pos_start >= 0) {

StringBuilder builder = new StringBuilder();

int pos_end = -1;

while (pos_start >= 0) {

builder.append(str, pos_end + 1, pos_start);

pos_end = str.indexOf('}', pos_start + 2);

if (pos_end < 0) {

pos_end = pos_start - 1;

break;

}

String propName = str.substring(pos_start + 2, pos_end);

String replacement;

if (propName.length() == 0) {

replacement = null;

} else if (Globals.CATALINA_HOME_PROP.equals(propName)) {

replacement = getCatalinaHome();

} else if (Globals.CATALINA_BASE_PROP.equals(propName)) {

replacement = getCatalinaBase();

} else {

replacement = System.getProperty(propName);

}

if (replacement != null) {

builder.append(replacement);

} else {

builder.append(str, pos_start, pos_end + 1);

}

pos_start = str.indexOf("${", pos_end + 1);

}

builder.append(str, pos_end + 1, str.length());

result = builder.toString();

}

return result;

}

/**

* Initialize daemon.

*/

public void init()

throws Exception

{

// Set Catalina path

setCatalinaHome(); // 设置catalina.home, 在catalina.bat启动Bootstarp.java时通过-Dcatalina.home传入; 没有就重新设置

setCatalinaBase(); // 设置catalina.base, 在catalina.bat启动Bootstarp.java时通过-Dcatalina.base传入; 没有就重新设置

initClassLoaders(); // 使用catalina.properties初始化了3个ClassLoader, 在tomcat7x中catalina.loader和server.loader为空;

// 所以catalinaLoader = commonLoader; sharedLoader = commonLoader;

// commonLoader没有parent classLoader, catalinaLoader和sharedLoader的parent classLoader是commonLoader

Thread.currentThread().setContextClassLoader(catalinaLoader);

SecurityClassLoad.securityClassLoad(catalinaLoader);

// Load our startup class and call its process() method

if (log.isDebugEnabled())

log.debug("Loading startup class");

Class<?> startupClass =

catalinaLoader.loadClass

("org.apache.catalina.startup.Catalina");

Object startupInstance = startupClass.newInstance();

// Set the shared extensions class loader

if (log.isDebugEnabled())

log.debug("Setting startup class properties");

String methodName = "setParentClassLoader";

Class<?> paramTypes[] = new Class[1];

paramTypes[0] = Class.forName("java.lang.ClassLoader");

Object paramValues[] = new Object[1];

paramValues[0] = sharedLoader;

Method method =

startupInstance.getClass().getMethod(methodName, paramTypes);

method.invoke(startupInstance, paramValues); // 调用Catalina.setParentClassLoader(), sharedLoader作为参数, 参数类型是ClassLoader

catalinaDaemon = startupInstance; // catalina守护进程

}

/**

* Load daemon.

*/

private void load(String[] arguments)

throws Exception {

// Call the load() method

String methodName = "load";

Object param[];

Class<?> paramTypes[];

if (arguments==null || arguments.length==0) {

paramTypes = null;

param = null;

} else {

paramTypes = new Class[1];

paramTypes[0] = arguments.getClass();

param = new Object[1];

param[0] = arguments;

}

Method method =

catalinaDaemon.getClass().getMethod(methodName, paramTypes);

if (log.isDebugEnabled())

log.debug("Calling startup class " + method);

method.invoke(catalinaDaemon, param); // catalina.java 下有俩个load方法, 一个有参一个无参

}

/**

* getServer() for configtest

*/

private Object getServer() throws Exception {

String methodName = "getServer";

Method method =

catalinaDaemon.getClass().getMethod(methodName);

return method.invoke(catalinaDaemon);

}

// ----------------------------------------------------------- Main Program

/**

* Load the Catalina daemon.

*/

public void init(String[] arguments)

throws Exception {

init();

load(arguments);

}

/**

* Start the Catalina daemon.

*/

public void start()

throws Exception {

if( catalinaDaemon==null ) init();

Method method = catalinaDaemon.getClass().getMethod("start", (Class [] )null);

method.invoke(catalinaDaemon, (Object [])null);

}

/**

* Stop the Catalina Daemon.

*/

public void stop()

throws Exception {

Method method = catalinaDaemon.getClass().getMethod("stop", (Class [] ) null);

method.invoke(catalinaDaemon, (Object [] ) null);

}

/**

* Stop the standalone server.

*/

public void stopServer()

throws Exception {

Method method =

catalinaDaemon.getClass().getMethod("stopServer", (Class []) null);

method.invoke(catalinaDaemon, (Object []) null);

}

/**

* Stop the standalone server.

*/

public void stopServer(String[] arguments)

throws Exception {

Object param[];

Class<?> paramTypes[];

if (arguments==null || arguments.length==0) {

paramTypes = null;

param = null;

} else {

paramTypes = new Class[1];

paramTypes[0] = arguments.getClass();

param = new Object[1];

param[0] = arguments;

}

Method method =

catalinaDaemon.getClass().getMethod("stopServer", paramTypes);

method.invoke(catalinaDaemon, param);

}

/**

* Set flag.

*/

public void setAwait(boolean await)

throws Exception {

Class<?> paramTypes[] = new Class[1];

paramTypes[0] = Boolean.TYPE;

Object paramValues[] = new Object[1];

paramValues[0] = Boolean.valueOf(await);

Method method =

catalinaDaemon.getClass().getMethod("setAwait", paramTypes);

method.invoke(catalinaDaemon, paramValues);

}

public boolean getAwait()

throws Exception

{

Class<?> paramTypes[] = new Class[0];

Object paramValues[] = new Object[0];

Method method =

catalinaDaemon.getClass().getMethod("getAwait", paramTypes);

Boolean b=(Boolean)method.invoke(catalinaDaemon, paramValues);

return b.booleanValue();

}

/**

* Destroy the Catalina Daemon.

*/

public void destroy() {

// FIXME

}

/**

* Main method and entry point when starting Tomcat via the provided

* scripts.

*

* @param args Command line arguments to be processed

*/

public static void main(String args[]) {

if (daemon == null) { // stop时不为空

// Don't set daemon until init() has completed

Bootstrap bootstrap = new Bootstrap();

try {

bootstrap.init(); // 执行init()

} catch (Throwable t) {

handleThrowable(t);

t.printStackTrace();

return;

}

daemon = bootstrap; // 守护进程

} else {

// When running as a service the call to stop will be on a new

// thread so make sure the correct class loader is used to prevent

// a range of class not found exceptions.

Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);

}

try { // catalina.bat把start作为最后一个参数启动

String command = "start";

if (args.length > 0) {

command = args[args.length - 1];

}

// 根据不同参数, 调用catalina.java中的同名方法; command = startd或start或onfigtest时, 先通过反射调用catalina.load方法

if (command.equals("startd")) {

args[args.length - 1] = "start";

daemon.load(args);

daemon.start();

} else if (command.equals("stopd")) {

args[args.length - 1] = "stop";

daemon.stop();

} else if (command.equals("start")) {

daemon.setAwait(true);

daemon.load(args);

daemon.start();

} else if (command.equals("stop")) {

daemon.stopServer(args);

} else if (command.equals("configtest")) {

daemon.load(args);

if (null==daemon.getServer()) {

System.exit(1);

}

System.exit(0);

} else {

log.warn("Bootstrap: command \"" + command + "\" does not exist.");

}

} catch (Throwable t) {

// Unwrap the Exception for clearer error reporting

if (t instanceof InvocationTargetException &&

t.getCause() != null) {

t = t.getCause();

}

handleThrowable(t);

t.printStackTrace();

System.exit(1);

}

}

public void setCatalinaHome(String s) {

System.setProperty(Globals.CATALINA_HOME_PROP, s);

}

public void setCatalinaBase(String s) {

System.setProperty(Globals.CATALINA_BASE_PROP, s);

}

/**

* Set the <code>catalina.base</code> System property to the current

* working directory if it has not been set.

*/

private void setCatalinaBase() {

if (System.getProperty(Globals.CATALINA_BASE_PROP) != null)

return;

if (System.getProperty(Globals.CATALINA_HOME_PROP) != null)

System.setProperty(Globals.CATALINA_BASE_PROP,

System.getProperty(Globals.CATALINA_HOME_PROP));

else

System.setProperty(Globals.CATALINA_BASE_PROP,

System.getProperty("user.dir"));

}

/**

* Set the <code>catalina.home</code> System property to the current

* working directory if it has not been set.

*/

private void setCatalinaHome() {

if (System.getProperty(Globals.CATALINA_HOME_PROP) != null)

return;

File bootstrapJar =

new File(System.getProperty("user.dir"), "bootstrap.jar");

if (bootstrapJar.exists()) {

try {

System.setProperty // 设置catalina.home为user.dir的父目录

(Globals.CATALINA_HOME_PROP,

(new File(System.getProperty("user.dir"), ".."))

.getCanonicalPath());

} catch (Exception e) {

// Ignore

System.setProperty(Globals.CATALINA_HOME_PROP,

System.getProperty("user.dir"));

}

} else {

System.setProperty(Globals.CATALINA_HOME_PROP,

System.getProperty("user.dir"));

}

}

/**

* Get the value of the catalina.home environment variable.

*/

public static String getCatalinaHome() {

return System.getProperty(Globals.CATALINA_HOME_PROP,

System.getProperty("user.dir"));

}

/**

* Get the value of the catalina.base environment variable.

*/

public static String getCatalinaBase() {

return System.getProperty(Globals.CATALINA_BASE_PROP, getCatalinaHome());

}

// Copied from ExceptionUtils since that class is not visible during start

private static void handleThrowable(Throwable t) {

if (t instanceof ThreadDeath) {

throw (ThreadDeath) t;

}

if (t instanceof VirtualMachineError) {

throw (VirtualMachineError) t;

}

// All other instances of Throwable will be silently swallowed

}

}

(三)Bootstrap.jar的更多相关文章

  1. (三)Bootstrap.jar

    catalina.bat 在最后启动了bootstrap.jar, 传递了start作为参数(如果多个参数的话,start在尾部). 然后org.apache.catalina.startup.Boo ...

  2. 【转】Eclipse下启动tomcat报错:/bin/bootstrap.jar which is referenced by the classpath, does not exist.

    转载地址:http://blog.csdn.net/jnqqls/article/details/8946964 1.错误: 在Eclipse下启动tomcat的时候,报错为:Eclipse下启动to ...

  3. 解决Eclipse下启动tomcat报错:/bin/bootstrap.jar which is referenced by the classpath, does not exist.

    1.错误症状:右击tomcat server,选择start,出现下图所示错误 2.错误原因: 我为了方便管理,把tomcat安装到了当前的eclipse-project目录下:E:/workspac ...

  4. 在IDEA中用三个jar包链接MongoDB数据库——实现增删改查

    安装Robo 3T连接MongoDB数据库教程:https://blog.csdn.net/baidu_39298625/article/details/98845789 使用Robo 3T操作Mon ...

  5. 响应式开发(三)-----Bootstrap框架的安装使用

    下载 Bootstrap 可以从http://getbootstrap.com/上下载 Bootstrap 的最新版本. Download Bootstrap:下载 Bootstrap.点击该按钮,您 ...

  6. mave之:java的web项目必须要的三个jar的pom形式

    jsp-api javax.servlet-api jstl <!-- jsp --> <dependency> <groupId>javax.servlet< ...

  7. web项目与jsp有关的三个jar的依赖

    <!-- jsp --> <dependency> <groupId>javax.servlet</groupId> <artifactId> ...

  8. 项目打jar包,怎么把第三放jar包一起打入

    <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> < ...

  9. Tomcat内存溢出的三种情况及解决办法分析

    Tomcat内存溢出的原因 在生产环境中tomcat内存设置不好很容易出现内存溢出.造成内存溢出是不一样的,当然处理方式也不一样. 这里根据平时遇到的情况和相关资料进行一个总结.常见的一般会有下面三种 ...

随机推荐

  1. python之数据类型详解

    python之数据类型详解 二.列表list  (可以存储多个值)(列表内数字不需要加引号) sort s1=[','!'] # s1.sort() # print(s1) -->['!', ' ...

  2. python slenium 中CSS定位

    以百度为例 一.通过id.class定位 1.#id:python:driver.find_element_by_css_selector('input#kw') 2..class:python:dr ...

  3. iis7.5 配置伪静态

    1)首先新建一个应用程序池,名称任意,比如:nettest,托管管道模式先暂时设置为集成模式,等下面的一系列设置完成之后再设置成经典模式: 2)部署好站点,并将此站点的应用程序池设置为nettest; ...

  4. SQLALchemy中关于复杂关系表模型的映射处理

    映射在第五步,我们还是一步一步来哈 一. 关系介绍 举一个比较经典的关系,部门与员工(以下是我的需求情况,算是把该有的关系都涉及到了) 1.每个部门会有很多成员(这里排除一个成员属于多个部门的情况) ...

  5. mysql导入excel表格

    https://jingyan.baidu.com/album/fc07f9891cb56412ffe5199a.html?picindex=1

  6. 1. vs code 设置快捷键与eclipse一样

    keybindings.json文件路径在:C:\Users\Administrator\AppData\Roaming\Code\User\keybindings.json { "key& ...

  7. Mac 系统下创建可双击执行文件,cd到执行文件当前目录

    在mac下之前我一直用.sh文件,但是要去终端里才能执行,后来得知可以写.command文件,双击及可执行,很方便,特此记录 #!/bin/bash basepath=$(cd `dirname $0 ...

  8. nginx的命令

  9. Jmeter分布式部署- linux

    https://www.cnblogs.com/beginner-boy/p/7836276.html https://www.cnblogs.com/wuhenyan/p/6419368.html ...

  10. [JavaScript,Java,C#,C++,Ruby,Perl,PHP,Python][转]流式接口(Fluent interface)

    原文:https://en.m.wikipedia.org/wiki/Fluent_interface(英文,完整) 转载:https://zh.wikipedia.org/wiki/流式接口(中文, ...