alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*   
 *  Copyright 1999-2004 The Apache Sofware Foundation.
 *
 *  Licensed 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.tomcat.startup;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Hashtable;
import java.util.Properties;

import org.apache.tomcat.util.IntrospectionUtils;
import org.apache.tomcat.util.res.StringManager;
// Depends: StringManager, resources


/**
 * This task will stop tomcat
 *
 * @author Costin Manolache
 */
public class StopTomcat { 
    static final String DEFAULT_CONFIG="conf/server.xml";
    private static StringManager sm =
	StringManager.getManager("org.apache.tomcat.resources");

    String tomcatHome=null;

    String host=null;
    int port=-1;
    String secret;
    // explicit command line params ( for port, host or secret )
    boolean commandLineParams=false;
    String secretFile=null;
    String shutdown=null;
    String args[];
    boolean help=false;
    boolean isAjp13=false;
    boolean isAjp12=false;
    
    public StopTomcat() 
    {
    }

    // -------------------- Parameters --------------------
    public void setSecretFile( String s ) {
	secretFile=s;
	commandLineParams=true;
    }

    public void setAjpid( String s ) {
	secretFile=s;
	commandLineParams=true;
    }

    public void setAjpid12( String s ) {
        secretFile=s;
        commandLineParams=true;
        isAjp12=true;
        isAjp13=false;
    }

    public void setAjpid13( String s ) {
        secretFile=s;
        commandLineParams=true;
        isAjp12=false;
        isAjp13=true;
    }

    public void setH( String s ) {
	tomcatHome=s;
	System.getProperties().put("tomcat.home", s);
    }

    public void setHome( String s ) {
	tomcatHome=s;
	System.getProperties().put("tomcat.home", s);
    }

    public void setHost( String h ) {
	host=h;
	commandLineParams=true;
    }

    public void setPort( int port ) {
	this.port=port;
	commandLineParams=true;
    }

    /** When tomcat is started, a secret ( random ) key will be generated
	in ajp12.id. If you run StopTomcat from the same host, it'll
	read the key and use it. If you run from a different host, you'll
	have to specify it manually
    */
    public void setPass( String s ) {
	secret=s;
	commandLineParams=true;
    }
    
    public void setSecret( String s ) {
	secret=s;
	commandLineParams=true;
    }

    public void setHelp( boolean b ) {
        help = b;
    }

    // Generic properties / attributes

    public void setAttribute(String s, Object o ) {
	if( s.equals("args")  )
	    setArgs((String [])o);
    }

    public void setProperty( String name, String v ) {
	if( !name.equals("stop")  )
            // unknown property
            help = true;
    }

    public void setAjp13( boolean b ) {
        isAjp13=b;
        isAjp12=!b;
    }

    public void setAjp12( boolean b ) {
        isAjp12=b;
        isAjp13=!b;
    }

    public void setArgs( String args[] ) {
	this.args=args;
    }
    
    // -------------------- Ant execute --------------------

    public void execute() throws Exception {
	if( args!=null )
	    processArgs( args );
        if( help ) {
            printUsage();
            return;
        }
	System.out.println(sm.getString("tomcat.stop"));
	try {
	    stopTomcat(); // stop serving
	}
	catch (java.net.ConnectException ex) {
	    System.out.println(sm.getString("tomcat.connectexception"));
	} catch (Exception te ) {
		throw te;
	}
	return;
    }

    // -------------------- Implementation --------------------
    
    void stopTomcat() throws Exception {
        // if a parameter isn't set, try to read it from a file
        if( port < 0 || host == null || secret == null ) {
            String tchome=getTomcatHome();

            String defAjp12File=tchome + "/conf/ajp12.id";
            String defAjp13File=tchome + "/conf/ajp13.id";
            String ajpFile=secretFile;

            int portSave=port;
            String hostSave=host;
            String secretSave=secret;

            boolean pickAjp=(!isAjp13 && !isAjp12);

            // try to read unset parameters from appropriate file
            try {
                if( ajpFile==null ) {
                    if (isAjp13) {
                        ajpFile=defAjp13File;
                    } else if (isAjp12) {
                        ajpFile=defAjp12File;
                    } else {
                        File f=new File( defAjp13File );
                        if( f.exists() ) {
                            ajpFile=defAjp13File;
                            isAjp13=true;
                        } else {
                            f=new File( defAjp12File );
                            if( f.exists() ) {
                                ajpFile=defAjp12File; 
                                isAjp12=true;
                            }
                        }
                    }
                } else if( pickAjp ) {
                    // default to ajp12 if file specifed with no protocal
                    isAjp12=true;
                }

                if( isAjp13 ) {
                    Properties props=new Properties();
                    props.load( new FileInputStream( ajpFile ));

                    String line=props.getProperty( "port" );
                    if( port < 0 ) {
                        try {
                            port=Integer.parseInt( line );
                        } catch(NumberFormatException ex ) {
                            ex.printStackTrace();
                        }
                    }
                
                    line=props.getProperty( "address" );
                    if( host==null ) host=line;
                    line=props.getProperty( "secret" );
                    if( secret==null ) secret=line;
                    shutdown=props.getProperty( "shutdown" );
                    // if shutdown not enabled in default ajp13 file and
                    // picking ajp, try ajp12 default file
                    if( shutdown==null && secretFile == null && pickAjp) {
                        isAjp12=true;
                        isAjp13=false;
                        port=portSave;
                        host=hostSave;
                        secret=secretSave;
                        ajpFile=defAjp12File;
                    }
                }

                if( isAjp12 ) {
                    BufferedReader rd=new BufferedReader
                        ( new FileReader(ajpFile));
                    String line=rd.readLine();
                
                    if( port < 0 ) {
                        try {
                            port=Integer.parseInt( line );
                        } catch(NumberFormatException ex ) {
                            ex.printStackTrace();
                        }
                    }

                    line=rd.readLine();
                    if( host==null ) host=line;
                    line=rd.readLine();
                    if( secret==null ) secret=line;
                }
            } catch( IOException ex ) {
                //ex.printStackTrace();
                System.out.println("Can't read " + ajpFile);
                // System.out.println(ex.toString());
                if( ! commandLineParams )
                    return;
            }
        }

	if( "".equals( secret ) )
	    secret=null;
		
	System.out.println("Stopping tomcat on " + host + ":" +port +" "
			   + secret);
	InetAddress address=null;
	if( host!=null && !"".equals( host )) {
	    try {
		address=InetAddress.getByName( host );
	    } catch( UnknownHostException ex ) {
		ex.printStackTrace();
	    }
	}
	stopTomcat( address,port, secret );
    }
    
    public String getTomcatHome() {
        if (tomcatHome != null)
            return tomcatHome;
	// Try to establish install and home locations
	String tchome=IntrospectionUtils.guessInstall("tomcat.install",
				"tomcat.home","stop-tomcat.jar");
	// Use the "tomcat.home" property to resolve the default filename
	tchome = System.getProperty("tomcat.home");
	if (tchome == null) {
	    System.out.println(sm.getString("tomcat.nohome"));
	    tchome = ".";
	    // Assume current working directory
	}
	return tchome;
    }
    
    /**
     *  This particular implementation will search for an AJP12
     * 	connector ( that have a special stop command ).
     */
    public void stopTomcat(InetAddress address, int portInt, String secret )
	throws IOException 
    {
	// use Ajp12 to stop the server...
	try {
	    if (address == null)
		address = InetAddress.getLocalHost();
	    Socket socket = new Socket(address, portInt);
	    OutputStream os=socket.getOutputStream();
            if( isAjp13 ) 
                sendAjp13Stop( os, secret );
            else
                sendAjp12Stop( os, secret );

            // Setting soLinger to 0 will help make sure the connection is
            // closed on NetWare.  If the other side closes the connection
            // first, we get a SocketException so catch and ignore it
            try {
                socket.setSoLinger(true, 0);
            }
            catch (java.net.SocketException ignore) {
            }
	    os.flush();
	    os.close();
	    //	    socket.close();
	} catch(IOException ex ) {
	    System.out.println("Error stopping Tomcat with Ajp12 on " +
				      address + ":" + portInt + " " + ex);
	}
    }

    /** Small AJP12 client util
     */
    public void sendAjp12Stop( OutputStream os, String secret )
	throws IOException
    {
	byte stopMessage[]=new byte[2];
	stopMessage[0]=(byte)254;
	stopMessage[1]=(byte)15;
	os.write( stopMessage );
	if(secret!=null ) 
	    sendAjp12String( os, secret );

        // flush the stream and give the backend a chance to read the request
        // and shut down before we close the socket
        os.flush();
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException ignore) {
        }
    }

    /** Small AJP13 client util
     */
    public void sendAjp13Stop( OutputStream os, String secret )
	throws IOException
    {
	byte stopMessage[]=new byte[5];
	stopMessage[0]=(byte)0x12;
	stopMessage[1]=(byte)0x34;
        int len=1;
        if( secret != null )
            len=secret.length() + 4; // 1==shutdown cmd, 2==string len, 1=\0
        stopMessage[2]= (byte) ( len/256 );
        stopMessage[3]= (byte) (len % 256 );
        stopMessage[4]= 7; // JK_AJP13_SHUTDOWN
        
	os.write( stopMessage );
        if( secret != null )
            sendAjp13String( os, secret );

        // flush the stream and give the backend a chance to read the request
        // and shut down before we close the socket
        os.flush();
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException ignore) {
        }
    }

    /** Small AJP12 client util
     */
    public void sendAjp12String( OutputStream os, String s )
	throws IOException
    {
	int len=s.length();
	os.write( len/256 );
	os.write( len%256 );
	os.write( s.getBytes() );// works only for ascii
    }
    
    /** Small AJP13 client util
     */
    public void sendAjp13String( OutputStream os, String s )
	throws IOException
    {
	int len=s.length();
	os.write( len/256 );
	os.write( len%256 );
	os.write( s.getBytes() );// works only for ascii
        os.write( (byte)0 );
    }
    
    /** Process arguments - set object properties from the list of args.
     */
    public  boolean processArgs(String[] args) {
	try {
	    return IntrospectionUtils.processArgs( this, args, getOptions1(),
					    null, getOptionAliases());
	} catch( Exception ex ) {
	    ex.printStackTrace();
	    return false;
	}

    }

    static String options1[]= { "help", "stop", "ajp12", "ajp13" };
    static Hashtable optionAliases=new Hashtable();
    static Hashtable optionDescription=new Hashtable();
    static {
	optionAliases.put("h", "home");
	optionAliases.put("?", "help");
    }

    public String[] getOptions1() {
	return options1;
    }

    public Hashtable getOptionAliases() {
	return optionAliases;
    }

    public static void printUsage() {
        System.out.println("Usage: java org.apache.tomcat.startup.StopTomcat {options}");
        System.out.println("  Options are:");
        System.out.println("    -ajp12                            Use Ajp12 protocol for shutdown");
        System.out.println("    -ajp13                            Use Ajp13 protocol for shutdown");
        System.out.println("                                          Shutdown feature of Ajp13");
        System.out.println("                                          connector must be enabled.");
        System.out.println("    -ajpid file (or -secretFile file) Use this file instead of conf/ajp13.id");
        System.out.println("                                          or conf/ajp12.id.  You must set");
        System.out.println("                                          -ajp13 option if file is from");
        System.out.println("                                          Ajp13 connector");
        System.out.println("    -help (or -?)                     Show this usage report");
        System.out.println("    -host                       Host to send the shutdown command");
        System.out.println("    -home  (or -h )         Use this directory as tomcat.home, to");
        System.out.println("                                          find conf/ajp13.id or conf/ajp12.id");
        System.out.println("    -pass  (or -secret )      Password to use, aka secret");
        System.out.println("    -port                       Port to send the shutdown command");
        System.out.println("Note: the '-' on the options is optional.");
        System.out.println();
    }
    
    public static void main(String args[] ) {
	try {
	    StopTomcat tomcat=new StopTomcat();
	    tomcat.setArgs( args );
	    tomcat.execute();
	} catch(Exception ex ) {
	    System.out.println(sm.getString("tomcat.fatal"));
	    ex.printStackTrace();
	    System.exit(1);
	}
    }


}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.