diff --git a/plugins/embeddedjsp/pom.xml b/plugins/embeddedjsp/pom.xml
index cba2e1ced..9e69fcad7 100644
--- a/plugins/embeddedjsp/pom.xml
+++ b/plugins/embeddedjsp/pom.xml
@@ -68,7 +68,7 @@
org.apache.tomcat
- juli
+ tomcat-juli
taglibs
@@ -82,7 +82,7 @@
org.apache.tomcat
- jasper
+ tomcat-jasper
provided
diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java
index e1c048cc9..713fcb848 100644
--- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java
+++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPLoader.java
@@ -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 optionList = new ArrayList();
Set classPath = new HashSet();
- 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 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
}
diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPRuntime.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPRuntime.java
index ab9152846..1a47a4d00 100644
--- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPRuntime.java
+++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/JSPRuntime.java
@@ -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 -> 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 queryParams = urlHelper.parseQueryString(query, true);
if (queryParams != null && !queryParams.isEmpty()) {
diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/Generator.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/Generator.java
index 6a8ab7272..5327afcc8 100644
--- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/Generator.java
+++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/Generator.java
@@ -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(");");
diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/AnnotationHelper.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/AnnotationHelper.java
deleted file mode 100644
index 709d3c400..000000000
--- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/AnnotationHelper.java
+++ /dev/null
@@ -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);
- }
- }
-
-
-}
diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/InstanceHelper.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/InstanceHelper.java
new file mode 100644
index 000000000..7be48a920
--- /dev/null
+++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/InstanceHelper.java
@@ -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 INSTANCE_MANAGERS =
+ Collections.synchronizedMap(new WeakHashMap());
+
+
+ /**
+ * Private constructor (all methods static, no instance required)
+ */
+ private InstanceHelper() {}
+
+ /**
+ * Get the {@link InstanceManager} instance manager for a given
+ * {@link ServletConfig}.
+ *
+ * For any non-null servletConfig with a non-null {@link ServletContext},
+ * if no instance manager is defined, this method will produce a
+ * {@link SimpleInstanceManager} and associate it with that
+ * {@link ServletConfig} and its {@link ClassLoader}.
+ *
+ * @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 {@link InstanceManager} instance manager for a given
+ * {@link ClassLoader} instance, stored within the
+ * {@link InstanceHelper} {@link Map}.
+ *
+ * For any non-null classLoader, if no instance manager is defined,
+ * this method will produce a {@link SimpleInstanceManager}
+ * and associate it with that {@link ClassLoader}.
+ *
+ * @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 {@link InstanceManager} instance manager for a given
+ * {@link ClassLoader} instance, stored within the
+ * {@link InstanceHelper} {@link Map}.
+ *
+ * @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 {@link Object} using
+ * the provided {@link InstanceManager}.
+ *
+ * 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 {@link Object} previously post-constructed
+ * with the provided {@link InstanceManager}.
+ *
+ * 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);
+ }
+ }
+
+}
diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/TagHandlerPool.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/TagHandlerPool.java
index 2cc506f5e..c93de922c 100644
--- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/TagHandlerPool.java
+++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/runtime/TagHandlerPool.java
@@ -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);
diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspCServletContext.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspCServletContext.java
index cfbcd81f9..94fee5469 100644
--- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspCServletContext.java
+++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspCServletContext.java
@@ -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 createServlet(Class arg0) throws ServletException {
+ return (null);
+ }
+
+ @Override
+ public ServletRegistration getServletRegistration(String arg0) {
+ return (null);
+ }
+
+ @Override
+ public Map 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 createFilter(Class arg0) throws ServletException {
+ return (null);
+ }
+
+ @Override
+ public FilterRegistration getFilterRegistration(String arg0) {
+ return (null);
+ }
+
+ @Override
+ public Map getFilterRegistrations() {
+ return (null);
+ }
+
+ @Override
+ public SessionCookieConfig getSessionCookieConfig() {
+ return (null);
+ }
+
+ @Override
+ public void setSessionTrackingModes(Set arg0) {
+ return;
+ }
+
+ @Override
+ public Set getDefaultSessionTrackingModes() {
+ return (null);
+ }
+
+ @Override
+ public Set getEffectiveSessionTrackingModes() {
+ return (null);
+ }
+
+ @Override
+ public void addListener(String arg0) {
+ return;
+ }
+
+ @Override
+ public void addListener(T arg0) {
+ return;
+ }
+
+ @Override
+ public void addListener(Class extends EventListener> arg0) {
+ return;
+ }
+
+ @Override
+ public T createListener(Class 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");
+ }
}
diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspServlet.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspServlet.java
index 40ebac90c..fbe23424b 100644
--- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspServlet.java
+++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspServlet.java
@@ -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).
diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspServletWrapper.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspServletWrapper.java
index 9e118cbc7..8a04b2eea 100644
--- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspServletWrapper.java
+++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/servlet/JspServletWrapper.java
@@ -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",
diff --git a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/tagplugins/jstl/Util.java b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/tagplugins/jstl/Util.java
index 8ba6b66e9..4896a2fae 100644
--- a/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/tagplugins/jstl/Util.java
+++ b/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/tagplugins/jstl/Util.java
@@ -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;
diff --git a/plugins/embeddedjsp/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java b/plugins/embeddedjsp/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
index dbc807011..7d96f9ba2 100644
--- a/plugins/embeddedjsp/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
+++ b/plugins/embeddedjsp/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
@@ -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("Struts2 Embedded JSP Plugin - Complex Test Page");
+ 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
");
+ int lastHtmlIndex = responseString.indexOf("