On 10/14/09 20:10, Holger Hoffstätte wrote:
Nima Kaviani wrote:
I have developed a cross platform bundle that installs/uninstalls either
comm-win32 or comm-linux jars to enable communication with the serial port.
Everything works fine on Linux, however on windows, Felix seems to cache
win32com.dll along with other files and folders at the time of installing
comm-win32 but then it is unable to remove win32com.dll when comm-win32 gets
uninstalled.
This is a common problem especially on Windows. You still have outstanding
references from your code to the bundle class loader; this prevents the
class loader from being GC'ed on bundle uninstall. Since the classloader
keeps a reference to the native library and only clears it when it itself
is finalized, the library cannot be deleted since Windows does not allow
deletion of open files.

It is likely that the same happens on Linux - you just have not noticed it
since open files can be deleted on Linux. Whether that is a bug or feature
is..debatable.

The fix is simple: make sure you do not keep any references. :)
Good candidates are static singletons or other class references,
especially when they have escaped from the bundle and are kept alive outside.

As a consequence, the next time I bring up the framework, there
is a partially corrupted folder in the felix cache corresponding to the
presumably removed comm-win32 bundle which causes the following exception at
the time of starting the framework. Everything gets back to normal as soon
as I delete the corrupted bundle folder from the cache. The behavior happens
both with Felix 1.8.0 and 2.0.0.
Yup, common problem - I observed the same. See discussion here:
http://www.mail-archive.com/[email protected]/msg05211.html

Equinox is a bit more forgiving as it swallows the exception and puts the
"zombie" bundle cache on a blacklist that is deleted on the next start.
Whether that is better or not is again debatable; I think a zombie bundle
hogs the native library entry and prevents reloading a library with the
same name. If your bundle has the same lifecycle as the framework/JVM then
this should not be a problem.

In theory, we could potentially handle this situation differently in Felix, which could achieve a similar result. Typically, when we uninstall a bundle nothing really happens until refresh is called, in which case we perform the actual delete at that time. When the framework is stopped (or started) we do refreshes automatically, which causes uninstalled bundles to be deleted if no one refreshed explicitly.

The issue appears to be an error when deleting the cached directory for a given bundle, which we do in one recursive step to delete the entire directory. In theory, if we did this in two steps, where first we try to delete all native libraries for a given bundle, then we delete the entire bundle directory, then we might be able to handle the situation.

For example, if we get an error deleting the native libraries, we just stop and don't delete the bundle directory, but leave its recorded state as UNINSTALLED, then the next time the framework starts it will get deleted when the startup refresh is performed.

Unfortunately, this is only a partial solution to the overall issue, since this issue can also appear when refreshing an updated bundle.

-> richard


I wonder if there is a way to force Felix to remove the cached folder for
this bundle (along with the dll file)? or is there anything that I am not
doing properly at the time of uninstalling comm-win32 which somehow does not
release win32com.dll when it comes to cleaning the cache?
See above.

There *is* a way to make the classloader give up the reference and let go
of the native library, but it is evil and could kills kittens or even
bring a certain Dr. Watson to the crime scene. If you really want to have
it, send me an email. :)

Holger

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to