This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 21114 - Release all JarFile locks when ModuleManager.delete called
Summary: Release all JarFile locks when ModuleManager.delete called
Status: RESOLVED FIXED
Alias: None
Product: platform
Classification: Unclassified
Component: Module System (show other bugs)
Version: 3.x
Hardware: PC Windows ME/2000
: P2 blocker (vote)
Assignee: Jesse Glick
URL:
Keywords:
Depends on:
Blocks: 20323
  Show dependency tree
 
Reported: 2002-03-04 09:04 UTC by akemr
Modified: 2008-12-23 08:38 UTC (History)
1 user (show)

See Also:
Issue Type: ENHANCEMENT
Exception Reporter:


Attachments
Non-functional patch (10.07 KB, patch)
2002-03-04 18:12 UTC, Jesse Glick
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description akemr 2002-03-04 09:04:44 UTC
Jesse, could you please implement it as you suggested in #20323?
Thanks.
Comment 1 Jesse Glick 2002-03-04 10:01:55 UTC
Probably impl:

It might be possible in case a module is about to be deleted to create
a copy in /tmp (File.createTempFile) of all the JARs the classloader
had open, open the copy JARs, close the originals, and switch the
JarFile's used internally. Also, if and when the classloader is
finalized, close the copy JARs and delete them.
Comment 2 Jesse Glick 2002-03-04 18:12:18 UTC
Created attachment 4925 [details]
Non-functional patch
Comment 3 Jesse Glick 2002-03-04 18:24:16 UTC
I have partially solved this - at least the NB side of things. With
the attached patch, the module classloader does not keep an open
JarFile for the module after it has been deleted.

However it is not enough. As I found out, if a jar: URL is *ever*
opened in the VM, private JRE code keeps a hard reference to an open
JarFile for that JAR and never releases it! This means that if the
module classloader ever serves a request for ClassLoader.getResource
(which almost every module will), using a jar: URL, and the module is
not marked reloadable, the JAR will not be deletable (or upgradable)
in this VM session on Windows.

I filed a Java bug, will attach a URL when it is accepted.

The new unit test demonstrates the problem. It passes on Unix but
fails on Windows.

I can think of two possible ways to continue:

1. Do not use jar: URLs. Define and use a custom URL protocol which
behaves much like jar: but uses NB-specific knowledge about when a JAR
should be closed. After the JAR is closed (e.g. because of
ModuleManager.delete), it could be copied to a temp dir to serve old
URL connection requests. Pros: safe; we may want to do similar manual
rerouting of JAR entry requests in order to implement a fast JAR cache
at startup anyway. Cons: some work to implement; duplication of a lot
of JRE code.

2. Using reflection, delete entries from JarFileFactory.fileCache when
ModuleManager.delete is called, to make sure that no open JarFile is
retained. It would still be possible for "zombie" code in a dead
classloader to ask for URL resources from the module, but the patched
JarClassLoader would serve them from the copy JAR, making it possible
to still delete the original. Pros: simple and may be effective. Cons:
dangerous call to private impl code, cannot be guaranteed to work in
future JDK releases.

I will try to solve the problem using #2 for now. If we want to
implement JAR caches later for reasons of startup performance, it may
be worthwhile to rewrite to code to use style #1.
Comment 4 Jesse Glick 2002-03-05 11:17:14 UTC
Java bug: #4646668
Comment 5 Jesse Glick 2002-03-05 17:04:45 UTC
OK, using workaround #2 (reflection hack). Seems to work well enough
with JDK 1.3.0 and 1.4.0 on Win2000. Also does not seem to hurt
anything on Linux with JDK 1.3.1_02 nor 1.4.0 (though the fix is not
really necessary on Unix systems anyway). Will commit soon.

Ales - note that the JAR locks are released only after the module is
really deleted from the ModuleManager pool. They are *not* released
after just disabling a module. From Auto Update, you should be able to
do this: delete the Modules/*.xml file corresponding to the module;
listen for changes in the Lookup result on ModuleInfo and wait for the
module to disappear from the list (with some sanity timeout of
course); then physically delete the JAR. The same system should work
for other JARs associated with the module: declared Class-Path
extensions, locale/branding variants, and
modules/patches/module-code-name/ patch JARs.

Also Ales - please run the usual unit test suite on Windows after I
commit (you run Windows, correct?). I ran ModuleManagerTest in
isolation on Win2K because I do not have full XTest set up on that
partition, but it would be good to make sure everything (esp. the new
ModuleManagerTest.testModuleDeletion) passes OK for you as well,
especially using JDK 1.3.1. Since reflection is used, it is possible
for a random JDK to not have the same impl of jar: URL caching, in
which case JarClassLoader will print an exception to the log file, and
the fix will be disabled. I found that 1.3.0 seems to have a slightly
different impl from 1.3.1 and 1.4.0 - the fileCache field became
static.
Comment 6 Jesse Glick 2002-03-06 14:15:34 UTC
committed   * Up-To-Date  1.8        
core/src/org/netbeans/core/modules/JarClassLoader.java
committed   * Up-To-Date  1.23       
core/src/org/netbeans/core/modules/Module.java
committed   * Up-To-Date  1.25       
core/src/org/netbeans/core/modules/ModuleManager.java

committed   * Up-To-Date  1.15       
core/test/unit/src/org/netbeans/core/modules/ModuleManagerTest.java

committed   * Up-To-Date  1.6        
xtest/src/org/netbeans/core/modules/Module.java