ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/catalina/startup/Bootstrap.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/catalina/startup/Bootstrap.java
Status
scanned
Type
file
Name
Bootstrap.java
Extension
.java
Programming language
Java
Mime type
text/plain
File type
ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
20670 (20.2 KB)
MD5
8dd1d28a9dfa5feeddb8edb2c30e2f16
SHA1
be35951c7e6a773d7e06350cee7ee6c20148de03
SHA256
ee057986381976289175a71ad6f479a4a61bf26479459507e6ec40b724dce9b0
SHA512

      
    
SHA1_git
0233d7fd2e48dde3a649437fd8cee311cf80bbf0
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
Bootstrap.java | 20.2 KB |

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.catalina.startup; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.catalina.startup.ClassLoaderFactory.Repository; import org.apache.catalina.startup.ClassLoaderFactory.RepositoryType; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; /** * Bootstrap loader for Catalina. This application constructs a class loader for use in loading the Catalina internal * classes (by accumulating all of the JAR files found in the "server" directory under "catalina.home"), and starts the * regular execution of the container. The purpose of this roundabout approach is to keep the Catalina internal classes * (and any other classes they depend on, such as an XML parser) out of the system class path and therefore not visible * to application level classes. */ public final class Bootstrap { private static final Log log = LogFactory.getLog(Bootstrap.class); /** * Daemon object used by main. */ private static final Object daemonLock = new Object(); private static volatile Bootstrap daemon = null; private static final File catalinaBaseFile; private static final File catalinaHomeFile; private static final Pattern PATH_PATTERN = Pattern.compile("(\"[^\"]*\")|(([^,])*)"); static { // Will always be non-null String userDir = System.getProperty("user.dir"); // Home first String home = System.getProperty(Constants.CATALINA_HOME_PROP); File homeFile = null; if (home != null) { File f = new File(home); try { homeFile = f.getCanonicalFile(); } catch (IOException ioe) { homeFile = f.getAbsoluteFile(); } } if (homeFile == null) { // First fall-back. See if current directory is a bin directory // in a normal Tomcat install File bootstrapJar = new File(userDir, "bootstrap.jar"); if (bootstrapJar.exists()) { File f = new File(userDir, ".."); try { homeFile = f.getCanonicalFile(); } catch (IOException ioe) { homeFile = f.getAbsoluteFile(); } } } if (homeFile == null) { // Second fall-back. Use current directory File f = new File(userDir); try { homeFile = f.getCanonicalFile(); } catch (IOException ioe) { homeFile = f.getAbsoluteFile(); } } catalinaHomeFile = homeFile; System.setProperty(Constants.CATALINA_HOME_PROP, catalinaHomeFile.getPath()); // Then base String base = System.getProperty(Constants.CATALINA_BASE_PROP); if (base == null) { catalinaBaseFile = catalinaHomeFile; } else { File baseFile = new File(base); try { baseFile = baseFile.getCanonicalFile(); } catch (IOException ioe) { baseFile = baseFile.getAbsoluteFile(); } catalinaBaseFile = baseFile; } System.setProperty(Constants.CATALINA_BASE_PROP, catalinaBaseFile.getPath()); } // -------------------------------------------------------------- Variables /** * Daemon reference. */ private Object catalinaDaemon = null; ClassLoader commonLoader = null; ClassLoader catalinaLoader = null; ClassLoader sharedLoader = null; // -------------------------------------------------------- Private Methods private void initClassLoaders() { try { commonLoader = createClassLoader("common", null); if (commonLoader == null) { // no config file, default to this loader - we might be in a 'single' env. commonLoader = this.getClass().getClassLoader(); } catalinaLoader = createClassLoader("server", commonLoader); sharedLoader = createClassLoader("shared", commonLoader); } catch (Throwable t) { handleThrowable(t); log.error("Class loader creation threw exception", t); System.exit(1); } } private ClassLoader createClassLoader(String name, ClassLoader parent) throws Exception { String value = CatalinaProperties.getProperty(name + ".loader"); if ((value == null) || (value.isEmpty())) { return parent; } value = replace(value); List<Repository> repositories = new ArrayList<>(); String[] repositoryPaths = getPaths(value); for (String repository : repositoryPaths) { // Check for a JAR URL repository try { URI uri = new URI(repository); @SuppressWarnings("unused") URL url = uri.toURL(); repositories.add(new Repository(repository, RepositoryType.URL)); continue; } catch (IllegalArgumentException | MalformedURLException | URISyntaxException e) { // Ignore } // Local repository if (repository.endsWith("*.jar")) { repository = repository.substring(0, repository.length() - "*.jar".length()); repositories.add(new Repository(repository, RepositoryType.GLOB)); } else if (repository.endsWith(".jar")) { repositories.add(new Repository(repository, RepositoryType.JAR)); } else { repositories.add(new Repository(repository, RepositoryType.DIR)); } } return ClassLoaderFactory.createClassLoader(repositories, parent); } /** * System property replacement in the given string. * * @param str The original string * * @return the modified string */ private String replace(String str) { // Implementation is copied from ClassLoaderLogManager.replace(), // but added special processing for catalina.home and catalina.base. String result = str; int pos_start = str.indexOf("${"); if (pos_start >= 0) { StringBuilder builder = new StringBuilder(); int pos_end = -1; while (pos_start >= 0) { builder.append(str, pos_end + 1, pos_start); pos_end = str.indexOf('}', pos_start + 2); if (pos_end < 0) { pos_end = pos_start - 1; break; } String propName = str.substring(pos_start + 2, pos_end); String replacement; if (propName.isEmpty()) { replacement = null; } else if (Constants.CATALINA_HOME_PROP.equals(propName)) { replacement = getCatalinaHome(); } else if (Constants.CATALINA_BASE_PROP.equals(propName)) { replacement = getCatalinaBase(); } else { replacement = System.getProperty(propName); } if (replacement != null) { builder.append(replacement); } else { builder.append(str, pos_start, pos_end + 1); } pos_start = str.indexOf("${", pos_end + 1); } builder.append(str, pos_end + 1, str.length()); result = builder.toString(); } return result; } /** * Initialize daemon. * * @throws Exception Fatal initialization error */ public void init() throws Exception { initClassLoaders(); Thread.currentThread().setContextClassLoader(catalinaLoader); // Load our startup class and call its process() method if (log.isTraceEnabled()) { log.trace("Loading startup class"); } Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina"); Object startupInstance = startupClass.getConstructor().newInstance(); // Set the shared extensions class loader if (log.isTraceEnabled()) { log.trace("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); catalinaDaemon = startupInstance; } /** * Load daemon. */ private void load(String[] arguments) throws Exception { // Call the load() method String methodName = "load"; Object[] param; Class<?>[] paramTypes; if (arguments == null || arguments.length == 0) { paramTypes = null; param = null; } else { paramTypes = new Class[1]; paramTypes[0] = arguments.getClass(); param = new Object[1]; param[0] = arguments; } Method method = catalinaDaemon.getClass().getMethod(methodName, paramTypes); if (log.isTraceEnabled()) { log.trace("Calling startup class " + method); } method.invoke(catalinaDaemon, param); } /** * getServer() for configtest */ private Object getServer() throws Exception { String methodName = "getServer"; Method method = catalinaDaemon.getClass().getMethod(methodName); return method.invoke(catalinaDaemon); } // ----------------------------------------------------------- Main Program /** * Load the Catalina daemon. * * @param arguments Initialization arguments * * @throws Exception Fatal initialization error */ public void init(String[] arguments) throws Exception { init(); load(arguments); } /** * Start the Catalina daemon. * * @throws Exception Fatal start error */ public void start() throws Exception { if (catalinaDaemon == null) { init(); } Method method = catalinaDaemon.getClass().getMethod("start", (Class<?>[]) null); method.invoke(catalinaDaemon, (Object[]) null); } /** * Stop the Catalina Daemon. * * @throws Exception Fatal stop error */ public void stop() throws Exception { Method method = catalinaDaemon.getClass().getMethod("stop", (Class<?>[]) null); method.invoke(catalinaDaemon, (Object[]) null); } /** * Stop the standalone server. * * @throws Exception Fatal stop error */ public void stopServer() throws Exception { Method method = catalinaDaemon.getClass().getMethod("stopServer", (Class<?>[]) null); method.invoke(catalinaDaemon, (Object[]) null); } /** * Stop the standalone server. * * @param arguments Command line arguments * * @throws Exception Fatal stop error */ public void stopServer(String[] arguments) throws Exception { Object[] param; Class<?>[] paramTypes; if (arguments == null || arguments.length == 0) { paramTypes = null; param = null; } else { paramTypes = new Class[1]; paramTypes[0] = arguments.getClass(); param = new Object[1]; param[0] = arguments; } Method method = catalinaDaemon.getClass().getMethod("stopServer", paramTypes); method.invoke(catalinaDaemon, param); } /** * Set flag. * * @param await <code>true</code> if the daemon should block * * @throws Exception Reflection error */ public void setAwait(boolean await) throws Exception { Class<?>[] paramTypes = new Class[1]; paramTypes[0] = Boolean.TYPE; Object[] paramValues = new Object[1]; paramValues[0] = Boolean.valueOf(await); Method method = catalinaDaemon.getClass().getMethod("setAwait", paramTypes); method.invoke(catalinaDaemon, paramValues); } public boolean getAwait() throws Exception { Class<?>[] paramTypes = new Class[0]; Object[] paramValues = new Object[0]; Method method = catalinaDaemon.getClass().getMethod("getAwait", paramTypes); Boolean b = (Boolean) method.invoke(catalinaDaemon, paramValues); return b.booleanValue(); } /** * Destroy the Catalina Daemon. */ public void destroy() { } /** * Main method and entry point when starting Tomcat via the provided scripts. * * @param args Command line arguments to be processed */ public static void main(String[] args) { synchronized (daemonLock) { if (daemon == null) { // Don't set daemon until init() has completed Bootstrap bootstrap = new Bootstrap(); try { bootstrap.init(); } catch (Throwable t) { handleThrowable(t); log.error("Init exception", t); return; } daemon = bootstrap; } else { // When running as a service the call to stop will be on a new // thread so make sure the correct class loader is used to // prevent a range of class not found exceptions. Thread.currentThread().setContextClassLoader(daemon.catalinaLoader); } } try { String command = "start"; if (args.length > 0) { command = args[args.length - 1]; } switch (command) { case "startd": args[args.length - 1] = "start"; daemon.load(args); daemon.start(); break; case "stopd": args[args.length - 1] = "stop"; daemon.stop(); break; case "start": daemon.setAwait(true); daemon.load(args); daemon.start(); if (null == daemon.getServer()) { System.exit(1); } break; case "stop": daemon.stopServer(args); break; case "configtest": daemon.load(args); if (null == daemon.getServer()) { System.exit(1); } System.exit(0); break; default: log.warn("Bootstrap: command \"" + command + "\" does not exist."); break; } } catch (Throwable t) { // Unwrap the Exception for clearer error reporting Throwable throwable = t; if (throwable instanceof InvocationTargetException && throwable.getCause() != null) { throwable = throwable.getCause(); } handleThrowable(throwable); log.error("Error running command", throwable); System.exit(1); } } /** * Obtain the name of configured home (binary) directory. Note that home and base may be the same (and are by * default). * * @return the catalina home */ public static String getCatalinaHome() { return catalinaHomeFile.getPath(); } /** * Obtain the name of the configured base (instance) directory. Note that home and base may be the same (and are by * default). If this is not set the value returned by {@link #getCatalinaHome()} will be used. * * @return the catalina base */ public static String getCatalinaBase() { return catalinaBaseFile.getPath(); } /** * Obtain the configured home (binary) directory. Note that home and base may be the same (and are by default). * * @return the catalina home as a file */ public static File getCatalinaHomeFile() { return catalinaHomeFile; } /** * Obtain the configured base (instance) directory. Note that home and base may be the same (and are by default). If * this is not set the value returned by {@link #getCatalinaHomeFile()} will be used. * * @return the catalina base as a file */ public static File getCatalinaBaseFile() { return catalinaBaseFile; } // Copied from ExceptionUtils since that class is not visible during start static void handleThrowable(Throwable t) { if (t instanceof StackOverflowError) { // Swallow silently - it should be recoverable return; } if (t instanceof VirtualMachineError) { throw (VirtualMachineError) t; } // All other instances of Throwable will be silently swallowed } // Copied from ExceptionUtils so that there is no dependency on utils static Throwable unwrapInvocationTargetException(Throwable t) { if (t instanceof InvocationTargetException && t.getCause() != null) { return t.getCause(); } return t; } // Protected for unit testing static String[] getPaths(String value) { List<String> result = new ArrayList<>(); Matcher matcher = PATH_PATTERN.matcher(value); while (matcher.find()) { String path = value.substring(matcher.start(), matcher.end()); path = path.trim(); if (path.isEmpty()) { continue; } char first = path.charAt(0); char last = path.charAt(path.length() - 1); if (first == '"' && last == '"' && path.length() > 1) { path = path.substring(1, path.length() - 1); path = path.trim(); if (path.isEmpty()) { continue; } } else if (path.contains("\"")) { // Unbalanced quotes // Too early to use standard i18n support. The class path hasn't // been configured. throw new IllegalArgumentException( "The double quote [\"] character can only be used to quote paths. It must " + "not appear in a path. This loader path is not valid: [" + value + "]"); } else { // Not quoted - NO-OP } result.add(path); } return result.toArray(new String[0]); } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
6.5
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9