Author: markt
Date: Tue Sep 22 14:59:34 2015
New Revision: 1704647

URL: http://svn.apache.org/viewvc?rev=1704647&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=58444
Can't use _jsp_init() for initialising the InstanceManager or ExpressionFactory 
because custom JSP base classes will never call _jsp_init().
Refactor the init of these variable so that JSPs use lazy init. Tag files 
continue to use init before first use.

Added:
    tomcat/trunk/test/org/apache/jasper/runtime/TestCustomHttpJspPage.java   
(with props)
    tomcat/trunk/test/org/apache/jasper/runtime/TesterHttpJspBase.java   (with 
props)
    tomcat/trunk/test/webapp/bug5nnnn/bug58444.jsp   (with props)
Modified:
    tomcat/trunk/java/org/apache/jasper/compiler/Generator.java

Modified: tomcat/trunk/java/org/apache/jasper/compiler/Generator.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/Generator.java?rev=1704647&r1=1704646&r2=1704647&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/Generator.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/Generator.java Tue Sep 22 
14:59:34 2015
@@ -420,6 +420,77 @@ class Generator {
         page.visit(new ScriptingVarVisitor());
     }
 
+    /*
+     * Generates getters for
+     * - instance manager
+     * - expression factory
+     *
+     * For JSPs these methods use lazy init. This is not an option for tag 
files
+     * (at least it would be more complicated to generate) because the
+     * ServletConfig is not readily available.
+     */
+    private void generateGetters() {
+        out.printil("public javax.el.ExpressionFactory 
_jsp_getExpressionFactory() {");
+        out.pushIndent();
+        if (!ctxt.isTagFile()) {
+            out.printin("if (");
+            out.print(VAR_EXPRESSIONFACTORY);
+            out.println(" == null) {");
+            out.pushIndent();
+            out.printil("synchronized (this) {");
+            out.pushIndent();
+            out.printin("if (");
+            out.print(VAR_EXPRESSIONFACTORY);
+            out.println(" == null) {");
+            out.pushIndent();
+            out.printin(VAR_EXPRESSIONFACTORY);
+            out.println(" = 
_jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();");
+            out.popIndent();
+            out.printil("}");
+            out.popIndent();
+            out.printil("}");
+            out.popIndent();
+            out.printil("}");
+        }
+        out.printin("return ");
+        out.print(VAR_EXPRESSIONFACTORY);
+        out.println(";");
+        out.popIndent();
+        out.printil("}");
+
+        out.println();
+
+        out.printil("public org.apache.tomcat.InstanceManager 
_jsp_getInstanceManager() {");
+        out.pushIndent();
+        if (!ctxt.isTagFile()) {
+            out.printin("if (");
+            out.print(VAR_INSTANCEMANAGER);
+            out.println(" == null) {");
+            out.pushIndent();
+            out.printil("synchronized (this) {");
+            out.pushIndent();
+            out.printin("if (");
+            out.print(VAR_INSTANCEMANAGER);
+            out.println(" == null) {");
+            out.pushIndent();
+            out.printin(VAR_INSTANCEMANAGER);
+            out.println(" = 
org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());");
+            out.popIndent();
+            out.printil("}");
+            out.popIndent();
+            out.printil("}");
+            out.popIndent();
+            out.printil("}");
+        }
+        out.printin("return ");
+        out.print(VAR_INSTANCEMANAGER);
+        out.println(";");
+        out.popIndent();
+        out.printil("}");
+
+        out.println();
+    }
+
     /**
      * Generates the _jspInit() method for instantiating the tag handler pools.
      * For tag file, _jspInit has to be invoked manually, and the ServletConfig
@@ -449,23 +520,14 @@ class Generator {
             }
         }
 
-        out.printin(VAR_EXPRESSIONFACTORY);
-        out.print(" = _jspxFactory.getJspApplicationContext(");
+        // Tag files can't (easily) use lazy init for these so initialise them
+        // here.
         if (ctxt.isTagFile()) {
-            out.print("config");
-        } else {
-            out.print("getServletConfig()");
-        }
-        out.println(".getServletContext()).getExpressionFactory();");
-
-        out.printin(VAR_INSTANCEMANAGER);
-        out.print(" = 
org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(");
-        if (ctxt.isTagFile()) {
-            out.print("config");
-        } else {
-            out.print("getServletConfig()");
+            out.printin(VAR_EXPRESSIONFACTORY);
+            out.println(" = 
_jspxFactory.getJspApplicationContext(config.getServletContext()).getExpressionFactory();");
+            out.printin(VAR_INSTANCEMANAGER);
+            out.println(" = 
org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(config);");
         }
-        out.println(");");
 
         out.popIndent();
         out.printil("}");
@@ -618,10 +680,10 @@ class Generator {
             }
             out.println();
         }
-        out.printin("private javax.el.ExpressionFactory ");
+        out.printin("private volatile javax.el.ExpressionFactory ");
         out.print(VAR_EXPRESSIONFACTORY);
         out.println(";");
-        out.printin("private org.apache.tomcat.InstanceManager ");
+        out.printin("private volatile org.apache.tomcat.InstanceManager ");
         out.print(VAR_INSTANCEMANAGER);
         out.println(";");
         out.println();
@@ -655,6 +717,7 @@ class Generator {
         out.println();
 
 
+        generateGetters();
         generateInit();
         generateDestroy();
     }
@@ -2426,8 +2489,7 @@ class Generator {
                 out.print(" = (");
                 out.print(tagHandlerClassName);
                 out.print(")");
-                out.print(VAR_INSTANCEMANAGER);
-                out.print(".newInstance(\"");
+                out.print("_jsp_getInstanceManager().newInstance(\"");
                 out.print(tagHandlerClassName);
                 out.println("\", this.getClass().getClassLoader());");
             } else {
@@ -2438,16 +2500,14 @@ class Generator {
                 out.print("new ");
                 out.print(tagHandlerClassName);
                 out.println("());");
-                out.printin(VAR_INSTANCEMANAGER);
-                out.print(".newInstance(");
+                out.printin("_jsp_getInstanceManager().newInstance(");
                 out.print(tagHandlerVar);
                 out.println(");");
             }
         }
 
         private void writeDestroyInstance(String tagHandlerVar) {
-            out.printin(VAR_INSTANCEMANAGER);
-            out.print(".destroyInstance(");
+            out.printin("_jsp_getInstanceManager().destroyInstance(");
             out.print(tagHandlerVar);
             out.println(");");
         }
@@ -2887,10 +2947,6 @@ class Generator {
             return "_jspx_page_context";
         }
 
-        private String getExpressionFactoryVar() {
-            return VAR_EXPRESSIONFACTORY;
-        }
-
         /*
          * Creates a tag variable name by concatenating the given prefix and
          * shortName and encoded to make the resultant string a valid Java
@@ -2999,9 +3055,7 @@ class Generator {
                         || ((tai != null) && 
ValueExpression.class.getName().equals(tai.getTypeName()))) {
                     sb.append("new org.apache.jasper.el.JspValueExpression(");
                     sb.append(quote(mark));
-                    sb.append(',');
-                    sb.append(getExpressionFactoryVar());
-                    sb.append(".createValueExpression(");
+                    
sb.append(",_jsp_getExpressionFactory().createValueExpression(");
                     if (attr.getEL() != null) { // optimize
                         sb.append(elContext);
                         sb.append(',');
@@ -3034,9 +3088,7 @@ class Generator {
                         || ((tai != null) && 
MethodExpression.class.getName().equals(tai.getTypeName()))) {
                     sb.append("new org.apache.jasper.el.JspMethodExpression(");
                     sb.append(quote(mark));
-                    sb.append(',');
-                    sb.append(getExpressionFactoryVar());
-                    sb.append(".createMethodExpression(");
+                    
sb.append(",_jsp_getExpressionFactory().createMethodExpression(");
                     sb.append(elContext);
                     sb.append(',');
                     sb.append(quote(attrValue));
@@ -3972,8 +4024,7 @@ class Generator {
                 out.print(quote(attrName));
                 out.print(',');
                 if (attrInfos[i].isDeferredMethod()) {
-                    out.print(VAR_EXPRESSIONFACTORY);
-                    out.print(".createValueExpression(");
+                    
out.print("_jsp_getExpressionFactory().createValueExpression(");
                     out.print(toGetterMethod(attrName));
                     out.print(",javax.el.MethodExpression.class)");
                 } else {

Added: tomcat/trunk/test/org/apache/jasper/runtime/TestCustomHttpJspPage.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/jasper/runtime/TestCustomHttpJspPage.java?rev=1704647&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/jasper/runtime/TestCustomHttpJspPage.java 
(added)
+++ tomcat/trunk/test/org/apache/jasper/runtime/TestCustomHttpJspPage.java Tue 
Sep 22 14:59:34 2015
@@ -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.jasper.runtime;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestCustomHttpJspPage extends TomcatBaseTest {
+
+    /*
+     * Bug 58444
+     */
+    @Test
+    public void testCustomBasePageWhenUsingTagFiles() throws Exception {
+        getTomcatInstanceTestWebapp(true, true);
+
+        ByteChunk out = new ByteChunk();
+
+        int rc = getUrl("http://localhost:"; + getPort() + 
"/test/bug5nnnn/bug58444.jsp", out, null);
+
+        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
+
+        String result = out.toString();
+
+        Assert.assertTrue(result, result.contains("00-PASS"));
+    }
+}

Propchange: 
tomcat/trunk/test/org/apache/jasper/runtime/TestCustomHttpJspPage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/test/org/apache/jasper/runtime/TesterHttpJspBase.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/jasper/runtime/TesterHttpJspBase.java?rev=1704647&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/jasper/runtime/TesterHttpJspBase.java (added)
+++ tomcat/trunk/test/org/apache/jasper/runtime/TesterHttpJspBase.java Tue Sep 
22 14:59:34 2015
@@ -0,0 +1,70 @@
+/*
+ * 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.io.IOException;
+
+import javax.servlet.GenericServlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.HttpJspPage;
+
+public abstract class TesterHttpJspBase extends GenericServlet implements 
HttpJspPage {
+
+    private static final long serialVersionUID = 1L;
+
+
+    @Override
+    public void service(ServletRequest req, ServletResponse res) throws 
ServletException, IOException {
+        _jspService((HttpServletRequest) req, (HttpServletResponse) res);
+    }
+
+
+    @Override
+    public abstract void _jspService(HttpServletRequest request, 
HttpServletResponse response)
+            throws ServletException, IOException;
+
+
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        jspInit();
+    }
+
+
+    @Override
+    public void jspInit() {
+        // NO-OP by default
+    }
+
+
+    @Override
+    public void destroy() {
+        super.destroy();
+        jspDestroy();
+    }
+
+
+    @Override
+    public void jspDestroy() {
+        // NO-OP by default
+    }
+}

Propchange: tomcat/trunk/test/org/apache/jasper/runtime/TesterHttpJspBase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/test/webapp/bug5nnnn/bug58444.jsp
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/webapp/bug5nnnn/bug58444.jsp?rev=1704647&view=auto
==============================================================================
--- tomcat/trunk/test/webapp/bug5nnnn/bug58444.jsp (added)
+++ tomcat/trunk/test/webapp/bug5nnnn/bug58444.jsp Tue Sep 22 14:59:34 2015
@@ -0,0 +1,23 @@
+<%--
+  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.
+--%>
+<%@ page extends="org.apache.jasper.runtime.TesterHttpJspBase" %>
+<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
+<html>
+<body>
+<tags:echo echo="00-PASS" />
+</body>
+</html>
\ No newline at end of file

Propchange: tomcat/trunk/test/webapp/bug5nnnn/bug58444.jsp
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to