tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cos...@locus.apache.org
Subject cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/startup Main.java
Date Tue, 12 Dec 2000 00:42:51 GMT
costin      00/12/11 16:42:50

  Modified:    src/facade22/org/apache/tomcat/facade
                        Servlet22Interceptor.java ServletWrapper.java
                        WebXmlReader.java
               src/facade22/org/apache/tomcat/modules/facade22
                        JspInterceptor.java
               src/share/org/apache/tomcat/context ErrorHandler.java
               src/share/org/apache/tomcat/core Context.java Handler.java
               src/share/org/apache/tomcat/request AccessInterceptor.java
                        StaticInterceptor.java
               src/share/org/apache/tomcat/startup Main.java
  Log:
  First round of refactoring for Handler/ServletWrapper. Reorganized the code
  to make sure the right order of calls in the right state is enforced.
  
  It seems that Handler is still too complex, and a lot of servlet-specific code
  ( like handling of init, UnavailableException, etc) need to be moved in
  the right place ( ServletWrapper). The problem is that ServletWrapper is too
  complex.
  
  I'll start cleaning ServletWrapper and then move init/destroy - Handler will
  then be a very simple and maintainable class. I need your review on this one,
  please send comments if you find any problem.
  
  Revision  Changes    Path
  1.6       +4 -1      jakarta-tomcat/src/facade22/org/apache/tomcat/facade/Servlet22Interceptor.java
  
  Index: Servlet22Interceptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/Servlet22Interceptor.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Servlet22Interceptor.java	2000/11/02 21:51:39	1.5
  +++ Servlet22Interceptor.java	2000/12/12 00:42:40	1.6
  @@ -144,7 +144,10 @@
   	    ServletWrapper sw=new ServletWrapper();
   	    sw.setName( hN );
   	    sw.setContext( ct.getContext() );
  -	    log( "Create handler ");
  +	    // *.jsp -> jsp is a legacy default mapping  
  +	    if( ! "jsp".equals(hN) ) {
  +		log( "Create handler " + hN);
  +	    }
   	    ct.setHandler(sw);
   	    ct.getContext().addServlet(  sw );
   	}
  
  
  
  1.14      +124 -143  jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletWrapper.java
  
  Index: ServletWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/ServletWrapper.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ServletWrapper.java	2000/12/08 23:18:29	1.13
  +++ ServletWrapper.java	2000/12/12 00:42:40	1.14
  @@ -124,8 +124,19 @@
       public String toString() {
   	if( path==null )
   	    return "Servlet " + name + "(" + servletClassName  + ")";
  -	return "Jsp " + name + "(" + path + ")";
  +	return "Jsp " + name + "(" + path + "/" + servletClassName +  ")";
       }
  +
  +    // -------------------- Configuration hook
  +
  +    /** This method can called to add the servlet to the web application.
  +     * ( typlically used from the config - WebXmlReader ).
  +     */
  +    public void addServlet(Context ctx) throws TomcatException {
  +	context=ctx;
  +	//	System.out.println("Adding servlet " + this );
  +	context.addServlet( this );
  +    }
       
       // -------------------- Servlet specific properties 
       public void setLoadOnStartUp( int level ) {
  @@ -170,17 +181,21 @@
       }
   
       public String getServletClass() {
  -        return this.servletClassName;
  +        return getServletClassName();
       }
   
       public String getServletClassName() {
  -        return this.servletClassName;
  +	if( servletClassName == null )
  +	    servletClassName=name;
  +        return servletClassName;
       }
   
       public void setServletClassName(String servletClassName) {
   	servlet=null; // reset the servlet, if it was set
   	servletClass=null;
   	this.servletClassName=servletClassName;
  +	if( debug>0 && path!=null)
  +	    log( "setServletClassName for jsp " + servletClassName);
       }
       public void setServletClass(String servletClassName) {
   	setServletClassName(servletClassName);
  @@ -191,7 +206,8 @@
   	if ( ex != null ) {
   	    if ( ex instanceof UnavailableException &&
   		    ! ((UnavailableException)ex).isPermanent()) {
  -		// make updated UnavailableException, reporting a minimum of 1 second
  +		// make updated UnavailableException, reporting a minimum
  +		// of 1 second
   		int secs=1;
   		long moreWaitTime=unavailableTime - System.currentTimeMillis();
   		if( moreWaitTime > 0 )
  @@ -204,7 +220,7 @@
   
   
       public void reload() {
  -	if( initialized ) {
  +	if( getState()==STATE_READY ) {
   	    try {
   		destroy();
   	    } catch(Exception ex ) {
  @@ -212,12 +228,12 @@
   	    }
   	}
   
  -	if( servletClassName != null ) {
  +	if( getServletClassName() != null ) {
   	    // I can survive reload
   	    servlet=null;
   	    servletClass=null;
   	}
  -	initialized=false;
  +	setState( STATE_ADDED );
       }
       
       /** Security Role Ref represent a mapping between servlet role names and
  @@ -247,7 +263,9 @@
       // -------------------- 
   
       public Servlet getServlet() {
  +	
   	if(servlet==null) {
  +	    System.out.println("XXX getServlet for un-loaded servlet ");
   	    try {
   		loadServlet();
   	    } 	catch( Exception ex ) {
  @@ -303,116 +321,80 @@
   	}
       }
   
  +    // Special hook
  +    protected void preInit() throws Exception
  +    {
  +	if( debug > 0 )
  +	    log( "preInit " + servlet + " " + path + " " + servletClassName);
  +
  +	// Deal with Unavailable errors
  +	if( ! checkErrorExpired() ) {
  +	    // init can't proceed
  +	    setState( STATE_DELAYED_INIT );
  +	    return;
  +	}
  +	
  +	// For JSPs we rely on JspInterceptor to set the servlet class name.
  +	// We make no distinction between servlets and jsps.
  +	loadServlet();
  +    }
  +
       /** Load and init a the servlet pointed by this wrapper
        */
       private void loadServlet()
   	throws ClassNotFoundException, InstantiationException,
   	IllegalAccessException
       {
  -	// XXX Move this to an interceptor, so it will be configurable.
  -	// ( and easier to read )
  -	// 	log("LoadServlet " + servletClass + " "
  -	// 			   + servletClassName);
  +	if( debug>0)
  +	    log("LoadServlet " + name + " " + servletName + " " +
  +		servletClass + " " + servletClassName);
   
   	// default
   	if( servletClassName==null )
  -	    servletClassName=servletName;
  +	    servletClassName=name;
   	
   	if (servletClass == null) {
  -	    if (servletClassName == null) {
  -		// It happens :-(
  -		throw new IllegalStateException("Can't happen - classname "
  -						+ "is null, who added this ?");
  -	    }
   	    servletClass=context.getClassLoader().loadClass(servletClassName);
   	}
   	
   	servlet = (Servlet)servletClass.newInstance();
  -
  -	// hack for internal servlets
  -	if( ! servletClassName.startsWith("org.apache.tomcat") ) return;
       }
   
  -    /** Override Handler's init - load the servlet before calling
  -	and interceptor
  -    */
  -    public void init()
  -    	throws Exception
  -   {
  -	// if initialized, then we were sync blocked when first init() succeeded
  -	if( initialized ) return;
  -	// if exception present, then we were sync blocked when first init() failed
  -	// or an interceptor set an inital exeception
  -	// in the latter case, preServletInit() and postServletInit() interceptors
  -	// don't get called
  -	if ( isExceptionPresent() ) return;
  -
  -       // make sure the servlet is loaded before calling preInit
  -	// Jsp case - maybe another Jsp engine is used
  -
  -	if( servlet==null && path != null && ! jspServletInitialized ) {
  -	    //	    log("Calling handleJspInit " + servletClassName);
  -	    // dual mode
  -	    handleJspInit();
  -	    jspServletInitialized=true;
  -	}
   
  -	if( servlet==null ) {
  -	    // try to load servlet, save exception if one occurs
  -	    try {
  -		loadServlet();
  -	    } catch ( Exception ex ) {
  -		// save init exception
  -		setErrorException( ex );
  -		setExceptionPermanent( true );
  -		return;
  -	    }
  -	}
  -
  -	// Call pre, doInit and post
  -	BaseInterceptor cI[]=context.getContainer().getInterceptors();
  -	for( int i=0; i< cI.length; i++ ) {
  -	    try {
  -		cI[i].preServletInit( context, this );
  -	    } catch( TomcatException ex) {
  -		log("preServletInit" , ex);
  -	    }
  -	}
  -
  -	doInit();
  -
  -	// doInit() catches exceptions, so post interceptors are always called	
  -	for( int i=0; i< cI.length; i++ ) {
  -	    try {
  -		cI[i].postServletInit( context, this );
  -	    } catch( TomcatException ex) {
  -		log("postServletInit" , ex);
  -	    }
  -	}
  +    public ServletConfig getServletConfig() {
  +	if( configF==null )
  +	    configF=new ServletConfigImpl( this );
  +	return configF;
       }
  -
  +    
       protected void doInit()
   	throws Exception
       {
   	isReloadable=context.getReloadable();
           configF = new ServletConfigImpl(this);
   
  -	// ASSERT synchronized at higher level, initialized must be false
   	try {
   	    final Servlet sinstance = servlet;
   	    final ServletConfig servletConfig = configF;
   	    servlet.init(servletConfig);
  -	    initialized=true;
   	} catch( UnavailableException ex ) {
  -	    setServletUnavailable( ex );
  -	    servlet=null;
  -	} catch( Exception ex ) {
  -	    // other init exceptions are treated as permanent
  -	    // XXX need a context setting for unavailable time
  -	    setErrorException(ex);
  -	    setExceptionPermanent(true);
  +	    // Implement the "UnavailableException" specification
  +	    // servlet exception state
  +	    setErrorException( ex );
  +	    if ( ex.isPermanent() ) {
  +		setState( STATE_DISABLED );
  +	    } else {
  +		setState( STATE_DELAYED_INIT );
  +		setServletUnavailable( ex );
  +	    }
   	    servlet=null;
  +	    throw ex;
  +	    // it's a normal exception, servlet will
  +	    // not be initialized.
   	}
  +
  +	// other exceptions are just thrown -
  +	// init() will deal with them.
       }
   
       protected void doService(Request req, Response res)
  @@ -428,11 +410,16 @@
   				  req.getContext().getPath()  + "/" + path );
   	    req.setAttribute( "javax.servlet.include.servlet_path", path );
   	}
  +
   
  -	// if servlet is not available
  -	if ( isExceptionPresent() ) {
  -	    // get if error has expired
  -	    checkErrorExpired( req, res );
  +	// if unavailable
  +	if( ! checkErrorExpired() ) {
  +	    // if error still present
  +	    Exception ex=getErrorException();
  +	    if( ex!=null ) {
  +		// save error state on request and response
  +		saveError( req, res, ex );
  +	    }
   	    // if we have an error on this request
   	    if ( req.isExceptionPresent()) {
   		// if in included, defer handling to higher level
  @@ -441,8 +428,7 @@
   		// otherwise handle error
   		contextM.handleError( req, res, getErrorException());
   	    }
  -	    context.log(getServletName() +
  -			" unavailable time expired, trying again ");
  +	    return; // we can't handle it
   	}
   
   	// Get facades - each req have one facade per context
  @@ -463,26 +449,30 @@
   	    req.setFacade( reqF );
   	    res.setFacade( resF );
   	}
  +
  +	if( servlet==null ) {
  +	    System.out.println("XXX servlet==null " + getState() );
  +	    loadServlet();
  +	}
   	
   	try {
   	    doService( reqF, resF );
  -	} catch ( Exception ex ) {
  -	    // support for UnavailableException
  -	    if ( ex instanceof UnavailableException ) {
  -		// if error not set
  -		if ( ! isExceptionPresent() ) {
  -		    synchronized(this) {
  -			if ( ! isExceptionPresent() ) {
  -			    setServletUnavailable( (UnavailableException)ex );
  -			    // XXX if the UnavailableException is permanent we are supposed
  -			    // to destroy the servlet.  Synchronization of this destruction
  -			    // needs review before adding this.
  -			}
  +	} catch ( UnavailableException ex ) {
  +	    if ( ex.isPermanent() ) {
  +		setState( STATE_DISABLED );
  +	    } else {
  +		setServletUnavailable((UnavailableException)ex );
  +	    }
  +	    if ( null != getErrorException() ) {
  +		synchronized(this) {
  +		    if ( null!= getErrorException() ) {
  +			// servlet exception state
  +			setErrorException( ex );
   		    }
   		}
   	    }
  -	    throw ex; // will be saved/handled by Handler
   	}
  +	// other exceptions will be thrown
       }
   
       protected void doService(HttpServletRequest req, HttpServletResponse res)
  @@ -501,55 +491,46 @@
       // -------------------- Jsp hooks
       ServletWrapper jspServletW=null;
       
  -    // <servlet><jsp-file> case - we know it's a jsp
  -    void handleJspInit() {
  -	// XXX Jsp Servlet is initialized, the servlet is not generated -
  -	// we can't hook in! It's jspServet that has to pass the config -
  -	// but it can't so easily, plus  it'll have to hook in.
  -	// I don't think that ever worked anyway - and I don't think
  -	// it can work without integrating Jsp handling into tomcat
  -	// ( using interceptor )
  -	jspServletW = (ServletWrapper)context.getServletByName("jsp");
  -	servletClassName = jspServletW.getServletClass();
  -    }
  +//     // <servlet><jsp-file> case - we know it's a jsp
  +//     void handleJspInit() {
  +// 	// XXX Jsp Servlet is initialized, the servlet is not generated -
  +// 	// we can't hook in! It's jspServet that has to pass the config -
  +// 	// but it can't so easily, plus  it'll have to hook in.
  +// 	// I don't think that ever worked anyway - and I don't think
  +// 	// it can work without integrating Jsp handling into tomcat
  +// 	// ( using interceptor )
  +// 	jspServletW = (ServletWrapper)context.getServletByName("jsp");
  +// 	servletClassName = jspServletW.getServletClass();
  +//     }
   
       // -------------------- Utility methods --------------------
   
  +    /** Set unavailable time
  +     */
       private void setServletUnavailable( UnavailableException ex ) {
  -	// servlet exception state
  -	setErrorException( ex );
  -	if ( ex.isPermanent() ) {
  -	    setExceptionPermanent( true );
  -	} else {
  -	    setExceptionPermanent( false );
  -	    unavailableTime=System.currentTimeMillis();
  -	    unavailableTime += ex.getUnavailableSeconds() * 1000;
  -	}
  +	unavailableTime=System.currentTimeMillis();
  +	unavailableTime += ex.getUnavailableSeconds() * 1000;
       }
   
       /** Check if error exception is present and if so, has the error
   	expired.  Sets error on request and response if un-expired
   	error found.
        */
  -
  -    private void checkErrorExpired( Request req, Response res ) {
  -	// synchronize so another request can't expire the error
  -	synchronized(this) {
  -	    // if error still present
  -	    if ( isExceptionPresent() ) {
  -		// if permanent exception or timer not expired
  -		if ( isExceptionPermanent() ||
  -			(unavailableTime - System.currentTimeMillis()) > 0) {
  -		    // save error state on request and response
  -		    saveError( req, res, getErrorException() );
  -		} else {
  -		    // we can try again
  -		    setErrorException(null);
  -		    setExceptionPermanent(false);
  -		    unavailableTime=-1;
  -		}
  -	    }
  +    private boolean checkErrorExpired() {
  +	if( unavailableTime == -1 )
  +	    return true;
  +	
  +	// if permanent exception this code isn't called
  +	// if timer not expired
  +	if ( (unavailableTime - System.currentTimeMillis()) < 0) {
  +	    // we can try again
  +	    setErrorException(null);
  +	    unavailableTime=-1;
  +	    context.log(getServletName() +
  +			" unavailable time expired, trying again ");
  +	    return true;
   	}
  +	// still unavailable
  +	return false;
       }
  -
   }
  
  
  
  1.6       +14 -3     jakarta-tomcat/src/facade22/org/apache/tomcat/facade/WebXmlReader.java
  
  Index: WebXmlReader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/facade/WebXmlReader.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- WebXmlReader.java	2000/12/08 23:18:29	1.5
  +++ WebXmlReader.java	2000/12/12 00:42:40	1.6
  @@ -53,8 +53,8 @@
   	throws TomcatException
       {
   	//	addServlet( ctx, "default", "org.apache.tomcat.servlets.DefaultServlet");
  -// 	addServlet( ctx, "invoker", "org.apache.tomcat.servlets.InvokerServlet");
  -	Handler sw=addServlet( ctx, "jsp", "org.apache.jasper.servlet.JspServlet");
  +	// 	addServlet( ctx, "invoker", "org.apache.tomcat.servlets.InvokerServlet");
  +	//	Handler sw=addServlet( ctx, "jsp", "org.apache.jasper.servlet.JspServlet");
   	//	sw.addInitParam("jspCompilerPlugin", "org.apache.jasper.compiler.JikesJavaCompiler");
   
   // 	ctx.addServletMapping( "/servlet/*", "invoker");
  @@ -187,7 +187,18 @@
   	    // Servlet
   	    xh.addRule("web-app/servlet", xh.objectCreate("org.apache.tomcat.facade.ServletWrapper")
); // servlet-wrapper
   	    xh.addRule("web-app/servlet", xh.setParent( "setContext") ); // remove it from stack
when done
  -	    xh.addRule("web-app/servlet", xh.addChild("addServlet", "org.apache.tomcat.core.Handler")
);
  +	    //	    xh.addRule("web-app/servlet", xh.addChild("addServlet", "org.apache.tomcat.core.Handler")
);
  +
  +	    xh.addRule("web-app/servlet", new XmlAction() {
  +			   public void end( SaxContext xctx)
  +			       throws Exception {
  +			       ServletWrapper sw=(ServletWrapper)
  +				   xctx.currentObject();
  +			       Context cctx=(Context)xctx.previousObject();
  +			       sw.addServlet(cctx);
  +			   }
  +		       }
  +		   );
   	    // remove it from stack when done
   	    xh.addRule("web-app/servlet/servlet-name", xh.methodSetter("setServletName",0) );
   	    xh.addRule("web-app/servlet/servlet-class", xh.methodSetter("setServletClass",0));
  
  
  
  1.14      +6 -1      jakarta-tomcat/src/facade22/org/apache/tomcat/modules/facade22/JspInterceptor.java
  
  Index: JspInterceptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/facade22/org/apache/tomcat/modules/facade22/JspInterceptor.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- JspInterceptor.java	2000/12/08 23:18:33	1.13
  +++ JspInterceptor.java	2000/12/12 00:42:42	1.14
  @@ -122,9 +122,14 @@
   	}
       }
   
  +    /** Set the HttpJspBase classloader before init,
  +	as required by Jasper
  +    */
       public void preServletInit( Context ctx, Handler sw )
   	throws TomcatException
       {
  +	if( ! (sw instanceof ServletWrapper) )
  +	    return;
   	Servlet theServlet = ((ServletWrapper)sw).getServlet();
   	if (theServlet instanceof HttpJspBase)  {
   	    if( debug > 0 )
  @@ -224,7 +229,7 @@
   	    // set initial exception on the servlet if one is present
   	    if ( jspInfo.isExceptionPresent() ) {
   		wrapper.setErrorException(jspInfo.getCompileException());
  -		wrapper.setExceptionPermanent(true);
  +		wrapper.setState(Handler.STATE_DISABLED);
   	    }
   	} catch( TomcatException ex ) {
   	    log("mapJspPage: request=" + req + ", jspInfo=" + jspInfo + ", servletName=" + servletName
+ ", classN=" + classN, ex);
  
  
  
  1.11      +10 -18    jakarta-tomcat/src/share/org/apache/tomcat/context/ErrorHandler.java
  
  Index: ErrorHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/context/ErrorHandler.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- ErrorHandler.java	2000/12/08 23:18:40	1.10
  +++ ErrorHandler.java	2000/12/12 00:42:43	1.11
  @@ -179,16 +179,14 @@
   	if( debug>0 )
   	    ctx.log( "Handler " + errorServlet + " " + errorPath);
   
  -	try {
  -	    errorServlet.service( req, res );
  -	} catch( IOException e ) {
  -	    // ASSERT: Only thrown by included servlets
  -	    // we can ignore it and it's very common - probably the user
  +	errorServlet.service( req, res );
  +	Exception ex=res.getErrorException();
  +	if( ex!=null && ! (ex instanceof IOException) ) {
  +	    // we can ignore IOException - probably the user
   	    // has clicked "STOP"
  -	} catch( Exception e ) {
   	    // we need to log any other error - something may be
   	    // broken if the error servlet has errors.
  -	    ctx.log( "Error in errorServlet", e);
  +	    ctx.log( "Error in errorServlet", ex);
   	} 
       }
   
  @@ -280,16 +278,14 @@
   	if( debug>0 )
   	    ctx.log( "Handler " + errorServlet + " " + errorPath);
   
  -	try {
  -	    errorServlet.service( req, res );
  -	} catch( IOException e ) {
  -	    // ASSERT: Only thrown by included servlets
  -	    // we can ignore it and it's very common - probably the user
  +	errorServlet.service( req, res );
  +	Exception ex=res.getErrorException();
  +	if( ! (ex instanceof IOException) ) {
  +	    // we can ignore IOException - probably the user
   	    // has clicked "STOP"
  -	} catch( Exception e ) {
   	    // we need to log any other error - something may be
   	    // broken if the error servlet has errors.
  -	    ctx.log( "Error in errorServlet", e);
  +	    ctx.log( "Error in errorServlet", ex);
   	} 
       }
   
  @@ -335,7 +331,6 @@
       int sbNote=0;
       
       NotFoundHandler() {
  -	initialized=true;
   	setOrigin( Handler.ORIGIN_INTERNAL );
   	name="tomcat.notFoundHandler";
       }
  @@ -388,7 +383,6 @@
       int sbNote=0;
   
       ExceptionHandler() {
  -	initialized=true;
   	setOrigin( Handler.ORIGIN_INTERNAL );
   	name="tomcat.exceptionHandler";
       }
  @@ -462,7 +456,6 @@
       int sbNote=0;
   
       StatusHandler() {
  -	initialized=true;
   	setOrigin( Handler.ORIGIN_INTERNAL );
   	name="tomcat.statusHandler";
       }
  @@ -523,7 +516,6 @@
       int sbNote=0;
   
       RedirectHandler() {
  -	initialized=true;
   	setOrigin( Handler.ORIGIN_INTERNAL );
   	name="tomcat.redirectHandler";
       }
  
  
  
  1.128     +4 -0      jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java
  
  Index: Context.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java,v
  retrieving revision 1.127
  retrieving revision 1.128
  diff -u -r1.127 -r1.128
  --- Context.java	2000/11/20 21:00:54	1.127
  +++ Context.java	2000/12/12 00:42:44	1.128
  @@ -820,6 +820,7 @@
       	throws TomcatException
       {
   	wrapper.setContext( this );
  +	wrapper.setState( Handler.STATE_ADDED );
   	String name=wrapper.getName();
   
           // check for duplicates
  @@ -835,6 +836,9 @@
       public final  void removeServletByName(String servletName)
   	throws TomcatException
       {
  +	Handler h=getServletByName( servletName );
  +	if( h!=null )
  +	    h.setState( Handler.STATE_NEW );
   	servlets.remove( servletName );
       }
   
  
  
  
  1.26      +168 -75   jakarta-tomcat/src/share/org/apache/tomcat/core/Handler.java
  
  Index: Handler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Handler.java,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- Handler.java	2000/12/08 23:18:43	1.25
  +++ Handler.java	2000/12/12 00:42:46	1.26
  @@ -135,15 +135,43 @@
   
       // -------------------- State --------------------
   
  +    /** The handler is new, not part of any application.
  +     *  You must to add the handler to application before doing
  +     *  anything else.
  +     *  To ADDED by calling Context.addHandler().
  +     *  From ADDED by calling Context.removeHandler();
  +     */
       public static final int STATE_NEW=0;
   
  +    /** The handler is added to an application and can be initialized.
  +     *  To READY by calling init(), if success
  +     *  TO DISABLED by calling init if it fails ( exception )
  +     *  From READY by calling destroy()
  +     */
       public static final int STATE_ADDED=1;
  -
  -    public static final int STATE_READY=2;
  -
  -    public static final int STATE_TEMP_DISABLED=3;
   
  +    /** 
  +     * If init() fails or preInit() detects the handler is still
  +     * unavailable.
  +     */
  +    public static final int STATE_DELAYED_INIT=2;
  +
  +    /** The handler has been succesfully initialized and is ready to
  +     * serve requests. If the handler is not in this state a 500 error
  +     * should be reported. ( customize - may be 404 )
  +     * To ADDED by calling destroy()
  +     * FROM ADDED by calling init()
  +     */
  +    public static final int STATE_READY=3;
  +
  +    /** Handler is unable to perform - any attempt to use it should
  +     *  report an internal error. This is the result of an internal
  +     *  exception or an error in init()
  +     *  To ADDED by calling destroy()
  +     *  From ADDED by calling init() ( if failure )
  +     */
       public static final int STATE_DISABLED=4;
  +
       
   
       // -------------------- Properties --------------------
  @@ -152,13 +180,8 @@
       
       protected String name;
   
  -    protected int state=STATE_NEW;
  +    private int state=STATE_NEW;
       
  -    /** True if it can handle requests.
  -	404 or error if not.
  -    */
  -    protected boolean initialized=false;
  -    
       Hashtable initArgs=null;
   
       // who creates the servlet definition
  @@ -172,7 +195,6 @@
       protected boolean loadingOnStartup=false;
   
       protected Exception errorException=null;
  -    protected boolean exceptionPermanent=false;
       
       // Debug
       protected int debug=0;
  @@ -278,18 +300,6 @@
   	return errorException;
       }
   
  -    public boolean isExceptionPresent() {
  -	return ( errorException != null );
  -    }
  -
  -    public void setExceptionPermanent( boolean permanent ) {
  -	exceptionPermanent = permanent;
  -    }
  -
  -    public boolean isExceptionPermanent() {
  -	return exceptionPermanent;
  -    }
  -
       // -------------------- Jsp specific code
       
       public String getPath() {
  @@ -335,47 +345,115 @@
   
       /** Destroy a handler, and notify all the interested interceptors
        */
  -    public final void destroy() throws Exception {
  -	if ( ! initialized ) {
  +    public final void destroy() {
  +	if ( state!=STATE_READY ) {
  +	    // reset exception
   	    errorException = null;
   	    return;// already destroyed or not init.
   	}
  -	initialized=false;
  +	setState( STATE_ADDED );
   
   	// XXX post will not be called if any error happens in destroy.
   	// That's how tomcat worked before - I think it's a bug !
  -	doDestroy();
  +	try {
  +	    doDestroy();
  +	} catch( Exception ex ) {
  +	    log( "Error during destroy ", ex );
  +	}
  +	
   
   	errorException=null;
       }
   
   
       /** Call the init method, and notify all interested listeners.
  +     *  This is a final method to insure consistent behavior on errors.
  +     *  It also saves handlers from dealing with synchronization issues.
        */
  -    public /* final */ void init()
  -	throws Exception
  +    public final void init()
       {
  -	// if initialized, then we were sync blocked when first init() succeeded
  -	if( initialized ) return;
  -	// if exception present, then we were sync blocked when first init() failed
  -	// or an interceptor set an inital exeception
  -	if (errorException != null) throw errorException;
  -	try {
  -	    doInit();
  -	    initialized=true;
  -	} catch( Exception ex ) {
  -	    // save error, assume permanent
  -	    setErrorException(ex);
  -	    setExceptionPermanent(true);
  +	// we use getState() as a workaround for bugs in VMs
  +	
  +	if( getState() == STATE_READY || getState() == STATE_DISABLED )
  +	    return;
  +
  +	synchronized( this ) {
  +	    // check again - if 2 threads are in init(), the first one will
  +	    // init and the second will enter the sync block after that
  +	    if( getState() == STATE_READY ) 
  +		return;
  +
  +	    // if exception present, then we were sync blocked when first
  +	    // init() failed or an interceptor set an inital exeception
  +	    // A different thread got an error in init() - throw
  +	    // the same error.
  +	    if (getState() == STATE_DISABLED )
  +		return; //throw errorException;
  +
  +	    try {
  +		// special preInit() hook
  +		preInit();
  +		// preInit may either throw exception or setState DELAYED_INIT
  +	    } catch( Exception ex ) {
  +		// save error, assume permanent
  +		log("Exception in preInit  " + ex.getMessage(), ex );
  +		setErrorException(ex);
  +		setState(STATE_DISABLED);
  +		return;
  +	    }
  +	    
  +	    // we'll try again later 
  +	    if( getState() == STATE_DELAYED_INIT ||
  +		getState()==STATE_DISABLED ) { // or disabled 
  +		return;
  +	    }
  +	    // preInit have no exceptions and doesn't delay us
  +	    // We can run init hooks and init
  +
  +	    // Call pre, doInit and post
  +	    BaseInterceptor cI[]=context.getContainer().getInterceptors();
  +	    for( int i=0; i< cI.length; i++ ) {
  +		try {
  +		    cI[i].preServletInit( context, this );
  +		} catch( TomcatException ex) {
  +		    // log, but ignore.
  +		    log("preServletInit" , ex);
  +		}
  +	    }
  +		
  +	    try {
  +		doInit();
  +		// if success, we are ready to serve
  +	    } catch( Exception ex ) {
  +		// save error, assume permanent
  +		log("Exception in init  " + ex.getMessage(), ex );
  +		setErrorException(ex);
  +		state=STATE_DISABLED;
  +	    }
  +	    
  +	    for( int i=0; i< cI.length; i++ ) {
  +		try {
  +		    cI[i].postServletInit( context, this );
  +		} catch( TomcatException ex) {
  +		    log("postServletInit" , ex);
  +		}
  +	    }
  +
  +	    // Now that both pre/post hooks have been called, the
  +	    // servlet is ready to serve.
  +
  +	    // We are still in the sync block, that means other threads
  +	    // are waiting for this to be over.
  +
  +	    // if no error happened and if doInit didn't put us in
  +	    // a special state, we are ready
  +	    if( state!=STATE_DISABLED &&
  +		getErrorException() != null ) {
  +		state=STATE_READY;
  +	    }
   	}
       }
   
  -    // XXX XXX XXX
  -    // Must be changed - it's very confusing since it has the same name
  -    // with the servlet's service() method.
  -    // The Handler is at a different ( lower ) level, we should
  -    // use different names ( invoke() ? )
  -
       /** Call the service method, and notify all listeners
        *
        * @exception Exception if an error happens during handling of
  @@ -391,28 +469,16 @@
        *  runtime exceptions )
        */
       public final void service(Request req, Response res)
  -	throws Exception
       {
  -	if( ! initialized ) {
  -	    Exception ex=null;
  -	    synchronized( this ) {
  -		// we may be initialized when we enter the sync block
  -		if( ! initialized ) {
  -		    try {
  -			init();
  -		    } catch ( Exception e ) {
  -			errorException = e;
  -			exceptionPermanent = true;
  -		    }
  -		}
  -		// get copy of exception, if any, before leaving sync lock
  -		ex=errorException;
  +	if( state!=STATE_READY ) {
  +	    if( state!= STATE_DISABLED ) {
  +		init();
   	    }
  -	    // if error occurred
  -	    if ( ex != null ) {
  +	    if( state== STATE_DISABLED ) {
  +		// the init failed because of an exception
  +		Exception ex=getErrorException();
   		// save error state on request and response
   		saveError( req, res, ex );
  -		log("Exception in init  " + ex.getMessage(), ex );
   		// if in included, defer handling to higher level
   		if (res.isIncluded()) return;
   		// handle init error since at top level
  @@ -421,43 +487,51 @@
   		else
   		    contextM.handleError( req, res, ex );
   		return;
  -	    }
  +	    } 
   	}
   	
  -	//	if( ! internal ) {
  -	// no distinction for internal handlers !
   	BaseInterceptor reqI[]=
   	    req.getContainer().getInterceptors(Container.H_preService);
   	for( int i=0; i< reqI.length; i++ ) {
   	    reqI[i].preService( req, res );
   	}
  -	//}
   
  +	Exception serviceException=null;
   	try {
   	    doService( req, res );
   	} catch( Exception ex ) {
   	    // save error state on request and response
  -	    saveError( req, res, ex );
  +	    serviceException=ex;
  +	    saveError( req, res, ex);
   	}
   
  -	// continue with the postService
  -	//	if( ! internal ) {
  +	// continue with the postService ( roll back transactions, etc )
   	reqI=req.getContainer().getInterceptors(Container.H_postService);
   	for( int i=0; i< reqI.length; i++ ) {
   	    reqI[i].postService( req, res );
   	}
  -	//	}
   
   	// if no error
  -	if( ! res.isExceptionPresent() ) return;
  +	if( serviceException == null ) return;
  +
   	// if in included, defer handling to higher level
   	if (res.isIncluded()) return;
  +	
   	// handle original error since at top level
   	contextM.handleError( req, res, res.getErrorException() );
       }
   
       // -------------------- methods you can override --------------------
   
  +    protected void handleInitError( Throwable t ) {
  +
  +    }
  +    
  +    protected void handleServiceError( Request req, Response res, Throwable t )
  +    {
  +
  +    }
  +    
       /** Reload notification. This hook is called whenever the
        *  application ( this handler ) is reloaded
        */
  @@ -471,6 +545,22 @@
   
       }
   
  +    /** Special hook called before init and init hooks. 
  +     *
  +     *  This hook will set the state of the handler for the init() hooks
  +     * ( for example load the servlet class, other critical preparations ).
  +     *  If it fails, the servlet will be disabled and no other call will
  +     *  succed.
  +     *  The hook can also delay initialization ( put handler in  DELAY_INIT
  +     *  state ). The application will be unavailable ( no service will be
  +     *  called ), and preInit will be called to check if the state changed.
  +     *  ( this can be used to implement UnavailableException )
  +     *
  +     */
  +    protected void preInit() throws Exception {
  +
  +    }
  +    
       /** Initialize the handler. Handler can override this
        *	method to initialize themself.
        */
  @@ -505,7 +595,10 @@
   
       protected final void log( String s ) {
   	if ( logger==null ) 
  -	    contextM.log(s);
  +	    if( contextM!=null )
  +		contextM.log(s);
  +	    else
  +		System.out.println("(cm==null) " + s );
   	else 
   	    logger.log(s);
       }
  
  
  
  1.26      +4 -5      jakarta-tomcat/src/share/org/apache/tomcat/request/AccessInterceptor.java
  
  Index: AccessInterceptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/AccessInterceptor.java,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- AccessInterceptor.java	2000/12/08 23:18:48	1.25
  +++ AccessInterceptor.java	2000/12/12 00:42:48	1.26
  @@ -216,8 +216,10 @@
   	Container ctxCt=ctx.getContainer();
   	SecurityConstraints ctxSecurityC=(SecurityConstraints)ctxCt.
   	    getNote( secMapNote );
  -	if( ctxSecurityC==null)
  -	    ctxCt.setNote( secMapNote, new SecurityConstraints() );
  +	if( ctxSecurityC==null) {
  +	    ctxSecurityC= new SecurityConstraints();
  +	    ctxCt.setNote( secMapNote, ctxSecurityC );
  +	}
   
   	if( ct.getRoles()!=null || ct.getTransport()!=null ) {
   	    if( debug > 0 )
  @@ -342,7 +344,6 @@
       int sbNote=0;
       
       BasicAuthHandler() {
  -	initialized=true;
   	setOrigin( Handler.ORIGIN_INTERNAL );
   	name="tomcat.basicAuthHandler";
       }
  @@ -389,7 +390,6 @@
   class FormAuthHandler extends Handler {
       
       FormAuthHandler() {
  -	initialized=true;
   	setOrigin( Handler.ORIGIN_INTERNAL );
   	name="tomcat.formAuthHandler";
       }
  @@ -447,7 +447,6 @@
   class FormSecurityCheckHandler extends Handler {
       
       FormSecurityCheckHandler() {
  -	initialized=true;
   	setOrigin( Handler.ORIGIN_INTERNAL );
   	name="tomcat.formSecurityCheck";
       }
  
  
  
  1.26      +0 -2      jakarta-tomcat/src/share/org/apache/tomcat/request/StaticInterceptor.java
  
  Index: StaticInterceptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/StaticInterceptor.java,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- StaticInterceptor.java	2000/12/08 23:18:49	1.25
  +++ StaticInterceptor.java	2000/12/12 00:42:48	1.26
  @@ -217,7 +217,6 @@
       int realFileNote;
   
       FileHandler() {
  -	initialized=true;
   	setOrigin( Handler.ORIGIN_INTERNAL );
   	name="tomcat.fileHandler";
       }
  @@ -329,7 +328,6 @@
       int sbNote=0;
       
       DirHandler() {
  -	initialized=true;
   	setOrigin( Handler.ORIGIN_INTERNAL );
   	name="tomcat.dirHandler";
       }
  
  
  
  1.15      +1 -1      jakarta-tomcat/src/share/org/apache/tomcat/startup/Main.java
  
  Index: Main.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/startup/Main.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- Main.java	2000/11/30 06:17:13	1.14
  +++ Main.java	2000/12/12 00:42:49	1.15
  @@ -282,7 +282,7 @@
   				      "org.apache.tomcat.task.StartTomcat");
   	    processArgs( proxy, args );
   	    setAttribute( proxy, "parentClassLoader", parentL );
  -	    setAttribute( proxy, "serverClassPath", urls );
  +	    //	    setAttribute( proxy, "serverClassPath", urls );
   	    execute(  proxy, "execute" );
   	    return;
   	} catch( Exception ex ) {
  
  
  

Mime
View raw message