diff --git a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java index 6a420858494..17dff8cca6c 100644 --- a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java +++ b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyJasperInitializer.java @@ -27,11 +27,9 @@ import java.util.List; import javax.servlet.ServletContext; import org.apache.jasper.servlet.JasperInitializer; -import org.apache.jasper.servlet.TldPreScanned; import org.apache.jasper.servlet.TldScanner; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; - import org.xml.sax.SAXException; /** @@ -105,7 +103,7 @@ public class JettyJasperInitializer extends JasperInitializer if (tldUrls != null) { if (LOG.isDebugEnabled()) LOG.debug("Tld pre-scan detected"); - return new TldPreScanned(context,namespaceAware,validate,blockExternal,tldUrls); + return new JettyTldPreScanned(context,namespaceAware,validate,blockExternal,tldUrls); } if (LOG.isDebugEnabled()) LOG.debug("Defaulting to jasper tld scanning"); diff --git a/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyTldPreScanned.java b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyTldPreScanned.java new file mode 100644 index 00000000000..e4042909c3d --- /dev/null +++ b/apache-jsp/src/main/java/org/eclipse/jetty/apache/jsp/JettyTldPreScanned.java @@ -0,0 +1,106 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.apache.jsp; + +import java.net.URL; +import java.util.Collection; + +import javax.servlet.ServletContext; + +import org.apache.jasper.servlet.TldPreScanned; +import org.apache.tomcat.util.descriptor.tld.TldResourcePath; + +/** + * JettyTldPreScanned + * + * Change to TldPreScanned to not require that the tlds have been + * pre-scanned from a jar file, but rather may be files in the + * file system. + * + * This is important for running in the jetty maven plugin + * environment in multi-module builds, where modules that contain tlds + * may be in the reactor at the same time as a webapp being run with the + * plugin. That means that the tlds will be used from their location in + * the file system, rather than from their assembled jar. + * + */ +public class JettyTldPreScanned extends TldPreScanned +{ + private final Collection _jettyPreScannedURLs; + + /** + * @param context + * @param namespaceAware + * @param validation + * @param blockExternal + * @param preScannedTlds + */ + public JettyTldPreScanned(ServletContext context, boolean namespaceAware, boolean validation, boolean blockExternal, Collection preScannedTlds) + { + super(context, namespaceAware, validation, blockExternal, preScannedTlds); + _jettyPreScannedURLs = preScannedTlds; + } + + /** + * @see org.apache.jasper.servlet.TldPreScanned#scanJars() + */ + @Override + public void scanJars() + { + if (_jettyPreScannedURLs != null) + { + for (URL url : _jettyPreScannedURLs) + { + String str = url.toExternalForm(); + int a = str.indexOf("jar:"); + int b = str.indexOf("META-INF"); + if (b < 0) + throw new IllegalStateException("Bad tld url: "+str); + + String path = str.substring(b); + if (a >= 0) + { + int c = str.indexOf("!/"); + String fileUrl = str.substring(a + 4, c); + try + { + parseTld(new TldResourcePath(new URL(fileUrl), null, path)); + } + catch (Exception e) + { + throw new IllegalStateException(e); + } + } + else + { + try + { + parseTld(new TldResourcePath(url, null, null)); + } + catch (Exception e) + { + throw new IllegalStateException(e); + } + } + } + } + } + +} diff --git a/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyTldPreScanned.java b/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyTldPreScanned.java new file mode 100644 index 00000000000..21c37dd3d7b --- /dev/null +++ b/apache-jsp/src/test/java/org/eclipse/jetty/jsp/TestJettyTldPreScanned.java @@ -0,0 +1,74 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.jsp; + +import static org.junit.Assert.*; + +import java.io.File; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.tomcat.util.descriptor.tld.TaglibXml; +import org.apache.tomcat.util.descriptor.tld.TldResourcePath; +import org.eclipse.jetty.apache.jsp.JettyTldPreScanned; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.Test; + +/** + * TestJettyTldPreScanned + * + * + */ +public class TestJettyTldPreScanned +{ + + /** + * Test that a tld inside a jar can be scanned, as can a tld not inside a jar. + */ + @Test + public void testIt() + throws Exception + { + File jar = MavenTestingUtils.getTestResourceFile("taglib.jar"); + File tld = MavenTestingUtils.getTestResourceFile("META-INF/foo-taglib.tld"); + + List list = new ArrayList<>(); + list.add(new URL("jar:"+jar.toURI().toURL().toString()+"!/META-INF/bar-taglib.tld")); + list.add(tld.toURI().toURL()); + + JettyTldPreScanned preScanned = new JettyTldPreScanned(new ServletContextHandler().getServletContext(),false,false,false,list); + preScanned.scanJars(); + Map map = preScanned.getTldResourcePathTaglibXmlMap(); + assertNotNull(map); + assertEquals(2, map.size()); + for (TldResourcePath p: map.keySet()) + { + URL u = p.getUrl(); + TaglibXml tlx = map.get(p); + assertNotNull(tlx); + if (!"foo".equals(tlx.getShortName()) && !"bar".equals(tlx.getShortName())) + fail("unknown tag"); + } + } + +} diff --git a/apache-jsp/src/test/resources/META-INF/foo-taglib.tld b/apache-jsp/src/test/resources/META-INF/foo-taglib.tld new file mode 100644 index 00000000000..f13333980ce --- /dev/null +++ b/apache-jsp/src/test/resources/META-INF/foo-taglib.tld @@ -0,0 +1,25 @@ + + + + + + 1.0 + 1.2 + foo + http://www.foo.com/taglib + foo example + + + foodate + com.foo.DateTag + TAGDEPENDENT + Display Date + + tz + false + + + + diff --git a/apache-jsp/src/test/resources/taglib.jar b/apache-jsp/src/test/resources/taglib.jar new file mode 100644 index 00000000000..af1aa0c1186 Binary files /dev/null and b/apache-jsp/src/test/resources/taglib.jar differ