improve classpath building and add test for JSTL
git-svn-id: https://svn.apache.org/repos/asf/struts/sandbox/trunk@801835 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/struts2-jsp-plugin/pom.xml b/struts2-jsp-plugin/pom.xml
index 94695ba..0562e3b 100644
--- a/struts2-jsp-plugin/pom.xml
+++ b/struts2-jsp-plugin/pom.xml
@@ -79,6 +79,19 @@
<version>1.0</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>taglibs</groupId>
+ <artifactId>standard</artifactId>
+ <version>1.1.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jstl</artifactId>
+ <version>1.1.2</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
<!--<build>
diff --git a/struts2-jsp-plugin/src/main/java/org/apache/struts2/JSPLoader.java b/struts2-jsp-plugin/src/main/java/org/apache/struts2/JSPLoader.java
index 3fa97c4..75e3bc7 100644
--- a/struts2-jsp-plugin/src/main/java/org/apache/struts2/JSPLoader.java
+++ b/struts2-jsp-plugin/src/main/java/org/apache/struts2/JSPLoader.java
@@ -21,8 +21,10 @@
package org.apache.struts2;
import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate;
+import com.opensymphony.xwork2.util.finder.UrlSet;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import com.opensymphony.xwork2.util.URLUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.xwork.StringUtils;
import org.apache.struts2.compiler.MemoryClassLoader;
@@ -45,7 +47,11 @@
import java.util.*;
/**
- * Uses jasper to extract a JSP from the classpath to a file and compile it
+ * Uses jasper to extract a JSP from the classpath to a file and compile it. The classpathc used for
+ * compilation is built by finding all the jar files using the current class loader (Thread), then adding
+ * the plugin jar and the jars that contain these classes:
+ * javax.servlet.Servlet
+ * javax.servlet.jsp.JspPage
*/
public class JSPLoader {
private static final Logger LOG = LoggerFactory.getLogger(JSPLoader.class);
@@ -95,7 +101,7 @@
* Compiles the given source code into java bytecode
*
*/
- private void compileJava(String className, final String source, Set<String> extraClassPath) {
+ private void compileJava(String className, final String source, Set<String> extraClassPath) throws IOException {
JavaCompiler compiler =
ToolProvider.getSystemJavaCompiler();
@@ -133,28 +139,34 @@
//build classpath
List<String> optionList = new ArrayList<String>();
- StringBuilder classPath = new StringBuilder();
- //this jar
- classPath.append(getJarUrl(EmbeddedJSPResult.class));
- classPath.append(";");
- //servlet api
- classPath.append(getJarUrl(Servlet.class));
- classPath.append(";");
- //jsp api
- classPath.append(getJarUrl(JspPage.class));
+ Set<String> classPath = new HashSet<String>();
- if (!extraClassPath.isEmpty())
- classPath.append(";");
+ //find available jars
+ UrlSet urlSet = new UrlSet(getClassLoaderInterface());
+ urlSet = urlSet.matching(".*?\\.jar(!/)?$");
+ List<URL> urls = urlSet.getUrls();
+ if (urls != null) {
+ for (URL url : urls) {
+ File file = FileUtils.toFile(URLUtil.normalizeToFileProtocol(url));
+ classPath.add(file.getAbsolutePath());
+ }
+ }
+
+
+ //this jar
+ classPath.add(getJarUrl(EmbeddedJSPResult.class));
+ //servlet api
+ classPath.add(getJarUrl(Servlet.class));
+ //jsp api
+ classPath.add(getJarUrl(JspPage.class));
//add extra classpath entries (jars where tlds were found will be here)
for (Iterator<String> iterator = extraClassPath.iterator(); iterator.hasNext();) {
String entry = iterator.next();
- classPath.append(entry);
- if (iterator.hasNext())
- classPath.append(";");
+ classPath.add(entry);
}
- optionList.addAll(Arrays.asList("-classpath", classPath.toString()));
+ optionList.addAll(Arrays.asList("-classpath", StringUtils.join(classPath, ";")));
//compile
@@ -177,8 +189,7 @@
private JspC compileJSP(String location) throws JasperException {
JspC jspC = new JspC();
- //TODO: get this from context so OSGI works
- jspC.setClassLoaderInterface(new ClassLoaderInterfaceDelegate(Thread.currentThread().getContextClassLoader()));
+ jspC.setClassLoaderInterface(getClassLoaderInterface());
jspC.setCompile(false);
jspC.setJspFiles(location);
jspC.setPackage(DEFAULT_PACKAGE);
@@ -186,6 +197,11 @@
return jspC;
}
+ private ClassLoaderInterfaceDelegate getClassLoaderInterface() {
+ //TODO: get this from context so OSGI works
+ return new ClassLoaderInterfaceDelegate(Thread.currentThread().getContextClassLoader());
+ }
+
private static URI toURI(String name) {
try {
return new URI(name);
diff --git a/struts2-jsp-plugin/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java b/struts2-jsp-plugin/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
index 025a0ee..6663842 100644
--- a/struts2-jsp-plugin/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
+++ b/struts2-jsp-plugin/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
@@ -95,6 +95,13 @@
}
}
+ public void testJSTL() throws Exception {
+ result.setLocation("org/apache/struts2/jstl.jsp");
+ result.execute(null);
+
+ assertEquals("XXXXXXXXXXX", cleanup(response.getContentAsString()));
+ }
+
public void testCachedInstances() throws InterruptedException {
ServletCache cache = new ServletCache();
diff --git a/struts2-jsp-plugin/src/test/resources/org/apache/struts2/jstl.jsp b/struts2-jsp-plugin/src/test/resources/org/apache/struts2/jstl.jsp
new file mode 100644
index 0000000..63b586a
--- /dev/null
+++ b/struts2-jsp-plugin/src/test/resources/org/apache/struts2/jstl.jsp
@@ -0,0 +1,6 @@
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+
+<c:set var="number" value="10"/>
+<c:forEach begin="0" end="${number}">
+X
+</c:forEach>
\ No newline at end of file