Bug 50597

Summary: Class.newInstance is used for Dynamic instance filters causing InstantiationException
Product: Tomcat 7 Reporter: Ismael Juma <mlists>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Severity: normal    
Priority: P2    
Version: 7.0.6   
Target Milestone: ---   
Hardware: All   
OS: All   

Description Ismael Juma 2011-01-16 12:25:24 UTC
Class.newInstance is called even when the following method ServletContext.addFilter method is called:

javax.servlet.FilterRegistration.Dynamic addFilter(java.lang.String s, javax.servlet.Filter filter);

This leads to an InstantiationException at runtime if there is no no-args constructor for the filter (pasted below). I'll supply a simple patch that fixes the issue for me.

SEVERE: Exception starting filter testFilter
java.lang.InstantiationException: test.TestFilter
        at java.lang.Class.newInstance0(Class.java:340)
        at java.lang.Class.newInstance(Class.java:308)
        at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultIn
        at org.apache.catalina.core.ApplicationFilterConfig.getFilter(Applicatio
        at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(Applica
        at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFi
        at org.apache.catalina.core.StandardContext.filterStart(StandardContext.
        at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:
        at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5035)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
Comment 1 Ismael Juma 2011-01-16 12:27:26 UTC
The simple patch that fixes it for me is:

[ijuma@localhost]~/src/tomcat% svn diff
Index: java/org/apache/catalina/core/ApplicationFilterConfig.java
--- java/org/apache/catalina/core/ApplicationFilterConfig.java	(revision 1059421)
+++ java/org/apache/catalina/core/ApplicationFilterConfig.java	(working copy)
@@ -367,10 +367,10 @@
             this.filter = null;
         } else {
-            // Allocate a new filter instance
-            getFilter();
+            if (filterDef.getFilter() == null) {
+              // Allocate a new filter instance
+              getFilter();
+            }

I don't know if this is the best way, but it works because after returning from that method the following is executed in the constructor (which is the same that getFilter does for the case where Tomcat has the class but not the instance of Filter):

        if (filterDef.getFilter() != null) {
            this.filter = filterDef.getFilter();
Comment 2 Mark Thomas 2011-01-17 12:13:09 UTC
Thanks for the patch. It has been applied to 7.0.x and will be included in 7.0.7 onwards.
Comment 3 Ismael Juma 2011-01-17 15:06:04 UTC