FileDocCategorySizeDatePackage
Embedded.javaAPI DocGlassfish v2 API36158Fri May 04 22:32:30 BST 2007org.apache.catalina.startup

Embedded

public class Embedded extends org.apache.catalina.core.StandardService implements org.apache.catalina.Lifecycle
Convenience class to embed a Catalina servlet container environment inside another application. You must call the methods of this class in the following order to ensure correct operation.
  • Instantiate a new instance of this class.
  • Set the relevant properties of this object itself. In particular, you will want to establish the default Logger to be used, as well as the default Realm if you are using container-managed security.
  • Call createEngine() to create an Engine object, and then call its property setters as desired.
  • Call createHost() to create at least one virtual Host associated with the newly created Engine, and then call its property setters as desired. After you customize this Host, add it to the corresponding Engine with engine.addChild(host).
  • Call createContext() to create at least one Context associated with each newly created Host, and then call its property setters as desired. You SHOULD create a Context with a pathname equal to a zero-length string, which will be used to process all requests not mapped to some other Context. After you customize this Context, add it to the corresponding Host with host.addChild(context).
  • Call addEngine() to attach this Engine to the set of defined Engines for this object.
  • Call createConnector() to create at least one TCP/IP connector, and then call its property setters as desired.
  • Call addConnector() to attach this Connector to the set of defined Connectors for this object. The added Connector will use the most recently added Engine to process its received requests.
  • Repeat the above series of steps as often as required (although there will typically be only one Engine instance created).
  • Call start() to initiate normal operations of all the attached components.
After normal operations have begun, you can add and remove Connectors, Engines, Hosts, and Contexts on the fly. However, once you have removed a particular component, it must be thrown away -- you can create a new one with the same characteristics if you merely want to do a restart.

To initiate a normal shutdown, call the stop() method of this object.

IMPLEMENTATION NOTE: The main() method of this class is a simple example that exercizes the features of dynamically starting and stopping various components. You can execute this by executing the following steps (on a Unix platform):

cd $CATALINA_HOME
./bin/catalina.sh embedded
author
Craig R. McClanahan
version
$Revision: 1.13 $ $Date: 2007/05/05 05:32:29 $

Fields Summary
private static com.sun.org.apache.commons.logging.Log
log
protected boolean
useNaming
Is naming enabled ?
protected org.apache.catalina.Engine[]
engines
The set of Engines that have been deployed in this server. Normally there will only be one.
protected HashMap
authenticators
Custom mappings of login methods to authenticators
protected static final String
info
Descriptive information about this server implementation.
protected org.apache.catalina.util.LifecycleSupport
lifecycle
The lifecycle event support for this component.
protected org.apache.catalina.Logger
logger
The default logger to be used by this component itself. Unless this is overridden, log messages will be writted to standard output.
protected org.apache.catalina.Realm
realm
The default realm to be used by all containers associated with this compoennt.
protected static final org.apache.catalina.util.StringManager
sm
The string manager for this package.
protected String
socketFactory
The socket factory that will be used when a secure Connector is created. If a standard Connector is created, the internal (to the Connector class default socket factory class) will be used instead.
protected boolean
started
Has this component been started yet?
protected boolean
await
Use await.
Constructors Summary
public Embedded()
Construct a new instance of this class with default properties.


    // ----------------------------------------------------------- Constructors


                   
      

        this(null, null);

    
public Embedded(org.apache.catalina.Logger logger, org.apache.catalina.Realm realm)
Construct a new instance of this class with specified properties.

param
logger Logger implementation to be inherited by all components (unless overridden further down the container hierarchy)
param
realm Realm implementation to be inherited by all components (unless overridden further down the container hierarchy)


        super();
        setLogger(logger);
        setRealm(realm);
        setSecurityProtection();
        
    
Methods Summary
public voidaddAuthenticator(org.apache.catalina.Authenticator authenticator, java.lang.String loginMethod)

        if ((authenticator != null) && !(authenticator instanceof Valve)) {
            throw new IllegalArgumentException(
                sm.getString("embedded.authenticatorNotInstanceOfValve"));
        }
        if (authenticators == null) {
            synchronized (this) {
                if (authenticators == null) {
                    authenticators = new HashMap();
                }
            }
        }
        authenticators.put(loginMethod, authenticator);
    
public synchronized voidaddConnector(org.apache.catalina.Connector connector)
Add a new Connector to the set of defined Connectors. The newly added Connector will be associated with the most recently added Engine.

param
connector The connector to be added
exception
IllegalStateException if no engines have been added yet


        if( log.isDebugEnabled() ) {
            log.debug("Adding connector (" + connector.getInfo() + ")");
        }

        // Make sure we have a Container to send requests to
        if (engines.length < 1)
            throw new IllegalStateException
                (sm.getString("embedded.noEngines"));

        /*
         * Add the connector. This will set the connector's container to the
         * most recently added Engine
         */
        super.addConnector(connector);
    
public synchronized voidaddEngine(org.apache.catalina.Engine engine)
Add a new Engine to the set of defined Engines.

param
engine The engine to be added


        if( log.isDebugEnabled() )
            log.debug("Adding engine (" + engine.getInfo() + ")");

        // Add this Engine to our set of defined Engines
        Engine results[] = new Engine[engines.length + 1];
        for (int i = 0; i < engines.length; i++)
            results[i] = engines[i];
        results[engines.length] = engine;
        engines = results;

        // Start this Engine if necessary
        if (started && (engine instanceof Lifecycle)) {
            try {
                ((Lifecycle) engine).start();
            } catch (LifecycleException e) {
                log.error("Engine.start", e);
            }
        }

        this.container = engine;
    
public voidaddLifecycleListener(org.apache.catalina.LifecycleListener listener)
Add a lifecycle event listener to this component.

param
listener The listener to add


        lifecycle.addLifecycleListener(listener);

    
public org.apache.catalina.ConnectorcreateConnector(java.net.InetAddress address, int port, boolean secure)
Create, configure, and return a new TCP/IP socket connector based on the specified properties.

param
address InetAddress to bind to, or null if the connector is supposed to bind to all addresses on this server
param
port Port number to listen to
param
secure true if the generated connector is supposed to be SSL-enabled, and false otherwise

	return createConnector(address != null? address.toString() : null,
			       port, secure);
    
public org.apache.catalina.ConnectorcreateConnector(java.lang.String address, int port, boolean secure)

        String protocol = "http";
        if (secure) {
            protocol = "https";
        }

        return createConnector(address, port, protocol);
    
public org.apache.catalina.ConnectorcreateConnector(java.net.InetAddress address, int port, java.lang.String protocol)

	return createConnector(address != null? address.toString() : null,
			       port, protocol);
    
public org.apache.catalina.ConnectorcreateConnector(java.lang.String address, int port, java.lang.String protocol)


        Connector connector = null;

	if (address != null) {
	    /*
	     * InetAddress.toString() returns a string of the form
	     * "<hostname>/<literal_IP>". Get the latter part, so that the
	     * address can be parsed (back) into an InetAddress using
	     * InetAddress.getByName().
	     */
	    int index = address.indexOf('/");
	    if (index != -1) {
		address = address.substring(index + 1);
	    }
	}

	if (log.isDebugEnabled()) {
            log.debug("Creating connector for address='" +
		      ((address == null) ? "ALL" : address) +
		      "' port='" + port + "' protocol='" + protocol + "'");
	}

        try {

            Class clazz = 
                Class.forName("org.apache.coyote.tomcat5.CoyoteConnector");
            connector = (Connector) clazz.newInstance();

            if (address != null) {
                IntrospectionUtils.setProperty(connector, "address", 
                                               "" + address);
            }
            IntrospectionUtils.setProperty(connector, "port", "" + port);

            if (protocol.equals("ajp")) {
                IntrospectionUtils.setProperty
                    (connector, "protocolHandlerClassName",
                     "org.apache.jk.server.JkCoyoteHandler");
            } else if (protocol.equals("https")) {
                connector.setScheme("https");
                connector.setSecure(true);
                try {
                    Class serverSocketFactoryClass = Class.forName
                       ("org.apache.coyote.tomcat5.CoyoteServerSocketFactory");
                    ServerSocketFactory factory = 
                        (ServerSocketFactory) 
                        serverSocketFactoryClass.newInstance();
                    connector.setFactory(factory);
                } catch (Exception e) {
                    log.error("Couldn't load SSL server socket factory.");
                }
            }

        } catch (Exception e) {
            log.error("Couldn't create connector.");
        } 

        return (connector);

    
public org.apache.catalina.ContextcreateContext(java.lang.String path, java.lang.String docBase)
Create, configure, and return a Context that will process all HTTP requests received from one of the associated Connectors, and directed to the specified context path on the virtual host to which this Context is connected.

After you have customized the properties, listeners, and Valves for this Context, you must attach it to the corresponding Host by calling:

host.addChild(context);
which will also cause the Context to be started if the Host has already been started.

param
path Context path of this application ("" for the default application for this host, must start with a slash otherwise)
param
docBase Absolute pathname to the document base directory for this web application
exception
IllegalArgumentException if an invalid parameter is specified


        if( log.isDebugEnabled() )
            log.debug("Creating context '" + path + "' with docBase '" +
                       docBase + "'");

        StandardContext context = new StandardContext();

        context.setDebug(debug);
        context.setDocBase(docBase);
        context.setPath(path);

        ContextConfig config = new ContextConfig();
        config.setCustomAuthenticators(authenticators);
        config.setDebug(debug);
        ((Lifecycle) context).addLifecycleListener(config);

        return (context);

    
public org.apache.catalina.EnginecreateEngine()
Create, configure, and return an Engine that will process all HTTP requests received from one of the associated Connectors, based on the specified properties.


        if( log.isDebugEnabled() )
            log.debug("Creating engine");

        StandardEngine engine = new StandardEngine();

        engine.setDebug(debug);
        // Default host will be set to the first host added
        engine.setLogger(logger);       // Inherited by all children
        engine.setRealm(realm);         // Inherited by all children

        return (engine);

    
public org.apache.catalina.HostcreateHost(java.lang.String name, java.lang.String appBase)
Create, configure, and return a Host that will process all HTTP requests received from one of the associated Connectors, and directed to the specified virtual host.

After you have customized the properties, listeners, and Valves for this Host, you must attach it to the corresponding Engine by calling:

engine.addChild(host);
which will also cause the Host to be started if the Engine has already been started. If this is the default (or only) Host you will be defining, you may also tell the Engine to pass all requests not assigned to another virtual host to this one:
engine.setDefaultHost(host.getName());

param
name Canonical name of this virtual host
param
appBase Absolute pathname to the application base directory for this virtual host
exception
IllegalArgumentException if an invalid parameter is specified


        if( log.isDebugEnabled() )
            log.debug("Creating host '" + name + "' with appBase '" +
                       appBase + "'");

        StandardHost host = new StandardHost();

        host.setAppBase(appBase);
        host.setDebug(debug);
        host.setName(name);

        return (host);

    
public org.apache.catalina.LoadercreateLoader(java.lang.ClassLoader parent)
Create and return a class loader manager that can be customized, and then attached to a Context, before it is started.

param
parent ClassLoader that will be the parent of the one created by this Loader


        if( log.isTraceEnabled() )
            log.trace("Creating Loader with parent class loader '" +
                       parent + "'");

        WebappLoader loader = new WebappLoader(parent);
        return (loader);

    
private static voidcustomize(org.apache.catalina.Context context)
Customize the specified context to have its own log file instead of inheriting the default one. This is just an example of what you can do; pretty much anything (such as installing special Valves) can be done prior to calling start().

param
context Context to receive a specialized logger


        // Create a customized file logger for this context
        String basename = context.getPath();
        if (basename.length() < 1)
            basename = "ROOT";
        else
            basename = basename.substring(1);

        FileLogger special = new FileLogger();
        special.setPrefix(basename + "_log.");
        special.setSuffix(".txt");
        special.setTimestamp(true);

        // Override the default logger for this context
        context.setLogger(special);

    
public org.apache.catalina.LifecycleListener[]findLifecycleListeners()
Get the lifecycle listeners associated with this lifecycle. If this Lifecycle has no listeners registered, a zero-length array is returned.


        return lifecycle.findLifecycleListeners();

    
public java.lang.StringgetCatalinaBase()

        return System.getProperty("catalina.base");
    
public java.lang.StringgetCatalinaHome()

        return System.getProperty("catalina.home");
    
public java.lang.StringgetInfo()
Return descriptive information about this Server implementation and the corresponding version number, in the format <description>/<version>.


        return (this.info);

    
public org.apache.catalina.LoggergetLogger()
Return the Logger for this component.


        return (this.logger);

    
public org.apache.catalina.RealmgetRealm()
Return the default Realm for our Containers.


        return (this.realm);

    
public java.lang.StringgetSocketFactory()
Return the secure socket factory class name.


        return (this.socketFactory);

    
protected voidinitDirs()


        String catalinaHome = System.getProperty("catalina.home");
        if (catalinaHome == null) {
            // Backwards compatibility patch for J2EE RI 1.3
            String j2eeHome = System.getProperty("com.sun.enterprise.home");
            if (j2eeHome != null) {
                catalinaHome=System.getProperty("com.sun.enterprise.home");
            } else if (System.getProperty("catalina.base") != null) {
                catalinaHome = System.getProperty("catalina.base");
            } else {
                // Use IntrospectionUtils and guess the dir
                catalinaHome = IntrospectionUtils.guessInstall
                    ("catalina.home", "catalina.base", "catalina.jar");
                if (catalinaHome == null) {
                    catalinaHome = IntrospectionUtils.guessInstall
                        ("tomcat.install", "catalina.home", "tomcat.jar");
                }
            }
        }
        // last resort - for minimal/embedded cases. 
        if(catalinaHome==null) {
            catalinaHome=System.getProperty("user.dir");
        }
        if (catalinaHome != null) {
            File home = new File(catalinaHome);
            if (!home.isAbsolute()) {
                try {
                    catalinaHome = home.getCanonicalPath();
                } catch (IOException e) {
                    catalinaHome = home.getAbsolutePath();
                }
            }
            System.setProperty("catalina.home", catalinaHome);
        }

        if (System.getProperty("catalina.base") == null) {
            System.setProperty("catalina.base",
                               catalinaHome);
        } else {
            String catalinaBase = System.getProperty("catalina.base");
            File base = new File(catalinaBase);
            if (!base.isAbsolute()) {
                try {
                    catalinaBase = base.getCanonicalPath();
                } catch (IOException e) {
                    catalinaBase = base.getAbsolutePath();
                }
            }
            System.setProperty("catalina.base", catalinaBase);
        } 

    
protected voidinitNaming()
Initialize naming - this should only enable java:env and root naming. If tomcat is embeded in an application that already defines those - it shouldn't do it. XXX The 2 should be separated, you may want to enable java: but not the initial context and the reverse XXX Can we "guess" - i.e. lookup java: and if something is returned assume false ? XXX We have a major problem with the current setting for java: url

        // Setting additional variables
        if (!useNaming) {
            // START SJSAS 5031700
            //log.info( "Catalina naming disabled");
            log.debug( "Catalina naming disabled");
            // END SJSAS 5031700
            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);
            if( log.isDebugEnabled() )
                log.debug("Setting naming prefix=" + 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");
            } else {
                log.debug( "INITIAL_CONTEXT_FACTORY alread set " + value );
            }
        }
    
public booleanisAwait()

        return await;
    
public booleanisUseNaming()
Return true if naming is enabled.



    // ------------------------------------------------------------- Properties


               
       

        return (this.useNaming);

    
public synchronized voidremoveContext(org.apache.catalina.Context context)
Remove the specified Context from the set of defined Contexts for its associated Host. If this is the last Context for this Host, the Host will also be removed.

param
context The Context to be removed


        if( log.isDebugEnabled() )
            log.debug("Removing context[" + context.getPath() + "]");

        // Is this Context actually among those that are defined?
        boolean found = false;
        for (int i = 0; i < engines.length; i++) {
            Container hosts[] = engines[i].findChildren();
            for (int j = 0; j < hosts.length; j++) {
                Container contexts[] = hosts[j].findChildren();
                for (int k = 0; k < contexts.length; k++) {
                    if (context == (Context) contexts[k]) {
                        found = true;
                        break;
                    }
                }
                if (found)
                    break;
            }
            if (found)
                break;
        }
        if (!found)
            return;

        // Remove this Context from the associated Host
        if( log.isDebugEnabled() )
            log.debug(" Removing this Context");
        context.getParent().removeChild(context);

    
public synchronized voidremoveEngine(org.apache.catalina.Engine engine)
Remove the specified Engine from the set of defined Engines, along with all of its related Hosts and Contexts. All associated Connectors are also removed.

param
engine The Engine to be removed


        if( log.isDebugEnabled() )
            log.debug("Removing engine (" + engine.getInfo() + ")");

        // Is the specified Engine actually defined?
        int j = -1;
        for (int i = 0; i < engines.length; i++) {
            if (engine == engines[i]) {
                j = i;
                break;
            }
        }
        if (j < 0)
            return;

        // Remove any Connector that is using this Engine
        if( log.isDebugEnabled() )
            log.debug(" Removing related Containers");
        while (true) {
            int n = -1;
            for (int i = 0; i < connectors.length; i++) {
                if (connectors[i].getContainer() == (Container) engine) {
                    n = i;
                    break;
                }
            }
            if (n < 0)
                break;
            // START SJSAS 6231069
            //removeConnector(connectors[n]);
            try{
                removeConnector(connectors[n]);
            } catch (Exception ex){
                log.error("Connector.stop", ex);
            }
            // END SJSAS 6231069
        }

        // Stop this Engine if necessary
        if (engine instanceof Lifecycle) {
            if( log.isDebugEnabled() )
                log.debug(" Stopping this Engine");
            try {
                ((Lifecycle) engine).stop();
            } catch (LifecycleException e) {
                log.error("Engine.stop", e);
            }
        }

        // Remove this Engine from our set of defined Engines
        if( log.isDebugEnabled() )
            log.debug(" Removing this Engine");
        int k = 0;
        Engine results[] = new Engine[engines.length - 1];
        for (int i = 0; i < engines.length; i++) {
            if (i != j)
                results[k++] = engines[i];
        }
        engines = results;

    
public synchronized voidremoveHost(org.apache.catalina.Host host)
Remove the specified Host, along with all of its related Contexts, from the set of defined Hosts for its associated Engine. If this is the last Host for this Engine, the Engine will also be removed.

param
host The Host to be removed


        if( log.isDebugEnabled() )
            log.debug("Removing host[" + host.getName() + "]");

        // Is this Host actually among those that are defined?
        boolean found = false;
        for (int i = 0; i < engines.length; i++) {
            Container hosts[] = engines[i].findChildren();
            for (int j = 0; j < hosts.length; j++) {
                if (host == (Host) hosts[j]) {
                    found = true;
                    break;

                }
            }
            if (found)
                break;
        }
        if (!found)
            return;

        // Remove this Host from the associated Engine
        if( log.isDebugEnabled() )
            log.debug(" Removing this Host");
        host.getParent().removeChild(host);

    
public voidremoveLifecycleListener(org.apache.catalina.LifecycleListener listener)
Remove a lifecycle event listener from this component.

param
listener The listener to remove


        lifecycle.removeLifecycleListener(listener);

    
public voidsetAwait(boolean b)

        await = b;
    
public voidsetCatalinaBase(java.lang.String s)

        System.setProperty( "catalina.base", s);
    
public voidsetCatalinaHome(java.lang.String s)

        System.setProperty( "catalina.home", s);
    
public voidsetLogger(org.apache.catalina.Logger logger)
Set the Logger for this component.

param
logger The new logger


        Logger oldLogger = this.logger;
        this.logger = logger;
        support.firePropertyChange("logger", oldLogger, this.logger);

    
public voidsetRealm(org.apache.catalina.Realm realm)
Set the default Realm for our Containers.

param
realm The new default realm


        Realm oldRealm = this.realm;
        this.realm = realm;
        support.firePropertyChange("realm", oldRealm, this.realm);

    
protected voidsetSecurityProtection()
Set the security package access/protection.

        SecurityConfig securityConfig = SecurityConfig.newInstance();
        securityConfig.setPackageDefinition();
        securityConfig.setPackageAccess();
    
public voidsetSocketFactory(java.lang.String socketFactory)
Set the secure socket factory class name.

param
socketFactory The new secure socket factory class name


        this.socketFactory = socketFactory;

    
public voidsetUseNaming(boolean useNaming)
Enables or disables naming support.

param
useNaming The new use naming value


        boolean oldUseNaming = this.useNaming;
        this.useNaming = useNaming;
        support.firePropertyChange("useNaming", Boolean.valueOf(oldUseNaming),
                                   Boolean.valueOf(this.useNaming));

    
public voidstart()
Prepare for the beginning of active use of the public methods of this component. This method should be called after configure(), and before any of the public methods of the component are utilized.

exception
LifecycleException if this component detects a fatal error that prevents this component from being used


        /* SJSAS 5022949
        if( log.isInfoEnabled() )
            log.info("Starting tomcat server");
         */
        // START SJSAS 6340446
        if (log.isDebugEnabled()) {
            log.debug("Starting Servlet container component of "
                      + ServerInfo.getServerInfo());
        }
        // END SJSAS 6340446

        // Validate the setup of our required system properties
        initDirs();

        // Initialize some naming specific properties
        initNaming();

        // Validate and update our current component state
        if (started)
            throw new LifecycleException
                (sm.getString("embedded.alreadyStarted"));
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;
        initialized = true;

        // Start our defined Connectors first
        for (int i = 0; i < connectors.length; i++) {
            connectors[i].initialize();
            if (connectors[i] instanceof Lifecycle)
                ((Lifecycle) connectors[i]).start();
        }

        // Start our defined Engines second
        for (int i = 0; i < engines.length; i++) {
            if (engines[i] instanceof Lifecycle)
                ((Lifecycle) engines[i]).start();
        }
    
public voidstop()
Gracefully terminate the active use of the public methods of this component. This method should be the last one called on a given instance of this component.

exception
LifecycleException if this component detects a fatal error that needs to be reported


        if( log.isDebugEnabled() )
            log.debug("Stopping embedded server");

        // Validate and update our current component state
        if (!started)
            throw new LifecycleException
                (sm.getString("embedded.notStarted"));
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;

        // Stop our defined Connectors first
        for (int i = 0; i < connectors.length; i++) {
            if (connectors[i] instanceof Lifecycle)
                ((Lifecycle) connectors[i]).stop();
        }

        // Stop our defined Engines second
        for (int i = 0; i < engines.length; i++) {
            if (engines[i] instanceof Lifecycle)
                ((Lifecycle) engines[i]).stop();
        }