FileDocCategorySizeDatePackage
StandardServer.javaAPI DocApache Tomcat 6.0.1423907Fri Jul 20 04:20:32 BST 2007org.apache.catalina.core

StandardServer

public final class StandardServer extends Object implements org.apache.catalina.Server, org.apache.catalina.Lifecycle, MBeanRegistration
Standard implementation of the Server interface, available for use (but not required) when deploying and starting Catalina.
author
Craig R. McClanahan
version
$Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $

Fields Summary
private static org.apache.juli.logging.Log
log
private static String
SERVER_LISTENER_CLASS_NAME
ServerLifecycleListener classname.
private Context
globalNamingContext
Global naming resources context.
private org.apache.catalina.deploy.NamingResources
globalNamingResources
Global naming resources.
private static final String
info
Descriptive information about this Server implementation.
private org.apache.catalina.util.LifecycleSupport
lifecycle
The lifecycle event support for this component.
private NamingContextListener
namingContextListener
The naming context listener for this web application.
private int
port
The port number on which we wait for shutdown commands.
private Random
random
A random number generator that is only used if the shutdown command string is longer than 1024 characters.
private org.apache.catalina.Service[]
services
The set of Services associated with this Server.
private String
shutdown
The shutdown command string we are looking for.
private static final org.apache.catalina.util.StringManager
sm
The string manager for this package.
private boolean
started
Has this component been started?
private boolean
initialized
Has this component been initialized?
protected PropertyChangeSupport
support
The property change support for this component.
private boolean
stopAwait
protected String
type
protected String
domain
protected String
suffix
protected ObjectName
oname
protected MBeanServer
mserver
Constructors Summary
public StandardServer()
Construct a default instance of this class.



    // ------------------------------------------------------------ Constructor


                
      

        super();
        ServerFactory.setServer(this);

        globalNamingResources = new NamingResources();
        globalNamingResources.setContainer(this);

        if (isUseNaming()) {
            if (namingContextListener == null) {
                namingContextListener = new NamingContextListener();
                addLifecycleListener(namingContextListener);
            }
        }

    
Methods Summary
public voidaddLifecycleListener(org.apache.catalina.LifecycleListener listener)
Add a LifecycleEvent listener to this component.

param
listener The listener to add


        lifecycle.addLifecycleListener(listener);

    
public voidaddPropertyChangeListener(java.beans.PropertyChangeListener listener)
Add a property change listener to this component.

param
listener The listener to add


        support.addPropertyChangeListener(listener);

    
public voidaddService(org.apache.catalina.Service service)
Add a new Service to the set of defined Services.

param
service The Service to be added


        service.setServer(this);

        synchronized (services) {
            Service results[] = new Service[services.length + 1];
            System.arraycopy(services, 0, results, 0, services.length);
            results[services.length] = service;
            services = results;

            if (initialized) {
                try {
                    service.initialize();
                } catch (LifecycleException e) {
                    log.error(e);
                }
            }

            if (started && (service instanceof Lifecycle)) {
                try {
                    ((Lifecycle) service).start();
                } catch (LifecycleException e) {
                    ;
                }
            }

            // Report this property change to interested listeners
            support.firePropertyChange("service", null, service);
        }

    
public voidawait()
Wait until a proper shutdown command is received, then return. This keeps the main thread alive - the thread pool listening for http connections is daemon threads.

        // Negative values - don't wait on port - tomcat is embedded or we just don't like ports
        if( port == -2 ) {
            // undocumented yet - for embedding apps that are around, alive.
            return;
        }
        if( port==-1 ) {
            while( true ) {
                try {
                    Thread.sleep( 100000 );
                } catch( InterruptedException ex ) {
                }
                if( stopAwait ) return;
            }
        }
        
        // Set up a server socket to wait on
        ServerSocket serverSocket = null;
        try {
            serverSocket =
                new ServerSocket(port, 1,
                                 InetAddress.getByName("127.0.0.1"));
        } catch (IOException e) {
            log.error("StandardServer.await: create[" + port
                               + "]: ", e);
            System.exit(1);
        }

        // Loop waiting for a connection and a valid command
        while (true) {

            // Wait for the next connection
            Socket socket = null;
            InputStream stream = null;
            try {
                socket = serverSocket.accept();
                socket.setSoTimeout(10 * 1000);  // Ten seconds
                stream = socket.getInputStream();
            } catch (AccessControlException ace) {
                log.warn("StandardServer.accept security exception: "
                                   + ace.getMessage(), ace);
                continue;
            } catch (IOException e) {
                log.error("StandardServer.await: accept: ", e);
                System.exit(1);
            }

            // Read a set of characters from the socket
            StringBuffer command = new StringBuffer();
            int expected = 1024; // Cut off to avoid DoS attack
            while (expected < shutdown.length()) {
                if (random == null)
                    random = new Random(System.currentTimeMillis());
                expected += (random.nextInt() % 1024);
            }
            while (expected > 0) {
                int ch = -1;
                try {
                    ch = stream.read();
                } catch (IOException e) {
                    log.warn("StandardServer.await: read: ", e);
                    ch = -1;
                }
                if (ch < 32)  // Control character or EOF terminates loop
                    break;
                command.append((char) ch);
                expected--;
            }

            // Close the socket now that we are done with it
            try {
                socket.close();
            } catch (IOException e) {
                ;
            }

            // Match against our command string
            boolean match = command.toString().equals(shutdown);
            if (match) {
                break;
            } else
                log.warn("StandardServer.await: Invalid command '" +
                                   command.toString() + "' received");

        }

        // Close the server socket and return
        try {
            serverSocket.close();
        } catch (IOException e) {
            ;
        }

    
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 org.apache.catalina.ServicefindService(java.lang.String name)
Return the specified Service (if it exists); otherwise return null.

param
name Name of the Service to be returned


        if (name == null) {
            return (null);
        }
        synchronized (services) {
            for (int i = 0; i < services.length; i++) {
                if (name.equals(services[i].getName())) {
                    return (services[i]);
                }
            }
        }
        return (null);

    
public org.apache.catalina.Service[]findServices()
Return the set of Services defined within this Server.


        return (services);

    
public java.lang.StringgetDomain()

        return domain;
    
public javax.naming.ContextgetGlobalNamingContext()
Return the global naming resources context.


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


               
       

        return (this.globalNamingContext);

    
public org.apache.catalina.deploy.NamingResourcesgetGlobalNamingResources()
Return the global naming resources.


        return (this.globalNamingResources);

    
public java.lang.StringgetInfo()
Return descriptive information about this Server implementation and the corresponding version number, in the format <description>/<version>.


        return (info);

    
public javax.management.ObjectNamegetObjectName()

        return oname;
    
public intgetPort()
Return the port number we listen to for shutdown commands.


        return (this.port);

    
public java.lang.StringgetServerInfo()
Report the current Tomcat Server Release number

return
Tomcat release identifier


        return ServerInfo.getServerInfo();
    
public javax.management.ObjectName[]getServiceNames()
Return the JMX service names.

        ObjectName onames[]=new ObjectName[ services.length ];
        for( int i=0; i<services.length; i++ ) {
            onames[i]=((StandardService)services[i]).getObjectName();
        }
        return onames;
    
public java.lang.StringgetShutdown()
Return the shutdown command string we are waiting for.


        return (this.shutdown);

    
public voidinit()

        initialize();
    
public voidinitialize()
Invoke a pre-startup initialization. This is used to allow connectors to bind to restricted ports under Unix operating environments.

        if (initialized) {
                log.info(sm.getString("standardServer.initialize.initialized"));
            return;
        }
        lifecycle.fireLifecycleEvent(INIT_EVENT, null);
        initialized = true;

        if( oname==null ) {
            try {
                oname=new ObjectName( "Catalina:type=Server");
                Registry.getRegistry(null, null)
                    .registerComponent(this, oname, null );
            } catch (Exception e) {
                log.error("Error registering ",e);
            }
        }
        
        // Register global String cache
        try {
            ObjectName oname2 = 
                new ObjectName(oname.getDomain() + ":type=StringCache");
            Registry.getRegistry(null, null)
                .registerComponent(new StringCache(), oname2, null );
        } catch (Exception e) {
            log.error("Error registering ",e);
        }

        // Initialize our defined Services
        for (int i = 0; i < services.length; i++) {
            services[i].initialize();
        }
    
private booleanisUseNaming()
Return true if naming should be used.

        boolean useNaming = true;
        // Reading the "catalina.useNaming" environment variable
        String useNamingProperty = System.getProperty("catalina.useNaming");
        if ((useNamingProperty != null)
            && (useNamingProperty.equals("false"))) {
            useNaming = false;
        }
        return useNaming;
    
public voidpostDeregister()

    
public voidpostRegister(java.lang.Boolean registrationDone)

    
public voidpreDeregister()

    
public javax.management.ObjectNamepreRegister(javax.management.MBeanServer server, javax.management.ObjectName name)

        oname=name;
        mserver=server;
        domain=name.getDomain();
        return name;
    
public voidremoveLifecycleListener(org.apache.catalina.LifecycleListener listener)
Remove a LifecycleEvent listener from this component.

param
listener The listener to remove


        lifecycle.removeLifecycleListener(listener);

    
public voidremovePropertyChangeListener(java.beans.PropertyChangeListener listener)
Remove a property change listener from this component.

param
listener The listener to remove


        support.removePropertyChangeListener(listener);

    
public voidremoveService(org.apache.catalina.Service service)
Remove the specified Service from the set associated from this Server.

param
service The Service to be removed


        synchronized (services) {
            int j = -1;
            for (int i = 0; i < services.length; i++) {
                if (service == services[i]) {
                    j = i;
                    break;
                }
            }
            if (j < 0)
                return;
            if (services[j] instanceof Lifecycle) {
                try {
                    ((Lifecycle) services[j]).stop();
                } catch (LifecycleException e) {
                    ;
                }
            }
            int k = 0;
            Service results[] = new Service[services.length - 1];
            for (int i = 0; i < services.length; i++) {
                if (i != j)
                    results[k++] = services[i];
            }
            services = results;

            // Report this property change to interested listeners
            support.firePropertyChange("service", service, null);
        }

    
public voidsetGlobalNamingContext(javax.naming.Context globalNamingContext)
Set the global naming resources context.

param
globalNamingContext The new global naming resource context


        this.globalNamingContext = globalNamingContext;

    
public voidsetGlobalNamingResources(org.apache.catalina.deploy.NamingResources globalNamingResources)
Set the global naming resources.

param
globalNamingResources The new global naming resources


        NamingResources oldGlobalNamingResources =
            this.globalNamingResources;
        this.globalNamingResources = globalNamingResources;
        this.globalNamingResources.setContainer(this);
        support.firePropertyChange("globalNamingResources",
                                   oldGlobalNamingResources,
                                   this.globalNamingResources);

    
public voidsetPort(int port)
Set the port number we listen to for shutdown commands.

param
port The new port number


        this.port = port;

    
public voidsetShutdown(java.lang.String shutdown)
Set the shutdown command we are waiting for.

param
shutdown The new shutdown command


        this.shutdown = shutdown;

    
public voidstart()
Prepare for the beginning of active use of the public methods of this component. This method should be called before any of the public methods of this component are utilized. It should also send a LifecycleEvent of type START_EVENT to any registered listeners.

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


        // Validate and update our current component state
        if (started) {
            log.debug(sm.getString("standardServer.start.started"));
            return;
        }

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);

        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;

        // Start our defined Services
        synchronized (services) {
            for (int i = 0; i < services.length; i++) {
                if (services[i] instanceof Lifecycle)
                    ((Lifecycle) services[i]).start();
            }
        }

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

    
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. It should also send a LifecycleEvent of type STOP_EVENT to any registered listeners.

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


        // Validate and update our current component state
        if (!started)
            return;

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);

        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;

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

        // Notify our interested LifecycleListeners
        lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);

    
public voidstopAwait()

        stopAwait=true;
    
public synchronized voidstoreConfig()
Write the configuration information for this entire Server out to the server.xml configuration file.

exception
javax.management.InstanceNotFoundException if the managed resource object cannot be found
exception
javax.management.MBeanException if the initializer of the object throws an exception, or persistence is not supported
exception
javax.management.RuntimeOperationsException if an exception is reported by the persistence mechanism


        ObjectName sname = null;    
        try {
           sname = new ObjectName("Catalina:type=StoreConfig");
           if(mserver.isRegistered(sname)) {
               mserver.invoke(sname, "storeConfig", null, null);            
           } else
               log.error("StoreConfig mbean not registered" + sname);
        } catch (Throwable t) {
            log.error(t);
        }

    
public synchronized voidstoreContext(org.apache.catalina.Context context)
Write the configuration information for Context out to the specified configuration file.

exception
javax.management.InstanceNotFoundException if the managed resource object cannot be found
exception
javax.management.MBeanException if the initializer of the object throws an exception, or persistence is not supported
exception
javax.management.RuntimeOperationsException if an exception is reported by the persistence mechanism

        
        ObjectName sname = null;    
        try {
           sname = new ObjectName("Catalina:type=StoreConfig");
           if(mserver.isRegistered(sname)) {
               mserver.invoke(sname, "store",
                   new Object[] {context}, 
                   new String [] { "java.lang.String"});
           } else
               log.error("StoreConfig mbean not registered" + sname);
        } catch (Throwable t) {
            log.error(t);
        }
 
    
public java.lang.StringtoString()
Return a String representation of this component.


        StringBuffer sb = new StringBuffer("StandardServer[");
        sb.append(getPort());
        sb.append("]");
        return (sb.toString());