geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From djen...@apache.org
Subject svn commit: r522103 - /geronimo/sandbox/djencks/tomcat-patches/GERONIMO-3010-2.patch
Date Sat, 24 Mar 2007 20:36:33 GMT
Author: djencks
Date: Sat Mar 24 13:36:32 2007
New Revision: 522103

URL: http://svn.apache.org/viewvc?view=rev&rev=522103
Log:
GERONIMO-3010 2nd version of tomcat/jasper patch

Added:
    geronimo/sandbox/djencks/tomcat-patches/GERONIMO-3010-2.patch

Added: geronimo/sandbox/djencks/tomcat-patches/GERONIMO-3010-2.patch
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/tomcat-patches/GERONIMO-3010-2.patch?view=auto&rev=522103
==============================================================================
--- geronimo/sandbox/djencks/tomcat-patches/GERONIMO-3010-2.patch (added)
+++ geronimo/sandbox/djencks/tomcat-patches/GERONIMO-3010-2.patch Sat Mar 24 13:36:32 2007
@@ -0,0 +1,1132 @@
+Index: java/org/apache/jasper/JspCompilationContext.java
+===================================================================
+--- java/org/apache/jasper/JspCompilationContext.java	(revision 521878)
++++ java/org/apache/jasper/JspCompilationContext.java	(working copy)
+@@ -589,12 +589,7 @@
+         try {
+             getJspLoader();
+             
+-            String name;
+-            if (isTagFile()) {
+-                name = tagInfo.getTagClassName();
+-            } else {
+-                name = getServletPackageName() + "." + getServletClassName();
+-            }
++            String name = getFQCN();
+             servletClass = jspLoader.loadClass(name);
+         } catch (ClassNotFoundException cex) {
+             throw new JasperException(Localizer.getMessage("jsp.error.unable.load"),
+@@ -607,6 +602,16 @@
+         return servletClass;
+     }
+ 
++    public String getFQCN() {
++        String name;
++        if (isTagFile()) {
++            name = tagInfo.getTagClassName();
++        } else {
++            name = getServletPackageName() + "." + getServletClassName();
++        }
++        return name;
++    }
++
+     // ==================== protected methods ==================== 
+ 
+     static Object outputDirLock = new Object();
+Index: java/org/apache/jasper/runtime/TagHandlerPool.java
+===================================================================
+--- java/org/apache/jasper/runtime/TagHandlerPool.java	(revision 521878)
++++ java/org/apache/jasper/runtime/TagHandlerPool.java	(working copy)
+@@ -21,7 +21,7 @@
+ import javax.servlet.jsp.JspException;
+ import javax.servlet.jsp.tagext.Tag;
+ 
+-import org.apache.AnnotationProcessor;
++import org.apache.catalina.lifecycle.LifecycleProvider;
+ import org.apache.jasper.Constants;
+ import org.apache.juli.logging.Log;
+ import org.apache.juli.logging.LogFactory;
+@@ -42,7 +42,7 @@
+     
+     // index of next available tag handler
+     private int current;
+-    protected AnnotationProcessor annotationProcessor = null;
++    protected LifecycleProvider lifecycleProvider = null;
+ 
+     public static TagHandlerPool getTagHandlerPool( ServletConfig config) {
+         TagHandlerPool result=null;
+@@ -78,8 +78,8 @@
+         }
+         this.handlers = new Tag[maxSize];
+         this.current = -1;
+-        this.annotationProcessor = 
+-            (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
++        this.lifecycleProvider =
++            (LifecycleProvider) config.getServletContext().getAttribute(LifecycleProvider.class.getName());
+     }
+ 
+     /**
+@@ -112,7 +112,7 @@
+      * @throws JspException if a tag handler cannot be instantiated
+      */
+     public Tag get(Class handlerClass) throws JspException {
+-	Tag handler = null;
++	Tag handler;
+         synchronized( this ) {
+             if (current >= 0) {
+                 handler = handlers[current--];
+@@ -123,9 +123,11 @@
+         // Out of sync block - there is no need for other threads to
+         // wait for us to construct a tag for this thread.
+         try {
+-            Tag instance = (Tag) handlerClass.newInstance();
+-            AnnotationHelper.postConstruct(annotationProcessor, instance);
+-            return instance;
++            if (lifecycleProvider != null) {
++                return (Tag) lifecycleProvider.newInstance(handlerClass.getName());
++            } else {
++                return (Tag) handlerClass.newInstance();
++            }
+         } catch (Exception e) {
+             throw new JspException(e.getMessage(), e);
+         }
+@@ -147,11 +149,11 @@
+         }
+         // There is no need for other threads to wait for us to release
+         handler.release();
+-        if (annotationProcessor != null) {
++        if (lifecycleProvider != null) {
+             try {
+-                AnnotationHelper.preDestroy(annotationProcessor, handler);
++                lifecycleProvider.destroyInstance(handler);
+             } catch (Exception e) {
+-                log.warn("Error processing preDestroy on tag instance of " 
++                log.warn("Error processing preDestroy on tag instance of "
+                         + handler.getClass().getName(), e);
+             }
+         }
+@@ -164,11 +166,11 @@
+     public synchronized void release() {
+         for (int i = current; i >= 0; i--) {
+             handlers[i].release();
+-            if (annotationProcessor != null) {
++            if (lifecycleProvider != null) {
+                 try {
+-                    AnnotationHelper.preDestroy(annotationProcessor, handlers[i]);
++                    lifecycleProvider.destroyInstance(handlers[i]);
+                 } catch (Exception e) {
+-                    log.warn("Error processing preDestroy on tag instance of " 
++                    log.warn("Error processing preDestroy on tag instance of "
+                             + handlers[i].getClass().getName(), e);
+                 }
+             }
+Index: java/org/apache/jasper/runtime/AnnotationHelper.java
+===================================================================
+--- java/org/apache/jasper/runtime/AnnotationHelper.java	(revision 521878)
++++ java/org/apache/jasper/runtime/AnnotationHelper.java	(working copy)
+@@ -1,61 +0,0 @@
+-/*
+- * Licensed to the Apache Software Foundation (ASF) under one or more
+- * contributor license agreements.  See the NOTICE file distributed with
+- * this work for additional information regarding copyright ownership.
+- * The ASF licenses this file to You 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.jasper.runtime;
+-
+-import java.lang.reflect.InvocationTargetException;
+-
+-import javax.naming.NamingException;
+-
+-import org.apache.AnnotationProcessor;
+-
+-
+-/**
+- * Verify the annotation and Process it.
+- *
+- * @author Fabien Carrion
+- * @author Remy Maucherat
+- * @version $Revision$, $Date$
+- */
+-public class AnnotationHelper {
+-
+-    
+-    /**
+-     * Call postConstruct method on the specified instance. Note: In Jasper, this
+-     * calls naming resources injection as well.
+-     */
+-    public static void postConstruct(AnnotationProcessor processor, Object instance)
+-        throws IllegalAccessException, InvocationTargetException, NamingException {
+-        if (processor != null) {
+-            processor.processAnnotations(instance);
+-            processor.postConstruct(instance);
+-        }
+-    }
+-    
+-    
+-    /**
+-     * Call preDestroy method on the specified instance.
+-     */
+-    public static void preDestroy(AnnotationProcessor processor, Object instance)
+-        throws IllegalAccessException, InvocationTargetException {
+-        if (processor != null) {
+-            processor.preDestroy(instance);
+-        }
+-    }
+-    
+-
+-}
+Index: java/org/apache/jasper/servlet/JspServletWrapper.java
+===================================================================
+--- java/org/apache/jasper/servlet/JspServletWrapper.java	(revision 521878)
++++ java/org/apache/jasper/servlet/JspServletWrapper.java	(working copy)
+@@ -31,7 +31,7 @@
+ import javax.servlet.http.HttpServletResponse;
+ import javax.servlet.jsp.tagext.TagInfo;
+ 
+-import org.apache.AnnotationProcessor;
++import org.apache.catalina.lifecycle.LifecycleProvider;
+ import org.apache.jasper.JasperException;
+ import org.apache.jasper.JspCompilationContext;
+ import org.apache.jasper.Options;
+@@ -139,12 +139,12 @@
+                     destroy();
+                     
+                     try {
++                        LifecycleProvider lifecycleProvider = (LifecycleProvider) config.getServletContext().getAttribute(LifecycleProvider.class.getName());
++                        if (lifecycleProvider != null) {
++                            theServlet = (Servlet) lifecycleProvider.newInstance(ctxt.getFQCN(), ctxt.getJspLoader());
++                        } else {
+                         servletClass = ctxt.load();
+-                        theServlet = (Servlet) servletClass.newInstance();
+-                        AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
+-                        if (annotationProcessor != null) {
+-                           annotationProcessor.processAnnotations(theServlet);
+-                           annotationProcessor.postConstruct(theServlet);
++                            theServlet = (Servlet) servletClass.newInstance();
+                         }
+                     } catch (IllegalAccessException e) {
+                         throw new JasperException(e);
+@@ -433,10 +433,10 @@
+     public void destroy() {
+         if (theServlet != null) {
+             theServlet.destroy();
+-            AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
+-            if (annotationProcessor != null) {
++            LifecycleProvider lifecycleProvider = (LifecycleProvider) config.getServletContext().getAttribute(LifecycleProvider.class.getName());
++            if (lifecycleProvider != null) {
+                 try {
+-                    annotationProcessor.preDestroy(theServlet);
++                    lifecycleProvider.destroyInstance(theServlet);
+                 } catch (Exception e) {
+                     // Log any exception, since it can't be passed along
+                     log.error(Localizer.getMessage("jsp.error.file.not.found",
+Index: java/org/apache/jasper/compiler/Generator.java
+===================================================================
+--- java/org/apache/jasper/compiler/Generator.java	(revision 521878)
++++ java/org/apache/jasper/compiler/Generator.java	(working copy)
+@@ -73,8 +73,8 @@
+ 
+     private static final String VAR_EXPRESSIONFACTORY = 
+         System.getProperty("org.apache.jasper.compiler.Generator.VAR_EXPRESSIONFACTORY", "_el_expressionfactory");
+-    private static final String VAR_ANNOTATIONPROCESSOR = 
+-        System.getProperty("org.apache.jasper.compiler.Generator.VAR_ANNOTATIONPROCESSOR", "_jsp_annotationprocessor");
++    private static final String VAR_LIFECYCLEPROVIDER =
++        System.getProperty("org.apache.jasper.compiler.Generator.VAR_LIFECYCLEPROVIDER", "_jsp_lifecycleprovider");
+ 
+     private ServletWriter out;
+ 
+@@ -410,14 +410,14 @@
+         }
+         out.println(".getServletContext()).getExpressionFactory();");
+ 
+-        out.printin(VAR_ANNOTATIONPROCESSOR);
+-        out.print(" = (org.apache.AnnotationProcessor) ");
++        out.printin(VAR_LIFECYCLEPROVIDER);
++        out.print(" = (org.apache.catalina.lifecycle.LifecycleProvider) ");
+         if (ctxt.isTagFile()) {
+             out.print("config");
+         } else {
+             out.print("getServletConfig()");
+         }
+-        out.println(".getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());");
++        out.println(".getServletContext().getAttribute(org.apache.catalina.lifecycle.LifecycleProvider.class.getName());");
+ 
+         out.popIndent();
+         out.printil("}");
+@@ -521,8 +521,8 @@
+         out.printin("private javax.el.ExpressionFactory ");
+         out.print(VAR_EXPRESSIONFACTORY);
+         out.println(";");
+-        out.printin("private org.apache.AnnotationProcessor ");
+-        out.print(VAR_ANNOTATIONPROCESSOR);
++        out.printin("private org.apache.catalina.lifecycle.LifecycleProvider ");
++        out.print(VAR_LIFECYCLEPROVIDER);
+         out.println(";");
+         out.println();
+     }
+@@ -2142,11 +2142,11 @@
+ 
+             String tagHandlerClassName = JspUtil
+                     .getCanonicalName(tagHandlerClass);
+-            out.printin(tagHandlerClassName);
+-            out.print(" ");
+-            out.print(tagHandlerVar);
+-            out.print(" = ");
+             if (isPoolingEnabled && !(n.implementsJspIdConsumer())) {
++                out.printin(tagHandlerClassName);
++                out.print(" ");
++                out.print(tagHandlerVar);
++                out.print(" = ");
+                 out.print("(");
+                 out.print(tagHandlerClassName);
+                 out.print(") ");
+@@ -2155,14 +2155,7 @@
+                 out.print(tagHandlerClassName);
+                 out.println(".class);");
+             } else {
+-                out.print("new ");
+-                out.print(tagHandlerClassName);
+-                out.println("();");
+-                out.printin("org.apache.jasper.runtime.AnnotationHelper.postConstruct(");
+-                out.print(VAR_ANNOTATIONPROCESSOR);
+-                out.print(", ");
+-                out.print(tagHandlerVar);
+-                out.println(");");
++                writeNewInstance(tagHandlerVar, tagHandlerClassName);
+             }
+ 
+             // includes setting the context
+@@ -2220,8 +2213,7 @@
+                         out.println("[0]++;");
+                     }
+                     out.printin(tagHandlerVar);
+-                    out
+-                            .println(".setBodyContent((javax.servlet.jsp.tagext.BodyContent) out);");
++                    out.println(".setBodyContent((javax.servlet.jsp.tagext.BodyContent) out);");
+                     out.printin(tagHandlerVar);
+                     out.println(".doInitBody();");
+ 
+@@ -2247,6 +2239,72 @@
+             n.setEndJavaLine(out.getJavaLine());
+         }
+ 
++        private void writeNewInstance(String tagHandlerVar, String tagHandlerClassName) {
++            //tries to generate this code:
++            /*
++            MyTag myTag;
++            if (lifeycleProvider == null) {
++                myTag = new myTag();
++            } else {
++                //  the class may be generated and only in the generated class's classloader.
++                myTag = lifecycleProvider.newInstance("org.foo.MyTag", this.getClass().getClassLoader());
++            }
++            */
++            out.printin(tagHandlerClassName);
++            out.print(" ");
++            out.print(tagHandlerVar);
++            out.println(";");
++            out.printin("if (");
++            out.print(VAR_LIFECYCLEPROVIDER);
++            out.println(" == null) {");
++            out.printin(tagHandlerVar);
++            out.print(" = new ");
++            out.print(tagHandlerClassName);
++            out.println("();");
++            out.printil("} else {");
++            out.printin(tagHandlerVar);
++            out.print(" = (");
++            out.print(tagHandlerClassName);
++            out.print(")");
++            out.print(VAR_LIFECYCLEPROVIDER);
++            out.print(".newInstance(\"");
++            out.print(tagHandlerClassName);
++            out.println("\", this.getClass().getClassLoader());");
++            out.printil("}");
++            //replaces this code:
++//            out.print("new ");
++//            out.print(tagHandlerClassName);
++//            out.println("();");
++//            out.printin("org.apache.jasper.runtime.AnnotationHelper.postConstruct(");
++//            out.print(VAR_LIFECYCLEPROVIDER);
++//            out.print(", ");
++//            out.print(tagHandlerVar);
++//            out.println(");");
++        }
++
++        private void writeDestroyInstance(String tagHandlerVar) {
++            //tries to generate this code:
++            /*
++            if (lifecycleProvider != null) {
++                lifecycleProvider.destroyInstance(myTag);
++            }
++            */
++            out.printin("if (");
++            out.print(VAR_LIFECYCLEPROVIDER);
++            out.println(" != null) {");
++            out.printin(VAR_LIFECYCLEPROVIDER);
++            out.print(".destroyInstance(");
++            out.print(tagHandlerVar);
++            out.println(");");
++            out.printil("}");
++            //replaces this code:
++//            out.printin("org.apache.jasper.runtime.AnnotationHelper.preDestroy(");
++//            out.print(VAR_LIFECYCLEPROVIDER);
++//            out.print(", ");
++//            out.print(tagHandlerVar);
++//            out.println(");");
++        }
++
+         private void generateCustomEnd(Node.CustomTag n, String tagHandlerVar,
+                 String tagEvalVar, String tagPushBodyCountVar) {
+ 
+@@ -2308,11 +2366,7 @@
+                 } else {
+                     out.printin(tagHandlerVar);
+                     out.println(".release();");
+-                    out.printin("org.apache.jasper.runtime.AnnotationHelper.preDestroy(");
+-                    out.print(VAR_ANNOTATIONPROCESSOR);
+-                    out.print(", ");
+-                    out.print(tagHandlerVar);
+-                    out.println(");");
++                    writeDestroyInstance(tagHandlerVar);
+                 }
+             }
+             if (isTagFile || isFragment) {
+@@ -2355,11 +2409,7 @@
+             } else {
+                 out.printin(tagHandlerVar);
+                 out.println(".release();");
+-                out.printin("org.apache.jasper.runtime.AnnotationHelper.preDestroy(");
+-                out.print(VAR_ANNOTATIONPROCESSOR);
+-                out.print(", ");
+-                out.print(tagHandlerVar);
+-                out.println(");");
++                writeDestroyInstance(tagHandlerVar);
+             }
+ 
+             if (n.implementsTryCatchFinally()) {
+@@ -2391,21 +2441,8 @@
+ 
+             String tagHandlerClassName = JspUtil
+                     .getCanonicalName(tagHandlerClass);
+-            out.printin(tagHandlerClassName);
+-            out.print(" ");
+-            out.print(tagHandlerVar);
+-            out.print(" = ");
+-            out.print("new ");
+-            out.print(tagHandlerClassName);
+-            out.println("();");
++            writeNewInstance(tagHandlerVar, tagHandlerClassName);
+ 
+-            // Resource injection
+-            out.printin("org.apache.jasper.runtime.AnnotationHelper.postConstruct(");
+-            out.print(VAR_ANNOTATIONPROCESSOR);
+-            out.print(", ");
+-            out.print(tagHandlerVar);
+-            out.println(");");
+-            
+             generateSetters(n, tagHandlerVar, handlerInfo, true);
+ 
+             // JspIdConsumer (after context has been set)
+@@ -2458,11 +2495,7 @@
+             syncScriptingVars(n, VariableInfo.AT_END);
+ 
+             // Resource injection
+-            out.printin("org.apache.jasper.runtime.AnnotationHelper.preDestroy(");
+-            out.print(VAR_ANNOTATIONPROCESSOR);
+-            out.print(", ");
+-            out.print(tagHandlerVar);
+-            out.println(");");
++            writeDestroyInstance(tagHandlerVar);
+ 
+             n.setEndJavaLine(out.getJavaLine());
+         }
+Index: java/org/apache/catalina/core/ApplicationFilterConfig.java
+===================================================================
+--- java/org/apache/catalina/core/ApplicationFilterConfig.java	(revision 521878)
++++ java/org/apache/catalina/core/ApplicationFilterConfig.java	(working copy)
+@@ -34,10 +34,10 @@
+ import javax.servlet.ServletContext;
+ import javax.servlet.ServletException;
+ 
+-import org.apache.AnnotationProcessor;
+ import org.apache.catalina.Context;
+ import org.apache.catalina.Globals;
+ import org.apache.catalina.deploy.FilterDef;
++import org.apache.catalina.lifecycle.LifecycleProvider;
+ import org.apache.catalina.security.SecurityUtil;
+ import org.apache.catalina.util.Enumerator;
+ import org.apache.catalina.util.StringManager;
+@@ -58,7 +58,7 @@
+ 
+     protected static StringManager sm =
+         StringManager.getManager(Constants.Package);
+-    
++
+     // ----------------------------------------------------------- Constructors
+ 
+ 
+@@ -78,8 +78,8 @@
+      * @exception InstantiationException if an exception occurs while
+      *  instantiating the filter object
+      * @exception ServletException if thrown by the filter's init() method
+-     * @throws NamingException 
+-     * @throws InvocationTargetException 
++     * @throws NamingException
++     * @throws InvocationTargetException
+      */
+     public ApplicationFilterConfig(Context context, FilterDef filterDef)
+         throws ClassCastException, ClassNotFoundException,
+@@ -91,7 +91,7 @@
+         if (restrictedFilters == null) {
+             restrictedFilters = new Properties();
+             try {
+-                InputStream is = 
++                InputStream is =
+                     this.getClass().getClassLoader().getResourceAsStream
+                         ("org/apache/catalina/core/RestrictedFilters.properties");
+                 if (is != null) {
+@@ -103,7 +103,7 @@
+                 context.getLogger().error(sm.getString("applicationFilterConfig.restrictedServletsResources"), e);
+             }
+         }
+-        
++
+         this.context = context;
+         setFilterDef(filterDef);
+ 
+@@ -136,7 +136,7 @@
+      */
+     protected static Properties restrictedFilters = null;
+ 
+-    
++
+     // --------------------------------------------------- FilterConfig Methods
+ 
+ 
+@@ -223,11 +223,11 @@
+      * @exception InstantiationException if an exception occurs while
+      *  instantiating the filter object
+      * @exception ServletException if thrown by the filter's init() method
+-     * @throws NamingException 
+-     * @throws InvocationTargetException 
++     * @throws NamingException
++     * @throws InvocationTargetException
+      */
+     Filter getFilter() throws ClassCastException, ClassNotFoundException,
+-        IllegalAccessException, InstantiationException, ServletException, 
++        IllegalAccessException, InstantiationException, ServletException,
+         InvocationTargetException, NamingException {
+ 
+         // Return the existing filter instance, if any
+@@ -236,32 +236,32 @@
+ 
+         // Identify the class loader we will be using
+         String filterClass = filterDef.getFilterClass();
+-        ClassLoader classLoader = null;
+-        if (filterClass.startsWith("org.apache.catalina."))
+-            classLoader = this.getClass().getClassLoader();
+-        else
+-            classLoader = context.getLoader().getClassLoader();
++        if (context instanceof StandardContext) {
++            LifecycleProvider lifecycleProvider = ((StandardContext) context).getLifecycleProvider();
++            this.filter = (Filter) lifecycleProvider.newInstance(filterClass);
++        } else {
+ 
+-        ClassLoader oldCtxClassLoader =
+-            Thread.currentThread().getContextClassLoader();
++            ClassLoader classLoader;
++            if (filterClass.startsWith("org.apache.catalina."))
++                classLoader = this.getClass().getClassLoader();
++            else
++                classLoader = context.getLoader().getClassLoader();
+ 
+-        // Instantiate a new instance of this filter and return it
+-        Class clazz = classLoader.loadClass(filterClass);
+-        if (!isFilterAllowed(clazz)) {
+-            throw new SecurityException
+-                (sm.getString("applicationFilterConfig.privilegedFilter",
+-                        filterClass));
+-        }
+-        this.filter = (Filter) clazz.newInstance();
+-        if (!context.getIgnoreAnnotations()) {
+-            if (context instanceof StandardContext) {
+-               AnnotationProcessor processor = ((StandardContext)context).getAnnotationProcessor();
+-               processor.processAnnotations(this.filter);
+-               processor.postConstruct(this.filter);
++            //tODO oldCtxClassLoader is not used.... is the intention to set the TCCL during construction and restore it?
++            ClassLoader oldCtxClassLoader =
++                    Thread.currentThread().getContextClassLoader();
++
++            // Instantiate a new instance of this filter and return it
++            Class clazz = classLoader.loadClass(filterClass);
++            if (!isFilterAllowed(clazz)) {
++                throw new SecurityException
++                        (sm.getString("applicationFilterConfig.privilegedFilter",
++                                filterClass));
+             }
++            this.filter = (Filter) clazz.newInstance();
+         }
+         if (context instanceof StandardContext &&
+-            ((StandardContext) context).getSwallowOutput()) {
++                context.getSwallowOutput()) {
+             try {
+                 SystemLogHandler.startCapture();
+                 filter.init(this);
+@@ -307,7 +307,7 @@
+             }
+             clazz = clazz.getSuperclass();
+         }
+-        
++
+         return (true);
+ 
+     }
+@@ -323,17 +323,17 @@
+         {
+             if (Globals.IS_SECURITY_ENABLED) {
+                 try {
+-                    SecurityUtil.doAsPrivilege("destroy", filter); 
+-                } catch(java.lang.Exception ex){                    
++                    SecurityUtil.doAsPrivilege("destroy", filter);
++                } catch(java.lang.Exception ex){
+                     context.getLogger().error("ApplicationFilterConfig.doAsPrivilege", ex);
+                 }
+                 SecurityUtil.remove(filter);
+-            } else { 
++            } else {
+                 filter.destroy();
+             }
+             if (!context.getIgnoreAnnotations()) {
+                 try {
+-                    ((StandardContext)context).getAnnotationProcessor().preDestroy(this.filter);
++                    ((StandardContext) context).getLifecycleProvider().destroyInstance(this.filter);
+                 } catch (Exception e) {
+                     context.getLogger().error("ApplicationFilterConfig.preDestroy", e);
+                 }
+@@ -358,8 +358,8 @@
+      * @exception InstantiationException if an exception occurs while
+      *  instantiating the filter object
+      * @exception ServletException if thrown by the filter's init() method
+-     * @throws NamingException 
+-     * @throws InvocationTargetException 
++     * @throws NamingException
++     * @throws InvocationTargetException
+      */
+     void setFilterDef(FilterDef filterDef)
+         throws ClassCastException, ClassNotFoundException,
+@@ -373,17 +373,17 @@
+             if (this.filter != null){
+                 if( Globals.IS_SECURITY_ENABLED) {
+                     try{
+-                        SecurityUtil.doAsPrivilege("destroy", filter);  
+-                    } catch(java.lang.Exception ex){    
++                        SecurityUtil.doAsPrivilege("destroy", filter);
++                    } catch(java.lang.Exception ex){
+                         context.getLogger().error("ApplicationFilterConfig.doAsPrivilege", ex);
+                     }
+                     SecurityUtil.remove(filter);
+-                } else { 
++                } else {
+                     filter.destroy();
+                 }
+                 if (!context.getIgnoreAnnotations()) {
+                     try {
+-                        ((StandardContext)context).getAnnotationProcessor().preDestroy(this.filter);
++                        ((StandardContext) context).getLifecycleProvider().destroyInstance(this.filter);
+                     } catch (Exception e) {
+                         context.getLogger().error("ApplicationFilterConfig.preDestroy", e);
+                     }
+Index: java/org/apache/catalina/core/StandardWrapper.java
+===================================================================
+--- java/org/apache/catalina/core/StandardWrapper.java	(revision 521878)
++++ java/org/apache/catalina/core/StandardWrapper.java	(working copy)
+@@ -19,6 +19,7 @@
+ package org.apache.catalina.core;
+ 
+ import java.lang.reflect.Method;
++import java.lang.reflect.InvocationTargetException;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.PrintStream;
+@@ -47,6 +48,7 @@
+ import javax.management.NotificationFilter;
+ import javax.management.NotificationListener;
+ import javax.management.ObjectName;
++import javax.naming.NamingException;
+ 
+ import org.apache.PeriodicEventListener;
+ import org.apache.catalina.Container;
+@@ -58,6 +60,7 @@
+ import org.apache.catalina.LifecycleException;
+ import org.apache.catalina.Loader;
+ import org.apache.catalina.Wrapper;
++import org.apache.catalina.lifecycle.LifecycleProvider;
+ import org.apache.catalina.security.SecurityUtil;
+ import org.apache.catalina.util.Enumerator;
+ import org.apache.catalina.util.InstanceSupport;
+@@ -1032,83 +1035,9 @@
+                     (sm.getString("standardWrapper.notClass", getName()));
+             }
+ 
+-            // Acquire an instance of the class loader to be used
+-            Loader loader = getLoader();
+-            if (loader == null) {
+-                unavailable(null);
+-                throw new ServletException
+-                    (sm.getString("standardWrapper.missingLoader", getName()));
+-            }
+-
+-            ClassLoader classLoader = loader.getClassLoader();
+-
+-            // Special case class loader for a container provided servlet
+-            //  
+-            if (isContainerProvidedServlet(actualClass) && 
+-                    ! ((Context)getParent()).getPrivileged() ) {
+-                // If it is a priviledged context - using its own
+-                // class loader will work, since it's a child of the container
+-                // loader
+-                classLoader = this.getClass().getClassLoader();
+-            }
+-
+-            // Load the specified servlet class from the appropriate class loader
+-            Class classClass = null;
++            LifecycleProvider lifecycleProvider = ((StandardContext)getParent()).getLifecycleProvider();
+             try {
+-                if (SecurityUtil.isPackageProtectionEnabled()){
+-                    final ClassLoader fclassLoader = classLoader;
+-                    final String factualClass = actualClass;
+-                    try{
+-                        classClass = (Class)AccessController.doPrivileged(
+-                                new PrivilegedExceptionAction(){
+-                                    public Object run() throws Exception{
+-                                        if (fclassLoader != null) {
+-                                            return fclassLoader.loadClass(factualClass);
+-                                        } else {
+-                                            return Class.forName(factualClass);
+-                                        }
+-                                    }
+-                        });
+-                    } catch(PrivilegedActionException pax){
+-                        Exception ex = pax.getException();
+-                        if (ex instanceof ClassNotFoundException){
+-                            throw (ClassNotFoundException)ex;
+-                        } else {
+-                            getServletContext().log( "Error loading "
+-                                + fclassLoader + " " + factualClass, ex );
+-                        }
+-                    }
+-                } else {
+-                    if (classLoader != null) {
+-                        classClass = classLoader.loadClass(actualClass);
+-                    } else {
+-                        classClass = Class.forName(actualClass);
+-                    }
+-                }
+-            } catch (ClassNotFoundException e) {
+-                unavailable(null);
+-                getServletContext().log( "Error loading " + classLoader + " " + actualClass, e );
+-                throw new ServletException
+-                    (sm.getString("standardWrapper.missingClass", actualClass),
+-                     e);
+-            }
+-
+-            if (classClass == null) {
+-                unavailable(null);
+-                throw new ServletException
+-                    (sm.getString("standardWrapper.missingClass", actualClass));
+-            }
+-
+-            // Instantiate and initialize an instance of the servlet class itself
+-            try {
+-                servlet = (Servlet) classClass.newInstance();
+-                // Annotation processing
+-                if (!((Context) getParent()).getIgnoreAnnotations()) {
+-                    if (getParent() instanceof StandardContext) {
+-                       ((StandardContext)getParent()).getAnnotationProcessor().processAnnotations(servlet);
+-                       ((StandardContext)getParent()).getAnnotationProcessor().postConstruct(servlet);
+-                    }
+-                }
++                servlet = (Servlet) lifecycleProvider.newInstance(actualClass);
+             } catch (ClassCastException e) {
+                 unavailable(null);
+                 // Restore the context ClassLoader
+@@ -1116,7 +1045,7 @@
+                     (sm.getString("standardWrapper.notServlet", actualClass), e);
+             } catch (Throwable e) {
+                 unavailable(null);
+-              
++
+                 // Added extra log statement for Bugzilla 36630:
+                 // http://issues.apache.org/bugzilla/show_bug.cgi?id=36630
+                 if(log.isDebugEnabled()) {
+@@ -1387,7 +1316,7 @@
+ 
+             // Annotation processing
+             if (!((Context) getParent()).getIgnoreAnnotations()) {
+-               ((StandardContext)getParent()).getAnnotationProcessor().preDestroy(instance);
++               ((StandardContext)getParent()).getLifecycleProvider().destroyInstance(instance);
+             }
+ 
+         } catch (Throwable t) {
+@@ -1430,7 +1359,7 @@
+                     }
+                     // Annotation processing
+                     if (!((Context) getParent()).getIgnoreAnnotations()) {
+-                       ((StandardContext)getParent()).getAnnotationProcessor().preDestroy(s);
++                       ((StandardContext)getParent()).getLifecycleProvider().destroyInstance(s);
+                     }
+                 }
+             } catch (Throwable t) {
+Index: java/org/apache/catalina/core/StandardContext.java
+===================================================================
+--- java/org/apache/catalina/core/StandardContext.java	(revision 521878)
++++ java/org/apache/catalina/core/StandardContext.java	(working copy)
+@@ -73,6 +73,8 @@
+ import org.apache.catalina.Loader;
+ import org.apache.catalina.Manager;
+ import org.apache.catalina.Wrapper;
++import org.apache.catalina.lifecycle.LifecycleProvider;
++import org.apache.catalina.lifecycle.LifecycleProviderToAnnotationProcessorAdapter;
+ import org.apache.catalina.deploy.ApplicationParameter;
+ import org.apache.catalina.deploy.ErrorPage;
+ import org.apache.catalina.deploy.FilterDef;
+@@ -174,9 +176,9 @@
+ 
+ 
+     /**
+-     * Annotation processor.
++     * Lifecycle provider.
+      */
+-    private AnnotationProcessor annotationProcessor = null;
++    private LifecycleProvider lifecycleProvider = null;
+ 
+ 
+    /**
+@@ -679,13 +681,21 @@
+     // ----------------------------------------------------- Context Properties
+ 
+ 
+-    public AnnotationProcessor getAnnotationProcessor() {
+-       return annotationProcessor;
++    public LifecycleProvider getLifecycleProvider() {
++       return lifecycleProvider;
+     }
+ 
+ 
++    public void setLifecycleProvider(LifecycleProvider lifecycleProvider) {
++       this.lifecycleProvider = lifecycleProvider;
++    }
++
+     public void setAnnotationProcessor(AnnotationProcessor annotationProcessor) {
+-       this.annotationProcessor = annotationProcessor;
++        //TODO verify these will be available when this is called.
++        ClassLoader applicationClassLoader = getLoader().getClassLoader();
++        ClassLoader containerClassLoader = this.getClass().getClassLoader();
++        boolean privileged = getPrivileged();
++        this.lifecycleProvider = new LifecycleProviderToAnnotationProcessorAdapter(annotationProcessor, applicationClassLoader, containerClassLoader, privileged);
+     }
+ 
+     
+@@ -3767,13 +3777,7 @@
+                 getLogger().debug(" Configuring event listener class '" +
+                     listeners[i] + "'");
+             try {
+-                Class clazz = loader.loadClass(listeners[i]);
+-                results[i] = clazz.newInstance();
+-                // Annotation processing
+-                if (!getIgnoreAnnotations()) {
+-                    getAnnotationProcessor().processAnnotations(results[i]);
+-                    getAnnotationProcessor().postConstruct(results[i]);
+-                }
++                results[i] = lifecycleProvider.newInstance(listeners[i]);
+             } catch (Throwable t) {
+                 getLogger().error
+                     (sm.getString("standardContext.applicationListener",
+@@ -3876,7 +3880,7 @@
+                 // Annotation processing
+                 if (!getIgnoreAnnotations()) {
+                     try {
+-                        getAnnotationProcessor().preDestroy(listeners[j]);
++                        getLifecycleProvider().destroyInstance(listeners[j]);
+                     } catch (Throwable t) {
+                         getLogger().error
+                             (sm.getString("standardContext.listenerStop",
+@@ -3895,7 +3899,7 @@
+                 if (listeners[j] == null)
+                     continue;
+                 try {
+-                    getAnnotationProcessor().preDestroy(listeners[j]);
++                    getLifecycleProvider().destroyInstance(listeners[j]);
+                 } catch (Throwable t) {
+                     getLogger().error
+                         (sm.getString("standardContext.listenerStop",
+@@ -4304,17 +4308,21 @@
+         // this can be configured in many places and not just in /WEB-INF/web.xml,
+         // there are not many solutions)
+         // Initialize annotation processor
+-        if (ok && !getIgnoreAnnotations()) {
+-            if (annotationProcessor == null) {
++        if (ok ) {
++            //TODO if && !getIgnoreAnnotations() then install a do-nothing annotation processor
++            if (lifecycleProvider == null) {
++                javax.naming.Context context = null;
+                 if (isUseNaming() && namingContextListener != null) {
+-                    annotationProcessor = 
+-                        new DefaultAnnotationProcessor(namingContextListener.getEnvContext());
+-                } else {
+-                    annotationProcessor = new DefaultAnnotationProcessor(null);
++                    context = namingContextListener.getEnvContext();
+                 }
++                AnnotationProcessor annotationProcessor = new DefaultAnnotationProcessor(context);
++                lifecycleProvider = new LifecycleProviderToAnnotationProcessorAdapter(annotationProcessor,
++                        getLoader().getClassLoader(),
++                        this.getClass().getClassLoader(),
++                        getPrivileged() );
+             }
+             getServletContext().setAttribute
+-                (AnnotationProcessor.class.getName(), annotationProcessor);
++                (LifecycleProvider.class.getName(), lifecycleProvider);
+         }
+ 
+         try {
+Index: java/org/apache/catalina/core/mbeans-descriptors.xml
+===================================================================
+--- java/org/apache/catalina/core/mbeans-descriptors.xml	(revision 521878)
++++ java/org/apache/catalina/core/mbeans-descriptors.xml	(working copy)
+@@ -25,8 +25,12 @@
+                is="true"
+                type="boolean"/>
+       
++     <attribute name="lifecycleProvider"
++                description="Object that creates and destroys servlets, filters, and listeners. Include dependency injection and postConstruct/preDestory handling"
++                type="org.apache.catalina.lifecycle.LifecycleProvider" />
++
+      <attribute name="annotationProcessor"
+-                description="Object that processes things like injection annotations"
++                description="Deprecated Object that processes things like injection annotations.  Use a LifecycleProvider instead"
+                 type="org.apache.AnnotationProcessor" />
+ 
+     <attribute name="antiJARLocking"
+Index: java/org/apache/catalina/lifecycle/LifecycleProviderToAnnotationProcessorAdapter.java
+===================================================================
+--- java/org/apache/catalina/lifecycle/LifecycleProviderToAnnotationProcessorAdapter.java	(revision 0)
++++ java/org/apache/catalina/lifecycle/LifecycleProviderToAnnotationProcessorAdapter.java	(revision 0)
+@@ -0,0 +1,132 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements.  See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership.  The ASF licenses this file
++ * to you 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.catalina.lifecycle;
++
++import java.util.Properties;
++import java.security.AccessController;
++import java.security.PrivilegedExceptionAction;
++import java.security.PrivilegedActionException;
++import java.lang.reflect.InvocationTargetException;
++
++import javax.servlet.Filter;
++import javax.servlet.Servlet;
++import javax.naming.NamingException;
++
++import org.apache.AnnotationProcessor;
++import org.apache.catalina.ContainerServlet;
++import org.apache.catalina.security.SecurityUtil;
++
++/**
++ * @version $Rev:$ $Date:$
++ */
++public class LifecycleProviderToAnnotationProcessorAdapter implements LifecycleProvider {
++
++    private final AnnotationProcessor annotationProcessor;
++    private final ClassLoader classLoader;
++    private final ClassLoader containerClassLoader;
++
++    private boolean privileged = false;
++    private Properties restrictedFilters = new Properties();
++    private Properties restrictedListeners = new Properties();
++    private Properties restrictedServlets = new Properties();
++
++
++    public LifecycleProviderToAnnotationProcessorAdapter(AnnotationProcessor annotationProcessor, ClassLoader classLoader, ClassLoader containerClassLoader, boolean privileged) {
++        this.annotationProcessor = annotationProcessor;
++        this.classLoader = classLoader;
++        this.containerClassLoader = containerClassLoader;
++        this.privileged = privileged;
++    }
++
++    public Object newInstance(String className) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException {
++        return newInstance(className, classLoader);
++    }
++
++    public Object newInstance(final String className, final ClassLoader classLoader) throws IllegalAccessException, NamingException, InvocationTargetException, InstantiationException, ClassNotFoundException {
++        Class clazz;
++        if (SecurityUtil.isPackageProtectionEnabled()){
++            try {
++                clazz = AccessController.doPrivileged(new PrivilegedExceptionAction<Class>() {
++
++                    public Class run() throws Exception {
++                        return loadClass(className, classLoader);
++                    }
++                });
++            } catch (PrivilegedActionException e) {
++                Throwable t =  e.getCause();
++                if (t instanceof ClassNotFoundException) {
++                    throw (ClassNotFoundException)t;
++                }
++                throw new RuntimeException(t);
++            }
++        } else {
++            clazz = loadClass(className, classLoader);
++        }
++        checkAccess(clazz);
++        Object instance = clazz.newInstance();
++        annotationProcessor.processAnnotations(instance);
++        annotationProcessor.postConstruct(instance);
++        return instance;
++    }
++
++    public void destroyInstance(Object instance) throws IllegalAccessException, InvocationTargetException {
++        annotationProcessor.preDestroy(instance);
++    }
++
++    protected Class loadClass(String className, ClassLoader classLoader) throws ClassNotFoundException {
++        if (className.startsWith("org.apache.catalina")) {
++            return containerClassLoader.loadClass(className);
++        }
++        try {
++            Class clazz = containerClassLoader.loadClass(className);
++            if (ContainerServlet.class.isAssignableFrom(clazz)) {
++                return clazz;
++            }
++        } catch (Throwable t) {
++            //ignore
++        }
++        return classLoader.loadClass(className);
++    }
++
++    private void checkAccess(Class clazz) {
++        if (privileged) return;
++        if (clazz.isAssignableFrom(Filter.class)) {
++            checkAccess(clazz, restrictedFilters);
++        } else if (clazz.isAssignableFrom(Servlet.class)) {
++            checkAccess(clazz, restrictedServlets);
++        } else {
++            checkAccess(clazz, restrictedListeners);
++        }
++     }
++
++    private void checkAccess(Class clazz, Properties restricted) {
++        while (clazz != null) {
++            if ("restricted".equals(restricted.getProperty(clazz.getName()))) {
++                throw new SecurityException("Restricted class" + clazz);
++            }
++            clazz = clazz.getSuperclass();
++        }
++
++    }
++
++
++
++}
+
+Property changes on: java/org/apache/catalina/lifecycle/LifecycleProviderToAnnotationProcessorAdapter.java
+___________________________________________________________________
+Name: svn:mime-type
+   + text/plain
+Name: svn:keywords
+   + Date Revision
+Name: svn:eol-style
+   + native
+
+Index: java/org/apache/catalina/lifecycle/LifecycleProvider.java
+===================================================================
+--- java/org/apache/catalina/lifecycle/LifecycleProvider.java	(revision 0)
++++ java/org/apache/catalina/lifecycle/LifecycleProvider.java	(revision 0)
+@@ -0,0 +1,37 @@
++/*
++ * Licensed to the Apache Software Foundation (ASF) under one
++ * or more contributor license agreements.  See the NOTICE file
++ * distributed with this work for additional information
++ * regarding copyright ownership.  The ASF licenses this file
++ * to you 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.catalina.lifecycle;
++
++import java.lang.reflect.InvocationTargetException;
++
++import javax.naming.NamingException;
++
++/**
++ * @version $Rev:$ $Date:$
++ */
++public interface LifecycleProvider {
++
++    Object newInstance(String className) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException;
++
++    Object newInstance(String fqcn, ClassLoader classLoader) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException;
++
++    void destroyInstance(Object o) throws IllegalAccessException, InvocationTargetException;
++}
+
+Property changes on: java/org/apache/catalina/lifecycle/LifecycleProvider.java
+___________________________________________________________________
+Name: svn:mime-type
+   + text/plain
+Name: svn:keywords
+   + Date Revision
+Name: svn:eol-style
+   + native
+
+Index: build.xml
+===================================================================
+--- build.xml	(revision 521878)
++++ build.xml	(working copy)
+@@ -263,6 +263,7 @@
+     <jar  jarfile="${jasper.jar}">
+       <fileset dir="${tomcat.classes}">
+         <include name="org/apache/*" />
++        <include name="org/apache/catalina/lifecycle/LifecycleProvider.class" />
+         <include name="org/apache/jasper/**" />
+         <!-- Javadoc and i18n exclusions -->
+         <exclude name="**/package.html" />



Mime
View raw message