https://bz.apache.org/bugzilla/show_bug.cgi?id=57743

            Bug ID: 57743
           Summary: Jar files in <webapp>/WEB-INF/lib are kept open,
                    preventing redeploy
           Product: Tomcat 8
           Version: 8.0.20
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: pa...@semmle.com

Created attachment 32592
  --> https://bz.apache.org/bugzilla/attachment.cgi?id=32592&action=edit
A patch against AbstractResourceSet.java, adding a call to gc() when it is
destroyed.

As described in 56390, keeping jar files in a webapp folder open will prevent
the application from being undeployed/redeployed on file systems which don't
like open files to be deleted (in practice, that seems to mean Windows-based
systems or NFS mounts).

Having observed the problem with tomcat 8.0.20, which is meant to contain the
fix for 56390, I believe I have uncovered the root cause. Here's what happens,
in my scenario:

 - A new .war is copied into $CATALINA_HOME/webapps; this is picked up by
`HostConfig.checkResources()`, which decides to redeploy the app.

 - To do this, it first undeploys it (HostConfig.java:1250 in the TOMCAT_8_0_20
tag), and then attempts to delete the exploded war (line 1251).

 - In my case, the undeploy triggered a servlet's `destroy()` method, which
triggered some class loading from WEB-INF/lib. Thus, the context's
`WebResourceRoot` was used immediately before the attempt to delete the webapp
folder, and opened a jar file.

 - Even though the `JarInputStreamWrapper` was properly closed, the handle to
the jar remains open -- by design of `AbstractArchiveResource`, it is not
closed immediately but with the next periodically scheduled call to `gc()`, as
part of `StandardRoot.backgroundProcess()`.

As a result, when $CATALINA_HOME is on an NFS mount tomcat fails to delete the
exploded webapp directory, and things go bad.

The attached patch fixes the problem in my testing; it simply changes
`AbstractResourceSet.destroyInternal()` so that instead of doing nothing it
calls `gc()`, which will close any jar files which no longer have open input
streams. This seems like it's necessary to avoid a resource leak even on
systems that allow the deletion of open files, since if I'm not mistaken after
the context has been detached it will no longer receive `gc()` calls from the
background process thread.

-- 
You are receiving this mail because:
You are the assignee for the bug.

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

Reply via email to