You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dw...@apache.org on 2008/08/15 06:33:18 UTC

svn commit: r686143 [2/3] - in /geronimo/server/trunk: ./ plugins/monitoring/mconsole-war/src/main/webapp/WEB-INF/view/ repository/ repository/org/apache/tomcat/ repository/org/apache/tomcat/catalina/6.0.16-G652117/ repository/org/apache/tomcat/catalin...

Added: geronimo/server/trunk/repository/org/apache/tomcat/TOMCAT_6_0_18-G678601.patch
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/repository/org/apache/tomcat/TOMCAT_6_0_18-G678601.patch?rev=686143&view=auto
==============================================================================
--- geronimo/server/trunk/repository/org/apache/tomcat/TOMCAT_6_0_18-G678601.patch (added)
+++ geronimo/server/trunk/repository/org/apache/tomcat/TOMCAT_6_0_18-G678601.patch Thu Aug 14 21:33:17 2008
@@ -0,0 +1,2834 @@
+Index: java/org/apache/InstanceManager.java
+===================================================================
+--- java/org/apache/InstanceManager.java	(revision 0)
++++ java/org/apache/InstanceManager.java	(revision 0)
+@@ -0,0 +1,45 @@
++/*
++ * 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;
++
++import java.lang.reflect.InvocationTargetException;
++
++import javax.naming.NamingException;
++
++/**
++ * @version $Rev:$ $Date:$
++ */
++public interface InstanceManager {
++
++    public Object newInstance(String className)
++    	throws IllegalAccessException, InvocationTargetException, NamingException, 
++    		InstantiationException, ClassNotFoundException;
++
++    public Object newInstance(String fqcn, ClassLoader classLoader) 
++    	throws IllegalAccessException, InvocationTargetException, NamingException, 
++    		InstantiationException, ClassNotFoundException;
++
++    public void newInstance(Object o) 
++		throws IllegalAccessException, InvocationTargetException, NamingException;
++
++    public void destroyInstance(Object o)
++    	throws IllegalAccessException, InvocationTargetException;
++}
+
+Property changes on: java/org/apache/InstanceManager.java
+___________________________________________________________________
+Name: svn:eol-style
+   + native
+
+Index: java/org/apache/jasper/JspCompilationContext.java
+===================================================================
+--- java/org/apache/jasper/JspCompilationContext.java	(revision 3168)
++++ java/org/apache/jasper/JspCompilationContext.java	(working copy)
+@@ -609,12 +609,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"),
+@@ -627,6 +622,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 3168)
++++ 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.InstanceManager;
+ 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 InstanceManager instanceManager = null;
+ 
+     public static TagHandlerPool getTagHandlerPool( ServletConfig config) {
+         TagHandlerPool result=null;
+@@ -78,8 +78,7 @@
+         }
+         this.handlers = new Tag[maxSize];
+         this.current = -1;
+-        this.annotationProcessor = 
+-            (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
++        instanceManager = InstanceManagerFactory.getInstanceManager(config);
+     }
+ 
+     /**
+@@ -112,7 +111,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 +122,13 @@
+         // 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 (Constants.USE_INSTANCE_MANAGER_FOR_TAGS) {
++        		return (Tag) instanceManager.newInstance(handlerClass.getName(), handlerClass.getClassLoader());
++        	} else {
++                Tag instance = (Tag) handlerClass.newInstance();
++                instanceManager.newInstance(instance);
++                return instance;
++        	}
+         } catch (Exception e) {
+             throw new JspException(e.getMessage(), e);
+         }
+@@ -147,13 +150,11 @@
+         }
+         // There is no need for other threads to wait for us to release
+         handler.release();
+-        if (annotationProcessor != null) {
+-            try {
+-                AnnotationHelper.preDestroy(annotationProcessor, handler);
+-            } catch (Exception e) {
+-                log.warn("Error processing preDestroy on tag instance of " 
+-                        + handler.getClass().getName(), e);
+-            }
++        try {
++            instanceManager.destroyInstance(handler);
++        } catch (Exception e) {
++            log.warn("Error processing preDestroy on tag instance of "
++                    + handler.getClass().getName(), e);
+         }
+     }
+ 
+@@ -164,13 +165,11 @@
+     public synchronized void release() {
+         for (int i = current; i >= 0; i--) {
+             handlers[i].release();
+-            if (annotationProcessor != null) {
+-                try {
+-                    AnnotationHelper.preDestroy(annotationProcessor, handlers[i]);
+-                } catch (Exception e) {
+-                    log.warn("Error processing preDestroy on tag instance of " 
+-                            + handlers[i].getClass().getName(), e);
+-                }
++            try {
++                instanceManager.destroyInstance(handlers[i]);
++            } catch (Exception e) {
++                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 3168)
++++ 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: 467222 $, $Date: 2006-10-23 23:17:11 -0400 (Mon, 23 Oct 2006) $
+- */
+-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/runtime/InstanceManagerFactory.java
+===================================================================
+--- java/org/apache/jasper/runtime/InstanceManagerFactory.java	(revision 0)
++++ java/org/apache/jasper/runtime/InstanceManagerFactory.java	(revision 0)
+@@ -0,0 +1,44 @@
++/*
++ * 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 javax.servlet.ServletConfig;
++
++import org.apache.InstanceManager;
++
++/**
++ * @version $Rev:$ $Date:$
++ */
++public class InstanceManagerFactory {
++
++    private InstanceManagerFactory() {
++    }
++
++    public static InstanceManager getInstanceManager(ServletConfig config) {
++        InstanceManager instanceManager = 
++        	(InstanceManager) config.getServletContext().getAttribute(InstanceManager.class.getName());
++        if (instanceManager == null) {
++            throw new IllegalStateException("No org.apache.InstanceManager set in ServletContext");
++        }
++        return instanceManager;
++    }
++
++}
+
+Property changes on: java/org/apache/jasper/runtime/InstanceManagerFactory.java
+___________________________________________________________________
+Name: svn:eol-style
+   + native
+
+Index: java/org/apache/jasper/servlet/JspServletWrapper.java
+===================================================================
+--- java/org/apache/jasper/servlet/JspServletWrapper.java	(revision 3168)
++++ 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.InstanceManager;
+ import org.apache.jasper.JasperException;
+ import org.apache.jasper.JspCompilationContext;
+ import org.apache.jasper.Options;
+@@ -39,6 +39,7 @@
+ import org.apache.jasper.compiler.JavacErrorDetail;
+ import org.apache.jasper.compiler.JspRuntimeContext;
+ import org.apache.jasper.compiler.Localizer;
++import org.apache.jasper.runtime.InstanceManagerFactory;
+ import org.apache.jasper.runtime.JspSourceDependent;
+ import org.apache.juli.logging.Log;
+ import org.apache.juli.logging.LogFactory;
+@@ -68,7 +69,6 @@
+ 
+     private Servlet theServlet;
+     private String jspUri;
+-    private Class servletClass;
+     private Class tagHandlerClass;
+     private JspCompilationContext ctxt;
+     private long available = 0L;
+@@ -139,15 +139,10 @@
+                     destroy();
+                     
+                     Servlet servlet = null;
+-                    
++
+                     try {
+-                        servletClass = ctxt.load();
+-                        servlet = (Servlet) servletClass.newInstance();
+-                        AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
+-                        if (annotationProcessor != null) {
+-                           annotationProcessor.processAnnotations(servlet);
+-                           annotationProcessor.postConstruct(servlet);
+-                        }
++                        InstanceManager instanceManager = InstanceManagerFactory.getInstanceManager(config);
++                        servlet = (Servlet) instanceManager.newInstance(ctxt.getFQCN(), ctxt.getJspLoader());
+                     } catch (IllegalAccessException e) {
+                         throw new JasperException(e);
+                     } catch (InstantiationException e) {
+@@ -423,15 +418,13 @@
+     public void destroy() {
+         if (theServlet != null) {
+             theServlet.destroy();
+-            AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
+-            if (annotationProcessor != null) {
+-                try {
+-                    annotationProcessor.preDestroy(theServlet);
+-                } catch (Exception e) {
+-                    // Log any exception, since it can't be passed along
+-                    log.error(Localizer.getMessage("jsp.error.file.not.found",
+-                           e.getMessage()), e);
+-                }
++            InstanceManager instanceManager = InstanceManagerFactory.getInstanceManager(config);
++            try {
++                instanceManager.destroyInstance(theServlet);
++            } catch (Exception e) {
++                // Log any exception, since it can't be passed along
++                log.error(Localizer.getMessage("jsp.error.file.not.found",
++                        e.getMessage()), e);
+             }
+         }
+     }
+Index: java/org/apache/jasper/Constants.java
+===================================================================
+--- java/org/apache/jasper/Constants.java	(revision 3168)
++++ java/org/apache/jasper/Constants.java	(working copy)
+@@ -199,4 +199,7 @@
+      */
+     public static final String SESSION_PARAMETER_NAME = "jsessionid";
+ 
++    public static final boolean USE_INSTANCE_MANAGER_FOR_TAGS =
++        Boolean.valueOf(System.getProperty("org.apache.jasper.Constants.USE_INSTANCE_MANAGER_FOR_TAGS", "false")).booleanValue();
++
+ }
+Index: java/org/apache/jasper/compiler/Generator.java
+===================================================================
+--- java/org/apache/jasper/compiler/Generator.java	(revision 3168)
++++ 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_INSTANCEMANAGER =
++        System.getProperty("org.apache.jasper.compiler.Generator.VAR_INSTANCEMANAGER", "_jsp_instancemanager");
+ 
+     private ServletWriter out;
+ 
+@@ -413,14 +413,14 @@
+         }
+         out.println(".getServletContext()).getExpressionFactory();");
+ 
+-        out.printin(VAR_ANNOTATIONPROCESSOR);
+-        out.print(" = (org.apache.AnnotationProcessor) ");
++        out.printin(VAR_INSTANCEMANAGER);
++        out.print(" = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(");
+         if (ctxt.isTagFile()) {
+             out.print("config");
+         } else {
+             out.print("getServletConfig()");
+         }
+-        out.println(".getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());");
++        out.println(");");
+ 
+         out.popIndent();
+         out.printil("}");
+@@ -524,8 +524,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.InstanceManager ");
++        out.print(VAR_INSTANCEMANAGER);
+         out.println(";");
+         out.println();
+     }
+@@ -2135,11 +2135,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(") ");
+@@ -2148,14 +2148,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
+@@ -2213,8 +2206,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();");
+ 
+@@ -2240,6 +2232,40 @@
+             n.setEndJavaLine(out.getJavaLine());
+         }
+ 
++        private void writeNewInstance(String tagHandlerVar, String tagHandlerClassName) {
++        	if (Constants.USE_INSTANCE_MANAGER_FOR_TAGS) {
++        		out.printin(tagHandlerClassName);
++        		out.print(" ");
++        		out.print(tagHandlerVar);
++        		out.print(" = (");
++        		out.print(tagHandlerClassName);
++        		out.print(")");
++        		out.print(VAR_INSTANCEMANAGER);
++        		out.print(".newInstance(\"");
++        		out.print(tagHandlerClassName);
++        		out.println("\", this.getClass().getClassLoader());");
++        	} else {
++        		out.printin(tagHandlerClassName);
++        		out.print(" ");
++        		out.print(tagHandlerVar);
++        		out.print(" = (");
++        		out.print("new ");
++        		out.print(tagHandlerClassName);
++        		out.println("());");
++        		out.printin(VAR_INSTANCEMANAGER);
++        		out.print(".newInstance(");
++        		out.print(tagHandlerVar);
++        		out.println(");");
++        	}
++        }
++
++        private void writeDestroyInstance(String tagHandlerVar) {
++            out.printin(VAR_INSTANCEMANAGER);
++            out.print(".destroyInstance(");
++            out.print(tagHandlerVar);
++            out.println(");");
++        }
++
+         private void generateCustomEnd(Node.CustomTag n, String tagHandlerVar,
+                 String tagEvalVar, String tagPushBodyCountVar) {
+ 
+@@ -2301,11 +2327,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) {
+@@ -2348,11 +2370,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()) {
+@@ -2384,21 +2402,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)
+@@ -2451,11 +2456,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/AnnotationProcessor.java
+===================================================================
+--- java/org/apache/AnnotationProcessor.java	(revision 3168)
++++ java/org/apache/AnnotationProcessor.java	(working copy)
+@@ -1,37 +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;
+-
+-import java.lang.reflect.InvocationTargetException;
+-
+-import javax.naming.NamingException;
+-
+-/**
+- * Comment
+- *
+- * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
+- * @version $Revision: 467222 $
+- */
+-public interface AnnotationProcessor {
+-    public void postConstruct(Object instance)
+-        throws IllegalAccessException, InvocationTargetException;
+-    public void preDestroy(Object instance)
+-        throws IllegalAccessException, InvocationTargetException;
+-    public void processAnnotations(Object instance)
+-        throws IllegalAccessException, InvocationTargetException, NamingException;
+-}
+Index: java/org/apache/catalina/core/DefaultInstanceManager.java
+===================================================================
+--- java/org/apache/catalina/core/DefaultInstanceManager.java	(revision 0)
++++ java/org/apache/catalina/core/DefaultInstanceManager.java	(revision 0)
+@@ -0,0 +1,437 @@
++/*
++ * 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.core;
++
++
++import java.lang.reflect.Field;
++import java.lang.reflect.InvocationTargetException;
++import java.lang.reflect.Method;
++import java.lang.reflect.Modifier;
++import java.util.Map;
++import java.util.Properties;
++import java.security.AccessController;
++import java.security.PrivilegedExceptionAction;
++import java.security.PrivilegedActionException;
++import java.io.InputStream;
++import java.io.IOException;
++
++import javax.annotation.PostConstruct;
++import javax.annotation.PreDestroy;
++import javax.annotation.Resource;
++import javax.ejb.EJB;
++import javax.naming.Context;
++import javax.naming.NamingException;
++import javax.persistence.PersistenceContext;
++import javax.persistence.PersistenceUnit;
++import javax.xml.ws.WebServiceRef;
++import javax.servlet.Filter;
++import javax.servlet.Servlet;
++
++import org.apache.InstanceManager;
++import org.apache.catalina.security.SecurityUtil;
++import org.apache.catalina.ContainerServlet;
++import org.apache.catalina.core.Constants;
++import org.apache.catalina.util.StringManager;
++
++/**
++ * @version $Rev:$ $Date:$
++ */
++public class DefaultInstanceManager implements InstanceManager {
++
++    private final Context context;
++    private final Map<String, Map<String, String>> injectionMap;
++    protected final ClassLoader classLoader;
++    protected final ClassLoader containerClassLoader;
++    protected boolean privileged;
++    protected boolean ignoreAnnotations;
++    private Properties restrictedFilters = new Properties();
++    private Properties restrictedListeners = new Properties();
++    private Properties restrictedServlets = new Properties();
++
++    public DefaultInstanceManager(Context context, Map<String, Map<String, String>> injectionMap, org.apache.catalina.Context catalinaContext, ClassLoader containerClassLoader) {
++        classLoader = catalinaContext.getLoader().getClassLoader();
++        privileged = catalinaContext.getPrivileged();
++        this.containerClassLoader = containerClassLoader;
++        ignoreAnnotations = catalinaContext.getIgnoreAnnotations();
++        StringManager sm = StringManager.getManager(Constants.Package);
++        try {
++            InputStream is =
++                this.getClass().getClassLoader().getResourceAsStream
++                    ("org/apache/catalina/core/RestrictedServlets.properties");
++            if (is != null) {
++                restrictedServlets.load(is);
++            } else {
++                catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedServletsResource"));
++            }
++        } catch (IOException e) {
++            catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedServletsResource"), e);
++        }
++
++        try {
++            InputStream is =
++                    this.getClass().getClassLoader().getResourceAsStream
++                            ("org/apache/catalina/core/RestrictedListeners.properties");
++            if (is != null) {
++                restrictedListeners.load(is);
++            } else {
++                catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedListenersResources"));
++            }
++        } catch (IOException e) {
++            catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedListenersResources"), e);
++        }
++        try {
++            InputStream is =
++                    this.getClass().getClassLoader().getResourceAsStream
++                            ("org/apache/catalina/core/RestrictedFilters.properties");
++            if (is != null) {
++                restrictedFilters.load(is);
++            } else {
++                catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedFiltersResources"));
++            }
++        } catch (IOException e) {
++            catalinaContext.getLogger().error(sm.getString("defaultInstanceManager.restrictedServletsResources"), e);
++        }
++        this.context = context;
++        this.injectionMap = injectionMap;
++    }
++
++    public Object newInstance(String className) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException {
++        Class clazz = loadClassMaybePrivileged(className, classLoader);
++        return newInstance(clazz.newInstance(), clazz);
++    }
++
++    public Object newInstance(final String className, final ClassLoader classLoader) throws IllegalAccessException, NamingException, InvocationTargetException, InstantiationException, ClassNotFoundException {
++        Class clazz = classLoader.loadClass(className);
++        return newInstance(clazz.newInstance(), clazz);
++    }
++
++    public void newInstance(Object o) 
++		throws IllegalAccessException, InvocationTargetException, NamingException {
++    	newInstance(o, o.getClass());
++    }
++
++    private Object newInstance(Object instance, Class clazz) throws IllegalAccessException, InvocationTargetException, NamingException {
++        if (!ignoreAnnotations) {
++            Map<String, String> injections = injectionMap.get(clazz.getName());
++            processAnnotations(instance, injections);
++            postConstruct(instance, clazz);
++        }
++        return instance;
++    }
++
++    public void destroyInstance(Object instance) throws IllegalAccessException, InvocationTargetException {
++        if (!ignoreAnnotations) {
++            preDestroy(instance, instance.getClass());
++        }
++    }
++
++    /**
++     * Call postConstruct method on the specified instance recursively from deepest superclass to actual class.
++     *
++     * @param instance object to call postconstruct methods on
++     * @param clazz    (super) class to examine for postConstruct annotation.
++     * @throws IllegalAccessException if postConstruct method is inaccessible.
++     * @throws java.lang.reflect.InvocationTargetException
++     *                                if call fails
++     */
++    protected void postConstruct(Object instance, Class clazz)
++            throws IllegalAccessException, InvocationTargetException {
++        Class superClass = clazz.getSuperclass();
++        if (superClass != Object.class) {
++            postConstruct(instance, superClass);
++        }
++
++        Method[] methods = clazz.getDeclaredMethods();
++        Method postConstruct = null;
++        for (Method method : methods) {
++            if (method.isAnnotationPresent(PostConstruct.class)) {
++                if ((postConstruct != null)
++                        || (method.getParameterTypes().length != 0)
++                        || (Modifier.isStatic(method.getModifiers()))
++                        || (method.getExceptionTypes().length > 0)
++                        || (!method.getReturnType().getName().equals("void"))) {
++                    throw new IllegalArgumentException("Invalid PostConstruct annotation");
++                }
++                postConstruct = method;
++            }
++        }
++
++        // At the end the postconstruct annotated
++        // method is invoked
++        if (postConstruct != null) {
++            boolean accessibility = postConstruct.isAccessible();
++            postConstruct.setAccessible(true);
++            postConstruct.invoke(instance);
++            postConstruct.setAccessible(accessibility);
++        }
++
++    }
++
++
++    /**
++     * Call preDestroy method on the specified instance recursively from deepest superclass to actual class.
++     *
++     * @param instance object to call preDestroy methods on
++     * @param clazz    (super) class to examine for preDestroy annotation.
++     * @throws IllegalAccessException if preDestroy method is inaccessible.
++     * @throws java.lang.reflect.InvocationTargetException
++     *                                if call fails
++     */
++    protected void preDestroy(Object instance, Class clazz)
++            throws IllegalAccessException, InvocationTargetException {
++        Class superClass = clazz.getSuperclass();
++        if (superClass != Object.class) {
++            preDestroy(instance, superClass);
++        }
++
++        Method[] methods = clazz.getDeclaredMethods();
++        Method preDestroy = null;
++        for (Method method : methods) {
++            if (method.isAnnotationPresent(PreDestroy.class)) {
++                if ((method.getParameterTypes().length != 0)
++                        || (Modifier.isStatic(method.getModifiers()))
++                        || (method.getExceptionTypes().length > 0)
++                        || (!method.getReturnType().getName().equals("void"))) {
++                    throw new IllegalArgumentException("Invalid PreDestroy annotation");
++                }
++                preDestroy = method;
++                break;
++            }
++        }
++
++        // At the end the postconstruct annotated
++        // method is invoked
++        if (preDestroy != null) {
++            boolean accessibility = preDestroy.isAccessible();
++            preDestroy.setAccessible(true);
++            preDestroy.invoke(instance);
++            preDestroy.setAccessible(accessibility);
++        }
++
++    }
++
++
++    /**
++     * Inject resources in specified instance.
++     *
++     * @param instance   instance to inject into
++     * @param injections map of injections for this class from xml deployment descriptor
++     * @throws IllegalAccessException       if injection target is inaccessible
++     * @throws javax.naming.NamingException if value cannot be looked up in jndi
++     * @throws java.lang.reflect.InvocationTargetException
++     *                                      if injection fails
++     */
++    protected void processAnnotations(Object instance, Map<String, String> injections)
++            throws IllegalAccessException, InvocationTargetException, NamingException {
++
++        if (context == null) {
++            // No resource injection
++            return;
++        }
++
++        // Initialize fields annotations
++        Field[] fields = instance.getClass().getDeclaredFields();
++        for (Field field : fields) {
++            if (injections != null && injections.containsKey(field.getName())) {
++                lookupFieldResource(context, instance, field, injections.get(field.getName()));
++            } else if (field.isAnnotationPresent(Resource.class)) {
++                Resource annotation = field.getAnnotation(Resource.class);
++                lookupFieldResource(context, instance, field, annotation.name());
++            } else if (field.isAnnotationPresent(EJB.class)) {
++                EJB annotation = field.getAnnotation(EJB.class);
++                lookupFieldResource(context, instance, field, annotation.name());
++            } else if (field.isAnnotationPresent(WebServiceRef.class)) {
++                WebServiceRef annotation =
++                        field.getAnnotation(WebServiceRef.class);
++                lookupFieldResource(context, instance, field, annotation.name());
++            } else if (field.isAnnotationPresent(PersistenceContext.class)) {
++                PersistenceContext annotation =
++                        field.getAnnotation(PersistenceContext.class);
++                lookupFieldResource(context, instance, field, annotation.name());
++            } else if (field.isAnnotationPresent(PersistenceUnit.class)) {
++                PersistenceUnit annotation =
++                        field.getAnnotation(PersistenceUnit.class);
++                lookupFieldResource(context, instance, field, annotation.name());
++            }
++        }
++
++        // Initialize methods annotations
++        Method[] methods = instance.getClass().getDeclaredMethods();
++        for (Method method : methods) {
++            String methodName = method.getName();
++            if (injections != null && methodName.startsWith("set") && methodName.length() > 3) {
++                String fieldName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
++                if (injections.containsKey(fieldName)) {
++                    lookupMethodResource(context, instance, method, injections.get(fieldName));
++                    break;
++                }
++            }
++            if (method.isAnnotationPresent(Resource.class)) {
++                Resource annotation = method.getAnnotation(Resource.class);
++                lookupMethodResource(context, instance, method, annotation.name());
++            } else if (method.isAnnotationPresent(EJB.class)) {
++                EJB annotation = method.getAnnotation(EJB.class);
++                lookupMethodResource(context, instance, method, annotation.name());
++            } else if (method.isAnnotationPresent(WebServiceRef.class)) {
++                WebServiceRef annotation =
++                        method.getAnnotation(WebServiceRef.class);
++                lookupMethodResource(context, instance, method, annotation.name());
++            } else if (method.isAnnotationPresent(PersistenceContext.class)) {
++                PersistenceContext annotation =
++                        method.getAnnotation(PersistenceContext.class);
++                lookupMethodResource(context, instance, method, annotation.name());
++            } else if (method.isAnnotationPresent(PersistenceUnit.class)) {
++                PersistenceUnit annotation =
++                        method.getAnnotation(PersistenceUnit.class);
++                lookupMethodResource(context, instance, method, annotation.name());
++            }
++        }
++
++    }
++
++
++    protected Class loadClassMaybePrivileged(final String className, final ClassLoader classLoader) throws 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);
++        return clazz;
++    }
++
++    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();
++        }
++
++    }
++
++    /**
++     * Inject resources in specified field.
++     *
++     * @param context  jndi context to extract value from
++     * @param instance object to inject into
++     * @param field    field target for injection
++     * @param name     jndi name value is bound under
++     * @throws IllegalAccessException       if field is inaccessible
++     * @throws javax.naming.NamingException if value is not accessible in naming context
++     */
++    protected static void lookupFieldResource(Context context,
++            Object instance, Field field, String name)
++            throws NamingException, IllegalAccessException {
++
++        Object lookedupResource;
++        boolean accessibility;
++
++        if ((name != null) &&
++                (name.length() > 0)) {
++            lookedupResource = context.lookup(name);
++        } else {
++            lookedupResource = context.lookup(instance.getClass().getName() + "/" + field.getName());
++        }
++
++        accessibility = field.isAccessible();
++        field.setAccessible(true);
++        field.set(instance, lookedupResource);
++        field.setAccessible(accessibility);
++    }
++
++    /**
++     * Inject resources in specified method.
++     *
++     * @param context  jndi context to extract value from
++     * @param instance object to inject into
++     * @param method   field target for injection
++     * @param name     jndi name value is bound under
++     * @throws IllegalAccessException       if method is inaccessible
++     * @throws javax.naming.NamingException if value is not accessible in naming context
++     * @throws java.lang.reflect.InvocationTargetException
++     *                                      if setter call fails
++     */
++    protected static void lookupMethodResource(Context context,
++            Object instance, Method method, String name)
++            throws NamingException, IllegalAccessException, InvocationTargetException {
++
++        if (!method.getName().startsWith("set")
++                || method.getParameterTypes().length != 1
++                || !method.getReturnType().getName().equals("void")) {
++            throw new IllegalArgumentException("Invalid method resource injection annotation");
++        }
++
++        Object lookedupResource;
++        boolean accessibility;
++
++        if ((name != null) &&
++                (name.length() > 0)) {
++            lookedupResource = context.lookup(name);
++        } else {
++            lookedupResource =
++                    context.lookup(instance.getClass().getName() + "/" + method.getName().substring(3));
++        }
++
++        accessibility = method.isAccessible();
++        method.setAccessible(true);
++        method.invoke(instance, lookedupResource);
++        method.setAccessible(accessibility);
++    }
++}
+
+Property changes on: java/org/apache/catalina/core/DefaultInstanceManager.java
+___________________________________________________________________
+Name: svn:eol-style
+   + native
+
+Index: java/org/apache/catalina/core/RestrictedListeners.properties
+===================================================================
+--- java/org/apache/catalina/core/RestrictedListeners.properties	(revision 0)
++++ java/org/apache/catalina/core/RestrictedListeners.properties	(revision 0)
+@@ -0,0 +1,15 @@
++# 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.
++
+
+Property changes on: java/org/apache/catalina/core/RestrictedListeners.properties
+___________________________________________________________________
+Name: svn:eol-style
+   + native
+
+Index: java/org/apache/catalina/core/ApplicationFilterConfig.java
+===================================================================
+--- java/org/apache/catalina/core/ApplicationFilterConfig.java	(revision 3168)
++++ java/org/apache/catalina/core/ApplicationFilterConfig.java	(working copy)
+@@ -19,14 +19,12 @@
+ package org.apache.catalina.core;
+ 
+ 
+-import java.io.IOException;
+-import java.io.InputStream;
+ import java.io.Serializable;
+ import java.lang.reflect.InvocationTargetException;
+ import java.util.ArrayList;
+ import java.util.Enumeration;
++import java.util.HashMap;
+ import java.util.Map;
+-import java.util.Properties;
+ 
+ import javax.naming.NamingException;
+ import javax.servlet.Filter;
+@@ -34,7 +32,7 @@
+ import javax.servlet.ServletContext;
+ import javax.servlet.ServletException;
+ 
+-import org.apache.AnnotationProcessor;
++import org.apache.InstanceManager;
+ import org.apache.catalina.Context;
+ import org.apache.catalina.Globals;
+ import org.apache.catalina.deploy.FilterDef;
+@@ -58,7 +56,7 @@
+ 
+     protected static StringManager sm =
+         StringManager.getManager(Constants.Package);
+-    
++
+     // ----------------------------------------------------------- Constructors
+ 
+ 
+@@ -78,8 +76,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,
+@@ -88,22 +86,6 @@
+ 
+         super();
+ 
+-        if (restrictedFilters == null) {
+-            restrictedFilters = new Properties();
+-            try {
+-                InputStream is = 
+-                    this.getClass().getClassLoader().getResourceAsStream
+-                        ("org/apache/catalina/core/RestrictedFilters.properties");
+-                if (is != null) {
+-                    restrictedFilters.load(is);
+-                } else {
+-                    context.getLogger().error(sm.getString("applicationFilterConfig.restrictedFiltersResources"));
+-                }
+-            } catch (IOException e) {
+-                context.getLogger().error(sm.getString("applicationFilterConfig.restrictedServletsResources"), e);
+-            }
+-        }
+-        
+         this.context = context;
+         setFilterDef(filterDef);
+ 
+@@ -130,13 +112,12 @@
+      */
+     private FilterDef filterDef = null;
+ 
+-
+     /**
+-     * Restricted filters (which can only be loaded by a privileged webapp).
++     * the InstanceManager used to create and destroy filter instances.
+      */
+-    protected static Properties restrictedFilters = null;
++    private transient InstanceManager instanceManager;
+ 
+-    
++
+     // --------------------------------------------------- FilterConfig Methods
+ 
+ 
+@@ -223,11 +204,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 +217,10 @@
+ 
+         // 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();
++        this.filter = (Filter) getInstanceManager().newInstance(filterClass);
+ 
+-        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.getIgnoreAnnotations()) {
+-            if (context instanceof StandardContext) {
+-               AnnotationProcessor processor = ((StandardContext)context).getAnnotationProcessor();
+-               processor.processAnnotations(this.filter);
+-               processor.postConstruct(this.filter);
+-            }
+-        }
+         if (context instanceof StandardContext &&
+-            ((StandardContext) context).getSwallowOutput()) {
++                context.getSwallowOutput()) {
+             try {
+                 SystemLogHandler.startCapture();
+                 filter.init(this);
+@@ -289,31 +248,7 @@
+ 
+     }
+ 
+-
+     /**
+-     * Return <code>true</code> if loading this filter is allowed.
+-     */
+-    protected boolean isFilterAllowed(Class filterClass) {
+-
+-        // Privileged webapps may load all servlets without restriction
+-        if (context.getPrivileged()) {
+-            return true;
+-        }
+-
+-        Class clazz = filterClass;
+-        while (clazz != null && !clazz.getName().equals("javax.servlet.Filter")) {
+-            if ("restricted".equals(restrictedFilters.getProperty(clazz.getName()))) {
+-                return (false);
+-            }
+-            clazz = clazz.getSuperclass();
+-        }
+-        
+-        return (true);
+-
+-    }
+-
+-
+-    /**
+      * Release the Filter instance associated with this FilterConfig,
+      * if there is one.
+      */
+@@ -323,17 +258,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).getInstanceManager().destroyInstance(this.filter);
+                 } catch (Exception e) {
+                     context.getLogger().error("ApplicationFilterConfig.preDestroy", e);
+                 }
+@@ -358,8 +293,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 +308,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).getInstanceManager().destroyInstance(this.filter);
+                     } catch (Exception e) {
+                         context.getLogger().error("ApplicationFilterConfig.preDestroy", e);
+                     }
+@@ -403,5 +338,18 @@
+ 
+     // -------------------------------------------------------- Private Methods
+ 
++    private InstanceManager getInstanceManager() {
++        if (instanceManager == null) {
++            if (context instanceof StandardContext) {
++                instanceManager = ((StandardContext)context).getInstanceManager();
++            } else {
++                instanceManager = new DefaultInstanceManager(null,
++                        new HashMap<String, Map<String, String>>(),
++                        context,
++                        getClass().getClassLoader()); 
++            }
++        }
++        return instanceManager;
++    }
+ 
+ }
+Index: java/org/apache/catalina/core/StandardWrapper.java
+===================================================================
+--- java/org/apache/catalina/core/StandardWrapper.java	(revision 3168)
++++ java/org/apache/catalina/core/StandardWrapper.java	(working copy)
+@@ -18,27 +18,14 @@
+ 
+ package org.apache.catalina.core;
+ 
+-import java.lang.reflect.Method;
+-import java.io.IOException;
+-import java.io.InputStream;
+ import java.io.PrintStream;
++import java.lang.reflect.Method;
+ import java.util.ArrayList;
+ import java.util.Enumeration;
+ import java.util.HashMap;
+ import java.util.HashSet;
+-import java.util.Properties;
+ import java.util.Stack;
+-import java.security.AccessController;
+-import java.security.PrivilegedActionException;
+-import java.security.PrivilegedExceptionAction;
+-import javax.servlet.Servlet;
+-import javax.servlet.ServletConfig;
+-import javax.servlet.ServletContext;
+-import javax.servlet.ServletException;
+-import javax.servlet.ServletRequest;
+-import javax.servlet.ServletResponse;
+-import javax.servlet.SingleThreadModel;
+-import javax.servlet.UnavailableException;
++
+ import javax.management.ListenerNotFoundException;
+ import javax.management.MBeanNotificationInfo;
+ import javax.management.Notification;
+@@ -47,6 +34,14 @@
+ import javax.management.NotificationFilter;
+ import javax.management.NotificationListener;
+ import javax.management.ObjectName;
++import javax.servlet.Servlet;
++import javax.servlet.ServletConfig;
++import javax.servlet.ServletContext;
++import javax.servlet.ServletException;
++import javax.servlet.ServletRequest;
++import javax.servlet.ServletResponse;
++import javax.servlet.SingleThreadModel;
++import javax.servlet.UnavailableException;
+ 
+ import org.apache.PeriodicEventListener;
+ import org.apache.catalina.Container;
+@@ -56,8 +51,8 @@
+ import org.apache.catalina.InstanceEvent;
+ import org.apache.catalina.InstanceListener;
+ import org.apache.catalina.LifecycleException;
+-import org.apache.catalina.Loader;
+ import org.apache.catalina.Wrapper;
++import org.apache.InstanceManager;
+ import org.apache.catalina.security.SecurityUtil;
+ import org.apache.catalina.util.Enumerator;
+ import org.apache.catalina.util.InstanceSupport;
+@@ -96,22 +91,6 @@
+         pipeline.setBasic(swValve);
+         broadcaster = new NotificationBroadcasterSupport();
+ 
+-        if (restrictedServlets == null) {
+-            restrictedServlets = new Properties();
+-            try {
+-                InputStream is = 
+-                    this.getClass().getClassLoader().getResourceAsStream
+-                        ("org/apache/catalina/core/RestrictedServlets.properties");
+-                if (is != null) {
+-                    restrictedServlets.load(is);
+-                } else {
+-                    log.error(sm.getString("standardWrapper.restrictedServletsResource"));
+-                }
+-            } catch (IOException e) {
+-                log.error(sm.getString("standardWrapper.restrictedServletsResource"), e);
+-            }
+-        }
+-        
+     }
+ 
+ 
+@@ -287,12 +266,7 @@
+                                                          ServletRequest.class,
+                                                          ServletResponse.class};
+     
+-    /**
+-     * Restricted servlets (which can only be loaded by a privileged webapp).
+-     */
+-    protected static Properties restrictedServlets = null;
+-    
+-    
++
+     // ------------------------------------------------------------- Properties
+ 
+ 
+@@ -1043,83 +1017,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;
++            InstanceManager instanceManager = ((StandardContext)getParent()).getInstanceManager();
+             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) instanceManager.newInstance(actualClass);
+             } catch (ClassCastException e) {
+                 unavailable(null);
+                 // Restore the context ClassLoader
+@@ -1127,7 +1027,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()) {
+@@ -1139,14 +1039,6 @@
+                     (sm.getString("standardWrapper.instantiate", actualClass), e);
+             }
+ 
+-            // Check if loading the servlet in this web application should be
+-            // allowed
+-            if (!isServletAllowed(servlet)) {
+-                throw new SecurityException
+-                    (sm.getString("standardWrapper.privilegedServlet",
+-                                  actualClass));
+-            }
+-
+             // Special handling for ContainerServlet instances
+             if ((servlet instanceof ContainerServlet) &&
+                   (isContainerProvidedServlet(actualClass) ||
+@@ -1398,7 +1290,7 @@
+ 
+             // Annotation processing
+             if (!((Context) getParent()).getIgnoreAnnotations()) {
+-               ((StandardContext)getParent()).getAnnotationProcessor().preDestroy(instance);
++               ((StandardContext)getParent()).getInstanceManager().destroyInstance(instance);
+             }
+ 
+         } catch (Throwable t) {
+@@ -1441,7 +1333,7 @@
+                     }
+                     // Annotation processing
+                     if (!((Context) getParent()).getIgnoreAnnotations()) {
+-                       ((StandardContext)getParent()).getAnnotationProcessor().preDestroy(s);
++                       ((StandardContext)getParent()).getInstanceManager().destroyInstance(s);
+                     }
+                 }
+             } catch (Throwable t) {
+@@ -1619,33 +1511,6 @@
+     }
+ 
+ 
+-    /**
+-     * Return <code>true</code> if loading this servlet is allowed.
+-     */
+-    protected boolean isServletAllowed(Object servlet) {
+-
+-        // Privileged webapps may load all servlets without restriction
+-        if (((Context) getParent()).getPrivileged()) {
+-            return true;
+-        }
+-        
+-        if (servlet instanceof ContainerServlet) {
+-            return (false);
+-        }
+-
+-        Class clazz = servlet.getClass();
+-        while (clazz != null && !clazz.getName().equals("javax.servlet.http.HttpServlet")) {
+-            if ("restricted".equals(restrictedServlets.getProperty(clazz.getName()))) {
+-                return (false);
+-            }
+-            clazz = clazz.getSuperclass();
+-        }
+-        
+-        return (true);
+-
+-    }
+-
+-
+     protected Method[] getAllDeclaredMethods(Class c) {
+ 
+         if (c.equals(javax.servlet.http.HttpServlet.class)) {
+Index: java/org/apache/catalina/core/StandardContext.java
+===================================================================
+--- java/org/apache/catalina/core/StandardContext.java	(revision 3168)
++++ java/org/apache/catalina/core/StandardContext.java	(working copy)
+@@ -31,6 +31,8 @@
+ import java.util.HashMap;
+ import java.util.Hashtable;
+ import java.util.Iterator;
++import java.util.List;
++import java.util.Map;
+ import java.util.Stack;
+ import java.util.TreeMap;
+ 
+@@ -59,7 +61,7 @@
+ import javax.servlet.http.HttpSessionAttributeListener;
+ import javax.servlet.http.HttpSessionListener;
+ 
+-import org.apache.AnnotationProcessor;
++import org.apache.InstanceManager;
+ import org.apache.catalina.Container;
+ import org.apache.catalina.ContainerListener;
+ import org.apache.catalina.Context;
+@@ -77,6 +79,8 @@
+ import org.apache.catalina.deploy.ErrorPage;
+ import org.apache.catalina.deploy.FilterDef;
+ import org.apache.catalina.deploy.FilterMap;
++import org.apache.catalina.deploy.Injectable;
++import org.apache.catalina.deploy.InjectionTarget;
+ import org.apache.catalina.deploy.LoginConfig;
+ import org.apache.catalina.deploy.MessageDestination;
+ import org.apache.catalina.deploy.MessageDestinationRef;
+@@ -88,7 +92,6 @@
+ import org.apache.catalina.startup.ContextConfig;
+ import org.apache.catalina.startup.TldConfig;
+ import org.apache.catalina.util.CharsetMapper;
+-import org.apache.catalina.util.DefaultAnnotationProcessor;
+ import org.apache.catalina.util.ExtensionValidator;
+ import org.apache.catalina.util.RequestUtil;
+ import org.apache.catalina.util.URLEncoder;
+@@ -174,9 +177,9 @@
+ 
+ 
+     /**
+-     * Annotation processor.
++     * Lifecycle provider.
+      */
+-    private AnnotationProcessor annotationProcessor = null;
++    private InstanceManager instanceManager = null;
+ 
+ 
+    /**
+@@ -679,13 +682,13 @@
+     // ----------------------------------------------------- Context Properties
+ 
+ 
+-    public AnnotationProcessor getAnnotationProcessor() {
+-       return annotationProcessor;
++    public InstanceManager getInstanceManager() {
++       return instanceManager;
+     }
+ 
+ 
+-    public void setAnnotationProcessor(AnnotationProcessor annotationProcessor) {
+-       this.annotationProcessor = annotationProcessor;
++    public void setInstanceManager(InstanceManager instanceManager) {
++       this.instanceManager = instanceManager;
+     }
+ 
+     
+@@ -3774,7 +3777,6 @@
+             log.debug("Configuring application event listeners");
+ 
+         // Instantiate the required listeners
+-        ClassLoader loader = getLoader().getClassLoader();
+         String listeners[] = findApplicationListeners();
+         Object results[] = new Object[listeners.length];
+         boolean ok = true;
+@@ -3783,13 +3785,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] = instanceManager.newInstance(listeners[i]);
+             } catch (Throwable t) {
+                 getLogger().error
+                     (sm.getString("standardContext.applicationListener",
+@@ -3889,29 +3885,26 @@
+                         ok = false;
+                     }
+                 }
+-                // Annotation processing
+-                if (!getIgnoreAnnotations()) {
+-                    try {
+-                        getAnnotationProcessor().preDestroy(listeners[j]);
+-                    } catch (Throwable t) {
+-                        getLogger().error
+-                            (sm.getString("standardContext.listenerStop",
+-                                listeners[j].getClass().getName()), t);
+-                        ok = false;
+-                    }
++                try {
++                    getInstanceManager().destroyInstance(listeners[j]);
++                } catch (Throwable t) {
++                    getLogger().error
++                       (sm.getString("standardContext.listenerStop",
++                            listeners[j].getClass().getName()), t);
++                    ok = false;
+                 }
+             }
+         }
+ 
+         // Annotation processing
+         listeners = getApplicationEventListeners();
+-        if (!getIgnoreAnnotations() && listeners != null) {
++        if (listeners != null) {
+             for (int i = 0; i < listeners.length; i++) {
+                 int j = (listeners.length - 1) - i;
+                 if (listeners[j] == null)
+                     continue;
+                 try {
+-                    getAnnotationProcessor().preDestroy(listeners[j]);
++                    getInstanceManager().destroyInstance(listeners[j]);
+                 } catch (Throwable t) {
+                     getLogger().error
+                         (sm.getString("standardContext.listenerStop",
+@@ -4308,21 +4301,18 @@
+         // Binding thread
+         oldCCL = bindThread();
+ 
+-        // Set annotation processing parameter for Jasper (unfortunately, since
+-        // 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 ) {
++            if (instanceManager == null) {
++                javax.naming.Context context = null;
+                 if (isUseNaming() && namingContextListener != null) {
+-                    annotationProcessor = 
+-                        new DefaultAnnotationProcessor(namingContextListener.getEnvContext());
+-                } else {
+-                    annotationProcessor = new DefaultAnnotationProcessor(null);
++                    context = namingContextListener.getEnvContext();
+                 }
++                Map<String, Map<String, String>> injectionMap = 
++                	buildInjectionMap(getIgnoreAnnotations() ? new NamingResources(): getNamingResources());
++                instanceManager = new DefaultInstanceManager
++                	(context, injectionMap, this, this.getClass().getClassLoader());
++                getServletContext().setAttribute(InstanceManager.class.getName(), instanceManager);
+             }
+-            getServletContext().setAttribute
+-                (AnnotationProcessor.class.getName(), annotationProcessor);
+         }
+ 
+         try {
+@@ -4418,6 +4408,48 @@
+         //cacheContext();
+     }
+ 
++    private Map<String, Map<String, String>> buildInjectionMap(NamingResources namingResources) {
++        Map<String, Map<String, String>> injectionMap = new HashMap<String, Map<String, String>>();
++        for (Injectable resource: namingResources.findLocalEjbs()) {
++            addInjectionTarget(resource, injectionMap);
++        }
++        for (Injectable resource: namingResources.findEjbs()) {
++            addInjectionTarget(resource, injectionMap);
++        }
++        for (Injectable resource: namingResources.findEnvironments()) {
++            addInjectionTarget(resource, injectionMap);
++        }
++        for (Injectable resource: namingResources.findMessageDestinationRefs()) {
++            addInjectionTarget(resource, injectionMap);
++        }
++        for (Injectable resource: namingResources.findResourceEnvRefs()) {
++            addInjectionTarget(resource, injectionMap);
++        }
++        for (Injectable resource: namingResources.findResources()) {
++            addInjectionTarget(resource, injectionMap);
++        }
++        for (Injectable resource: namingResources.findServices()) {
++            addInjectionTarget(resource, injectionMap);
++        }
++        return injectionMap;
++    }
++
++    private void addInjectionTarget(Injectable resource, Map<String, Map<String, String>> injectionMap) {
++        List<InjectionTarget> injectionTargets = resource.getInjectionTargets();
++        if (injectionTargets != null && injectionTargets.size() > 0) {
++            String jndiName = resource.getName();
++            for (InjectionTarget injectionTarget: injectionTargets) {
++                String clazz = injectionTarget.getTargetClass();
++                Map<String, String> injections = injectionMap.get(clazz);
++                if (injections == null) {
++                    injections = new HashMap<String, String>();
++                    injectionMap.put(clazz, injections);
++                }
++                injections.put(injectionTarget.getTargetName(), jndiName);
++            }
++        }
++    }
++
+     /**
+      * Processes TLDs.
+      *
+Index: java/org/apache/catalina/core/LocalStrings.properties
+===================================================================
+--- java/org/apache/catalina/core/LocalStrings.properties	(revision 3168)
++++ java/org/apache/catalina/core/LocalStrings.properties	(working copy)
+@@ -201,7 +201,6 @@
+ standardWrapper.notContext=Parent container of a Wrapper must be a Context
+ standardWrapper.notFound=Servlet {0} is not available
+ standardWrapper.notServlet=Class {0} is not a Servlet
+-standardWrapper.privilegedServlet=Servlet of class {0} is privileged and cannot be loaded by this web application
+ standardWrapper.releaseFilters=Release filters exception for servlet {0}
+ standardWrapper.serviceException=Servlet.service() for servlet {0} threw exception
+ standardWrapper.statusHeader=HTTP Status {0} - {1}
+@@ -210,7 +209,9 @@
+ standardWrapper.unloadException=Servlet {0} threw unload() exception
+ standardWrapper.unloading=Cannot allocate servlet {0} because it is being unloaded
+ standardWrapper.waiting=Waiting for {0} instance(s) to be deallocated
+-standardWrapper.restrictedServletsResource=Restricted servlets property file not found
+ 
+-applicationFilterConfig.restrictedFiltersResource=Restricted filters property file not found
+-applicationFilterConfig.privilegedFilter=Filter of class {0} is privileged and cannot be loaded by this web application
++defaultInstanceManager.restrictedServletsResource=Restricted servlets property file not found
++defaultInstanceManager.privilegedServlet=Servlet of class {0} is privileged and cannot be loaded by this web application
++defaultInstanceManager.restrictedFiltersResource=Restricted filters property file not found
++defaultInstanceManager.privilegedFilter=Filter of class {0} is privileged and cannot be loaded by this web application
++defaultInstanceManager.restrictedListenersResources="Restricted listeners property file not found
+\ No newline at end of file
+Index: java/org/apache/catalina/core/mbeans-descriptors.xml
+===================================================================
+--- java/org/apache/catalina/core/mbeans-descriptors.xml	(revision 3168)
++++ java/org/apache/catalina/core/mbeans-descriptors.xml	(working copy)
+@@ -41,9 +41,9 @@
+                is="true"
+                type="boolean"/>
+       
+-     <attribute name="annotationProcessor"
+-                description="Object that processes things like injection annotations"
+-                type="org.apache.AnnotationProcessor" />
++    <attribute name="instanceManager"
++                description="Object that creates and destroys servlets, filters, and listeners. Include dependency injection and postConstruct/preDestory handling"
++                type="org.apache.catalina.instanceManagement.InstanceManager" />
+ 
+     <attribute name="antiJARLocking"
+                description="Take care to not lock jar files"
+Index: java/org/apache/catalina/servlets/LocalStrings.properties
+===================================================================
+--- java/org/apache/catalina/servlets/LocalStrings.properties	(revision 3168)
++++ java/org/apache/catalina/servlets/LocalStrings.properties	(working copy)
+@@ -25,7 +25,6 @@
+ invokerServlet.notNamed=Cannot call invoker servlet with a named dispatcher
+ invokerServlet.noWrapper=Container has not called setWrapper() for this servlet
+ webdavservlet.jaxpfailed=JAXP initialization failed
+-webdavservlet.enternalEntityIgnored=The request included a reference to an external entity with PublicID {0} and SystemID {1} which was ignored
+ directory.filename=Filename
+ directory.lastModified=Last Modified
+ directory.parent=Up To {0}
+Index: java/org/apache/catalina/servlets/WebdavServlet.java
+===================================================================
+--- java/org/apache/catalina/servlets/WebdavServlet.java	(revision 3168)
++++ java/org/apache/catalina/servlets/WebdavServlet.java	(working copy)
+@@ -20,7 +20,6 @@
+ 
+ 
+ import java.io.IOException;
+-import java.io.StringReader;
+ import java.io.StringWriter;
+ import java.io.Writer;
+ import java.security.MessageDigest;
+@@ -37,7 +36,6 @@
+ import javax.naming.NamingEnumeration;
+ import javax.naming.NamingException;
+ import javax.naming.directory.DirContext;
+-import javax.servlet.ServletContext;
+ import javax.servlet.ServletException;
+ import javax.servlet.UnavailableException;
+ import javax.servlet.http.HttpServletRequest;
+@@ -59,7 +57,6 @@
+ import org.w3c.dom.Element;
+ import org.w3c.dom.Node;
+ import org.w3c.dom.NodeList;
+-import org.xml.sax.EntityResolver;
+ import org.xml.sax.InputSource;
+ import org.xml.sax.SAXException;
+ 
+@@ -290,8 +287,6 @@
+             documentBuilderFactory.setNamespaceAware(true);
+             documentBuilderFactory.setExpandEntityReferences(false);
+             documentBuilder = documentBuilderFactory.newDocumentBuilder();
+-            documentBuilder.setEntityResolver(
+-                    new WebdavResolver(this.getServletContext()));
+         } catch(ParserConfigurationException e) {
+             throw new ServletException
+                 (sm.getString("webdavservlet.jaxpfailed"));
+@@ -2828,26 +2823,6 @@
+     }
+ 
+ 
+-    // --------------------------------------------- WebdavResolver Inner Class
+-    /**
+-     * Work around for XML parsers that don't fully respect
+-     * {@link DocumentBuilderFactory#setExpandEntityReferences(false)}. External
+-     * references are filtered out for security reasons. See CVE-2007-5461.
+-     */
+-    private class WebdavResolver implements EntityResolver {
+-        private ServletContext context;
+-        
+-        public WebdavResolver(ServletContext theContext) {
+-            context = theContext;
+-        }
+-     
+-        public InputSource resolveEntity (String publicId, String systemId) {
+-            context.log(sm.getString("webdavservlet.enternalEntityIgnored",
+-                    publicId, systemId));
+-            return new InputSource(
+-                    new StringReader("Ignored external entity"));
+-        }
+-    }
+ };
+ 
+ 
+@@ -3170,4 +3145,3 @@
+ 
+ };
+ 
+-
+Index: java/org/apache/catalina/deploy/Injectable.java
+===================================================================
+--- java/org/apache/catalina/deploy/Injectable.java	(revision 0)
++++ java/org/apache/catalina/deploy/Injectable.java	(revision 0)
+@@ -0,0 +1,29 @@
++/*
++ * 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.deploy;
++
++import java.util.List;
++
++public interface Injectable {
++	public String getName();
++    public void addInjectionTarget(String injectionTargetName, String jndiName);
++    public List<InjectionTarget> getInjectionTargets();
++}
+
+Property changes on: java/org/apache/catalina/deploy/Injectable.java
+___________________________________________________________________
+Name: svn:eol-style
+   + native
+
+Index: java/org/apache/catalina/deploy/ContextEnvironment.java
+===================================================================
+--- java/org/apache/catalina/deploy/ContextEnvironment.java	(revision 3168)
++++ java/org/apache/catalina/deploy/ContextEnvironment.java	(working copy)
+@@ -19,6 +19,8 @@
+ package org.apache.catalina.deploy;
+ 
+ import java.io.Serializable;
++import java.util.ArrayList;
++import java.util.List;
+ 
+ 
+ /**
+@@ -29,7 +31,7 @@
+  * @version $Revision: 467222 $ $Date: 2006-10-23 23:17:11 -0400 (Mon, 23 Oct 2006) $
+  */
+ 
+-public class ContextEnvironment implements Serializable {
++public class ContextEnvironment implements Serializable, Injectable {
+ 
+ 
+     // ------------------------------------------------------------- Properties
+@@ -105,6 +107,18 @@
+         this.value = value;
+     }
+ 
++
++    private List<InjectionTarget> injectionTargets = new ArrayList<InjectionTarget>();
++
++    public void addInjectionTarget(String injectionTargetName, String jndiName) {
++        InjectionTarget target = new InjectionTarget(injectionTargetName, jndiName);
++        injectionTargets.add(target);
++    }
++
++    public List<InjectionTarget> getInjectionTargets() {
++        return injectionTargets;
++    }
++
+     // --------------------------------------------------------- Public Methods
+ 
+ 
+Index: java/org/apache/catalina/deploy/ResourceBase.java
+===================================================================
+--- java/org/apache/catalina/deploy/ResourceBase.java	(revision 3168)
++++ java/org/apache/catalina/deploy/ResourceBase.java	(working copy)
+@@ -21,6 +21,8 @@
+ import java.io.Serializable;
+ import java.util.Iterator;
+ import java.util.HashMap;
++import java.util.List;
++import java.util.ArrayList;
+ 
+ 
+ /**
+@@ -30,7 +32,7 @@
+  * @version $Revision: 467222 $ $Date: 2006-10-23 23:17:11 -0400 (Mon, 23 Oct 2006) $
+  */
+ 
+-public class ResourceBase implements Serializable {
++public class ResourceBase implements Serializable, Injectable {
+ 
+ 
+     // ------------------------------------------------------------- Properties
+@@ -111,8 +113,18 @@
+     public Iterator listProperties() {
+         return properties.keySet().iterator();
+     }
+-    
+-    
++
++    private List<InjectionTarget> injectionTargets = new ArrayList<InjectionTarget>();
++
++    public void addInjectionTarget(String injectionTargetName, String jndiName) {
++        InjectionTarget target = new InjectionTarget(injectionTargetName, jndiName);
++        injectionTargets.add(target);
++    }
++
++    public List<InjectionTarget> getInjectionTargets() {
++        return injectionTargets;
++    }
++
+     // -------------------------------------------------------- Package Methods
+ 
+ 
+Index: java/org/apache/catalina/deploy/MessageDestinationRef.java
+===================================================================
+--- java/org/apache/catalina/deploy/MessageDestinationRef.java	(revision 3168)
++++ java/org/apache/catalina/deploy/MessageDestinationRef.java	(working copy)
+@@ -19,6 +19,8 @@
+ package org.apache.catalina.deploy;
+ 
+ import java.io.Serializable;
++import java.util.ArrayList;
++import java.util.List;
+ 
+ 
+ /**
+@@ -31,7 +33,7 @@
+  * @since Tomcat 5.0
+  */
+ 
+-public class MessageDestinationRef implements Serializable {
++public class MessageDestinationRef implements Serializable, Injectable {
+ 
+ 
+     // ------------------------------------------------------------- Properties
+@@ -106,7 +108,17 @@
+         this.usage = usage;
+     }
+ 
++    private List<InjectionTarget> injectionTargets = new ArrayList<InjectionTarget>();
+ 
++    public void addInjectionTarget(String injectionTargetName, String jndiName) {
++        InjectionTarget target = new InjectionTarget(injectionTargetName, jndiName);
++        injectionTargets.add(target);
++    }
++
++    public List<InjectionTarget> getInjectionTargets() {
++        return injectionTargets;
++    }
++
+     // --------------------------------------------------------- Public Methods
+ 
+ 
+Index: java/org/apache/catalina/deploy/InjectionTarget.java
+===================================================================
+--- java/org/apache/catalina/deploy/InjectionTarget.java	(revision 0)
++++ java/org/apache/catalina/deploy/InjectionTarget.java	(revision 0)
+@@ -0,0 +1,55 @@
++/*
++ * 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.deploy;
++
++/**
++ * @version $Rev:$ $Date:$
++ */
++public class InjectionTarget {
++    private String targetClass;
++    private String targetName;
++
++
++    public InjectionTarget() {
++    }
++
++    public InjectionTarget(String targetClass, String targetName) {
++        this.targetClass = targetClass;
++        this.targetName = targetName;
++    }
++
++    public String getTargetClass() {

[... 693 lines stripped ...]