Return-Path: Delivered-To: apmail-geronimo-scm-archive@www.apache.org Received: (qmail 64975 invoked from network); 15 Aug 2008 04:34:12 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 15 Aug 2008 04:34:12 -0000 Received: (qmail 37356 invoked by uid 500); 15 Aug 2008 04:34:11 -0000 Delivered-To: apmail-geronimo-scm-archive@geronimo.apache.org Received: (qmail 37319 invoked by uid 500); 15 Aug 2008 04:34:11 -0000 Mailing-List: contact scm-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list scm@geronimo.apache.org Received: (qmail 37310 invoked by uid 99); 15 Aug 2008 04:34:10 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 14 Aug 2008 21:34:10 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 15 Aug 2008 04:33:21 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 9B87323889FE; Thu, 14 Aug 2008 21:33:19 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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... Date: Fri, 15 Aug 2008 04:33:18 -0000 To: scm@geronimo.apache.org From: dwoods@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080815043319.9B87323889FE@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 Bill Burke +- * @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> 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> 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 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 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() { ++ ++ 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 true 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>(), ++ 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 true 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> 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> buildInjectionMap(NamingResources namingResources) { ++ Map> injectionMap = new HashMap>(); ++ 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> injectionMap) { ++ List injectionTargets = resource.getInjectionTargets(); ++ if (injectionTargets != null && injectionTargets.size() > 0) { ++ String jndiName = resource.getName(); ++ for (InjectionTarget injectionTarget: injectionTargets) { ++ String clazz = injectionTarget.getTargetClass(); ++ Map injections = injectionMap.get(clazz); ++ if (injections == null) { ++ injections = new HashMap(); ++ 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"/> + +- ++ + + 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 injectionTargets = new ArrayList(); ++ ++ public void addInjectionTarget(String injectionTargetName, String jndiName) { ++ InjectionTarget target = new InjectionTarget(injectionTargetName, jndiName); ++ injectionTargets.add(target); ++ } ++ ++ public List 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 injectionTargets = new ArrayList(); ++ ++ public void addInjectionTarget(String injectionTargetName, String jndiName) { ++ InjectionTarget target = new InjectionTarget(injectionTargetName, jndiName); ++ injectionTargets.add(target); ++ } ++ ++ public List 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 injectionTargets = new ArrayList(); + ++ public void addInjectionTarget(String injectionTargetName, String jndiName) { ++ InjectionTarget target = new InjectionTarget(injectionTargetName, jndiName); ++ injectionTargets.add(target); ++ } ++ ++ public List 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 ...]