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