From 970ffa2b6b82db4bd9138a4ee4b4ca779ff561f5 Mon Sep 17 00:00:00 2001 From: markt Date: Thu, 13 May 2010 12:19:43 +0000 Subject: [PATCH] Identify source of TLD validation errors to aid debugging git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@943872 13f79535-47bb-0310-9956-ffa450edef68 --- .../catalina/startup/LocalStrings.properties | 3 + java/org/apache/catalina/startup/TldConfig.java | 82 ++++++++++++++++++++-- 2 files changed, 78 insertions(+), 7 deletions(-) diff --git a/java/org/apache/catalina/startup/LocalStrings.properties b/java/org/apache/catalina/startup/LocalStrings.properties index c9af91a43..a5c3f6feb 100644 --- a/java/org/apache/catalina/startup/LocalStrings.properties +++ b/java/org/apache/catalina/startup/LocalStrings.properties @@ -105,6 +105,9 @@ tldConfig.cce=Lifecycle event data object {0} is not a Context tldConfig.dirFail=Failed to process directory [{0}] for TLD files tldConfig.dirScan=Scanning for TLD files in directory [{0}] tldConfig.execute=Error processing TLD files for context path {0} +tldConfig.handlerError=Non-fatal error [{0}] reported processing [{1}]. +tldConfig.handlerWarning=Warning [{0}] reported processing [{1}]. +tldConfig.jarFail=Failed to process JAR [{0}] for TLD files tldConfig.webinfFail=Failed to process TLD found at [{0}] tldConfig.webinfScan=Scanning WEB-INF for TLD files in [{0}] tldConfig.webxmlAdd=Adding path [{0}] for URI [{1}] diff --git a/java/org/apache/catalina/startup/TldConfig.java b/java/org/apache/catalina/startup/TldConfig.java index 54f71e723..da190e37c 100644 --- a/java/org/apache/catalina/startup/TldConfig.java +++ b/java/org/apache/catalina/startup/TldConfig.java @@ -47,8 +47,10 @@ import org.apache.tomcat.JarScannerCallback; import org.apache.tomcat.util.ExceptionUtils; import org.apache.tomcat.util.res.StringManager; import org.apache.tomcat.util.digester.Digester; +import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; /** @@ -344,6 +346,43 @@ public final class TldConfig implements LifecycleListener { } } + private static class TldErrorHandler implements ErrorHandler { + + private Set errors = + new HashSet(); + + private Set warnings = + new HashSet(); + + @Override + public void error(SAXParseException exception) throws SAXException { + // Collect non-fatal errors + errors.add(exception); + } + + @Override + public void fatalError(SAXParseException exception) throws SAXException { + // Re-throw fatal errors + throw exception; + } + + @Override + public void warning(SAXParseException exception) throws SAXException { + // Collect warnings + warnings.add(exception); + } + + public Set getErrors() { + // Internal use only - don't worry about immutability + return errors; + } + + public Set getWarnings() { + // Internal use only - don't worry about immutability + return warnings; + } + } + // -------------------------------------------------------- Private Methods @@ -383,7 +422,8 @@ public final class TldConfig implements LifecycleListener { try { InputStream stream = context.getServletContext( ).getResourceAsStream(resourcePath); - tldScanStream(stream); + TldErrorHandler handler = tldScanStream(stream); + processErrorHandler(handler, resourcePath); taglibUris.add(descriptor.getTaglibURI()); webxmlTaglibUris.add(descriptor.getTaglibURI()); } catch (IOException ioe) { @@ -429,7 +469,8 @@ public final class TldConfig implements LifecycleListener { } InputStream stream = ctxt.getResourceAsStream(path); try { - tldScanStream(stream); + TldErrorHandler handler = tldScanStream(stream); + processErrorHandler(handler, path); } catch (IOException ioe) { log.warn(sm.getString("tldConfig.webinfFail", path), ioe); @@ -471,7 +512,9 @@ public final class TldConfig implements LifecycleListener { InputStream stream = null; try { stream = new FileInputStream(fileList[i]); - tldScanStream(stream); + TldErrorHandler handler = tldScanStream(stream); + processErrorHandler(handler, + fileList[i].getAbsolutePath()); } catch (IOException ioe) { log.warn(sm.getString("tldConfig.dirFail", fileList[i].getAbsolutePath()), @@ -498,21 +541,26 @@ public final class TldConfig implements LifecycleListener { * * Keep in sync with o.a.j.comiler.TldLocationsCache */ - private void tldScanJar(JarURLConnection conn) throws IOException { + private void tldScanJar(JarURLConnection conn) { JarFile jarFile = null; + String name = null; try { conn.setUseCaches(false); jarFile = conn.getJarFile(); Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); - String name = entry.getName(); + name = entry.getName(); if (!name.startsWith("META-INF/")) continue; if (!name.endsWith(".tld")) continue; InputStream stream = jarFile.getInputStream(entry); - tldScanStream(stream); + TldErrorHandler handler = tldScanStream(stream); + processErrorHandler(handler, conn.getURL() + name); } + } catch (IOException ioe) { + log.warn(sm.getString("tldConfig.jarFail", conn.getURL() + name), + ioe); } finally { if (jarFile != null) { try { @@ -526,6 +574,21 @@ public final class TldConfig implements LifecycleListener { /* + * Log the non-fatal errors and warnings + */ + private void processErrorHandler(TldErrorHandler handler, String source) { + for (SAXParseException e : handler.getWarnings()) { + log.warn(sm.getString( + "tldConfig.handlerWarning", e.getMessage(), source)); + } + for (SAXParseException e : handler.getErrors()) { + log.warn(sm.getString( + "tldConfig.handlerError", e.getMessage(), source)); + } + } + + + /* * Scan the TLD contents in the specified input stream, and register * any application event listeners found there. NOTE - This * method ensure that the InputStream is correctly closed. @@ -534,12 +597,16 @@ public final class TldConfig implements LifecycleListener { * * @throws IOException If the file cannot be read */ - private void tldScanStream(InputStream resourceStream) throws IOException { + private TldErrorHandler tldScanStream(InputStream resourceStream) + throws IOException { InputSource source = new InputSource(resourceStream); + TldErrorHandler result = new TldErrorHandler(); + synchronized (tldDigester) { try { + tldDigester.setErrorHandler(result); tldDigester.push(this); tldDigester.parse(source); } catch (SAXException s) { @@ -555,6 +622,7 @@ public final class TldConfig implements LifecycleListener { } } } + return result; } } -- 2.11.0