Module isolation
Stanley M. Ho
Stanley.Ho at Sun.COM
Fri Jun 15 17:19:58 PDT 2007
Hello Bryan,
Bryan Atsatt wrote:
> ...
> But this approach doesn't really work very well. What happens when,
> moments after releasing a module, another application is deployed that
> needs the same module? It gets a different instance. And that could
> easily lead to ClassCastExceptions and/or LinkageErrors.
>
> How is it possible to know when it is safe to "free up resources"?
The use case I have is that sometimes we might want to make a module
temporary unavailable (e.g. turning off a plugin in the IDE), without
shutting down the repository (possibly with hundreds/thousands of other
modules) or uninstall the module. In this case, the container will
trigger not only the release of the existing module instance (so it will
have a chance to be GCed eventually), but it will also make the module
definition invisible (through visibility policy) from other modules.
Without the second part, it has the potential problem you described.
Note that I don't think this is a common thing many developers want to
do. In fact, I think we should discourage most developers from calling
releaseModule() because of the potential consequences. On the other
hand, we shouldn't preclude this use case either. If you have better
suggestion to address this use case, I would like to hear it.
> Well, I agree in theory. But... I am struggling to understand how we
> provide an isolation model. If:
>
> - There is a 1:1 relation for ModuleDefinition<->Module instance, and
> - Isolation requires separate Module instances, then
> - Isolation requires separate ModuleDefinition instances
>
> If this is our isolation model, then how does a ModuleSystem instance
> support this? Clearly, it would need to keep a mapping from each
> ModuleDefinition to its Module instance. How is this simpler, or better?
>
> In your current model (just as in my detach() model), there is still a
> 1:1 from *at any given moment*, at least from the perspective of the
> definition.
>
> Are you thinking that the ModuleSystem would have to keep track of
> released modules?
The ModuleSystem instance would have a <ModuleDefinition, Module>
mapping, and this should be a very simple thing to support and maintain.
Also, the ModuleSystem needs to maintain this information anyway to
avoid multiple Module instances to be instantiated for a given
ModuleDefinition, or to avoid a Module instance to be instantiated if a
ModuleDefinition has been uninstalled or belongs to a repository which
has been shutdown. And yes, the ModuleSystem would have another map to
keep track of all the ModuleDefinitions that are no longer
usable/instantiated. Having the information centralized in one place has
other benefits too, e.g. if we want to find out what the outstanding
module instances from module definitions in all repositories, the
ModuleSystem can provide the answer easily.
My view is that ModuleSystem needs to keep track of various runtime
information related to ModuleDefinition and Module anyway, so I don't
see clear benefit in moving part of that information into other classes.
> But this approach means that the wrapper must be tightly coupled to the
> wrappee. While I can imagine this holding true in some cases, it
> certainly doesn't seem like the common case.
>
> Why should an applet container, for example, be required to know the
> *type* of ModuleDefinition subclasses in the repository?
>
> Providing some sort of copy() operation on the base class eliminates
> this kind of coupling.
Perhaps I still don't fully understand how you will want to create a new
repository for isolation, and why having the knowledge of the
ModuleDefinition subclasses is not acceptable in this context.
As I previously hinted, having some sort of copy() operation in the base
class is not feasible because many module definitions does not make
sense to be cloned. Cloning also implies that the underlying lifetime of
the ModuleDefinition (and the ModuleDefinitionContent) from two
different repositories could be arbitrarily tied, and I don't think it
makes sense unless the repositories have the same owner.
In the case of an applet container, my expectation is that the container
will construct some kind of AppletURLRespository for each codebase with
some ModuleDefinition subclass, and each ModuleDefinition is
instantiated with a custom ModuleDefinitionContent implementation with
the applet cache as the backing store. In other words, the applet
container or the AppletURLRepository already has knowledge about the
ModuleDefinition subclass. If the applet container needs a new
repository for isolation, then it would construct another
AppletURLRespository, and this new AppletURLRespository could construct
each ModuleDefinition using the existing ModuleDefinitionContent instance.
- Stanley
More information about the jsr277-eg-observer
mailing list