【Tomcat】《How Tomcat Works》英文版GPT翻译(第十七章)

2024-01-29 16:21:10 浏览数 (1)

Chapter 17: Tomcat Startup

Overview

This chapter focuses on Tomcat startup using two classes in the org.apache.catalina.startup package, Catalina and Bootstrap. The Catalina class is used to start and stop a Server object as well as parse the Tomcat configuration file, server.xml. The Bootstrap class is the entry point that creates an instance of Catalina and calls its process method. In theory, these two classes could have been merged. However, to support more than one mode of running Tomcat, a number of bootstrap classes are provided. For example, the aforementioned Bootstrap class is used for running Tomcat as a stand-alone application. Another class, org.apache.catalina.startup.BootstrapService, is used to run Tomcat as a Windows NT service.

本章重点介绍使用org.apache.catalina.startup包中的两个类CatalinaBootstrap 来启动 Tomcat

Catalina 类用于启动和停止一个Server对象,同时解析Tomcat的配置文件server.xml。

Bootstrap类是入口点,它创建Catalina的一个实例并调用其process方法。

理论上,这两个类可以合并。

然而,为了支持多种Tomcat运行模式,提供了许多引导类。

例如,上述的Bootstrap类用于作为独立应用程序运行Tomcat。另一个类org.apache.catalina.startup.BootstrapService用于将Tomcat作为Windows NT服务运行。

For user's convenience, Tomcat also comes with the batch files and shell scripts to start and stop the servlet container easily. With the help of these batch files and shell scripts, the user does not need to remember the options for the java.exe program to run the Bootstrap class. Instead, he/she can just run the appropriate batch file or shell script.

为了方便用户,Tomcat还提供了批处理文件和shell脚本,以便轻松启动和停止servlet容器。

借助这些批处理文件和shell脚本,用户无需记住java.exe程序运行Bootstrap类的选项,只需运行相应的批处理文件或shell脚本。

The first section of this chapter discusses the Catalina class and the second the Bootstrap class. To understand the topic of discussion in this chapter, make sure you have read Chapter 14 on servers and services, Chapter 15 on Digester, and Chapter 16 on shutdown hooks. The chapter also discusses how to run Tomcat on Windows and Unix/Linux in two sections. One section is dedicated to the discussion of batch files to start and stop Tomcat on Windows. The other section explains the shell scripts on Unix/Linux.

本章的第一部分讨论了Catalina类,第二部分讨论了Bootstrap类。

要理解本章讨论的主题,请确保您已经阅读了第14章关于服务器和服务、第15章关于解析器和第16章关于关闭挂钩的内容。

本章还讨论了如何在Windows和Unix/Linux上运行Tomcat,分为两个部分。

一个部分专门讨论了在Windows上启动和停止Tomcat的批处理文件。

另一个部分解释了Unix/Linux上的shell脚本。

The Catalina Class(卡塔琳娜级)

The org.apache.catalina.startup.Catalina class is the startup class. It contains a Digester that parses the server.xml file in the �TALINE_HOME%/conf directory. By understanding the rules added to this Digester, you can configure Tomcat the way you want it to be.

org.apache.catalina.startup.Catalina类是启动类。

它包含一个解析位于�TALINE_HOME%/conf目录下的server.xml文件的Digester。

通过理解添加到该Digester的规则,您可以按照自己的喜好配置Tomcat。

The Catalina class also encapsulates a Server object that will have a Service. As mentioned in Chapter 15, a Service object contains a container and one or more connectors. You use Catalina to start and stop the Server object.

Catalina类还封装了一个具有一个或多个连接器的容器的Server对象。

如第15章所述,Service对象包含一个容器和一个或多个连接器。

您可以使用Catalina来启动和停止Server对象。

You run Tomcat by instantiating the Catalina class and then calling its process method. You must pass the appropriate argument when calling this method. The first argument is start if you want to start Tomcat and stop if you want to send a shutdown command to stop it. There are also other acceptable arguments, such as -help, -config, -debug, and -nonaming.

通过实例化Catalina类并调用其process方法来运行Tomcat。

在调用此方法时,必须传递适当的参数。

如果要启动Tomcat,则第一个参数为start;如果要发送关闭命令以停止Tomcat,则为stop。

还有其他可接受的参数,如-help、-config、-debug和-nonaming。

Note The nonaming argument, when present, specifies that JNDI naming should not be supported. See the org.apache.naming package for more information on how JNDI naming is supported in Tomcat. 注意 当存在nonaming参数时,指定不支持JNDI命名。 有关Tomcat中如何支持JNDI命名的更多信息,请参阅org.apache.naming包。

Normally, you will need a Bootstrap class to instantiate Catalina and call its process method, even though the Catalina class has its own main method that provides an entry point. One of the Bootstrap classes is explained in the next section. You will also find out what the Bootstrap does in this section.

通常,您需要一个引导类来实例化Catalina并调用其process方法,即使Catalina类有自己的main方法作为入口点。

下一节将解释其中一个引导类的作用。您还将在本节了解引导类的功能。

The process method in the Catalina class in Tomcat 4 is given in Listing 17.1.

Tomcat 4中Catalina类的process方法如下所示(见代码清单17.1)。

Listing 17.1: The process method of the Catalina class

清单 17.1: Catalina 类的进程方法

代码语言:javascript复制
public void process(String args[]) {
 setCatalinaHome();
 setCatalinaBase();
 try {
 if (arguments(args))
 execute();
 }
 catch (Exception e) {
 e.printStackTrace(System.out);
 }
}

The process method sets two system properties, catalina.home and catalina.base.catalina.home defaults to the value of the user.dir property. The catalina.base property is assigned the value of catalina.home. Therefore, both properties have the value of the user.dir property.

process方法设置了两个系统属性,catalina.home和catalina.base。

catalina.home默认值为user.dir属性的值。

catalina.base属性被赋予catalina.home的值。

因此,这两个属性的值都是user.dir属性的值。

Note The user.dir system property refers to the user's working directory, i.e. the directory from which the java command is invoked. For the list of system properties, see the getProperties method of the java.lang.System class in the J2SE 1.4 API Specification documentation. 注意:user.dir系统属性指的是用户的工作目录,即执行java命令的目录。有关系统属性的列表,请参阅J2SE 1.4 API规范文档中java.lang.System类的getProperties方法。

The process method then calls the arguments method, passing the list of arguments. The arguments method, given in Listing 17.2, processes the command line arguments and returns true if the Catalina object should continue processing.

然后,process方法调用arguments方法,并传递参数列表。

arguments方法在17.2节中给出,它处理命令行参数,并在Catalina对象应继续处理时返回true。

Listing 17.2: The arguments method

清单 17.2: 参数方法

代码语言:javascript复制
  
    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("-debug")) {  
                debug = true;  
            }  
            else if (args[i].equals("-nonaming")) {  
                useNaming = false;  
            }  
            else if (args[i].equals("-help")) {  
                usage();  
                return (false);  
            }  
            else if (args[i].equals("start")) {  
                starting = true;  
            }  
            else if (args[i].equals("stop")) {  
                stopping = true;  
            }  
            else {  
                usage();  
                return (false);  
            }  
        }  
        return (true);  
    }

The process method examines the return value of the arguments method and calls the execute method if the arguments method returns true. The execute method is given in Listing 17.3.

process 方法检查 arguments 方法的返回值,如果 arguments 方法返回 true,则调用 execute 方法。执行方法见清单 17.3。

Listing 17.3: The execute method

清单 17.3:执行方法

代码语言:javascript复制
protected void execute() throws Exception {
  if (starting)
   start(); 
  else if (stopping)
   stop();
}

The execute method either calls the start method to start Tomcat or the stop method to stop Tomcat. The two methods are discussed in the following subsections.

执行方法要么调用 start 方法启动 Tomcat,要么调用 stop 方法停止 Tomcat。

下面的小节将讨论这两种方法。

Note In Tomcat 5, there is no more the execute method. The start or stop method is called from the process method. 注意 在 Tomcat 5 中,不再有 execute 方法。 start 或 stop 方法由 process 方法调用。

The start Method(启动方法)

The start method creates a Digester instance to process the server.xml file (Tomcat configuration file). Prior to parsing the XML file, the start method calls the push method on the Digester, passing the current Catalina object. This will cause the Catalina object to be the first object in the Digester's internal object stack. The parsing will result in the server variable to reference a Server object, which is by default will be of type org.apache.catalina.core.StandardServer. The start method will then call the initialize and start methods of the Server object. The start method in Catalina then continues by calling the await method on the Server object, causing the Server object to dedicate a thread to wait for a shutdown command. The await method does not return until a shutdown command is received. When the await method does return, the start method in Catalina calls the stop method of the Server object, which in effect stops the Server object and all other components. The start method also employs a shutdown hook to make sure the stop method of the Server object is executed should the user exit the application abruptly.

start方法创建一个Digester实例来处理server.xml文件(Tomcat配置文件)。

在解析XML文件之前,start方法在Digester上调用push方法,传递当前的Catalina对象。

这将导致Catalina对象成为Digester内部对象堆栈中的第一个对象。

解析将导致server变量引用一个Server对象,默认情况下,它将是org.apache.catalina.core.StandardServer类型。

然后,start方法将调用Server对象的initialize和start方法。

Catalina中的start方法继续通过调用Server对象的await方法,使Server对象专用一个线程等待关闭命令。

await方法直到接收到关闭命令才返回。

当await方法返回时,Catalina中的start方法调用Server对象的stop方法,实际上停止Server对象和所有其他组件。

start方法还使用一个shutdown hook来确保在用户突然退出应用程序时执行Server对象的stop方法。

The start method is given in Listing 17.4.

start方法的代码如17.4节所示。

Listing 17.4: The start method

清单 17.4:启动方法

代码语言:javascript复制


    protected void start() {
        // Create and execute our Digester
        Digester digester = createStartDigester();
        File file = configFile();
        try {
            InputSource is =
                    new InputSource("file://"   file.getAbsolutePath());
            FileInputStream fis = new FileInputStream(file);
            is.setByteStream(fis);
            digester.push(this);
            digester.parse(is);
            fis.close();
        }
        catch (Exception e) {
            System.out.println("Catalina.start: "   e);
            e.printstackTrace(System.out);
            System.exit(1);
        }
        // Setting additional variables
        if (!useNaming) {
            System.setProperty("catalina.useNaming", "false");
        }
        else {
            System.setProperty("catalina.useNaming", "true");
            String value = "org.apache.naming";
            String oldValue =
                    System.getProperty(javax.naming.Context.URL_PKG_PREFIXES);
            if (oldValue != null) {
                value = value   ":"   oldValue;
            }
            System.setProperty(javax.naming.Context.URL_PKG_PREFIXES, value);
            value = System.getProperty
                    (javax.naming.Context.INITIAL_CONTEXT_FACTORY);
            if (value == null) {
                System.setProperty
                        (javax.naming.Context.INITIAL_CONTEXT_FACTORY,
                                "org.apache.naming.java.javaURLContextFactory");
            }
        }
        // If a SecurityManager is being used, set properties for
        // checkPackageAccess() and checkPackageDefinition
        if( System.getSecurityManager() != null ) {
            String access = Security.getProperty("package.access");
            if( access != null && access.length() > 0 )
                access  = ",";
            else
                access = "sun.,";
            Security.setProperty("package.access",
                    access   "org.apache.catalina.,org.apache.jasper.");
            String definition = Security.getProperty("package.definition");
            if( definition != null && definition.length() > 0 )
                definition  = ",";
            else
                definition = "sun.,";
            Security.setProperty("package.definition",
                    // FIX ME package "javax." was removed to prevent HotSpot
                    // fatal internal errors
                    definition   "java.,org.apache.catalina.,org.apache.jasper.");
        }
        // Replace System.out and System.err with a custom PrintStream
        SystemLogHandler log = new SystemLogHandler(System.out);
        System.setOut(log);
        System.setErr(log);
        Thread shutdownHook = new CatalinaShutdownHook();
        // Start the new server
        if (server instanceof Lifecycle) {
            try {
                server.initialize();
                ((Lifecycle) server).start();
                try {
                    // Register shutdown hook
                    Runtime.getRuntime().addShutdownHook(shutdownHook);
                }
                catch (Throwable t) {
                    // This will fail on JDK 1.2. Ignoring, as Tomcat can run
                    // fine without the shutdown hook.
                }
                // Wait for the server to be told to shut down
                server.await();
            }
            catch (LifecycleException e) {
                System.out.println("Catalina.start: "   e);
                e.printStackTrace(System.out);
                if (e.getThrowable() != null) {
                    System.out.println("----- Root Cause -----");
                    e.getThrowable().printStackTrace(System.out);
                }
            }
        }
        // Shut down the server
        if (server instanceof Lifecycle) {
            try {
                try {
                    // Remove the ShutdownHook first so that server.stop()
                    // doesn't get invoked twice
                    Runtime.getRuntime().removeShutdownHook(shutdownHook);
                }
                catch (Throwable t) {
                    // This will fail on JDK 1.2. Ignoring, as Tomcat can run
                    // fine without the shutdown hook.
                }
                ((Lifecycle) server).stop();
            }
            catch (LifecycleException e) {
                System.out.println("Catalina.stop: "   e);
                e.printStackTrace(System.out);
                if (e.getThrowable() != null) {
                    System.out.println("----- Root Cause -----");
                    e.getThrowable().printStackTrace(System.out);
                }
            }
        }
    }

The stop Method(停止方法)

The stop method stops the Catalina and causes the Server object to stop. The stop method is given in Listing 17.5

stop 方法会停止 Catalina 并导致服务器对象停止。

清单 17.5 给出了 stop 方法

Listing 17.5: The stop Method

清单 17.5:stop 方法

代码语言:javascript复制

    protected void stop() {
        // Create and execute our Digester
        Digester digester = createStopDigester();
        File file = configFile();
        try {
            InputSource is =
                    new InputSource("file://"   file.getAbsolutePath());
            FileInputStream fis = new FileInputStream(file);
            is.setByteStream(fis);
            digester.push(this);
            digester.parse(is);
            fis.close();
        }
        catch (Exception e) {
            System.out.println("Catalina.stop: "   e);
            e.printStackTrace(System.out);
            System.exit(1);
        }
        // Stop the existing server
        try {
            Socket socket = new Socket("127.0.0.1", server.getPort());
            OutputStream stream = socket.getoutputStream();
            String shutdown = server.getShutdown();
            for (int i = 0; i < shutdown.length(); i  )
                stream.write(shutdown.charAt(i));
            stream.flush();
            stream.close();
            socket.close();
        }
        catch (IOException e) {
            System.out.println("Catalina.stop: "   e);
            e.printStackTrace(System.out);
            System.exit(1);
        }
    }

Notice that the stop method creates a Digester instance by calling the createStopDigester method, pushes the current Catalina object to the Digester internal stack by calling the push method on the Digester and parses the configuration file. The rules added to the Digester are discussed in the subsection, "Stop Digester

请注意,停止方法通过调用 createStopDigester 方法创建 Digester 实例,通过调用 Digester 上的 push 方法将当前 Catalina 对象推送到 Digester 内部堆栈,并解析配置文件。

添加到 Digester 的规则将在 "停止 Digester "小节中讨论。

The stop method then stops the running Server object by sending a shutdown command.

然后,stop 方法会通过发送 shutdown 命令来停止正在运行的服务器对象。

Start Digester(启动消解器)

The createStartDigester in Catalina method creates a Digester instance and then adds to it rules for parsing the server.xml file. This XML document is used for Tomcat configuration and located in the �TALINE_HOME%/conf directory. The rules added to the Digester are key to understanding Tomcat configuration.

Catalina 方法中的 createStartDigester 会创建一个 Digester 实例,然后为其添加用于解析 server.xml 文件的规则。

该 XML 文件用于 Tomcat 配置,位于 �TALINE_HOME%/conf 目录中。

添加到 Digester 的规则是理解 Tomcat 配置的关键。

The createStartDigester method is presented in Listing 17.6.

清单 17.6 介绍了 createStartDigester 方法。

Listing 17.6: The createStartDigester method

清单 17.6:createStartDigester 方法

代码语言:javascript复制

    protected Digester createStartDigester() {
        // Initialize the digester
        Digester digester = new Digester();
        if (debug)
            digester.setDebug(999);
        digester.setValidating(false);
        // Configure the actions we will be using
        digester.addObjectCreate("Server",
                "org.apache.catalina.core.StandardServer", "className");
        digester.addSetProperties("Server");
        digester.addSetNext("Server", "setServer",
                "org.apache.catalina.Server");
        digester.addObjectCreate("Server/GlobalNamingResources",
                "org.apache.catalina.deploy.NamingResources");
        digester.addSetProperties("Server/GlobalNamingResources");
        digester.addSetNext("Server/GlobalNamingResources",
                "setGlobalNamingResources",
                "org.apache.catalina.deploy.NamingResources");
        digester.addObjectCreate("Server/Listener", null, "className");
        digester.addSetProperties("Server/Listener");
        digester.addSetNext("Server/Listener",
                "addLifecycleListener",
                "org.apache.catalina.LifecycleListener");
        digester.addObjectCreate("Server/Service",
                "org.apache.catalina.core.StandardService", "className");
        digester.addSetProperties("Server/Service");
        digester.addSetNext("Server/Service", "addService",
                "org.apache.catalina.Service");
        digester.addObjectCreate("Server/Service/Listener",
                null, "className");
        digester.addSetProperties("Server/Service/Listener");
        digester.addSetNext("Server/Service/Listener",
                "addLifecycleListener", "org.apache.catalina.LifecycleListener");
        digester.addObjectCreate("Server/Service/Connector",
                "org.apache.catalina.connector.http.HttpConnector",
                "className");
        digester.addSetProperties("Server/Service/Connector");
        digester.addSetNext("Server/Service/Connector",
                "addConnector", "org.apache.catalina.Connector");
        digester.addObjectCreate("Server/Service/Connector/Factory",
                "org.apache.catalina.net.DefaultServerSocketFactory",
                "className");
        digester.addSetProperties("Server/Service/Connector/Factory");
        digester.addSetNext("Server/Service/Connector/Factory",
                "setFactory", "org.apache.catalina.net.ServerSocketFactory");
        digester.addObjectCreate("Server/Service/Connector/Listener",
                null, "className");
        digester.addSetProperties("Server/Service/Connector/Listener");
        digester.addSetNext("Server/Service/Connector/Listener",
                "addLifecycleListener", "org.apache.catalina.LifecycleListener");
        // Add RuleSets for nested elements
        digester.addRuleSet(
                new NamingRuleSet("Server/GlobalNamingResources/"));
        digester.addRuleSet(new EngineRuleSet("Server/Service/"));
        digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"));
        digester.addRuleSet(new
                ContextRuleSet("Server/Service/Engine/Default"));
        digester.addRuleSet(
                new NamingRuleSet("Server/Service/Engine/DefaultContext/"));
        digester.addRuleSet(
                new ContextRuleSet("Server/Service/Engine/Host/Default"));
        digester.addRuleSet(
                new NamingRuleSet("Server/Service/Engine/Host/DefaultContext/"));
        digester.addRuleSet(
                new ContextRuleSet("Server/Service/Engine/Host/"));
        digester.addRuleSet(
                new NamingRuleSet("Server/Service/Engine/Host/Context/"));
        digester.addRule("Server/Service/Engine",
                new SetParentClassLoaderRule(digester, parentClassLoader));
        return (digester);
    }

The createStartDigester method creates an instance of org.apache.commons.digester.Digester class, and then adds rules.

createStartDigester 方法会创建一个 org.apache.commons.digester.Digester 类的实例,然后添加规则。

The first three rules are for the server element in the server.xml file. As you may already know, the server element is the root element. Here are the rules for the pattern server.

前三条规则针对的是 server.xml 文件中的服务器元素。

大家可能已经知道,server 元素是根元素。以下是模式服务器的规则。

代码语言:javascript复制

digester.addObjectCreate("Server",
        "org.apache.catalina.core.StandardServer", "className");
        digester.addSetProperties("Server");
        digester.addSetNext("Server", "setServer",
        "org.apache.catalina.Server");

The createStartDigester method creates an instance of org.apache.commons.digester.Digester class, and then adds rules.

createStartDigester方法创建了org.apache.commons.digester.Digester类的一个实例,然后添加规则。

The first three rules are for the server element in the server.xml file. As you may already know, the server element is the root element. Here are the rules for the pattern server.

前三个规则是用于server.xml文件中的server元素。

正如您可能已经知道的那样,server元素是根元素。

以下是用于pattern server的规则。

代码语言:javascript复制

digester.addObjectCreate("Server",
        "org.apache.catalina.core.StandardServer", "className");
        digester.addSetProperties("Server");
        digester.addSetNext("Server", "setServer",
        "org.apache.catalina.Server");

The first rule states that upon encountering the server element, the Digester must create an instance of org.apache.catalina.core.StandardServer. The exception is if the server element has a className attribute, in which case the value of the className attribute is the name of the class that must be instantiated instead.

第一条规则指出,当遇到server元素时,Digester必须创建一个org.apache.catalina.core.StandardServer的实例。

唯一的例外是如果server元素有一个className属性,在这种情况下,className属性的值就是必须实例化的类的名称。

The second rule populates the properties of the Server object with the values of the attributes having identical names.

第二条规则将Server对象的属性填充为具有相同名称的属性的值。

The third rule causes the Server object to be pushed to the stack and associated with the next object in the stack, which is an instance of Catalina, and its setServer method to be called. How can an instance of Catalina be in the Digester's object stack? Remember that the start method calls the push method of the Digester prior to parsing the server.xml file:

第三条规则导致Server对象被推送到堆栈并与堆栈中的下一个对象(即Catalina的实例)相关联,并调用其setServer方法。如何在Digester的对象堆栈中有Catalina的实例?

请记住,在解析server.xml文件之前,start方法会调用Digester的push方法。

代码语言:javascript复制
digester.push (this);

The line of code above causes the Catalina object to be pushed to the internal object stack in the Digester

上面这行代码会将 Catalina 对象推送到 Digester 的内部对象栈中。

You should be able to figure out the next rules by reading the method yourself. If you cannot, you should read Chapter 15 again.

通过自己阅读该方法,你应该能找出接下来的规则。

如果不能,则应再次阅读第 15 章。

Stop Digester(停止消解器)

The createStopDigester method returns a Digester object that stops the Server object gracefully. This method is given in Listing 17.7.

createStopDigester方法返回一个Digester对象,用于优雅地停止Server对象。该方法在代码清单17.7中给出。

Listing 17.7: The stop method

代码清单17.7:stop方法

代码语言:javascript复制
  
protected Digester createStopDigester() {  
    // Initialize the digester  
    Digester digester = new Digester();  
    if (debug)  
        digester.setDebug(999);  
    // Configure the rules we need for shutting down  
    digester.addObjectCreate("Server",  
            "org.apache.catalina.core.StandardServer", "className");  
    digester.addSetProperties("Server");  
    digester.addSetNext("Server", "setServer",  
            "org.apache.catalina.Server");  
    return (digester);  
}

Unlike the start Digester, the stop Digester is only interested in the root element.

与启动Digester不同,停止Digester只对根元素感兴趣。

The Bootstrap Class( Bootstrap 类)

The org.apache.catalina.startup.Bootstrap class is one of the classes that provide an entry point to start Tomcat. When you run the startup.bat or startup.sh file, you actually call the main method in this class. The main method creates three class loaders and instantiates the Catalina class. It then calls the process method on Catalina.

org.apache.catalina.startup.Bootstrap类是提供启动Tomcat入口点的类之一。

当您运行startup.bat或startup.sh文件时,实际上是调用此类中的main方法。

main方法创建了三个类加载器并实例化了Catalina类。然后它调用Catalina上的process方法。

The Bootstrap class is given in Listing 17.8

Bootstrap类如图17.8所示

Listing 17.8: The Bootstrap class

图17.8:Bootstrap类

代码语言:javascript复制


package org.apache.catalina.startup;
        import java.io.File;
        import java.lang.reflect.Method;
/**
 * Boostrap 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
 * @version $Revision: 1.36 $ $Date: 2002/04/01 19:51:31 $
 */
public final class Bootstrap {
    /**
     * Debugging detail level for processing the startup.
     */
    private static int debug = 0;
    /**
     * The main program for the bootstrap.
     *
     * @param args Command line arguments to be processed
     */
    public static void main(String args[]) {
        // Set the debug flag appropriately
        for (int i = 0; i < args.length; i  ) {
            if ("-debug".equals(args[i]))
                debug = 1;
        }
        // Configure catalina.base from catalina.home if not yet set
        if (System.getProperty("catalina.base") == null)
            System.setProperty("catalina.base", getCatalinaHome());
        // Construct the class loaders we will need
        ClassLoader commonLoader = null;
        ClassLoader catalinaLoader = null;
        ClassLoader sharedLoader = null;
        try {
            File unpacked[] = new File[1];
            File packed[] = new File[1];
            File packed2[] = new File[2];
            ClassLoaderFactory.setDebug(debug);
            unpacked[0] = new File(getCatalinaHome(),
                    "common"   File.separator   "classes");
            packed2[0] = new File(getCatalinaHome(),
                    "common"   File.separator   "endorsed");
            packed2[l] = new File(getCatalinaHome(),
                    "common"   File.separator   "lib");
            commonLoader =
                    ClassLoaderFactory.createClassLoader(unpacked, packed2, null);
            unpacked[0] = new File(getCatalinaHome(),
                    "server"   File.separator   "classes");
            packed[0] = new File(getCatalinaHome(),
                    "server"   File.separator   "lib");
            catalinaLoader =
                    ClassLoaderFactory.createClassLoader(unpacked, packed,
                            commonLoader);
            unpacked[0] = new File(getCatalinaBase(),
                    "shared"   File.separator   "classes");
            packed[0] = new File(getCatalinaBase(),
                    "shared"   File.separator   "lib");
            sharedLoader =
                    ClassLoaderFactory.createClassLoader(unpacked, packed,
                            commonLoader);
        }
        catch (Throwable t) {
            log('Class loader creation threw exception", t);
                    System.exit(1);
        }
        Thread.currentThread().setContextClassLoader(catalinaLoader);
        // Load our startup class and call its process() method
        try {
            SecurityClassLoad.securityClassLoad(catalinaLoader);
            // Instantiate a startup class instance
            if (debug >= 1)
                log("Loading startup class");
            Class startupClass =
                    catalinaLoader.loadClass
                            ("org.apache.catalina.startup.Catalina");
            Object startupInstance = startupClass.newInstance();
            // Set the shared extensions class loader
            if (debug >= 1)
                log("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);
            // Call the process() method
            if (debug >= 1)
                log("Calling startup class process() method");
            methodName = "process";
            paramTypes = new Class[1];
            paramTypes[0] = args.getClass();
            paramValues = new Object[l];
            paramValues[0] = args;
            method =
                    startupInstance.getClass().getMethod(methodName, paramTypes);
            method.invoke(startupInstance, paramValues);
        }
        catch (Exception e) {
            System.out.println("Exception during startup processing");
            e.printStackTrace(System.out);
            System.exit(2);
        }
    }
    /**
     * Get the value of the catalina.home environment variable.
     */
    private static String getCatalinaHome() {
        return System.getProperty("catalina.home",
                System.getProperty("user.dir"));
    }
    /**
     * Get the value of the catalina.base environment variable.
     */
    private static String getCatalinaBase() {
        return System.getProperty("catalina.base", getCatalinaHome());
    }
    /**
     * Log a debugging detail message.
     *
     * @param message The message to be logged
     */
    private static void log(String message) {
        System.out.print("Bootstrap: ");
        System.out.println(message);
    }
    /**
     * Log a debugging detail message with an exception.
     *
     * @param message The message to be logged
     * @param exception The exception to be logged
     */
    private static void log(String message, Throwable exception) {
        log(message);
        exception.printStackTrace(System.out);
    }
}

The Bootstrap class has four static methods, i.e. two log methods, the getCatalinaHome method, and the getCatalinaBase method. The getCatalinaHome method has the following implementation:

Bootstrap类有四个静态方法,即两个日志方法,getCatalinaHome方法和getCatalinaBase方法。getCatalinaHome方法的实现如下:

代码语言:javascript复制
return System.getProperty("catalina.home",
 System.getProperty("user.dir"));

which basically means, if no value has been previously set for catalina.home, it returns the value of the user.dir property

这基本上意味着,如果之前没有为catalina.home设置任何值,它将返回user.dir属性的值。

The getCatalinaBase method has the following implementation:

getCatalinaBase方法的实现如下:

代码语言:javascript复制
return System.getProperty("catalina.base", getCatalinaHome());

which means, it returns the value of catalina.home if there is no such property as catalina.base.

这意味着,如果没有"catalina.base"这个属性,它将返回"catalina.home"的值。

Both getCatalinaHome and getCatalinaBase are called from the main method of the Bootstrap class.

getCatalinaHome和getCatalinaBase都在Bootstrap类的main方法中被调用。

The main method of the Bootstrap class also constructs three class loaders for different purposes. The main reason for having different class loaders is to prevent application classes (servlets and other helper classes in a web application) from running classes outside the WEB-INF/classes and WEB-INF/lib directories. Jarred classes deployed to the �TALINE_HOME%/common/lib directory are also allowed.

Bootstrap类的main方法还为不同的目的构造了三个类加载器。

之所以有不同的类加载器,主要是为了防止应用程序类(Web应用程序中的Servlet和其他辅助类)在WEB-INF/classes和WEB-INF/lib目录之外运行类。

部署到�TALINE_HOME%/common/lib目录的打包类也是允许的。

The three class loaders are defined as follows.

这三个类加载器的定义如下。

代码语言:javascript复制
// Construct the class loaders we will need
ClassLoader commonLoader = null;
 ClassLoader catalinaLoader = null;
 ClassLoader sharedLoader = null;

Each class loader is then given a path it is allowed access to. The commonLoader class loader is allowed to load Java classes in three directories: �TALINA_HOME%/common/classes, �TALINA_HOME%/commo n/endorsed, and �TALINA_HOME%/common/lib.

每个类加载器都有一个允许访问的路径。

commonLoader 类加载器可以加载三个目录中的 Java 类:�TALINA_HOME%/common/classes、�TALINA_HOME%/commo n/endorsed,以及 �TALINA_HOME%/common/lib。

代码语言:javascript复制
  
  
try {  
        File unpacked[] = new File[1];  
        File packed[] = new File[1];  
        File packed2[] = new File[2];  
        ClassLoaderFactory.setDebug(debug);  
        unpacked[0] = new File(getCatalinaHome(),  
        "common"   File.separator   "classes");  
        packed2[0] = new File(getCatalinaHome(),  
        "common"   File.separator   "endorsed");  
        packed2[1] = new File(getCatalinaHome(),  
        "common"   File.separator   "lib");  
        commonLoader =  
        ClassLoaderFactory.createClassLoader(unpacked, packed2, null);

The catalinaLoader class loader is responsible for loading classes required by the Catalina servlet container to run. It can load Java classes in the �TALINA_HOME%/server/classes and �TALINA_HOME%/server/lib directories, as well as all directories that the commonLoader class loader can access.

catalinaLoader类加载器负责加载Catalina Servlet容器运行所需的类。

它可以加载位于�TALINA_HOME%/server/classes和�TALINA_HOME%/server/lib目录中的Java类,以及commonLoader类加载器可以访问的所有目录中的类。

代码语言:javascript复制
unpacked[0] = new File(getCatalinaHome(),
 "server"   File.separator   "classes");
 packed[0] = new File(getCatalinaHome(),
 "server"   File.separator   "lib");
 catalinaLoader =
 ClassLoaderFactory.createClassLoader(unpacked, packed,
 commonLoader);

The sharedLoader class loader can access the �TALINA_HOME%/shared/classesand �TALJNA_HOME%/shared/lib directories, as well as all directories available to the commonLoader class loader. The sharedLoader class loader is then assigned to be the parent class loader of every class loader of each Web application associated with a Context deployed in Tomcat.

共享加载器类加载器可以访问�TALINA_HOME%/shared/classes和�TALINA_HOME%/shared/lib目录,以及commonLoader类加载器可访问的所有目录。

然后,共享加载器类加载器被分配为与部署在Tomcat中的每个上下文相关联的每个Web应用程序的类加载器的父类加载器。

代码语言:javascript复制
 unpacked[0] = new File(getCatalinaBase(),
  "shared"   File.separator   "classes");
  packed[0] = new File(getCatalinaBase(),
  "shared"   File.separator   "lib");
  sharedLoader =
  ClassLoaderFactory.createClassLoader(unpacked, packed,
  commonLoader);
  }
  catch (Throwable t) {
  log('Class loader creation threw exception", t);
  System.exit(1);
 }

Notice that the sharedLoader class loader does not have access to the Catalina internal classes nor to the class paths defined in the CLASSPATH environment variable. See Chapter 8 for more details on how a class loader works.

请注意,sharedLoader类加载器无法访问Catalina内部类,也无法访问在CLASSPATH环境变量中定义的类路径。

有关类加载器工作原理的更多细节,请参阅第8章。

After creating the three class loaders, the main method then loads the Catalina class and creates an instance of it and assigns it to the startupInstance variable.

在创建了这三个类加载器之后,main方法会加载Catalina类,并创建一个实例并将其赋值给startupInstance变量。

代码语言:javascript复制
Class startupClass =
 catalinaLoader.loadClass
 ("org.apache.catalina.startup.Catalina");
 Object startupInstance = startupClass.newInstance();

Afterwards, it calls the setParentClassLoader method by passing the sharedLoader class loader.

之后,它会通过传递 sharedLoader 类加载器来调用 setParentClassLoader 方法。

代码语言:javascript复制

// Set the shared extensions class loader
 if (debug >= 1)
         log("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);

Finally, the main method calls the process method on the Catalina object.

最后,主方法调用 Catalina 对象上的 process 方法。

代码语言:javascript复制
// Call the process() method
 if (debug >= 1)
 log("Calling startup class process() method");
 methodName = "process";
 paramTypes = new Class[1];
 paramTypes[0] = args.getClass();
 paramValues = new Object[1];
 paramValues[0] = args;
 method =
 startupInstance.getClass().getMethod(methodName, paramTypes);
 method.invoke(startupInstance, paramValues);

Running Tomcat on Windows(在 Windows 上运行 Tomcat)

As you have learned in the previous sections, you call the Bootstrap class to run Tomcat as a stand-alone application. On a Windows platform, you do this by invoking the startup.bat batch file to start Tomcat and the shutdown.bat batch file to stop it. Both batch files can be found in the �TALINA_HOME%/bin directory. This section discusses the batch files. For those not familiar with the DOS command lines that can appear in a batch file, read the first subsection, "Introduction to Writing Batch Files".

正如您在前面的章节中了解到的,您可以调用Bootstrap类作为独立应用程序来运行Tomcat。

在Windows平台上,您可以通过调用startup.bat批处理文件来启动Tomcat,通过调用shutdown.bat批处理文件来停止Tomcat。

这两个批处理文件可以在�TALINA_HOME%/bin目录中找到。

本节讨论了这两个批处理文件。对于那些不熟悉批处理文件中可能出现的DOS命令行的人,可以阅读第一小节《编写批处理文件简介》

Introduction to Writing Batch Files(编写批处理文件简介)

DOS 命令部分简单了解即可。

This section offers an introduction to batch files so that you can understand the batch files for starting and stopping Tomcat. In particular, it explains the following commands: rem, if, echo, goto, label, etc. It does not pretend to provide a comprehensive coverage of the topic, however, for which you should consult other resources.

本节提供了批处理文件的介绍,以便您可以理解用于启动和停止Tomcat的批处理文件。

特别是,它解释了以下命令:rem、if、echo、goto、label等。然而,它并不打算提供对该主题的全面覆盖,对于此,您应该参考其他资源。

First and foremost, a batch file must have a .bat extension. You can invoke a batch file by double-clicking it from Windows Explorer or by typing the command from a DOS console. Once invoked, each line of instruction will be interpreted from the first line to the last. The language elements used in the batch files in Tomcat are explained in the following subsections.

首先,批处理文件必须具有.bat扩展名。您可以通过从Windows资源管理器双击它或在DOS控制台中键入命令来调用批处理文件。一旦被调用,每一行指令将从第一行到最后一行被解释。

Tomcat中批处理文件中使用的语言元素在以下子节中进行了解释。

Note DOS commands and environment variables are case-insensitive. 注意DOS命令和环境变量是不区分大小写的。

rem(删除)

The rem command is used for comments. A line beginning with rem is ignored and not processed.

rem 命令用于注释。以 rem 开头的行将被忽略,不会被处理。

pause(暂停)

The pause command halts the processing of a batch file and prompts the user to press a key. The processing continues upon the user pressing a key.

暂停命令停止批处理文件的处理,并提示用户按键。用户按键后,处理继续进行。

echo

This command displays the text after it to the DOS console. For example, the following line prints Hello World on the console and pauses. You need the pause command so that the console does not close as soon as it displays it.

该命令会在 DOS 控制台上显示后面的文本。

例如,下面一行在控制台上打印 Hello World 并暂停。您需要使用暂停命令,这样控制台才不会在显示后立即关闭。

代码语言:javascript复制
echo Hello World

pause

To echo the value of an environment variable, enclose the variable with %. For example, the following command prints the value of myVar.

要回显环境变量的值,请用 % 将变量括起来。例如,以下命令将打印 myVar 的值。

代码语言:javascript复制
echo %myVar%.

To print the name of the operating system, use the following command:

要打印操作系统名称,请使用以下命令:

代码语言:javascript复制
echo %OS%

echo off

echo off prevents the command lines in the batch file from being displayed. Only the result of the execution is displayed. However, the echo off command will still be displayed. To suppress the echo off command as well, use @echo off.

echo off命令用于阻止批处理文件中的命令行显示。

只显示执行结果,而不显示命令行。

然而,echo off命令本身仍然会显示。要同时抑制echo off命令的显示,可以使用 @echo off

@echo off

@echo off is similar to echo off, but it also suppresses the echo off command itself.

@echo off与echo off类似,但它还抑制了echo off命令本身的显示。

set

This command is used to set user defined or named environment variables. The environment variables set in a batch file live temporarily in memory and is destroyed as soon as the batch file finishes executing.

该命令用于设置用户定义的或命名的环境变量。

在批处理文件中设置的环境变量在内存中临时存在,并在批处理文件执行完毕后被销毁。

For example, the following set command creates an environment variable named THE_KING with a value of Elvis and displays it on the console.

例如,下面的 set 命令将创建一个名为 THE_KING、值为 Elvis 的环境变量,并将其显示在控制台中。

代码语言:javascript复制
set THE_KING=Elvis
echo %THE_KING%
pause

Note To refer to the value of a variable, enclose the variable name with the % characters. For instance, echo %the_king% means display the value of the THE_KING variable. 注 要引用变量的值,请用 % 字符括住变量名。 例如,echo %the_king% 表示显示变量 THE_KING 的值。

label

You use a colon to denote a label. You can then pass the label to the goto command to instruct the processing to jump to the line next to the label. Here is a label called end:

使用冒号来表示一个标签。然后可以将该标签传递给goto命令,以指示处理跳转到标签旁边的行。这里有一个名为"end"的标签:

代码语言:javascript复制
:end

See the goto command for a more descriptive example.

请参阅goto命令以获取更详细的示例。

goto

The goto command forces the batch file processing to jump to the line after the specified label. Consider the following example.

goto命令强制批处理文件处理跳转到指定标签后的行。考虑以下示例。

代码语言:javascript复制
echo Start
goto end
echo I can guarantee this line will not be executed
:end
echo End
pause

After printing Start on the first line, the batch file executes the goto command, which makes control jump to the line right after the end label. As a result, the third line is skipped.

在第一行打印 "开始 "后,批处理文件会执行 "goto "命令,使控制跳转到结束标签后的一行。

因此,第三行被跳过。

if

if is used to test a statement. It can be used in three different ways:

if用于测试一个语句。它可以以三种不同的方式使用:

  1. To test the value of a variable.
  2. To test the existence of a file
  3. To test the error value.
  4. 用于测试变量的值。
  5. 用于测试文件的存在性。
  6. 用于测试错误值。

To test a variable's value, use if in the following format:

要测试变量的值,请使用以下格式的if语句:

代码语言:javascript复制
if variable==value nextCommand

For example, the following if statement tests if the value of myVar is 3. If it is, it prints Correct on the console.

例如,下面的 if 语句测试 myVar 的值是否为 3,如果是,则在控制台中打印出 Correct。

代码语言:javascript复制
set myVar=3
if %myVar%==3 echo Correct

When run, the commands above evaluate the value of the variable myVar and prints Correct.

运行上述命令时,将评估变量 myVar 的值并打印出正确结果。

To use an if statement to test the existence of a file, use it in the following format:

要使用 if 语句测试文件是否存在,请按以下格式使用:

代码语言:javascript复制
if exist c:tempmyFile.txt goto start

If the myFile.txt file exists in the c:temp directory, control will go to the next line after the label start.

如果 myFile.txt 文件存在于 c:temp 目录中,控制将转到标签开始后的下一行。

You can also use the not keyword to negate a statement.

您还可以使用 not 关键字来否定语句。

not

The not keyword is used to negate a statement. For example, the following command prints Correct if the value of myVar is not 3.

not 关键字用于否定语句。

例如,如果 myVar 的值不是 3,则下面的命令打印出 Correct。

代码语言:javascript复制
set myVar=3
if not %myVar%==3 echo Correct
pause

The following command makes processing jump to end if the myFile.txt file does not exists in the c:temp directory.

如果 c:temp 目录中不存在 myFile.txt 文件,下面的命令会使处理跳转到结束。

if not exist c:tempmyFile.txt goto end

exist

The exist keyword is used in conjunction with the if statement to test the existence of a file. See the if statement for an example.

exist 关键字与 if 语句结合使用,用于测试文件是否存在。请参阅 if 语句的示例。

Accepting Parameters

You can pass parameters to a batch file. You use %1 to refer to the first parameter, %2 to the second, and so forth.

您可以向批处理文件传递参数。使用 %1 表示第一个参数,%2 表示第二个参数,以此类推。

For example, the following command prints the first parameter on the console.

例如,以下命令会在控制台打印第一个参数。

代码语言:javascript复制
echo %1

If your batch file is named test.bat and you invoke it by using test Hello, the word Hello will be displayed on the console.

如果批处理文件名为 test.bat,并使用 test Hello 调用该文件,控制台将显示 Hello 字样。

The following batch file checks the value of the first parameter. If it is start, it will print Starting application. If it is stop, Stopping application will be printed. Otherwise, Invalid parameter is printed.

下面的批处理文件将检查第一个参数的值。如果是 start,则会打印 Starting application(启动应用程序)。

如果是 stop,则打印 Stopping Application。否则将打印无效参数。

代码语言:javascript复制
echo off
if %1==start goto start

if %1==stop goto stop
goto invalid
:start
echo Starting application
goto end
:stop
echo Stopping application
goto end
:invalid
echo Invalid parameter
:end

To check whether a parameter has been passed to the batch file, compare "%1" with a blank string. For example, if no parameter is passed to the following batch file, No parameter will be printed on the console.

要检查是否有参数传递到批处理文件,请将"%1 "与空白字符串进行比较。

例如,如果没有参数传递给下面的批处理文件,则控制台将打印 "无参数"。

代码语言:javascript复制

if "%1" == "" echo No parameter

The above is the same as

也可以用下面的语法替换上面的操作

代码语言:javascript复制

if ""%1"" == """" echo No parameter

shift

The shift command shifts the parameters one parameter backward. This means the value of %2 is copied to %1, %3 to %2, and so forth. For example, the following batch file uses a shift command.

shift 命令将参数向后移动一个参数。这意味着 %2 的值被复制到 %1,%3 被复制到 %2,以此类推。例如,以下批处理文件使用了 shift 命令。

代码语言:javascript复制
echo off
shift
echo %1
echo %2

If you invoke the batch file by passing three parameters a, b, and c, you will get the following result:

如果通过 a、b 和 c 三个参数来调用批处理文件,会得到如下结果:

代码语言:javascript复制
b
c

The first parameter after shift can be referenced by using %0. The last parameter is now lost.

移位后的第一个参数可以使用 %0 引用。现在最后一个参数已丢失。

call

The call command is used to invoke another command.

调用命令用于调用另一条命令。

setLocal

You use setLocal in a batch file to indicate that any change to environment variables during the current batch file should be local to the batch file. The values of any changed environment variables will be restored at the end of the batch file or if an endLocal command is encountered.

在批处理文件中使用 setLocal,可以表明在当前批处理文件中对环境变量所做的任何更改都是批处理文件本地的。

任何已更改的环境变量值都将在批处理文件结束时或遇到 endLocal 命令时恢复。

start

Open a new Windows console. You can pass a title for the new window, such as:

打开一个 新的 Windows 控制台。您可以为新窗口指定一个标题,例如

代码语言:javascript复制

start "Title"

Additionally, you can pass a command that will be executed in the new console, right after the title:

此外,您还可以在标题后传递一条将在新控制台中执行的命令:

代码语言:javascript复制

start "Title" commandName

The catalina.bat Batch File(catalina.bat 批次文件)

The catalina.bat batch file can be used to start and stop Tomcat. Two other files, startup.bat and shutdown.bat, are provided to start and stop Tomcat more easily. The startup.bat and shutdown.bat call the catalina.bat file by passing the appropriate parameter.

catalina.bat批处理文件可用于启动和停止Tomcat。

还提供了startup.bat和shutdown.bat两个文件,以更轻松地启动和停止Tomcat。

startup.bat和shutdown.bat通过传递适当的参数来调用catalina.bat文件。

You must call catalina.bat from the bin directory under �TALINA_HOME% by using the following syntax:

您必须使用以下语法从�TALINA_HOME%下的bin目录中调用catalina.bat:

代码语言:javascript复制
catalina command

or from the �TALINE_HOME% by using the following

或者从�TALINA_HOME%中使用以下语法:

代码语言:javascript复制
bincatalina command

In both cases, possible values for command are as follows:

在这两种情况下,command的可能值如下:

  • debug. Start Catalina in a debugger
  • debug -security. Debug Catalina with a security manager
  • embedded. Start Catalina in embedded mode
  • jpda start. Start Catalina under JPDA debugger
  • run. Start Catalina in the current window
  • run -security. Start Catalina in the current window with a security manager
  • start. Start Catalina in a separate window
  • start -security. Start Catalina in a separate window with security manager
  • stop. Stop Catalina
  • debug. 在调试器中启动Catalina
  • debug -security. 在带有安全管理器的情况下调试Catalina
  • embedded. 在嵌入模式下启动Catalina
  • jpda start. 在JPDA调试器下启动Catalina
  • run. 在当前窗口中启动Catalina
  • run -security. 在当前窗口中带有安全管理器的情况下启动Catalina
  • start. 在单独的窗口中启动Catalina
  • start -security. 在单独的窗口中带有安全管理器的情况下启动Catalina
  • stop. 停止Catalina

For example, to start Catalina in a separate window, use the following command:

例如,要在单独的窗口中启动Catalina,请使用以下命令:

代码语言:javascript复制
catalina start

The catalina.bat batch file is given in Listing 17.9.

catalina.bat批处理文件如17.9节所示。

Listing 17.9: The catalina.bat File

17.9节:catalina.bat文件

代码语言:javascript复制

    @echo off  
if "%OS%" == "Windows_NT" setlocal  
            rem   
-------------------------------------------------------------------  
        --------  
    rem Start/Stop Script for the CATALINA Server  
            rem  
    rem Environment Variable Prequisites  
    rem  
    rem CATALINA_HOME May point at your Catalina "build" directory.  
            rem  
    rem CATALINA_BASE (Optional) Base directory for resolving dynamic  
    portions  
    rem of a Catalina installation. If not present,  
    resolves to  
    rem the same directory that CATALINA_HOME points to.  
    rem  
    rem CATALINA_OPTS (Optional) Java runtime options used when the  
"start",  
    rem "stop", or "run" command is executed.  
            rem  
    rem CATALINA_TMPDIR (Optional) Directory path location of temporary  
    directory  
    rem the JVM should use (java.io.tmpdir). Defaults to  
    rem �TALINA_BASE%temp.  
            rem  
    rem JAVA_HOME Must point at your Java Development Kit  
    installation.  
            rem  
    rem JAVA_OPTS (Optional) Java runtime options used when the  
"start",  
    rem "stop", or "run" command is executed.  
            rem  
    rem JSSE_HOME (Optional) May point at your Java Secure Sockets  
    Extension  
    rem (JSSE) installation, whose JAR files will be  
    added to the  
    rem system class path used to start Tomcat.  
    rem  
    rem JPDA_TRANSPORT (Optional) JPDA transport used when the "jpda  
    start"  
    rem command is executed. The default is "dt_shmem".  
    rem  
    rem JPDA_ADDRESS (Optional) Java runtime options used when the  
"jpda start"  
    rem command is executed. The default is "jdbconn".  
    rem  
    rem $Id: catalina.bat,v 1.3 2002/08/04 18:19:43 patrickl Exp $  
            rem   
-------------------------------------------------------------------  
        --------  
    rem Guess CATALINA_HOME if not defined  
if not "�TALINA_HOME%" == "" goto gotHome  
    set CATALINA_HOME=.  
            if exist "�TALINA_HOME%bincatalina.bat" goto okHome  
    set CATALINA_HOME=..  
            :gotHome  
if exist "�TALINA_HOME%bincatalina.bat" goto okHome  
    echo The CATALINA_HOME environment variable is not defined correctly  
    echo This environment variable is needed to run this program  
goto end  
:okHome  
    rem Get standard environment variables  
if exist "�TALINA_HOME%binsetenv.bat" call  
"�TALINA_HOME%binsetenv.bat"  
    rem Get standard Java environment variables  
if exist "�TALINA_HOME%binsetclasspath.bat" goto okSetclasspath  
    echo Cannot find �TALINA_HOME%binsetclasspath.bat  
    echo This file is needed to run this program  
goto end  
:okSetclasspath  
    set BASEDIR=�TALINA_HOME%  
    call "�TALINA_HOME%binsetclasspath.bat"  
    rem Add on extra jar files to CLASSPATH  
if "%JSSE_HOME%" == "" goto noJsse  
            set  
    CLASSPATH=%CLASSPATH%;%JSSE_HOME%libjcert.jar;%JSSE_HOME%libjnet  
            .ja  
            r;%JSSE_HOME%libjsse.jar  
:noJsse  
    set CLASSPATH=%CLASSPATH%;�TALINA_HOME%binbootstrap.jar  
if not "�TALINA_BASE%" == "" goto gotBase  
    set CATALINA_BASE=�TALINA_HOME%  
            :gotBase  
if not "�TALINA_TMPDIR%" == "" goto gotTmpdir  
    set CATALINA_TMPDIR=�TALINA_BASE%temp  
:gotTmpdir  
    rem ----- Execute The Requested Command -------------------------------  
            --------  
    echo Using CATALINA_BASE: �TALINA_BASE%  
    echo Using CATALINA_HOME: �TALINA_HOME%  
    echo Using CATALINA_TMPDIR: �TALINA_TMPDIR%  
    echo Using JAVA_HOME: %JAVA_HOME%  
    set _EXECJAVA=%_RUNJAVA%  
    set MAINCLASS=org.apache.catalina.startup.Bootstrap  
    set ACTION=start  
    set SECURITY_POLICY_FILE=  
            set DEBOG_OPTS=  
 set JPDA=  
 if not ""%1"" == ""jpda"" goto noJpda  
     set JPDA=jpda  
 if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport  
     set JPDA_TRANSPORT=dt_shmem  
 :gotJpdaTransport  
 if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress  
     set JPDA_ADDRESS=jdbconn  
 :gotJpdaAddress  
             shift  
 :noJpda  
 if ""%1"" == ""debug"" goto doDebug  
 if ""%1"" == ""embedded"" goto doEmbedded  
 if ""%1"" == ""run"" goto doRun  
 if ""%1"" == ""start"" goto doStart  
 if ""%1"" == ""stop"" goto doStop  
     echo Usage: catalina ( commands ... )  
     echo commands:  
     echo debug Start Catalina in a debugger  
     echo debug -security Debug org.apache.catalina.startup.Catalina with a security manager  
     echo embedded Start Catalina in embedded mode  
     echo jpda start Start Catalina under JPDA debugger  
     echo run Start Catalina in the current window  
     echo run -security Start in the current window with security  
     manager  
     echo start Start Catalina in a separate window  
     echo start -security Start in a separate window with security  
     manager  
     echo stop Stop Catalina  
 goto end  
 :doDebug  
             shift  
     set _EXECJAVA=%_RUNJDB%  
     set DEBUG_OPTS=-sourcepath "�TALINA_HOME%....jakarta-tomcat4.0catalinasrcshare"  
             if not ""%1"" == ""-security"" goto execCmd  
             shift  
     echo Using Security Manager  
     set SECURITY_POLICY_FILE=�TALINA_BASE%confcatalina.policy  
 goto execCmd  
 :doEmbedded  
             shift  
     set MAINCLASS=org.apache.catalina.startup.Embedded  
 goto execCmd  
 :doRun  
             shift  
 if not ""%1"" == ""-security"" goto execCmd  
             shift  
     echo Using Security Manager  
     set SECURITY_POLICY_FILE=�TALINA_BASE%confcatalina.policy  
 goto execCmd  
 :doStart  
             shift  
 if not "%OS%" == "Windows_NT" goto noTitle  
     set _EXECJAVA=start "Tomcat" %_RUNJAVA%  
             goto gotTitle  
 :noTitle  
     set _EXECJAVA=start %_RUNJAVA%  
 :gotTitle  
 if not ""%1"" == ""-security"" goto execCmd  
             shift  
     echo Using Security Manager  
     set SECURITY_POLICY_FILE=�TALINA_BASE%confcatalina.policy  
 goto execCmd  
 :doStop  
             shift  
     set ACTION=stop  
 goto execCmd  
 :execCmd  
     rem Get remaining unshifted command line arguments and save them in the  
     set CMD_LINE_ARGS=  
 :setArgs  
 if ""%1""=="""" goto doneSetArgs  
 set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1  
 shift  
 goto setArgs  
 :doneSetArgs  
 rem Execute Java with the applicable properties  
 if not "%JPDA%" == "" goto dojpda  
 if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity  
 %_EXECJAVA% %JAVA_OPTS% �TALINA_OPTS% �BUG_OPTS% -  
 Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -  
 Dcatalina.base="�TALINA_BASE%" -Dcatalina.home="�TALINA_HOME%" -  
 Djava.io.tmpdir="�TALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS%  
 �TION%  
 goto end  
 :doSecurity  
 %_EXECJAVA% %JAVA_OPTS% �TALINA_OPTS% �BUG_OPTS% -  
 Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -  
 Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%"  
 -Dcatalina.base="�TALINA_BASE%" -Dcatalina.home="�TALINA_HOME%" -  
 Djava.io.tmpdir="�TALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS%  
 �TION%  
 goto end  
 :doJpda  
 if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda  
 %_EXECJAVA% %JAVA_OPTS% �TALINA_OPTS% -Xdebug -  
 Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,su  
 s  
 pend=n �BUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -  
 classpath "%CLASSPATH%" -Dcatalina.base="�TALINA_BASE%" -  
 Dcatalina.home="�TALINA_HOME%" -Djava.io.tmpdir="�TALINA_TMPDIR%"  
 %MAINCLASS% %CMD_LINE_ARGS% �TION%  
 goto end  
 :doSecurityJpda  
 %_EXECJAVA% %JAVA_OPTS% �TALINA_OPTS% -  
 Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,su  
 s  
 pend=n �BUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -  
 classpath "%CLASSPATH%" -Djava.security.manager -  
 Djava.security.policy=="%SECURITY_POLICY_FILE%" -  
 Dcatalina.base="�TALINA_BASE%" -Dcatalina.home="�TALINA_HOME%" -  
 Djava.io.tmpdir="�TALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS%  
 �TION%  
 goto end  
:end

The catalina.bat file starts off by calling @echo off to suppress the commands. It then checks if the value of OS environment variable is Windows_NT (meaning the user is using Windows NT, Windows 2000, or Windows XP). If it is, it calls setLocal to make any changes to the environment variables local to the batch file.

catalina.bat 文件首先调用 @echo off 来抑制命令。

然后,它会检查操作系统环境变量的值是否为 Windows_NT(这意味着用户使用的是 Windows NT、Windows 2000 或 Windows XP)。

如果是,它将调用 setLocal 来更改批处理文件本地的环境变量。

代码语言:javascript复制
if "%OS%" == "Windows_NT" setlocal

It then sets the value of CATALINA_HOME if there is not yet a variable named CATALINA_HOME. By default, the CATALINA_HOME variable is nonexistent because you are not required to set this variable to run Tomcat.

如果尚未存在名为CATALINA_HOME的变量,则设置CATALINA_HOME的值。

默认情况下,CATALINA_HOME变量不存在,因为您不需要设置此变量来运行Tomcat。

If the CATALINA_HOME variable is not found, the batch file guesses the directory from which the batch file is invoked. First, it speculates that the catalina.bat file is run from the install directory, in which case it must find the catalina.bat file in the bin directory.

如果未找到CATALINA_HOME变量,则批处理文件会从批处理文件被调用的目录猜测目录。

首先,它推测catalina.bat文件是从安装目录运行的,在这种情况下,它必须在bin目录中找到catalina.bat文件。

代码语言:javascript复制
if not "�TALINA_HOME%" == "" goto gotHome
set CATALINA_HOME=.
if exist "�TALINA_HOME%bincatalina.bat" goto okHome

If the catalina.bat file is not found in the subdirectory bin under the current directory, the catalina.bat file could not have been invoked from the install directory. The batch file then guesses again. This time it reckons that the catalina.bat file is invoked from the bin directory under the install directory by setting the parent directory of bin to CATALINA_HOME and then checking the existence of catalina.bat under the bin directory.

如果在当前目录的子目录bin下找不到catalina.bat文件,则无法从安装目录调用catalina.bat文件。

批处理文件会再次猜测。

这次它认为catalina.bat文件是通过将bin的上级目录设置为CATALINA_HOME并检查bin目录下是否存在catalina.bat来调用的。

代码语言:javascript复制
set CATALINA_HOME=..
:gotHome
if exist "�TALINA_HOME%bincatalina.bat" goto okHome

If the guess was correct, it jumps to okHome. Otherwise, it prints an error message telling the user that CATALINA_HOME is not set correctly and jump to end, the label at the end of the batch file.

如果猜测是正确的,就跳转到okHome。

否则,它会打印一个错误消息,告诉用户CATALINA_HOME没有正确设置,并跳转到批处理文件末尾的标签end。

echo The CATALINA_HOME environment variable is not defined correctly echo This environment variable is needed to run this program goto end

echo CATALINA_HOME环境变量没有正确定义 echo 运行此程序需要该环境变量 goto end

If CATALINA_HOME is defined correctly, the batch file calls the setenv.bat to set the required environment variables, if the setenv.bat exists. If it does not exist, no error message will be raised.

如果CATALINA_HOME被正确定义,批处理文件会调用setenv.bat来设置所需的环境变量(如果setenv.bat存在)。

如果setenv.bat不存在,将不会出现错误消息。

代码语言:javascript复制
:okHome
rem Get standard environment variables
if exist "�TALINA_HOME%binsetenv.bat" call
"�TALINA_HOME%binsetenv.bat"

Next, it checks if the setclasspath.bat file exists. If the file cannot be found, it displays an error message and jumps to end to quit the batch file.

接下来,它会检查 setclasspath.bat 文件是否存在。

如果找不到该文件,就会显示一条错误信息,并跳转到结尾退出批处理文件。

代码语言:javascript复制
if exist "�TALINA_HOME%binsetclasspath.bat" goto okSetclasspath
echo Cannot find �TALINA_HOME%binsetclasspath.bat
echo This file is needed to run this program
goto end

If setclaspath.bat file is found, it sets the BASEDIR variable with the value of CATALINA_HOME and then calls the setclasspath.bat file to set the class path.

如果找到 setclaspath.bat 文件,它会用 CATALINA_HOME 的值设置 BASEDIR 变量,然后调用 setclasspath.bat 文件设置类路径。

代码语言:javascript复制
:okSetclasspath
set BASEDIR=�TALINA_HOME%
call "�TALINA_HOME%binsetclasspath.bat"

The setclasspath.bat file checks if the environment variable JAVA_HOME is defined correctly and set the following variables to used by the rest of the catalina.bat file.

setclasspath.bat 文件会检查环境变量 JAVA_HOME 是否定义正确,并设置以下变量供 catalina.bat 文件的其余部分使用。

代码语言:javascript复制
set JAVA_ENDORSED_DIRS=�SEDIR%commonendorsed
set CLASSPATH=%JAVA_HOME%libtools.jar
set _RUNJAVA="%JAVA_HOME%binjava"
set _RUNJAVAW="%JAVA_HOME%binjavaw"
set _RUNJDB="%JAVA_HOME%binjdb"
set _RUNJAVAC="%JAVA_HOME%binjavac"

The catalina.bat file then checks if Java Secure Socket Extension (JSSE) has been installed and the JSSE_HOME variable is set correctly. If JSSE_HOME variable is found, it is added to the CLASSPATH variable

然后,catalina.bat 文件会检查 Java 安全套接字扩展(JSSE)是否已安装,JSSE_HOME 变量是否设置正确。如果找到 JSSE_HOME 变量,则将其添加到 CLASSPATH 变量中

代码语言:javascript复制
if "%JSSE_HOME%" == "" goto noJsse
set
CLASSPATH=%CLASSPATH%;%JSSE_HOME%libjcert.jar;%JSSE_HOME%libjnet
.ja
r;%JSSE_HOME%libjsse.jar

If JSSE_HOME is not found, the batch file continues with the next line, which adds the bootstrap.jar in the bin directory to the CLASSPATH variable.

如果找不到 JSSE_HOME,批处理文件将继续下一行,将 bin 目录中的 bootstrap.jar 添加到 CLASSPATH 变量中。

代码语言:javascript复制
:noJsse
set CLASSPATH=%CLASSPATH%;�TALINA_HOME%binbootstrap.jar

Next, the catalina.bat file checks the value of CATALINA_BASE. If CATALINA_BASE is not found, it is created and the value of CATALINA_HOME is assigned to it.

接下来,catalina.bat 文件会检查 CATALINA_BASE 的值。如果找不到 CATALINA_BASE,就会创建它,并将 CATALINA_HOME 的值分配给它。

代码语言:javascript复制
if not "�TALINA_BASE%" == "" goto gotBase
set CATALINA_BASE=�TALINA_HOME%
:gotBase

Then, it checks the value of CATALINA_TMPDIR, which represents the temporary directory under CATALINA_BASE.

然后,它会检查 CATALINA_TMPDIR 的值,该值代表 CATALINA_BASE 下的临时目录。

代码语言:javascript复制
if not "�TALINA_TMPDIR%" == "" goto gotTmpdir
set CATALINA_TMPDIR=�TALINA_BASE%temp
:gotTmpdir

Next, it echoes the values of several variables:

接下来,它会回显几个变量的值:

代码语言:javascript复制
echo Using CATALINA_BASE: �TALINA_BASE%
echo Using CATALINA_HOME: �TALINA_HOME%
echo Using CATALINA_TMPDIR: �TALINA_TMPDIR%
echo Using JAVA_HOME: %JAVA_HOME%

Then, it assigns the value of _ RUNJAVA, a variable set in the setclaspath.bin to _ EXECJAVA. The value of _RUNJAVA is "%JAVA_HOME%binjava". In other words, it refers to the java.exe program in the bin directory under JAVA_HOME.

然后,它将 _ RUNJAVA(一个在 setclaspath.bin 中设置的变量)的值分配给 _ EXECJAVA。_RUNJAVA 的值是"%JAVA_HOME%binjava"。

换句话说,它指的是 JAVA_HOME 下 bin 目录中的 java.exe 程序。

代码语言:javascript复制
set _EXECJAVA=%_RUNJAVA%

It then sets the following variables:

然后设置以下变量

代码语言:javascript复制
set MAINCLASS=org.apache.catalina.startup.Bootstrap
set ACTION=start
set SECURITY_POLICY_FILE=
set DEBUG_OPTS=
set JPDA=

The catalina.bat file then checks whether the first parameter passed to it is jpda (for Java Platform Debugger Architecture). If it is, it sets the JPDA variable to jpda, then checks the JPDA_TRANSPORT and JPDA_ADDRESS variables, and shifts the parameters.

然后,catalina.bat 文件会检查传给它的第一个参数是否为 jpda(Java Platform Debugger Architecture,Java 平台调试器架构)。

如果是,则将 JPDA 变量设置为 jpda,然后检查 JPDA_TRANSPORT 和 JPDA_ADDRESS 变量,并移动参数。

代码语言:javascript复制
if not ""%1"" == ""jpda"" goto noJpda
set JPDA=jpda
if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport
set JPDA_TRANSPORT=dt_shmem
:gotJpdaTransport
if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress
set JPDA_ADDRESS=jdbconn
:gotJpdaAddress
shift

In most cases you will not use JPDA, therefore the value of the first parameters must be one of the following: debug, embedded, run, start, or stop.

在大多数情况下,您不会使用 JPDA,因此第一个参数的值必须是下列参数之一:调试、嵌入式、运行、启动或停止。

代码语言:javascript复制
:noJpda
if ""%1"" == ""debug"" goto doDebug
if ""%1"" == ""embedded"" goto doEmbedded
if ""%1"" == ""run"" goto doRun
if ""%1"" == ""start"" goto doStart
if ""%1"" == ""stop"" goto doStop

If the first parameter is not correct or no parameter exists, the batch file displays the usage instruction and exits.

如果第一个参数不正确或不存在参数,批处理文件将显示使用说明并退出。

代码语言:javascript复制
echo Usage: catalina ( commands ... )
echo commands:
echo debug Start Catalina in a debugger
echo debug -security Debug Catalina with a security manager
echo embedded Start Catalina in embedded mode
echo jpda start Start Catalina under JPDA debugger
echo run Start Catalina in the current window
echo run -security Start in the current window with security
manager
echo start Start Catalina in a separate window
echo start -security Start in a separate window with security
manager
echo stop Stop Catalina
goto end

If the first parameter is start, it goes to doStart. If it is stop, control jumps to doStop, etc.

如果第一个参数是 start,则进入 doStart。

如果是 stop,则跳转到 doStop,等等。

After the doStart label, the catalina.bat file calls the shift command to check the next parameter, if any. If present, the next parameter must be -security. Otherwise, it will be ignored. If the next parameter is -security, the shift command is called again and the SECURITY_POLICY_FILE variable is set to �TALINA_BASE%confcatalina.policy.

在 doStart 标签之后,catalina.bat 文件会调用 shift 命令检查下一个参数(如果有)。

如果有,下一个参数必须是 -security。否则将被忽略。

如果下一个参数是 -security,则再次调用 shift 命令,并将 SECURITY_POLICY_FILE 变量设置为 �TALINA_BASE%confcatalina.policy。

代码语言:javascript复制
:doStart
shift
if not "%OS%" == "Windows_NT" goto noTitle
set _EXECJAVA=start "Tomcat" %_RUNJAVA%
goto gotTitle
:noTitle
set _EXECJAVA=start %_RUNJAVA%
:gotTitle
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set SECURITY_POLICY_FILE=�TALINA_BASE%confcatalina.policy

At this stage, the value of _EXECJAVA is either one of the following:

在此阶段,_EXECJAVA 的值为以下任一值:

代码语言:javascript复制
start "Tomcat" "%JAVA_HOME%binjava"
start "%JAVA_HOME%binjava"

It then jumps to execCmd

然后跳转到 execCmd

代码语言:javascript复制
goto execCmd

The commands below the execCmd label obtains the remaining unshifted command line arguments and save them to CMD_LINE_ARGS and then jump to doneSetArgs.

execCmd 标签下面的命令会获取剩余的未移位命令行参数,并将其保存到 CMD_LINE_ARGS,然后跳转到 doneSetArgs。

代码语言:javascript复制
:execCmd
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs

Here are the command lines next to doneSetArgs.

下面是 doneSetArgs 旁边的命令行。

代码语言:javascript复制
:doneSetArgs
rem Execute Java with the applicable properties
if not "%JPDA%" == "" goto doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity
%_EXECJAVA% %JAVA_OPTS% �TALINA_OPTS% �BUG_OPTS% -
Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -
Dcatalina.base="�TALINA_BASE%" -Dcatalina.home="�TALINA_HOME%" -
Djava.io.tmpdir="�TALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS%
�TION%

For example, in my computer, on calling catalina start the above long preceding command line (starting with %_EXECJAVA% and ends with �TION%) translates into the following:

例如,在我的计算机上,当调用catalina start命令时,上述长命令行(以%_EXECJAVA%开头,以�TION%结尾)会被翻译为以下内容:

代码语言:javascript复制
start "Tomcat" "C:j2sdk1.4.2_02binjava" -
Djava.endorsed.dirs="..commonendorsed" -classpath
"C:j2sdk1.4.2_02libtools.jar;..binbootstrap.jar" -
Dcatalina.base=".." -Dcatalina,home=".." -Djava.io.tmpdir="..temp"
org.apache.catalina.startup.Bootstrap start

You should be able to figure out what the command is when the catalina.bat file is called by passing different parameters.

当调用 catalina.bat 文件时,通过传递不同的参数,您应该可以找出命令是什么。

Starting Tomcat on Windows

The startup.bat file, given in Listing 17.10, is provided as the shortcut to call the catalina.bat file. It calls the catalina.bat file by passing one argument, start.

清单 17.10 中的 startup.bat 文件是调用 catalina.bat 文件的快捷方式。

它通过传递一个参数 start 来调用 catalina.bat 文件。

Listing 17.10: The startup.bat file

清单 17.10:startup.bat 文件

代码语言:javascript复制

    @echo off
if "%OS%" == "Windows_NT" setlocal
    rem ----------------------------------------------------------------
    rem Start script for the CATALINA Server
            rem
    rem $Id: startup.bat,v 1.4 2002/08/04 18:19:43 patrickl Exp $
    rem ----------------------------------------------------------------
    rem Guess CATALINA_HOME if not defined
if not "�TALINA_HOME%" == "" goto gotHome
    set CATALINA_HOME=.
            if exist "�TALINA_HOME%bincatalina.bat" goto okHome
    set CATALINA_HOME=..
            :gotHome
if exist "�TALINA_HOME%bincatalina.bat" goto okHome
    echo The CATALINA_HOME environment variable is not defined correctly
    echo This environment variable is needed to run this program
goto end
:okHome
    set EXECUTABLE=�TALINA_HOME%bincatalina.bat
    rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
    echo Cannot find %EXECUTABLE%
    echo This file is needed to run this program
goto end
:okExec
    rem Get remaining unshifted command line arguments and save them in the
    set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs
call "%EXECUTABLE%" start %CMD_LINE_ARGS%
:end
Stripping all rem and echo commands, you get the following:
if "%OS%" == "Windows_NT" setlocal
if not "�TALINA_HOME%" == "" goto gotHome
set CATALINA_HOME=.
if exist "�TALINA_HOME%bincatalina.bat" goto okHome
set CATALINA_HOME=..
:gotHome
if exist "�TALINA_HOME%bincatalina.bat" goto okHome
goto end
:okHome
set EXECUTABLE=�TALINA_HOME%bincatalina.bat
if exist "%EXECUTABLE%" goto okExec
goto end
:okExec
rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
    set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
    shift
goto setArgs
:doneSetArgs
    call "%EXECUTABLE%" start %CMD_LINE_ARGS%
            :end

Stopping Tomcat on Windows(在 Windows 上停止 Tomcat)

The shutdown.bat file is provided as a shortcut to call catalina.bat by passing the stop argument. The shutdown.bat file is given in Listing 17.11.

shutdown.bat 文件是通过传递 stop 参数调用 catalina.bat 的快捷方式。

清单 17.11 中给出了 shutdown.bat 文件。

Listing 17.11: The shutdown.bat file

清单 17.11:shutdown.bat 文件

代码语言:javascript复制
@echo off
if "%OS%" == "Windows_NT" setlocal
rem 
-------------------------------------------------------------------
--------
rem Stop script for the CATALINA Server
rem
rem $Id: shutdown.bat,v 1.3 2002/08/04 18:19:43 patrickl Exp $
rem 
-------------------------------------------------------------------
--------
rem Guess CATALINA_HOME if not defined
if not "�TALINA_HOME%" == "" goto gotHome
set CATALINA_HOME=.
if exist "�TALINA_HOME%bincatalina.bat" goto okHome
set CATALINA_HOME=..
:gotHome
if exist "�TALINA_HOME%bincatalina.bat" goto okHome
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome
set EXECUTABLE=�TALINA_HOME%bincatalina.bat
rem Check that target executable exists
if exist "%EXECUTABLE%" goto okExec
echo Cannot find %EXECUTABLE%
echo This file is needed to run this program
goto end
:okExec
rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs
call "%EXECUTABLE%" stop %CMD_LINE_ARGS%
:end

Running Tomcat on Unix/Linux(在Unix/Linux上运行Tomcat)

Tomcat comes with shell scripts for starting and stopping Tomcat in Unix/Linux. These shell scripts have an .sh extension and reside in the bin directory of �TALINA_HOME%. Four of them-catalina.sh, startup.sh, shutdown.sh, and setclasspath.sh--will be the topic of this section.

Tomcat自带了用于在Unix/Linux上启动和停止Tomcat的shell脚本。

这些shell脚本以.sh为扩展名,位于�TALINA_HOME%的bin目录中。

其中四个文件-catalina.sh、startup.sh、shutdown.sh和setclasspath.sh-将是本节的主题。

This section starts by offering an introduction to shell scripts for those not familiar with or need to brush up their knowledge of shell scripts. It then covers catalina.sh, startup.sh, and shutdown.sh. setclasspath.sh is called by catalina.sh and therefore is explained briefly in the subsection that discusses catalina.sh.

本节首先介绍了shell脚本,供那些对shell脚本不熟悉或需要复习的人使用。

然后介绍了catalina.sh、startup.sh和shutdown.sh。

setclasspath.sh由catalina.sh调用,因此在讨论catalina.sh的子节中简要解释了它。

Introduction to Writing Unix/Linux Shell Scripts( 编写 Unix/Linux Shell 脚本入门)

This introduction to shell scripts is meant to give you enough information to be able to read the shell scripts accompanying Tomcat, especially the catalina.sh, startup.sh, shutdown.sh, and setclasspath.sh files. It is far from a complete coverage of the topic, for which you have to find another resource.

这个关于shell脚本的介绍旨在给您足够的信息,以便能够阅读附带Tomcat的shell脚本,特别是catalina.sh、startup.sh、shutdown.sh和setclasspath.sh文件。

这远非对该主题的完全覆盖,您需要寻找其他资源。

Physically, a shell file is a text file. You can use vi or other text editors to write it. Make sure you change the permission mode of the file to give it the permission to run, using the following syntax.

从物理上讲,shell文件是一个文本文件。您可以使用vi或其他文本编辑器来编写它。

确保您更改文件的权限模式,以赋予其运行权限,使用以下语法。

代码语言:javascript复制
$ chmod  x scriptName
$ chmod 755 scriptName

This will set read, write, and execute permissions for the owner of the file, and read and execute permissions for group and other users.

这将为文件所有者设置读取、写入和执行权限,并为组和其他用户设置读取和执行权限。

You can then execute your script using one of the following commands:

然后就可以使用以下命令之一执行脚本了:

代码语言:javascript复制
bash scriptName
sh scriptName
./scriptName

The script is executed line by line by the interpreter. Your shell script can have any extension or no extension. However, the .sh extension is the most common.

解释器会逐行执行脚本。shell 脚本可以有任何扩展名,也可以没有扩展名。

不过,.sh 扩展名是最常见的。

The following are some common commands that are sufficient for you to understand Tomcat shell scripts.

以下是一些常用命令,足以让你了解 Tomcat shell 脚本。

comment

Use # to indicate that a piece of text is a comment and is not to be interpreted. The # character can appear at the beginning of a line, in which case the whole line is a comment.

使用 # 表示某段文字是注释,不能解释。

# 字符可以出现在一行的开头,在这种情况下,整行都是注释。

代码语言:javascript复制
# This is a comment

It can also appear in the middle of a line. In this case, the text to the right of the # character is a comment. For example:

它也可以出现在一行的中间。在这种情况下,# 字符右边的文本就是注释。例如

代码语言:javascript复制
echo Hello # print Hello

clear

Use clear to clear the screen. For example, the following script starts by clearing the screen and then prints a string.

使用 clear 清除屏幕。

例如,下面的脚本首先清除屏幕,然后打印一个字符串。

代码语言:javascript复制
clear
echo Shell scripts are useful

exit

Use the exit command to exit the shell script. exit is normally followed by an exit status, where 0 means a successful execution of the shell script and a non-zero value means an abnormal exit (possibly because there is an error). Therefore, if you want to exit because your shell has encountered a problem, write this:

使用 exit 命令退出 shell 脚本。

exit 后通常会有一个退出状态,其中 0 表示 shell 脚本执行成功,非零值表示异常退出(可能是因为出现了错误)。

因此,如果您想因 shell 遇到问题而退出,请这样写:

代码语言:javascript复制
exit 1

echo

Use echo to print a string to the screen. For example, the following command prints Hello World on the console.

使用 echo 将字符串打印到屏幕上。例如,以下命令会在控制台上打印 Hello World。

代码语言:javascript复制
echo Hello World

Calling A Function

You can use a period (.) to call a function or run another shell script. For example, the following command calls the test.sh script in the same directory as the running script.

您可以使用句号(.)来调用函数或运行另一个 shell 脚本。

例如,以下命令调用了与运行脚本位于同一目录下的 test.sh 脚本。

代码语言:javascript复制
. ./test.sh

System and User Defined Variables

Variable names must begin with an alphanumeric character or an underscore. You set the value of a variable by using the equal sign. For example, the following line sets the variable myVar with Tootsie.

变量名必须以字母数字或下划线开头。使用等号可以设置变量的值。

例如,下面一行用 Tootsie 设置变量 myVar。

代码语言:javascript复制
myVar=Tootsie

Note that there must not be a space before and after the equal sign. Also note that variable names are case sensitive.

注意等号前后不能有空格。还要注意,变量名区分大小写。

To define a NULL for a variable, use a blank string or simply leave out the right hand side of the equation:

要为变量定义 NULL,请使用空白字符串或直接省略等式的右边部分:

代码语言:javascript复制
myVar=
myVar=""

To access the value of a variable, use the dollar sign ($) before the name of the variable. For example, here is how you print the value of myVar on the screen

要访问变量的值,请在变量名前使用美元符号 ($)。

例如,以下是在屏幕上打印 myVar 值的方法

代码语言:javascript复制
echo $myVar

The Unix/Linux operating systems provide a number of system variables. For example, HOME contains the current user's home directory, PWD contains the user's current location, PATH contains the path that will be searched to find an invoked command, and so on.

Unix/Linux 操作系统提供了许多系统变量。

例如,"HOME "包含当前用户的主目录,"PWD "包含用户的当前位置,"PATH "包含为查找调用的命令而搜索的路径,等等。

Warning You should not change a system variable without knowing exactly the effect of doing so.

警告 在不清楚更改系统变量会产生什么影响的情况下,请勿更改该变量。

expr

Use expr to evaluate an expression. An expression must be enclosed in back quote characters. The back quote key is normally located to the left of the 1 key on your keyboard. Here is a shell script that uses arithmetic expressions:

使用 expr 评估一个表达式。表达式必须用反引号括起来。反引号键通常位于键盘上 1 键的左侧。下面是一个使用算术表达式的 shell 脚本:

代码语言:javascript复制
sum=`expr 100   200`
echo $sum

This will create a user defined variable named sum and assigns 300 (the result of adding 100 to 200) to it. Running this script gives you 300 on the console.

这将创建一个名为 sum 的用户自定义变量,并将 300(100 与 200 相加的结果)赋值给它。

运行此脚本后,控制台会显示 300。

Here is another example:

下面是另一个例子:

代码语言:javascript复制
echo `expr 200   300`

This prints the following result on the screen:

在屏幕上打印出以下结果:

500

The special uname expression evaluates to the name of the operating system. For example, if you're using Linux, the following command prints Linux on the console.

特殊的 uname 表达式求值为操作系统名称。例如,如果你使用的是 Linux,下面的命令就会在控制台上打印出 Linux。

代码语言:javascript复制
echo `uname`

The special dirname filePath returns the directory of the file. For example, dirname /home/user1/test.sh returns /home/user1.

特殊的 dirname filePath 返回文件的目录。例如,dirname /home/user1/test.sh 返回 /home/user1。

Accessing Parameters

Just like you can pass arguments to a function, you can pass parameters to a shell script. You use

1 to refer to the first parameter,

2 to the second, and so forth.

# returns the number of parameters.

@ returns all the parameters.

就像为函数传递参数一样,你也可以为 shell 脚本传递参数。

第一个参数用

1 表示,第二个参数用

2 表示,以此类推。

# 返回参数个数。

@ 返回所有参数。

shift

This command shifts all parameters down by one.

1 gets the value of

2,

2 gets the value of

3, and so on.

该命令将所有参数向下移动一个。1 得到 2 的值,2 得到 3 的值,依此类推。

if ... then ... [else ... ] fi

An if statement tests a condition and executes the appropriate list of commands. Its syntax is as follows.

if 语句测试一个条件并执行相应的命令列表。

其语法如下

代码语言:javascript复制
if condition then
 list of commands
[else
 list of commands
]
fi

Note You can also use elif for else if.

注意 您也可以使用 elif 表示 else if。

For example, the following script will print Starting the application if you pass start as the first argument and Stopping the application if you pass stop as the first argument.

例如,如果将 start 作为第一个参数,下面的脚本将打印 "启动应用程序";如果将 stop 作为第一个参数,下面的脚本将打印 "停止应用程序"。

代码语言:javascript复制
if [ "$1" = "start" ]; then
 echo Starting the application
fi
if [ "$1" = "stop" ]; then
 echo Stopping the application
fi

Note With the condition, there must be a space after [ and a space before ] 注意 在条件中,[后面必须有空格,]前面必须有空格。

The $1 is enclosed in double quotes so that the interpreter won't throw an exception if there is no parameter used to call the script.

$1 用双引号括起来,这样解释器就不会在没有参数用于调用脚本时产生异常。

$0 refers to the command that is used to invoke the script. For example, if you invoke the following a script named test.sh by typing the following:

$0 是指用于调用脚本的命令。例如,如果输入以下命令调用名为 test.sh 的脚本

代码语言:javascript复制
./test.sh

$0 will then contain ./test.sh.

$0 然后将包含 ./test.sh

The following can be used as a condition:

以下条件可以用作判断条件:

  • -f file, true is file exists
  • -r file, true if you have read access to file
  • -z string, true if string is empty.
  • -n string, true if string is not empty
  • string1 = string2, true if string1 equals string2.
  • string1 != string2, true if string1 is not equal to string2.
  • -f 文件,如果文件存在则为真
  • -r 文件,如果对文件具有读取权限则为真
  • -z 字符串,如果字符串为空则为真。
  • -n 字符串,如果字符串不为空则为真
  • string1 = string2,如果 string1 等于 string2 则为真。
  • string1 != string2,如果 string1 不等于 string2 则为真。

for Loop

Use the for loop to repeatedly run the same piece of code. The syntax is as follows:

使用 for 循环重复运行同一段代码。语法如下

代码语言:javascript复制
for { var } in {list}
do
 list of commands
done

For example:

例如

代码语言:javascript复制
for i in 1 2 3
do
 echo iteration $i
done
prints
iteration 1
iteration 2
iteration 3

while Loop

The while loop has the following syntax.

while 循环的语法如下

代码语言:javascript复制
while [ condition ]
do
 list of commands
done

For example

比如下面的例子:

代码语言:javascript复制
n=1
while [ $n -lt 3 ];
do
 echo iteration $n
 n=$((n   1))
done

The output is

输出结果为

代码语言:javascript复制
iteration 1
iteration 2

The -lt in [ $n -lt 3]; means less than, so the condition says if the value of n is less than 3.

[ $n -lt 3]; 中的 -lt 表示小于,因此条件是 n 的值是否小于 3。

case

case lets you write alternatives of program execution. The syntax is as follows

情况下,您可以编写程序执行的替代方案。语法如下

代码语言:javascript复制

case $variable-name in
pattern1)
 list of commands
 ;;
pattern2)
 list of commands
 ;;
*)
 list of commands
 ;;
esac

The ;; ends the list of commands. The *) pattern will be executed if no other patterns match.

“;;”结束命令列表。如果没有其他模式匹配,将执行“*”模式。

For example, the following script evaluates the name of the operating system and prints it on the console. If you are not using cygwin, OS400 or Linux, the Operating system not recognized will be printed.

例如,以下脚本评估操作系统的名称并将其打印在控制台上。

如果您没有使用cygwin、OS400或Linux,将打印“未识别的操作系统”。

代码语言:javascript复制
case "`uname`" in
 CYGWIN*) echo cygwin;;
 OS400*) echo OS400;;
 Linux*) echo Linux;;
 *) echo Operating system not recognized
esac

Output Redirection

Use > to redirect the output to a file. For example, the following command

使用 > 将输出重定向到文件。

例如,以下命令。

代码语言:javascript复制
echo Hello > myFile.txt

creates a file named myFile.txt and write Hello to it. No output is displayed to the screen.

创建名为 myFile.txt 的文件,并向其中写入 Hello。屏幕上不会显示任何输出。

Also note that 1>&2 redirects error message on stdout to stderr and 2>&1 redirects output on stderr to stdout.

还要注意的是,1>&2 会将 stdout 上的错误信息重定向到 stderr,而 2>&1 会将 stderr 上的输出重定向到 stdout。

Conditional Executions

You can write a command or condition that determines the execution of another command. In this case, you use && and ||

您可以编写一条决定另一条命令执行的命令或条件。在这种情况下,您可以使用 && 和 ||

代码语言:javascript复制
command1 && command2

command2 is executed if command1 returns a 0 exit status, command1 can also be replaced by a condition. If the condition evaluates to true, command2 will be executed. Otherwise, command2 will not be executed.

如果命令 1 返回 0 的退出状态,命令 2 将被执行。

如果条件返回值为 true,命令 2 将被执行。否则,不执行命令 2。

代码语言:javascript复制
command1 || command2

command2 is executed if command1 returns a non-zero exit status.

如果命令 1 返回非零的退出状态,则执行命令 2。

代码语言:javascript复制
command1 && command2 || command3

if command1 returns a 0 exit status, execute command2. Otherwise, execute command3.

如果命令 1 返回 0 的退出状态,则执行命令 2。否则,执行命令 3。

The catalina.sh File

The catalina.sh file is used to start and stop Tomcat on Unix/Linux. To start Tomcat, you pass start as the first parameter to catalina.sh. To stop Tomcat, pass stop as the first parameter, instead. Here is the list of valid arguments):

catalina.sh文件用于在Unix/Linux上启动和停止Tomcat。

要启动Tomcat,您需要将start作为catalina.sh的第一个参数传递。

要停止Tomcat,需要将stop作为第一个参数传递。以下是有效参数的列表:

  • debug. Start Catalina in a debugger (not available on OS400)
  • debug -security. Debug Catalina with a security manager (not available on OS400)
  • embedded. Start Catalina in embedded mode
  • jpda start. Start Catalina under JPDA debugger
  • run. Start Catalina in the current window
  • run -security. Start in the current window with security manager
  • start. Start Catalina in a separate window
  • start -security. Start in a separate window with security manager
  • stop. Stop Catalina
  • debug. 以调试器模式启动Catalina(在OS400上不可用)
  • debug -security. 使用安全管理器调试Catalina(在OS400上不可用)
  • embedded. 以嵌入模式启动Catalina
  • jpda start. 在JPDA调试器下启动Catalina
  • run. 在当前窗口中启动Catalina
  • run -security. 在当前窗口中启动Catalina,并使用安全管理器
  • start. 在单独的窗口中启动Catalina
  • start -security. 在单独的窗口中启动Catalina,并使用安全管理器
  • stop. 停止Catalina

The catalina.sh file is given in Listing 17.12. Based on the introduction given in the preceding subsection, you should be able to figure out what it does.

catalina.sh文件在17.12节中给出。

根据前面子节中的介绍,您应该能够弄清楚它的作用。

Listing 17.12: The catalina.sh file

17.12节:catalina.sh文件

代码语言:javascript复制

#!/bin/sh
#
---------------------------------------------------------------------
--------
# Start/Stop Script for the CATALINA Server
#
# Environment Variable Prequisites
#
# CATALINA_HOME May point at your Catalina "build" directory.
#
# CATALINA_BASE (Optional) Base directory for resolving dynamic
portions
# of a Catalina installation. If not present,
resolves to
# the same directory that CATALINA_HOME points to.
#
# CATALINA_OPTS (Optional) Java runtime options used when the
"start",
# "stop", or "run" command is executed.
#
# CATALINA_TMPDIR (Optional) Directory path location of temporary
directory
# the JVM should use (java.io.tmpdir). Defaults to
# $CATALINA_BASE/temp.
#
# JAVA_HOME Must point at your Java Development Kit
installation.
#
# JAVA_OPTS (Optional) Java runtime options used when the
"start",
# "stop", or "run" command is executed.
#
# JPDA_TRANSPORT (Optional) JPDA transport used when the "jpda
start"
# command is executed. The default is "dt_socket".
#
# JPDA_ADDRESS (Optional) Java runtime options used when the "jpda
start"
# command is executed. The default is 8000.
#
# JSSE_HOME (Optional) May point at your Java Secure Sockets
Extension
# (JSSE) installation, whose JAR files will be added
to the
# system class path used to start Tomcat.
#
# CATALINA_PID (Optional) Path of the file which should contains
the pid
# of catalina startup Java process, when start (fork)
is used
#
# $Id: catalina.sh,v 1.8 2003/09/02 12:23:13 remm Exp $
#
---------------------------------------------------------------------
--------
# OS specific support. $var _must_ be set to either true or false.
cygwin=false
os400=false
case "`uname`" in
CYGWIN*) cygwin=true;;
OS400*) os400=true;;
esac
# resolve links - $0 may be a softlink
PRG="$0"
while [ -h "$PRG" ]; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> (.*)$'`
if expr "$link" : '.*/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`/"$link"
fi
done
# Get standard environment variables
PRGDIR=`dirname "$PRG"`
CATALINA_HOME=`cd "$PRGDIR/.." ; pwd`
if [ -r "$CATALINA_HOME"/bin/setenv.sh ]; then
. "$CATALINA_HOME"/bin/setenv.sh
fi
# For Cygwin, ensure paths are in UNIX format before anything is
touched
if $cygwin; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CATALINA_HOME" ] && CATALINA_HOME=`cygpath --unix
"$CATALINA_HOME"`
[ -n "$CATALINA_BASE" ] && CATALINA_BASE=`cygpath --unix
"$CATALINA_BASE"`
[ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix
"$CLASSPATH"`
[ -n "$JSSE_HOME" ] && JSSE_HOME=`cygpath --path --unix "$JSSE_HOME"`
fi
# For OS400
if $os400; then
# Set job priority to standard for interactive (interactive - 6) by
using
# the interactive priority - 6, the helper threads that respond to
requests
# will be running at the same priority as interactive jobs.
COMMAND='chgjob job('$JOBNAME') runpty(6)'
system $COMMAND
# Enable multi threading
export QIBM_MULTI_THREADED=Y
fi
# Get standard Java environment variables
if [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]; then
BASEDIR="$CATALINA_HOME"
. "$CATALINA_HOME"/bin/setclasspath.sh
else
echo "Cannot find $CATALINA_HOME/bin/setclasspath.sh"
echo "This file is needed to run this program"
exit 1
fi
# Add on extra jar files to CLASSPATH
if [ -n "$JSSE_HOME" ]; then
CLASSPATH="$CLASSPATH":"$JSSE_HOME"/lib/jcert.jar:"$JSSE_HOME"/lib/j
net
.jar:"$JSSE_HOME"/lib/jsse.jar
fi
CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar
if [ -z "$CATALINA_BASE" ] ; then
CATALINA_BASE="$CATALINA_HOME"
fi
if [ -z "$CATALINA_TMPDIR" ] ; then
# Define the java.io.tmpdir to use for Catalina
CATALINA_TMPDIR="$CATALINA_BASE"/temp
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
CATALINA_HOME=`cygpath --path --windows "$CATALINA_HOME"`
CATALINA_BASE=`cygpath --path --windows "$CATALINA_BASE"`
CATALINA_TMPDIR=`cygpath --path --windows "$CATALINA_TMPDIR"`
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
JSSE_HOME=`cygpath --path --windows "$JSSE_HOME"`
fi
# ----- Execute The Requested Command ---------------------------------
--------
echo "Using CATALINA_BASE: $CATALINA_BASE"
echo "Using CATALINA_HOME: $CATALINA_HOME"
echo "Using CATALINA_TMPDIR: $CATALINA_TMPDIR"
echo "Using JAVA_HOME: $JAVA_HOME"
if [ "$1" = "jpda" ] ; then
if [ -z "$JPDA_TRANSPORT" ]; then
JPDA_TRANSPORT="dt_socket"
fi
if [ -z "$JPDA_ADDRESS" ]; then
JPDA_ADDRESS="8000"
fi
if [ -z "$JPDA_OPTS" ]; then
JPDA_OPTS="-Xdebug -
Xrunjdwp:transport=$JPDA_TRANSPORT,address=$JPDA_ADDRESS,server=y,susp
e
nd=n"
fi
CATALINA_OPTS="$CATALINA_OPTS $JPDA_OPTS"
shift
fi
if [ "$1" = "debug" ] ; then
if $os400; then
echo "Debug command not available on OS400"
exit 1
else
shift
if [ "$1" = "-security" ] ; then
echo "Using Security Manager"
shift
exec "$_RUNJDB" $JAVA_OPTS $CATALINA_OPTS 
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath
"$CLASSPATH" 
-sourcepath "$CATALINA_HOME"/../../jakarta-tomcat4.0/catalina/src/share 
-Djava.security.manager 
-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy 
-Dcatalina.base="$CATALINA_BASE" 
-Dcatalina.home="$CATALINA_HOME" 
-Djava.io.tmpdir="$CATALINA_TMPDIR" 
org.apache.catalina.startup.Bootstrap "$@" start
else
exec "$_RUNJDB" $JAVA_OPTS $CATALINA_OPTS 
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath
"$CLASSPATH" 
-sourcepath "$CATALINA_HOME"/../../jakarta-tomcat4.0/catalina/src/share 
-Dcatalina.base="$CATALINA_BASE" 
-Dcatalina.home="$CATALINA_HOME" 
-Djava.io.tmpdir="$CATALINA_TMPDIR" 
org.apache.catalina.startup.Bootstrap "$@" start
fi
fi
elif [ "$1" = "embedded" ] ; then
shift
echo "Embedded Classpath: $CLASSPATH"
exec "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS 
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath "$CLASSPATH"

-Dcatalina.base="$CATALINA_BASE" 
-Dcatalina.home="$CATALINA_HOME" 
-Djava.io.tmpdir="$CATALINA_TMPDIR" 
org.apache.catalina.startup.Embedded "$@"
elif [ "$1" = "run" ]; then
shift
if [ "$1" = "-security" ] ; then
echo "Using Security Manager"
shift
exec "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS 
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath
"$CLASSPATH" 
-Djava.security.manager 
-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy 
-Dcatalina.base="$CATALINA_BASE" 
-Dcatalina.home="$CATALINA_HOME" 
-Djava.io.tmpdir="$CATALINA_TMPDIR" 
org.apache.catalina.startup.Bootstrap "$@" start
else
exec "$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS 
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath
"$CLASSPATH" 
-Dcatalina.base="$CATALINA_BASE" 
-Dcatalina.home="$CATALINA_HOME" 
-Djava.io.tmpdir="$CATALINA_TMPDIR" 
org.apache.catalina.startup.Bootstrap "$@" start
fi
elif [ "$1" = "start" ] ; then
shift
touch "$CATALINA_BASE"/logs/catalina.out
if [ "$1" = "-security" ] ; then
echo "Using Security Manager"
shift
"$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS 
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath
"$CLASSPATH" 
-Djava.security.manager 
-Djava.security.policy=="$CATALINA_BASE"/conf/catalina.policy 
-Dcatalina.base="$CATALINA_BASE" 
-Dcatalina.home="$CATALINA_HOME" 
-Djava.io.tmpdir="$CATALINA_TMPDIR" 
org.apache.catalina.startup.Bootstrap "$@" start 
>> "$CATALINA_BASE"/logs/catalina.out 2>&1 &
if [ ! -z "$CATALINA_PID" ]; then
echo $! > $CATALINA_PID
fi
else
"$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS 
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -classpath
"$CLASSPATH" 
-Dcatalina.base="$CATALINA_BASE" 
-Dcatalina.home="$CATALINA_HOME" 
-Djava.io.tmpdir="$CATALINA_TMPDIR" 
org.apache.catalina.startup.Bootstrap "$@" start 
>> "$CATALINA_BASE"/logs/catalina.out 2>&1 &
if [ ! -z "$CATALINA_PID" ]; then
echo $! > $CATALINA_PID
fi
fi
elif [ "$1" = "stop" ] ; then
shift
"$_RUNJAVA" $JAVA_OPTS $CATALINA_OPTS 
-Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" -clasapath "$CLASSPATH"

-Dcatalina.base="$CATALINA_BASE" 
-Dcatalina.home="$CATALINA_HOME" 
-Djava.io.tmpdir="$CATALINA_TMPDIR" 
org.apache.catalina.startup.Bootstrap "$@" stop
if [ "$1" = "-force" ] ; then
shift
if [ ! -z "$CATALINA_PID" ]; then
echo "Killing: `cat $CATALINA_PID`"
kill -9 `cat $CATALINA_PID`
fi
fi
else
echo "Usage: catalina.sh ( commands ... )"
echo "commands:"
if $os400; then
echo " debug Start Catalina in a debugger (not
available on OS400)"
echo " debug -security Debug Catalina with a security manager
(not available on OS400)"
else
echo " debug Start Catalina in a debugger"
echo " debug -security Debug Catalina with a security manager"
fi
echo " embedded Start Catalina in embedded mode"
echo " jpda start Start Catalina under JPDA debugger"
echo " run Start Catalina in the current window"
echo " run -security Start in the current window with security
manager"
echo " start Start Catalina in a separate window"
echo " start -security Start in a separate window with security
manager"
echo " stop Stop Catalina"
exit 1
fi

Starting Tomcat on Linux/Unix( 在 Linux/Unix 上启动 Tomcat)

To make your life even easier, you can use the startup.sh to start Tomcat, startup.sh sets the correct environment variables and calls catalina.sh by passing start. The startup.sh is given in Listing 17.13.

为了让您的工作更轻松,您可以使用 startup.sh 启动 Tomcat,startup.sh 设置正确的环境变量,并通过传递 start 调用 catalina.sh。

清单 17.13 提供了 startup.sh 文件。

Listing 17.13: The startup.sh file

清单 17.13:startup.sh 文件

代码语言:javascript复制
#!/bin/sh
# 
---------------------------------------------------------------------
-
--------
# Start Script for the CATALINA Server
#
# $Id: startup.sh,v 1.3 2002/08/04 18:19:43 patrickl Exp $
# 
---------------------------------------------------------------------
--------
# resolve links - $0 may be a softlink
PRG="$0"
while [ -h "$PRG" ] ; do
 ls=`ls -ld "$PRG"`
 link=`expr "$ls" : '.*-> (.*)$'`
 if expr "$link" : '.*/.*' > /dev/null; then
 PRG="$link"
 else
 PRG=`dirname "$PRG"`/"$link"
 fi
done
PRGDIR=`dirname "$PRG"`
EXECUTABLE=catalina.sh
# Check that target executable exists
if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then
 echo "Cannot find $PRGDIR/$EXECUTABLE"
 echo "This file is needed to run this program"
 exit 1
fi
exec "$PRGDIR"/"$EXECUTABLE" start "$@"

Stopping Tomcat on Linux/Unix(在 Linux/Unix 上停止 Tomcat)

You can easily stop Tomcat by running the shutdown.sh script. This script calls catalina.sh and passes stop as an argument to it.

您可以通过运行 shutdown.sh 脚本轻松停止 Tomcat。

该脚本调用 catalina.sh,并将 stop 作为参数传递给它。

Listing 17.14 presents shutdown.sh.

清单 17.14 介绍了 shutdown.sh。

代码语言:javascript复制

#!/bin/sh
#
---------------------------------------------------------------------
# Stop script for the CATALINA Server
#
# $Id: shutdown.sh,v 1.3 2002/08/04 18:19:43 patrickl Exp $
#
---------------------------------------------------------------------
# resolve links - $0 may be a softlink
PRG="$0"
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> (.*)$'`
if expr "$link" : '.*/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`/"$link"
fi
done
PRGDIR=`dirname "$PRG"`
EXECUTABLE=catalina.sh
# Check that target executable exists
if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then
echo "Cannot find $PRGDIR/$EXECUTABLE"
echo "This file is needed to run this program"
exit 1
fi
exec "$PRGDIR"/"$EXECUTABLE" stop "S@"

Listing 17.14: The shutdown.sh File

清单 17.14:shutdown.sh 文件

Summary

This chapter explains the two classes for starting up the application, Catalina and Bootstrap, both of which are members of the org.apache.catalina.startup package. You have also learned about batch files and shell scripts that provides easy ways to start and stop Tomcat on Windows and Unix/Linux.

本章介绍了用于启动应用程序的两个类:Catalina 和 Bootstrap,它们都是 org.apache.catalina.startup 包的成员。

您还了解了批处理文件和 shell 脚本,它们提供了在 Windows 和 Unix/Linux 上启动和停止 Tomcat 的简便方法。

0 人点赞