Author: markt Date: Mon Sep 14 12:39:45 2009 New Revision: 814617 URL: http://svn.apache.org/viewvc?rev=814617&view=rev Log: Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=47834 As well as the JAR as directory feature requested, this adds looking at all files to see if they are JARs rather than using the presence of a .jar extension. These features are optional for the Servlet spec but required for RFC66 in an OSGI environment. Both options are configurable with system properties and default to off.
Modified: tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/startup/TldConfig.java tomcat/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java tomcat/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java tomcat/trunk/webapps/docs/config/systemprops.xml Modified: tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties?rev=814617&r1=814616&r2=814617&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties Mon Sep 14 12:39:45 2009 @@ -94,6 +94,7 @@ tldConfig.cce=Lifecycle event data object {0} is not a Context tldConfig.classloaderFail=Failed to process ''{0}'' for TLDs. tldConfig.classloaderStart=Scanning for TLDs in classloader hierarchy +tldConfig.dirScan=Scanning for TLD files in directory ''{0}'' tldConfig.execute=Error processing TLD files for context path {0} tldConfig.jarUrlStart=Scanning for TLD files in URL ''{0}'' tldConfig.webinflibStart=Scanning WEB-INF/lib for JARs containing META-INF/**/*.TLD Modified: tomcat/trunk/java/org/apache/catalina/startup/TldConfig.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/TldConfig.java?rev=814617&r1=814616&r2=814617&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/startup/TldConfig.java (original) +++ tomcat/trunk/java/org/apache/catalina/startup/TldConfig.java Mon Sep 14 12:39:45 2009 @@ -19,9 +19,12 @@ package org.apache.catalina.startup; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.JarURLConnection; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; @@ -69,6 +72,16 @@ "org.apache.jasper.compiler.TldLocationsCache.SCAN_CLASSPATH", "true")).booleanValue(); + private static final boolean SCAN_ALL_FILES = Boolean.valueOf( + System.getProperty( + "org.apache.jasper.compiler.TldLocationsCache.SCAN_ALL_FILES", + "false")).booleanValue(); + + private static final boolean SCAN_ALL_DIRS = Boolean.valueOf( + System.getProperty( + "org.apache.jasper.compiler.TldLocationsCache.SCAN_ALL_DIRS", + "false")).booleanValue(); + // Names of JARs that are known not to contain any TLDs private static HashSet<String> noTldJars; @@ -564,10 +577,73 @@ tldScanJar((JarURLConnection) conn); } else { String urlStr = url.toString(); - if (urlStr.startsWith("file:") - && urlStr.endsWith(JAR_EXT)) { - URL jarURL = new URL("jar:" + urlStr + "!/"); - tldScanJar((JarURLConnection) jarURL.openConnection()); + if (urlStr.startsWith("file:")) { + if (urlStr.endsWith(JAR_EXT)) { + URL jarURL = new URL("jar:" + urlStr + "!/"); + tldScanJar((JarURLConnection) jarURL.openConnection()); + } else { + File f; + try { + f = new File(url.toURI()); + if (f.isFile() && SCAN_ALL_FILES) { + // Treat this file as a JAR + URL jarURL = new URL("jar:" + urlStr + "!/"); + tldScanJar((JarURLConnection) jarURL.openConnection()); + } else if (f.isDirectory() && SCAN_ALL_DIRS) { + File metainf = new File(f.getAbsoluteFile() + + File.separator + "META-INF"); + if (metainf.isDirectory()) { + tldScanDir(metainf); + } + } + } catch (URISyntaxException e) { + // Wrap the exception and re-throw + IOException ioe = new IOException(); + ioe.initCause(e); + throw ioe; + } + } + } + } + } + + /* + * Scans the directory identified by startPath, along with its + * sub-directories, for TLDs. + * + * Keep in sync with o.a.j.comiler.TldLocationsCache + */ + private void tldScanDir(File start) { + + if (log.isTraceEnabled()) { + log.trace(sm.getString("tldConfig.dirScan", start.getAbsolutePath())); + } + + File[] fileList = start.listFiles(); + if (fileList != null) { + for (int i = 0; i < fileList.length; i++) { + // Scan recursively + if (fileList[i].isDirectory()) { + tldScanDir(fileList[i]); + } else if (fileList[i].getAbsolutePath().endsWith(TLD_EXT)) { + InputStream stream = null; + try { + stream = new FileInputStream(fileList[i]); + tldScanStream(stream); + } catch (IOException ioe) { + log.warn(sm.getString("tldConfig.dirFail", + fileList[i].getAbsolutePath()), + ioe); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (Throwable t) { + // do nothing + } + } + } + } } } } Modified: tomcat/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java?rev=814617&r1=814616&r2=814617&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java (original) +++ tomcat/trunk/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java Mon Sep 14 12:39:45 2009 @@ -17,6 +17,7 @@ package org.apache.jasper.compiler; +import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; @@ -111,20 +112,24 @@ // the following is a workaround until these problems are resolved. private InputStream getResourceAsStream(String uri) throws FileNotFoundException { - try { - // see if file exists on the filesystem first - String real = ctxt.getRealPath(uri); - if (real == null) { + // Is uri absolute? + if (uri.startsWith("file:")) { + return new FileInputStream(new File(uri.substring(5))); + } else { + try { + // see if file exists on the filesystem + String real = ctxt.getRealPath(uri); + if (real == null) { + return ctxt.getResourceAsStream(uri); + } else { + return new FileInputStream(real); + } + } catch (FileNotFoundException ex) { + // if file not found on filesystem, get the resource through + // the context return ctxt.getResourceAsStream(uri); - } else { - return new FileInputStream(real); } - } catch (FileNotFoundException ex) { - // if file not found on filesystem, get the resource through - // the context - return ctxt.getResourceAsStream(uri); } - } /** Modified: tomcat/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java?rev=814617&r1=814616&r2=814617&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java (original) +++ tomcat/trunk/java/org/apache/jasper/compiler/TldLocationsCache.java Mon Sep 14 12:39:45 2009 @@ -17,10 +17,13 @@ package org.apache.jasper.compiler; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.JarURLConnection; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; @@ -101,6 +104,16 @@ "org.apache.jasper.compiler.TldLocationsCache.SCAN_CLASSPATH", "true")).booleanValue(); + private static final boolean SCAN_ALL_FILES = Boolean.valueOf( + System.getProperty( + "org.apache.jasper.compiler.TldLocationsCache.SCAN_ALL_FILES", + "false")).booleanValue(); + + private static final boolean SCAN_ALL_DIRS = Boolean.valueOf( + System.getProperty( + "org.apache.jasper.compiler.TldLocationsCache.SCAN_ALL_DIRS", + "false")).booleanValue(); + // Names of JARs that are known not to contain any TLDs private static HashSet<String> noTldJars; @@ -478,10 +491,67 @@ tldScanJar((JarURLConnection) conn); } else { String urlStr = url.toString(); - if (urlStr.startsWith(FILE_PROTOCOL) - && urlStr.endsWith(JAR_EXT)) { - URL jarURL = new URL("jar:" + urlStr + "!/"); - tldScanJar((JarURLConnection) jarURL.openConnection()); + if (urlStr.startsWith("file:")) { + if (urlStr.endsWith(JAR_EXT)) { + URL jarURL = new URL("jar:" + urlStr + "!/"); + tldScanJar((JarURLConnection) jarURL.openConnection()); + } else { + File f; + try { + f = new File(url.toURI()); + if (f.isFile() && SCAN_ALL_FILES) { + // Treat this file as a JAR + URL jarURL = new URL("jar:" + urlStr + "!/"); + tldScanJar((JarURLConnection) jarURL.openConnection()); + tldScanJar((JarURLConnection) jarURL.openConnection()); + } else if (f.isDirectory() && SCAN_ALL_DIRS) { + File metainf = new File(f.getAbsoluteFile() + + File.separator + "META-INF"); + if (metainf.isDirectory()) { + tldScanDir(metainf); + } + } + } catch (URISyntaxException e) { + // Wrap the exception and re-throw + IOException ioe = new IOException(); + ioe.initCause(e); + throw ioe; + } + } + } + } + } + + /* + * Scans the directory identified by startPath, along with its + * sub-directories, for TLDs. + * + * Keep in sync with o.a.c.startup.TldConfig + */ + private void tldScanDir(File start) throws IOException { + + File[] fileList = start.listFiles(); + if (fileList != null) { + for (int i = 0; i < fileList.length; i++) { + // Scan recursively + if (fileList[i].isDirectory()) { + tldScanDir(fileList[i]); + } else if (fileList[i].getAbsolutePath().endsWith(TLD_EXT)) { + InputStream stream = null; + try { + stream = new FileInputStream(fileList[i]); + tldScanStream( + fileList[i].toURI().toString(), null, stream); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (Throwable t) { + // do nothing + } + } + } + } } } } Modified: tomcat/trunk/webapps/docs/config/systemprops.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/systemprops.xml?rev=814617&r1=814616&r2=814617&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/systemprops.xml (original) +++ tomcat/trunk/webapps/docs/config/systemprops.xml Mon Sep 14 12:39:45 2009 @@ -103,6 +103,23 @@ be used.</p> </property> + <property name="org.apache.jasper.compiler. TldLocationsCache.SCAN_ALL_FILES"> + <p>When scanning the class path for TLDs, should Jasper scan all files + as if they are JAR files even if they do not have a .jar file extension? + This is intended for use in embedded environments where custom + classloaders allow for archives on the classpath with non-standard file + extensions. If not specified, the default value of <code>false</code> will + be used.</p> + </property> + + <property name="org.apache.jasper.compiler. TldLocationsCache.SCAN_ALL_DIRS"> + <p>When scanning the class path for TLDs, should Jasper scan all + directories as if they are unpacked JAR files? This is intended for use in + embedded environments where custom classloaders allow for directories + representing unpacked WAR files on the classpath. If not specified, the + default value of <code>false</code> will be used.</p> + </property> + <property name="org.apache.jasper.runtime. BodyContentImpl.LIMIT_BUFFER"> <p>If <code>true</code>, any tag buffer that expands beyond <code>org.apache.jasper.Constants.DEFAULT_TAG_BUFFER_SIZE</code> will be --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org