Update Embedded JSP Plugin to utilize the most current Tomcat Juli/Jasper still compatible with JDK 7.

- Replaced AnnotationHelper with InstanceHelper due to removal of AnnotationProcessor in Tomcat 7+.
- Tomcat Juli/Jasper Maven artifact ids changed with Tomcat 7+.
- Addition of tomcat-api dependency due to changes in Jasper for Tomcat 7+.
- Applied changes to embedded plugin modules required due to Jasper API changes.
- Additional unit tests for better test coverage.
This commit is contained in:
JCgH4164838Gh792C124B5
2018-12-31 01:16:24 -05:00
parent 600203bbea
commit b2b3b556f3
14 changed files with 692 additions and 128 deletions
+2 -2
View File
@@ -68,7 +68,7 @@
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>juli</artifactId>
<artifactId>tomcat-juli</artifactId>
</dependency>
<dependency>
<groupId>taglibs</groupId>
@@ -82,7 +82,7 @@
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>jasper</artifactId>
<artifactId>tomcat-jasper</artifactId>
<scope>provided</scope>
</dependency>
@@ -23,6 +23,8 @@ import com.opensymphony.xwork2.FileManagerFactory;
import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate;
import com.opensymphony.xwork2.util.finder.UrlSet;
import com.opensymphony.xwork2.util.fs.DefaultFileManager;
import com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.commons.io.FileUtils;
@@ -172,8 +174,6 @@ public class JSPLoader {
List<String> optionList = new ArrayList<String>();
Set<String> classPath = new HashSet<String>();
FileManager fileManager = ServletActionContext.getContext().getInstance(FileManagerFactory.class).getFileManager();
//find available jars
ClassLoaderInterface classLoaderInterface = getClassLoaderInterface();
UrlSet urlSet = new UrlSet(classLoaderInterface);
@@ -181,11 +181,19 @@ public class JSPLoader {
//find jars
List<URL> urls = urlSet.getUrls();
for (URL url : urls) {
URL normalizedUrl = fileManager.normalizeToFileProtocol(url);
File file = FileUtils.toFile(ObjectUtils.defaultIfNull(normalizedUrl, url));
if (file.exists())
classPath.add(file.getAbsolutePath());
if (urls != null && urls.size() > 0) {
final FileManagerFactory fileManagerFactoryGetInstance = ServletActionContext.getContext().getInstance(FileManagerFactory.class);
final FileManagerFactory contextFileManagerFactory = (fileManagerFactoryGetInstance != null ? fileManagerFactoryGetInstance : (FileManagerFactory) ServletActionContext.getContext().get(StrutsConstants.STRUTS_FILE_MANAGER_FACTORY));
final FileManagerFactory fileManagerFactory = (contextFileManagerFactory != null ? contextFileManagerFactory : new DefaultFileManagerFactory());
final FileManager fileManagerGetInstance = fileManagerFactory.getFileManager();
final FileManager contextFileManager = (fileManagerGetInstance != null ? fileManagerGetInstance : (FileManager) ServletActionContext.getContext().get(StrutsConstants.STRUTS_FILE_MANAGER));
final FileManager fileManager = (contextFileManager != null ? contextFileManager : new DefaultFileManager());
for (URL url : urls) {
URL normalizedUrl = fileManager.normalizeToFileProtocol(url);
File file = FileUtils.toFile(ObjectUtils.defaultIfNull(normalizedUrl, url));
if (file.exists())
classPath.add(file.getAbsolutePath());
}
}
//these should be in the list already, but I am feeling paranoid
@@ -197,8 +205,8 @@ public class JSPLoader {
classPath.add(getJarUrl(JspPage.class));
try {
Class annotationsProcessor = Class.forName("org.apache.AnnotationProcessor");
classPath.add(getJarUrl(annotationsProcessor));
Class instanceManager = Class.forName("org.apache.tomcat.InstanceManager");
classPath.add(getJarUrl(instanceManager));
} catch (ClassNotFoundException e) {
//ok ignore
}
@@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.HttpJspPage;
import java.util.HashMap;
import java.util.Map;
import org.apache.struts2.views.util.DefaultUrlHelper;
/**
* Maintains a cache of jsp locations -&gt; servlet instances for those jsps. When a jsp is requested
@@ -49,11 +50,13 @@ public abstract class JSPRuntime {
public static void handle(String location, boolean flush) throws Exception {
final HttpServletResponse response = ServletActionContext.getResponse();
final HttpServletRequest request = ServletActionContext.getRequest();
final UrlHelper urlHelper = ServletActionContext.getContext().getInstance(UrlHelper.class);
int i = location.indexOf("?");
if (i > 0) {
//extract params from the url and add them to the request
final UrlHelper urlHelperGetInstance = ServletActionContext.getContext().getInstance(UrlHelper.class);
final UrlHelper contextUrlHelper = (urlHelperGetInstance != null ? urlHelperGetInstance : (UrlHelper) ServletActionContext.getContext().get(StrutsConstants.STRUTS_URL_HELPER));
final UrlHelper urlHelper = (contextUrlHelper != null ? contextUrlHelper : new DefaultUrlHelper());
String query = location.substring(i + 1);
Map<String, Object> queryParams = urlHelper.parseQueryString(query, true);
if (queryParams != null && !queryParams.isEmpty()) {
@@ -76,8 +76,8 @@ class Generator {
private static final String VAR_EXPRESSIONFACTORY =
System.getProperty("org.apache.struts2.jasper.compiler.Generator.VAR_EXPRESSIONFACTORY", "_el_expressionfactory");
private static final String VAR_ANNOTATIONPROCESSOR =
System.getProperty("org.apache.struts2.jasper.compiler.Generator.VAR_ANNOTATIONPROCESSOR", "_jsp_annotationprocessor");
private static final String VAR_INSTANCEMANAGER =
System.getProperty("org.apache.struts2.jasper.compiler.Generator.VAR_INSTANCEMANAGER", "_jsp_instancemanager");
private ServletWriter out;
@@ -421,15 +421,14 @@ class Generator {
out.print("getServletConfig()");
}
out.println(".getServletContext()).getExpressionFactory();");
out.printin(VAR_ANNOTATIONPROCESSOR);
out.print(" = (org.apache.AnnotationProcessor) ");
out.printin(VAR_INSTANCEMANAGER);
out.print(" = (org.apache.tomcat.InstanceManager) ");
if (ctxt.isTagFile()) {
out.print("config");
} else {
out.print("getServletConfig()");
}
out.println(".getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());");
out.println(".getServletContext().getAttribute(org.apache.tomcat.InstanceManager.class.getName());");
out.popIndent();
out.printil("}");
@@ -533,8 +532,8 @@ class Generator {
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.tomcat.InstanceManager ");
out.print(VAR_INSTANCEMANAGER);
out.println(";");
out.println();
}
@@ -2210,8 +2209,8 @@ class Generator {
out.print("new ");
out.print(tagHandlerClassName);
out.println("();");
out.printin("org.apache.struts2.jasper.runtime.AnnotationHelper.postConstruct(");
out.print(VAR_ANNOTATIONPROCESSOR);
out.printin("org.apache.struts2.jasper.runtime.InstanceHelper.postConstruct(");
out.print(VAR_INSTANCEMANAGER);
out.print(", ");
out.print(tagHandlerVar);
out.println(");");
@@ -2360,8 +2359,8 @@ class Generator {
} else {
out.printin(tagHandlerVar);
out.println(".release();");
out.printin("org.apache.struts2.jasper.runtime.AnnotationHelper.preDestroy(");
out.print(VAR_ANNOTATIONPROCESSOR);
out.printin("org.apache.struts2.jasper.runtime.InstanceHelper.preDestroy(");
out.print(VAR_INSTANCEMANAGER);
out.print(", ");
out.print(tagHandlerVar);
out.println(");");
@@ -2407,8 +2406,8 @@ class Generator {
} else {
out.printin(tagHandlerVar);
out.println(".release();");
out.printin("org.apache.struts2.jasper.runtime.AnnotationHelper.preDestroy(");
out.print(VAR_ANNOTATIONPROCESSOR);
out.printin("org.apache.struts2.jasper.runtime.InstanceHelper.preDestroy(");
out.print(VAR_INSTANCEMANAGER);
out.print(", ");
out.print(tagHandlerVar);
out.println(");");
@@ -2452,8 +2451,8 @@ class Generator {
out.println("();");
// Resource injection
out.printin("org.apache.struts2.jasper.runtime.AnnotationHelper.postConstruct(");
out.print(VAR_ANNOTATIONPROCESSOR);
out.printin("org.apache.struts2.jasper.runtime.InstanceHelper.postConstruct(");
out.print(VAR_INSTANCEMANAGER);
out.print(", ");
out.print(tagHandlerVar);
out.println(");");
@@ -2510,8 +2509,8 @@ class Generator {
syncScriptingVars(n, VariableInfo.AT_END);
// Resource injection
out.printin("org.apache.struts2.jasper.runtime.AnnotationHelper.preDestroy(");
out.print(VAR_ANNOTATIONPROCESSOR);
out.printin("org.apache.struts2.jasper.runtime.InstanceHelper.preDestroy(");
out.print(VAR_INSTANCEMANAGER);
out.print(", ");
out.print(tagHandlerVar);
out.println(");");
@@ -1,75 +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.struts2.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-24 05:17:11 +0200 (Tue, 24 Oct 2006) $
*/
public class AnnotationHelper {
/**
* Call postConstruct method on the specified instance. Note: In Jasper, this
* calls naming resources injection as well.
*
* @param processor annotation processor
* @param instance object instance
*
* @throws IllegalAccessException on error
* @throws InvocationTargetException on error
* @throws NamingException on error
*/
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.
*
* @param processor annotation processor
* @param instance object instance
*
* @throws IllegalAccessException on error
* @throws InvocationTargetException on error
*/
public static void preDestroy(AnnotationProcessor processor, Object instance)
throws IllegalAccessException, InvocationTargetException {
if (processor != null) {
processor.preDestroy(instance);
}
}
}
@@ -0,0 +1,191 @@
/*
* 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.struts2.jasper.runtime;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import javax.naming.NamingException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import org.apache.tomcat.InstanceManager;
import org.apache.tomcat.SimpleInstanceManager;
/**
* A helper module for processing instance objects using InstanceManager instances.
*
* Since AnnotationProcessor was removed in Tomcat 7+, this module performs a similar purpose using
* InstanceManager processing (the effective replacement). This module's logic is a blending
* of the original Struts 2 AnnotationHelper and logic ideas from an old Geronimo update
* (https://issues.apache.org/jira/browse/GERONIMO-3010)
*
* Original AnnotationHelper: Verify the annotation and Process it (@author Fabien Carrion, @author Remy Maucherat)
*/
public class InstanceHelper {
private static final Map<ClassLoader, InstanceManager> INSTANCE_MANAGERS =
Collections.synchronizedMap(new WeakHashMap<ClassLoader, InstanceManager>());
/**
* Private constructor (all methods static, no instance required)
*/
private InstanceHelper() {}
/**
* Get the <code>{@link InstanceManager}</code> instance manager for a given
* <code>{@link ServletConfig}</code>.
*
* For any non-null servletConfig with a non-null <code>{@link ServletContext}</code>,
* if no instance manager is defined, this method will produce a
* <code>{@link SimpleInstanceManager}</code> and associate it with that
* <code>{@link ServletConfig}</code> and its <code>{@link ClassLoader}</code>.
*
* @param servletConfig
*
* @return
*/
public static InstanceManager getServletInstanceManager(ServletConfig servletConfig) {
if (servletConfig == null) {
return null;
}
final ServletContext servletContext = servletConfig.getServletContext();
if (servletContext == null) {
return null;
}
final ClassLoader classLoader = servletContext.getClassLoader();
final Object potentialInstanceManager = servletContext.getAttribute(InstanceManager.class.getName());
InstanceManager instanceManager;
if (potentialInstanceManager == null) {
instanceManager = new SimpleInstanceManager();
setClassLoaderInstanceManager(classLoader, instanceManager);
servletContext.setAttribute(InstanceManager.class.getName(), instanceManager);
return instanceManager;
}
else {
instanceManager = getClassLoaderInstanceManager(classLoader);
if (instanceManager == null || ! instanceManager.equals(potentialInstanceManager) ) {
if (potentialInstanceManager instanceof InstanceManager) {
instanceManager = (InstanceManager) potentialInstanceManager;
setClassLoaderInstanceManager(classLoader, instanceManager);
return instanceManager;
} else {
return null;
}
} else {
return instanceManager;
}
}
}
/**
* Get the <code>{@link InstanceManager}</code> instance manager for a given
* <code>{@link ClassLoader}</code> instance, stored within the
* <code>{@link InstanceHelper} {@link Map}</code>.
*
* For any non-null classLoader, if no instance manager is defined,
* this method will produce a <code>{@link SimpleInstanceManager}</code>
* and associate it with that <code>{@link ClassLoader}</code>.
*
* @param classLoader
*
* @return
*/
public static InstanceManager getClassLoaderInstanceManager(ClassLoader classLoader) {
if (classLoader == null) {
return null;
}
InstanceManager instanceManager = INSTANCE_MANAGERS.get(classLoader);
if (instanceManager == null) {
instanceManager = new SimpleInstanceManager();
setClassLoaderInstanceManager(classLoader, instanceManager);
}
return instanceManager;
}
/**
* Set the <code>{@link InstanceManager}</code> instance manager for a given
* <code>{@link ClassLoader}</code> instance, stored within the
* <code>{@link InstanceHelper} {@link Map}</code>.
*
* @param classLoader
* @param instanceManager
*/
protected static void setClassLoaderInstanceManager(ClassLoader classLoader, InstanceManager instanceManager) {
if (classLoader != null) {
INSTANCE_MANAGERS.put(classLoader, instanceManager);
}
}
/**
* Post-construct an instance of the specified <code>{@link Object}</code> using
* the provided <code>{@link InstanceManager}</code>.
*
* Note: This method replaces the old postContruct method in the AnnotationHelper.
* Note: In Jasper, this calls naming resources injection as well.
*
* @param instanceManager
* @param instance
*
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws NamingException
*/
public static void postConstruct(InstanceManager instanceManager, Object instance)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException,
NamingException {
if (instanceManager == null) {
throw new IllegalArgumentException("postConstruct - instanceManager is null");
} else if (instance == null) {
throw new IllegalArgumentException("postConstruct - instanceClass is null");
} else {
instanceManager.newInstance(instance);
}
}
/**
* Pre-destroy an instance <code>{@link Object}</code> previously post-constructed
* with the provided <code>{@link InstanceManager}</code>.
*
* Note: This method replaces the old preDestroy method in the AnnotationHelper.
*
* @param instanceManager instance manager
* @param instance object instance
*
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
*/
public static void preDestroy(InstanceManager instanceManager, Object instance)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
if (instanceManager == null) {
throw new IllegalArgumentException("preDestroy - instanceManager is null");
} else if (instance == null) {
throw new IllegalArgumentException("preDestroy - instance is null");
} else {
instanceManager.destroyInstance(instance);
}
}
}
@@ -22,10 +22,10 @@ import javax.servlet.ServletConfig;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import org.apache.AnnotationProcessor;
import org.apache.struts2.jasper.Constants;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.InstanceManager;
/**
* Pool of tag handlers that can be reused.
@@ -43,7 +43,7 @@ public class TagHandlerPool {
// 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;
@@ -79,8 +79,7 @@ public class TagHandlerPool {
}
this.handlers = new Tag[maxSize];
this.current = -1;
this.annotationProcessor =
(AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
this.instanceManager = InstanceHelper.getServletInstanceManager(config);
}
/**
@@ -124,8 +123,10 @@ public class TagHandlerPool {
// 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);
final Tag instance = (Tag) handlerClass.newInstance();
if (instanceManager != null) {
InstanceHelper.postConstruct(instanceManager, instance);
}
return instance;
} catch (Exception e) {
throw new JspException(e.getMessage(), e);
@@ -148,9 +149,9 @@ public class TagHandlerPool {
}
// There is no need for other threads to wait for us to release
handler.release();
if (annotationProcessor != null) {
if (instanceManager != null) {
try {
AnnotationHelper.preDestroy(annotationProcessor, handler);
InstanceHelper.preDestroy(instanceManager, handler);
} catch (Exception e) {
log.warn("Error processing preDestroy on tag instance of "
+ handler.getClass().getName(), e);
@@ -165,9 +166,9 @@ public class TagHandlerPool {
public synchronized void release() {
for (int i = current; i >= 0; i--) {
handlers[i].release();
if (annotationProcessor != null) {
if (instanceManager != null) {
try {
AnnotationHelper.preDestroy(annotationProcessor, handlers[i]);
InstanceHelper.preDestroy(instanceManager, handlers[i]);
} catch (Exception e) {
log.warn("Error processing preDestroy on tag instance of "
+ handlers[i].getClass().getName(), e);
@@ -28,15 +28,23 @@ import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.descriptor.JspConfigDescriptor;
import org.apache.struts2.ServletActionContext;
@@ -421,6 +429,139 @@ public class JspCServletContext implements ServletContext {
}
@Override
public int getEffectiveMajorVersion() {
return (2);
}
@Override
public int getEffectiveMinorVersion() {
return (3);
}
@Override
public boolean setInitParameter(String arg0, String arg1) {
return (false);
}
@Override
public ServletRegistration.Dynamic addServlet(String arg0, String arg1) {
return (null);
}
@Override
public ServletRegistration.Dynamic addServlet(String arg0, Servlet arg1) {
return (null);
}
@Override
public ServletRegistration.Dynamic addServlet(String arg0, Class<? extends Servlet> arg1) {
return (null);
}
@Override
public <T extends Servlet> T createServlet(Class<T> arg0) throws ServletException {
return (null);
}
@Override
public ServletRegistration getServletRegistration(String arg0) {
return (null);
}
@Override
public Map<String, ? extends ServletRegistration> getServletRegistrations() {
return (null);
}
@Override
public FilterRegistration.Dynamic addFilter(String arg0, String arg1) {
return (null);
}
@Override
public FilterRegistration.Dynamic addFilter(String arg0, Filter arg1) {
return (null);
}
@Override
public FilterRegistration.Dynamic addFilter(String arg0, Class<? extends Filter> arg1) {
return (null);
}
@Override
public <T extends Filter> T createFilter(Class<T> arg0) throws ServletException {
return (null);
}
@Override
public FilterRegistration getFilterRegistration(String arg0) {
return (null);
}
@Override
public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
return (null);
}
@Override
public SessionCookieConfig getSessionCookieConfig() {
return (null);
}
@Override
public void setSessionTrackingModes(Set<SessionTrackingMode> arg0) {
return;
}
@Override
public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
return (null);
}
@Override
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
return (null);
}
@Override
public void addListener(String arg0) {
return;
}
@Override
public <T extends EventListener> void addListener(T arg0) {
return;
}
@Override
public void addListener(Class<? extends EventListener> arg0) {
return;
}
@Override
public <T extends EventListener> T createListener(Class<T> arg0) throws ServletException {
return (null);
}
@Override
public JspConfigDescriptor getJspConfigDescriptor() {
return (null);
}
@Override
public ClassLoader getClassLoader() {
return (null);
}
@Override
public void declareRoles(String... arg0) {
return;
}
@Override
public String getVirtualServerName() {
return ("JspCServletContext_VirtualServer");
}
}
@@ -37,7 +37,7 @@ import org.apache.struts2.jasper.compiler.Localizer;
import org.apache.struts2.jasper.security.SecurityUtil;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.PeriodicEventListener;
import org.apache.tomcat.PeriodicEventListener;
/**
* The JSP engine (a.k.a Jasper).
@@ -32,7 +32,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.tagext.TagInfo;
import org.apache.AnnotationProcessor;
import org.apache.struts2.jasper.JasperException;
import org.apache.struts2.jasper.JspCompilationContext;
import org.apache.struts2.jasper.Options;
@@ -41,8 +40,10 @@ import org.apache.struts2.jasper.compiler.JavacErrorDetail;
import org.apache.struts2.jasper.compiler.JspRuntimeContext;
import org.apache.struts2.jasper.compiler.Localizer;
import org.apache.struts2.jasper.runtime.JspSourceDependent;
import org.apache.struts2.jasper.runtime.InstanceHelper;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.InstanceManager;
/**
* The JSP engine (a.k.a Jasper).
@@ -144,10 +145,9 @@ public class JspServletWrapper {
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);
final InstanceManager instanceManager = InstanceHelper.getServletInstanceManager(config);
if (instanceManager != null) {
InstanceHelper.postConstruct(instanceManager, servlet);
}
} catch (IllegalAccessException e) {
throw new JasperException(e);
@@ -424,10 +424,10 @@ public class JspServletWrapper {
public void destroy() {
if (theServlet != null) {
theServlet.destroy();
AnnotationProcessor annotationProcessor = (AnnotationProcessor) config.getServletContext().getAttribute(AnnotationProcessor.class.getName());
if (annotationProcessor != null) {
final InstanceManager instanceManager = InstanceHelper.getServletInstanceManager(config);
if (instanceManager != null) {
try {
annotationProcessor.preDestroy(theServlet);
InstanceHelper.preDestroy(instanceManager, theServlet);
} catch (Exception e) {
// Log any exception, since it can't be passed along
log.error(Localizer.getMessage("jsp.error.file.not.found",
@@ -28,6 +28,7 @@ import java.io.UnsupportedEncodingException;
import java.util.Locale;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
@@ -283,6 +284,16 @@ public class Util {
public void write(int b) throws IOException {
bos.write(b);
}
@Override
public boolean isReady() {
return (true);
}
@Override
public void setWriteListener(WriteListener arg0) {
return;
}
};
private boolean isWriterUsed;
private boolean isStreamUsed;
@@ -34,11 +34,15 @@ import com.opensymphony.xwork2.util.fs.DefaultFileManager;
import junit.framework.TestCase;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.dispatcher.HttpParameters;
import org.apache.struts2.jasper.runtime.InstanceHelper;
import org.apache.struts2.views.util.DefaultUrlHelper;
import org.apache.struts2.views.util.UrlHelper;
import org.apache.tomcat.InstanceManager;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.mock.web.MockServletContext;
import javax.servlet.Servlet;
@@ -49,10 +53,12 @@ import java.util.*;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class EmbeddedJSPResultTest extends TestCase {
private HttpServletRequest request;
private MockHttpServletResponse response;
private MockServletContext context;
private MockServletConfig config;
private EmbeddedJSPResult result;
public void testScriptlet() throws Exception {
@@ -241,6 +247,56 @@ public class EmbeddedJSPResultTest extends TestCase {
}
}
public void testComplex() throws Exception {
result.setLocation("org/apache/struts2/complex0.jsp");
result.execute(null);
String responseString = response.getContentAsString();
assertNotNull("result is null?", responseString);
int titleIndex = responseString.indexOf("<title>Struts2 Embedded JSP Plugin - Complex Test Page</title>");
int responseLength = responseString.length();
int testValue1Index = responseString.indexOf("testvalue1 set/if worked.");
int testValue5Index = responseString.indexOf("testvalue5 set/if worked.");
int lastGroupIndex = responseString.indexOf("End include tests<br/>");
int lastHtmlIndex = responseString.indexOf("</html>");
assertTrue("Did not find title ?", titleIndex > 0);
assertTrue("Test value 1 not present or index not > title index ?", testValue1Index > titleIndex);
assertTrue("Test value 5 not present or index not > test value 1 index ?", testValue5Index > testValue1Index);
assertTrue("Last group index not present or index not > test value 5 index ?", lastGroupIndex > testValue5Index);
assertTrue("Last html index not present or index not > last group index ?", lastHtmlIndex > lastGroupIndex);
assertTrue("Response not at least length: 3400 ?", responseLength > 3400);
}
public void testInstanceHelper() throws Exception {
InstanceManager instanceManagerServlet = InstanceHelper.getServletInstanceManager(config);
InstanceManager instanceManagerClassLoader = InstanceHelper.getClassLoaderInstanceManager(context.getClassLoader());
assertNotNull("instanceManager (servlet) is null ?", instanceManagerServlet);
assertNotNull("instanceManager (classloader) is null ?", instanceManagerClassLoader);
assertEquals("instanceManager (servlet) is not equal to instanceManager (classloader) ?", instanceManagerServlet, instanceManagerClassLoader);
final Double instanceDouble = new Double(0);
final Long instanceLong = new Long(0);
final Object instanceObject = new Object();
final String instanceString = new String("test string");
final MockHttpServletRequest intanceMockHttpServletRequest = new MockHttpServletRequest();
intanceMockHttpServletRequest.setContextPath("context path");
InstanceHelper.postConstruct(instanceManagerServlet, instanceDouble);
InstanceHelper.postConstruct(instanceManagerServlet, instanceLong);
InstanceHelper.postConstruct(instanceManagerServlet, instanceObject);
InstanceHelper.postConstruct(instanceManagerServlet, instanceString);
InstanceHelper.postConstruct(instanceManagerServlet, intanceMockHttpServletRequest);
assertEquals("test string value changed after postConstruct ?", instanceString, "test string");
assertEquals("mock servlet request context path value changed after postConstruct ?",
intanceMockHttpServletRequest.getContextPath(), "context path");
InstanceHelper.preDestroy(instanceManagerServlet, instanceDouble);
InstanceHelper.preDestroy(instanceManagerServlet, instanceLong);
InstanceHelper.preDestroy(instanceManagerServlet, instanceObject);
InstanceHelper.preDestroy(instanceManagerServlet, instanceString);
InstanceHelper.preDestroy(instanceManagerServlet, intanceMockHttpServletRequest);
assertEquals("test string value changed after preDestroy ?", instanceString, "test string");
assertEquals("mock servlet request context path value changed after preDestroy ?",
intanceMockHttpServletRequest.getContextPath(), "context path");
}
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -250,6 +306,7 @@ public class EmbeddedJSPResultTest extends TestCase {
request = EasyMock.createNiceMock(HttpServletRequest.class);
response = new MockHttpServletResponse();
context = new MockServletContext();
config = new MockServletConfig(context);
final Map params = new HashMap();
@@ -0,0 +1,221 @@
<%--
/*
* 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.
*/
--%>
<!-- Test a bunch of imports this page does not use, then the taglibs it does use -->
<%@ page import="org.apache.commons.lang3.StringUtils" %>
<%@ page import="com.opensymphony.xwork2.util.AnnotationUtils" %>
<%@ page import="com.opensymphony.xwork2.util.ClassLoaderUtil" %>
<%@ page import="com.opensymphony.xwork2.util.ProxyUtil" %>
<%@ page import="com.opensymphony.xwork2.util.ResolverUtil" %>
<%@ page import="com.opensymphony.xwork2.util.TextParseUtil" %>
<%@ page import="com.opensymphony.xwork2.util.WildcardUtil" %>
<%@ page import="org.apache.struts2.StrutsConstants" %>
<%@ page import="org.apache.struts2.StrutsConstants" %>
<%@ page import="org.apache.struts2.util.ComponentUtils" %>
<%@ page import="org.apache.struts2.util.ContainUtil" %>
<%@ page import="org.apache.struts2.util.StrutsUtil" %>
<%@ page import="org.apache.struts2.util.URLDecoderUtil" %>
<%@ page import="org.apache.struts2.util.VelocityStrutsUtil" %>
<%@ taglib prefix="r" uri="http://jakarta.apache.org/taglibs/request-1.0" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Struts2 Embedded JSP Plugin - Complex Test Page</title>
</head>
<body>
<div class="fakeCSSClass">
<h1>Embedded JSP - Test JSTL Set/If Tag - Borrows structure from Struts 2 Showcase</h1>
</div>
<div class="fakeCSSClass">
<div class="fakeCSSClass2">
<div class="fakeCSSClass3">
<p>
This is a jsp to test the JSTL If/Choose Tags. There's a few combination being tested.
The characters in bold an non-bold should be the same.
</p>
<b>1 - Foo -</b>
<c:if test="${true}">
Foo
</c:if>
<c:if test="${false}">
Bar
</c:if>
<br/>
<b>2 - Bar -</b>
<c:choose>
<c:when test="${false}">
Foo
</c:when>
<c:otherwise>
Bar
</c:otherwise>
</c:choose>
<br/>
<b>3 - FooFooFoo - </b>
<c:choose>
<c:when test="${true}">
Foo
<c:choose>
<c:when test="${true}">
FooFoo
</c:when>
<c:otherwise>
BarBar
</c:otherwise>
</c:choose>
</c:when>
<c:otherwise>
Bar
</c:otherwise>
</c:choose>
<br/>
<b>4 - FooBarBar - </b>
<c:choose>
<c:when test="${true}">
Foo
<c:choose>
<c:when test="${false}">
FooFoo
</c:when>
<c:otherwise>
BarBar
</c:otherwise>
</c:choose>
</c:when>
<c:otherwise>
Bar
</c:otherwise>
</c:choose>
<br/>
<b>5 - BarFooFoo - </b>
<c:choose>
<c:when test="${false}">
Foo
</c:when>
<c:otherwise>
Bar
<c:choose>
<c:when test="${true}">
FooFoo
</c:when>
<c:otherwise>
BarBar
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
<br/>
<b>6 - BarBarBar - </b>
<c:choose>
<c:when test="${false}">
Foo
</c:when>
<c:otherwise>
Bar
<c:choose>
<c:when test="${false}">
FooFoo
</c:when>
<c:otherwise>
BarBar
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
<br/>
</div>
</div>
</div>
<div>
Request headers:<br/>
<r:headers id="hdrs">
<jsp:getProperty name="hdrs" property="name"/> = <jsp:getProperty name="hdrs" property="header"/>
</r:headers>
<br/>
User-Agent:<br/>
<r:existsHeader name="User-Agent">
User-Agent=<r:header name="User-Agent"/>
</r:existsHeader>
<r:existsHeader name="User-Agent" value="false">
No User-Agent
</r:existsHeader>
<br/>
Request parameters:<br/>
<r:parameters id="param">
<jsp:getProperty name="param" property="name"/> = <jsp:getProperty name="param" property="value"/>
</r:parameters>
<br/>
Request attributes:<br/>
<r:attributes id="att">
<jsp:getProperty name="att" property="name"/> = <jsp:getProperty name="att" property="value"/>
</r:attributes>
<br/>
</div>
<div>
Start set/out/if tests<br/>
<c:set var = "testvalue1" scope = "page" value = "${'value1'}" />
<c:set var = "testvalue2" scope = "page" value = "${'value2'}" />
<c:set var = "testvalue3" scope = "page" value = "${'value3'}" />
<c:set var = "testvalue4" scope = "page" value = "${'value4'}" />
<c:set var = "testvalue5" scope = "page" value = "${'value5'}" />
All test values:<br/>
testvalue1: <c:out default="" value="${testvalue1}" /><br/>
testvalue2: <c:out default="" value="${testvalue2}" /><br/>
testvalue3: <c:out default="" value="${testvalue3}" /><br/>
testvalue4: <c:out default="" value="${testvalue4}" /><br/>
testvalue5: <c:out default="" value="${testvalue5}" /><br/>
<c:if test="${testvalue1=='value1'}">
testvalue1 set/if worked.<br/>
</c:if>
<c:if test="${testvalue2=='value2'}">
testvalue2 set/if worked.<br/>
</c:if>
<c:if test="${testvalue3=='value3'}">
testvalue3 set/if worked.<br/>
</c:if>
<c:if test="${testvalue4=='value4'}">
testvalue4 set/if worked.<br/>
</c:if>
<c:if test="${testvalue5=='value5'}">
testvalue5 set/if worked.<br/>
</c:if>
<br/>
End set/out/if tests<br/>
</div>
<div>
<br/>
Start include tests<br/>
<jsp:include page="org/apache/struts2/simple0.jsp"/>
<jsp:include page="org/apache/struts2/sub/simple0.jsp"/>
<jsp:include page="org/apache/struts2/printParam.jsp">
<jsp:param name="username" value="JG"/>
</jsp:include>
<%@ include file="org/apache/struts2/simple0.jsp" %>
<jsp:include page="org/apache/struts2/scriptlet.jsp"/>
<jsp:include page="org/apache/struts2/tag0.jsp"/>
<jsp:include page="org/apache/struts2/beans.jsp"/>
<jsp:include page="org/apache/struts2/el.jsp"/>
<jsp:include page="org/apache/struts2/jstl.jsp"/>
<br/>
<br/>
End include tests<br/>
</div>
</body>
</html>
+11 -4
View File
@@ -759,8 +759,15 @@
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>jasper</artifactId>
<version>6.0.53</version>
<artifactId>tomcat-jasper</artifactId>
<version>8.5.37</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-api</artifactId>
<version>8.5.37</version>
<scope>provided</scope>
</dependency>
@@ -836,8 +843,8 @@
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>juli</artifactId>
<version>6.0.53</version>
<artifactId>tomcat-juli</artifactId>
<version>8.5.37</version>
</dependency>
<!-- Commons -->