Talk:Lazy Start Bundles
BJ Hargrave changed the design to activate lazy-start bundles upon first class or resource load requests. This is not how the current lazy-start implementation works in Equinox.
In the past we have not thought of any reason a bundle would need to be activated because a resource was loaded from it. Are there any reasons why a bundle would need to be activated before a resource is allowed to load from it?
BJ Hargrave 14:29, 7 September 2006 (EDT)
Well I would rather change the trigger to be "create a class loader" instead of "first class (or resource) load". In reality it is the class loader creation event that should be the trigger for lazy start. Class loader creation may be triggered by a class load (by following a wire into the bundle or Bundle.loadClass) or a resource request (by following a wire into the bundle or Bundle.getResource). While the framework should be free to create the class loader earlier if it so desires, the visible effect of the creation of the class loader (lazy start) does not need to be visible until the class loader is first used (first class or resource load is requested).
Tjwatson.us.ibm.com 14:39, 7 September 2006 (EDT)
I need to investigate this approach more. It may make things simplier and it may help solve the class circularity issues. In this model the classloader would be created and the bundle would be activated before even asking for the class being requested. This should help prevent the circularity issue.
Tjwatson.us.ibm.com 16:25, 11 September 2006 (EDT)
I ran into some deadlock issues with lazy starting upon classloader creation. This ends up being a VM limitation. The problem is a lot of VMs lock the classloader when the VM initiates a classload.
The scenario is pretty ugly to explain. Here is an attempt ...
- Bundle X requires Bundle Y and the package foo is split and exported across the two bundles
- When Bundle Y is starting it loads a class in the foo package from Bundle X using Bundle.loadClass
- This causes Bundle X's classloader to be created and Bundle X is starts
- Then we attemp to load the class from class from Bundle X's classloader but ...
- While Bundle X is starting it starts another thread that ends up loading a class from package foo (Bundle X's classloader is locked at this point on some VM's). The package is split across Bundle Y and X.
- We attempt to load the class from Bundle Y first, the classloader was already created so we try to load a class from it. At this point the classloader for Y detects that it is not started so it waits for a period of time for bundle Y to finish.
- Meanwhile the thread trying to start Bundle Y is trying to load a class from Bundle X's classloader. Eventually it needs to obtain the lock the Bundle X's classloader so that ClassLoader.findLoadedClass and ClassLoader.defineClass are thread safe. So it deadlocks waiting for the classloader lock.
- Eventually we timeout waiting for Bundle Y to start and both treads are allowed to continue.
For now I think we may have to loosen the wording on the spec to state that a lazy-start bundle must be started some time between when the classloader is created and the first class/resources is loaded.
Future VM specifications are supposed to make it clear that the native VM must not lock the ClassLoader when loading classes and the ClassLoader.findLoadedClass and ClassLoader.defineClass must be thread safe. On such a VM it will be possible to avoid most of the deadlock and ClassCircularityErrors issues in lazy-start by starting a bundle immediately after the classloader is created.
Tjwatson.us.ibm.com 10:32, 12 September 2006 (EDT)
As it turns out we have real usecases that require an exceptions type directive on the lazy-start policy. We will have to take this into consideration if OSGi does not except the directive on lazy-start bundles.