On 7/16/2013 4:07 PM, Caldarale, Charles R wrote:
From: André Warnier [mailto:a...@ice-sa.com] Subject: Re: [OT] Cannot
cleanly undeploy a web application

What probably happens here, is that one level below the InputStream
which holds the filehandle in Java, is some native file object
which has the file open. The InputStream object is discarded at tbe
Java level, but is only really destroyed at the next GC.

That sounds quite feasible.  The real error is that whoever owned the
InputStream failed to close it, and simply removed all references to
it, making it unreachable.  The next GC did the close() as part of
its cleanup work.  The fix would be to find the InputStream and
explicitly close it.

- Chuck


Folks,

It's unfortunate that I can't include multiple parts into the reply.

Ultimately, it's a programmer error. Reading javadoc is good for what ails you.

Andre, exactly right. When I caught this on visualvm, there was an InputStream with reference to native code but nothing else.

Yep Chuck, I failed to close the InputStream - mainly because . . .

Mark, thanks for pointing out (gently) to RTFJD. While JarURLConnection does not have a close method, JarFile certainly does. As well as I should be checking the return value from JarURLConnection.getJarFile . . .

Taking those two thoughts in mind, a more correct (still ugly, but it works) method might be:

public ArrayList<String> getResources(String resourcePath,
                                      String ending) {
    Pattern p =
        Pattern.compile("^" + resourcePath + "/.+(" + ending + ")$");
    try {
        JarURLConnection urlCon =
            (JarURLConnection) url.openConnection();
        urlCon.setUseCaches(false);
        JarFile jar = urlCon.getJarFile();
        if (null != jar) {
            Enumeration<JarEntry> je = jar.entries();
            while (je.hasMoreElements()) {
                String entry = je.nextElement().getName();
                if (log.isDebugEnabled()) {
                    log.debug("JAR entry: " + entry);
                }
                Matcher m = p.matcher(entry);
                if (m.matches()) {
                    resources.add(entry);
                }
            }
            jar.close();
        } else {
            if (log.isErrorEnabled()) {
                log.error("Failed to get JarFile entry");
            }
        }
    } catch (IOException ex) {
        if (log.isErrorEnabled()) {
            log.error("Could not open resource", ex);
        }
    }
    return this.resources;
}

Thanks, I was looking at the wrong javadoc.

. . . . sticking to admin stuff, it's less dangerous
/mde/

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to