[ 
https://issues.apache.org/jira/browse/GERONIMO-6534?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

xiezhi updated GERONIMO-6534:
-----------------------------
    Description: 
The method ScanJar and ScanJars are from GeronimoTldLocationsCache.java. I 
think it has not been well thought over. The error or exception which raised in 
scanning entry files should not be past. I actually met a problem when failed 
to get uri from a tld file because of some validation reason. There is no 
exception or any other error message. It took a lot of time to find the root 
cause in debug model.
I think it is not a good practice to ignore the exceptions here.

    /**
     * Scans the given JarURLConnection for TLD files located in META-INF
     * (or a subdirectory of it), adding an implicit map entry to the taglib
     * map for any TLD that has a <uri> element.
     *
     * @param conn The JarURLConnection to the JAR file to scan
     * @param ignore true if any exceptions raised when processing the given
     * JAR should be ignored, false otherwise
     */
    private void scanJar(JarURLConnection conn, boolean ignore)
                throws JasperException {

        JarFile jarFile = null;
        String resourcePath = conn.getJarFileURL().toString();
        try {
            if (redeployMode) {
                conn.setUseCaches(false);
            }
            jarFile = conn.getJarFile();
            Enumeration entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = (JarEntry) entries.nextElement();
                String name = entry.getName();
                if (!name.startsWith("META-INF/")) continue;
                if (!name.endsWith(".tld")) continue;
                InputStream stream = jarFile.getInputStream(entry);
                try {
                    String uri = getUriFromTld(resourcePath, stream);
                    // Add implicit map entry only if its uri is not already
                    // present in the map
                    if (uri != null && mappings.get(uri) == null) {
                        mappings.put(uri, new String[]{ resourcePath, name });
                    }
                } finally {
                    if (stream != null) {
                        try {
                            stream.close();
                        } catch (Throwable t) {
                            // do nothing
                        }
                    }
                }
            }
        } catch (Exception ex) {
            if (!redeployMode) {
                // if not in redeploy mode, close the jar in case of an error
                if (jarFile != null) {
                    try {
                        jarFile.close();
                    } catch (Throwable t) {
                        // ignore
                    }
                }
            }
            if (!ignore) {
                throw new JasperException(ex);
            }
        } finally {
            if (redeployMode) {
                // if in redeploy mode, always close the jar
                if (jarFile != null) {
                    try {
                        jarFile.close();
                    } catch (Throwable t) {
                        // ignore
                    }
                }
            }
        }
    }
        
------------------------------------------------------------------------------------------
      
            /*
     * Scans all JARs accessible to the webapp's classloader and its
     * parent classloaders for TLDs.
     * 
     * The list of JARs always includes the JARs under WEB-INF/lib, as well as
     * all shared JARs in the classloader delegation chain of the webapp's
     * classloader.
     *
     * Considering JARs in the classloader delegation chain constitutes a
     * Tomcat-specific extension to the TLD search
     * order defined in the JSP spec. It allows tag libraries packaged as JAR
     * files to be shared by web applications by simply dropping them in a 
     * location that all web applications have access to (e.g.,
     * <CATALINA_HOME>/common/lib).
     *
     * The set of shared JARs to be scanned for TLDs is narrowed down by
     * the <tt>noTldJars</tt> class variable, which contains the names of JARs
     * that are known not to contain any TLDs.
     */
    private void scanJars() throws Exception {

        ClassLoader webappLoader
            = Thread.currentThread().getContextClassLoader();
        ClassLoader loader = webappLoader;

        while (loader != null) {
            if (loader instanceof URLClassLoader) {
                URL[] urls = ((URLClassLoader) loader).getURLs();
                for (int i=0; i<urls.length; i++) {
                    URLConnection conn = urls[i].openConnection();
                    if (conn instanceof JarURLConnection) {
                        if (needScanJar(loader, webappLoader,
                                        ((JarURLConnection) 
conn).getJarFile().getName())) {
                            scanJar((JarURLConnection) conn, true);
                        }
                    } else {
                        String urlStr = urls[i].toString();
                        if (urlStr.startsWith(FILE_PROTOCOL)
                                && urlStr.endsWith(JAR_FILE_SUFFIX)
                                && needScanJar(loader, webappLoader, urlStr)) {
                            URL jarURL = new URL("jar:" + urlStr + "!/");
                            scanJar((JarURLConnection) jarURL.openConnection(),
                                    true);
                        }
                    }
                }
            }

            loader = loader.getParent();
        }
    }

  was:
The method ScanJar and ScanJars are from GeronimoTldLocationsCache.java. I 
think it has not been well thought out. The error or exception which raised in 
scanning entry files should not be past. I actually met a problem when failed 
to get uri from a tld file because of some validation reason. There is no 
exception or any other error message. It took a lot of time to find the root 
cause in debug model.
I think it is not a good practice to ignore the exceptions here.

    /**
     * Scans the given JarURLConnection for TLD files located in META-INF
     * (or a subdirectory of it), adding an implicit map entry to the taglib
     * map for any TLD that has a <uri> element.
     *
     * @param conn The JarURLConnection to the JAR file to scan
     * @param ignore true if any exceptions raised when processing the given
     * JAR should be ignored, false otherwise
     */
    private void scanJar(JarURLConnection conn, boolean ignore)
                throws JasperException {

        JarFile jarFile = null;
        String resourcePath = conn.getJarFileURL().toString();
        try {
            if (redeployMode) {
                conn.setUseCaches(false);
            }
            jarFile = conn.getJarFile();
            Enumeration entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = (JarEntry) entries.nextElement();
                String name = entry.getName();
                if (!name.startsWith("META-INF/")) continue;
                if (!name.endsWith(".tld")) continue;
                InputStream stream = jarFile.getInputStream(entry);
                try {
                    String uri = getUriFromTld(resourcePath, stream);
                    // Add implicit map entry only if its uri is not already
                    // present in the map
                    if (uri != null && mappings.get(uri) == null) {
                        mappings.put(uri, new String[]{ resourcePath, name });
                    }
                } finally {
                    if (stream != null) {
                        try {
                            stream.close();
                        } catch (Throwable t) {
                            // do nothing
                        }
                    }
                }
            }
        } catch (Exception ex) {
            if (!redeployMode) {
                // if not in redeploy mode, close the jar in case of an error
                if (jarFile != null) {
                    try {
                        jarFile.close();
                    } catch (Throwable t) {
                        // ignore
                    }
                }
            }
            if (!ignore) {
                throw new JasperException(ex);
            }
        } finally {
            if (redeployMode) {
                // if in redeploy mode, always close the jar
                if (jarFile != null) {
                    try {
                        jarFile.close();
                    } catch (Throwable t) {
                        // ignore
                    }
                }
            }
        }
    }
        
------------------------------------------------------------------------------------------
      
            /*
     * Scans all JARs accessible to the webapp's classloader and its
     * parent classloaders for TLDs.
     * 
     * The list of JARs always includes the JARs under WEB-INF/lib, as well as
     * all shared JARs in the classloader delegation chain of the webapp's
     * classloader.
     *
     * Considering JARs in the classloader delegation chain constitutes a
     * Tomcat-specific extension to the TLD search
     * order defined in the JSP spec. It allows tag libraries packaged as JAR
     * files to be shared by web applications by simply dropping them in a 
     * location that all web applications have access to (e.g.,
     * <CATALINA_HOME>/common/lib).
     *
     * The set of shared JARs to be scanned for TLDs is narrowed down by
     * the <tt>noTldJars</tt> class variable, which contains the names of JARs
     * that are known not to contain any TLDs.
     */
    private void scanJars() throws Exception {

        ClassLoader webappLoader
            = Thread.currentThread().getContextClassLoader();
        ClassLoader loader = webappLoader;

        while (loader != null) {
            if (loader instanceof URLClassLoader) {
                URL[] urls = ((URLClassLoader) loader).getURLs();
                for (int i=0; i<urls.length; i++) {
                    URLConnection conn = urls[i].openConnection();
                    if (conn instanceof JarURLConnection) {
                        if (needScanJar(loader, webappLoader,
                                        ((JarURLConnection) 
conn).getJarFile().getName())) {
                            scanJar((JarURLConnection) conn, true);
                        }
                    } else {
                        String urlStr = urls[i].toString();
                        if (urlStr.startsWith(FILE_PROTOCOL)
                                && urlStr.endsWith(JAR_FILE_SUFFIX)
                                && needScanJar(loader, webappLoader, urlStr)) {
                            URL jarURL = new URL("jar:" + urlStr + "!/");
                            scanJar((JarURLConnection) jarURL.openConnection(),
                                    true);
                        }
                    }
                }
            }

            loader = loader.getParent();
        }
    }


> A potential coding flaw makes scan jar fail without any error or exception
> --------------------------------------------------------------------------
>
>                 Key: GERONIMO-6534
>                 URL: https://issues.apache.org/jira/browse/GERONIMO-6534
>             Project: Geronimo
>          Issue Type: Improvement
>      Security Level: public(Regular issues) 
>          Components: Tomcat
>    Affects Versions: 2.1.8, 2.2.1
>            Reporter: xiezhi
>            Priority: Minor
>         Attachments: GERONIMO-6534.patch
>
>
> The method ScanJar and ScanJars are from GeronimoTldLocationsCache.java. I 
> think it has not been well thought over. The error or exception which raised 
> in scanning entry files should not be past. I actually met a problem when 
> failed to get uri from a tld file because of some validation reason. There is 
> no exception or any other error message. It took a lot of time to find the 
> root cause in debug model.
> I think it is not a good practice to ignore the exceptions here.
>     /**
>      * Scans the given JarURLConnection for TLD files located in META-INF
>      * (or a subdirectory of it), adding an implicit map entry to the taglib
>      * map for any TLD that has a <uri> element.
>      *
>      * @param conn The JarURLConnection to the JAR file to scan
>      * @param ignore true if any exceptions raised when processing the given
>      * JAR should be ignored, false otherwise
>      */
>     private void scanJar(JarURLConnection conn, boolean ignore)
>                 throws JasperException {
>         JarFile jarFile = null;
>         String resourcePath = conn.getJarFileURL().toString();
>         try {
>             if (redeployMode) {
>                 conn.setUseCaches(false);
>             }
>             jarFile = conn.getJarFile();
>             Enumeration entries = jarFile.entries();
>             while (entries.hasMoreElements()) {
>                 JarEntry entry = (JarEntry) entries.nextElement();
>                 String name = entry.getName();
>                 if (!name.startsWith("META-INF/")) continue;
>                 if (!name.endsWith(".tld")) continue;
>                 InputStream stream = jarFile.getInputStream(entry);
>                 try {
>                     String uri = getUriFromTld(resourcePath, stream);
>                     // Add implicit map entry only if its uri is not already
>                     // present in the map
>                     if (uri != null && mappings.get(uri) == null) {
>                         mappings.put(uri, new String[]{ resourcePath, name });
>                     }
>                 } finally {
>                     if (stream != null) {
>                         try {
>                             stream.close();
>                         } catch (Throwable t) {
>                             // do nothing
>                         }
>                     }
>                 }
>             }
>         } catch (Exception ex) {
>             if (!redeployMode) {
>                 // if not in redeploy mode, close the jar in case of an error
>                 if (jarFile != null) {
>                     try {
>                         jarFile.close();
>                     } catch (Throwable t) {
>                         // ignore
>                     }
>                 }
>             }
>             if (!ignore) {
>                 throw new JasperException(ex);
>             }
>         } finally {
>             if (redeployMode) {
>                 // if in redeploy mode, always close the jar
>                 if (jarFile != null) {
>                     try {
>                         jarFile.close();
>                     } catch (Throwable t) {
>                         // ignore
>                     }
>                 }
>             }
>         }
>     }
>       
> ------------------------------------------------------------------------------------------
>     
>           /*
>      * Scans all JARs accessible to the webapp's classloader and its
>      * parent classloaders for TLDs.
>      * 
>      * The list of JARs always includes the JARs under WEB-INF/lib, as well as
>      * all shared JARs in the classloader delegation chain of the webapp's
>      * classloader.
>      *
>      * Considering JARs in the classloader delegation chain constitutes a
>      * Tomcat-specific extension to the TLD search
>      * order defined in the JSP spec. It allows tag libraries packaged as JAR
>      * files to be shared by web applications by simply dropping them in a 
>      * location that all web applications have access to (e.g.,
>      * <CATALINA_HOME>/common/lib).
>      *
>      * The set of shared JARs to be scanned for TLDs is narrowed down by
>      * the <tt>noTldJars</tt> class variable, which contains the names of JARs
>      * that are known not to contain any TLDs.
>      */
>     private void scanJars() throws Exception {
>         ClassLoader webappLoader
>             = Thread.currentThread().getContextClassLoader();
>         ClassLoader loader = webappLoader;
>         while (loader != null) {
>             if (loader instanceof URLClassLoader) {
>                 URL[] urls = ((URLClassLoader) loader).getURLs();
>                 for (int i=0; i<urls.length; i++) {
>                     URLConnection conn = urls[i].openConnection();
>                     if (conn instanceof JarURLConnection) {
>                         if (needScanJar(loader, webappLoader,
>                                         ((JarURLConnection) 
> conn).getJarFile().getName())) {
>                             scanJar((JarURLConnection) conn, true);
>                         }
>                     } else {
>                         String urlStr = urls[i].toString();
>                         if (urlStr.startsWith(FILE_PROTOCOL)
>                                 && urlStr.endsWith(JAR_FILE_SUFFIX)
>                                 && needScanJar(loader, webappLoader, urlStr)) 
> {
>                             URL jarURL = new URL("jar:" + urlStr + "!/");
>                             scanJar((JarURLConnection) 
> jarURL.openConnection(),
>                                     true);
>                         }
>                     }
>                 }
>             }
>             loader = loader.getParent();
>         }
>     }



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to