📄 servletwrapper.java
字号:
*/ private void loadServlet() throws ClassNotFoundException, InstantiationException, IllegalAccessException { // XXX Move this to an interceptor, so it will be configurable. // ( and easier to read ) // System.out.println("LoadServlet " + servletClass + " " // + servletClassName); if (servletClass == null) { if (servletClassName == null) { throw new IllegalStateException("Can't happen - classname " + "is null, who added this ?"); } ServletLoader loader=context.getServletLoader(); servletClass=loader.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 { // make sure the servlet in loaded before calling preInit // Jsp case - maybe another Jsp engine is used if( servlet==null && path != null && servletClassName == null) { // System.out.println("Handle Jsp init " + servletClassName); handleJspInit(); } // Will throw exception if it can't load, let upper // levels handle this // try { if( servlet==null ) loadServlet(); // } catch( ClassNotFoundException ex ) { // } catch( InstantiationException ex ) { //} catch( IllegalStateException ex ) { //} // Call pre, doInit and post super.init(); } protected void doInit() throws Exception { // The servlet is loaded and not null - otherwise init() // throws exception try { // if multiple threads will call the same servlet at once, // we should have only one init synchronized( this ) { // we may have 2 threads entering doInit, // the first one may init the servlet if( initialized ) return; final Servlet sinstance = servlet; final ServletConfig servletConfig = configF; // init - only if unavailable was null or // unavailable period expired servlet.init(servletConfig); initialized=true; } } catch( UnavailableException ex ) { unavailable=ex; unavailableTime=System.currentTimeMillis(); unavailableTime += ex.getUnavailableSeconds() * 1000; servlet=null; throw ex; } catch( Exception ex ) { unavailable=ex; servlet=null; throw ex; } } /** Override service to hook reloading - it can be done in a clean * interceptor. It also hooks jsp - we should have a separate * JspHandler * * @exception IOException if an input/output error occurs and we are * processing an included servlet (otherwise it is swallowed and * handled by the top level error handler mechanism) * @exception ServletException if a servlet throws an exception and * we are processing an included servlet (otherwise it is swallowed * and handled by the top level error handler mechanism) */ public void service(Request req, Response res) throws IOException, ServletException { try { handleReload(req); } catch( TomcatException ex ) { ex.printStackTrace();// what to do ? } // <servlet><jsp-file> case if( path!=null ) { if( path.startsWith("/")) req.setAttribute( "javax.servlet.include.request_uri", req.getContext().getPath() + path ); else req.setAttribute( "javax.servlet.include.request_uri", req.getContext().getPath() + "/" + path ); req.setAttribute( "javax.servlet.include.servlet_path", path ); } if( unavailable!=null ) { // check servlet availability, throw appropriate exception if not servletAvailable(); } // called only if unavailable==null or timer expired. // will do an init try { super.service( req, res ); } catch( IOException e ) { throw e; } catch ( UnavailableException e ) { // if unavailable not set, assume thrown from service(), not init() if (unavailable == null) { synchronized(this) { if (unavailable == null) { unavailable = e; // XXX if the UnavailableException is permanent we are supposed // to destroy the servlet. Synchronization of this destruction // needs review before adding this. unavailableTime = System.currentTimeMillis(); unavailableTime += e.getUnavailableSeconds() * 1000; } } } throw e; } catch( ServletException e ) { throw e; } } protected void doService(Request req, Response res) throws Exception { // We are initialized and fine if (servlet instanceof SingleThreadModel) { synchronized(servlet) { servlet.service(req.getFacade(), res.getFacade()); } } else { servlet.service(req.getFacade(), res.getFacade()); } } // -------------------- Reloading -------------------- // XXX Move it to interceptor - so it can be customized // Reloading // XXX ugly - should find a better way to deal with invoker // The problem is that we are just clearing up invoker, not // the class loaded by invoker. void handleReload(Request req) throws TomcatException { // That will be reolved after we reset the context - and many // other conflicts. if( isReloadable ) {// && ! "invoker".equals( getServletName())) { ServletLoader loader=context.getServletLoader(); if( loader!=null) { // XXX no need to check after we remove the old loader if( loader.shouldReload() ) { // workaround for destroy try { destroy(); } catch(Exception ex ) { context.log( "Error in destroy ", ex ); } initialized=false; loader.reload(); ContextManager cm=context.getContextManager(); cm.doReload( req, context ); servlet=null; servletClass=null; /* Initial attempt to shut down the context and sessions. String path=context.getPath(); String docBase=context.getDocBase(); // XXX all other properties need to be saved // or something else ContextManager cm=context.getContextManager(); cm.removeContext(path); Context ctx=new Context(); ctx.setPath( path ); ctx.setDocBase( docBase ); cm.addContext( ctx ); context=ctx; // XXX shut down context, remove sessions, etc */ } } } } // -------------------- Jsp hooks // <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 ) ServletWrapper jspServletW = context.getServletByName("jsp"); servletClassName = jspServletW.getServletClass(); } // -------------------- Unavailable -------------------- /** Check if we can try again an init */ private void servletAvailable() throws IOException, ServletException { // if permanently unavailable, rethrow exception if (unavailable instanceof UnavailableException && ((UnavailableException)unavailable).isPermanent()) throw (UnavailableException)unavailable; // we have a timer - maybe we can try again - how much // do we have to wait - (in mSec) long moreWaitTime=unavailableTime - System.currentTimeMillis(); if( moreWaitTime > 0 ) { // get seconds left, rounded up to at least one second int secs = (int)((moreWaitTime + 999) / 1000); // throw updated exception throw new UnavailableException(unavailable.getMessage(), secs); } // we can try again unavailable=null; unavailableTime=-1; context.log(getServletName() + " unavailable time expired," + " try again "); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -