Module isolation
Bryan Atsatt
bryan.atsatt at oracle.com
Thu Jun 14 18:57:42 PDT 2007
Stanley M. Ho wrote:
> Hi Bryan,
>
> Bryan Atsatt wrote:
>>
>> Can you please explain the use case for releaseModule()?
>
> If a repository instance is long-lived, the instantiated module
> instances from the module definitions in the repository would be cached
> for a long period of time; calling releaseModule() could help freeing up
> resources when necessary, without requiring the repository instance to
> be shutdown. This is also a use case from NetBeans.
Sorry, but this is just a bit fuzzy to me. I suspect that a concrete use
case is an application server, when it has stopped an application,
*could* release any modules used by that application.
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"?
I don't think you can have it both ways. Either classes are shared for
the lifetime of the process, or they are shared *only* within a well
bounded scope. Not both.
To me, this is exactly why we need an isolation model: to provide a well
defined scope whose lifecycle can be correctly managed.
>
> Also, when a module definition is reloaded/uninstalled, or when the
> repository is shutdown, we will disable the module definitions in the
> repository from the module system so any existing module instance would
> be released and no new module instance can be instantiated. However,
> releasing the module instance alone is not sufficient because that
> module instance may be referenced by some importers. Hence, we want to
> call releaseModule() on the importers as well for these module instances
> to eventually become unreachable and be GCed.
>
>> Would you agree that if we did not support releaseModule(), caching the
>> Module instance in the ModuleDefinition would eliminate some complexity?
>
> No. I actually think caching the Module instance in the ModuleDefinition
> would add complexity to the design and the implementation. If the module
> instances are cached in the ModuleSystem, the ModuleSystem could fully
> control the access of these module instances and update/change them
> internally. ModuleDefinition is supposed to be stateless, and I think it
> should be kept this way.
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?
>
>> Isolation requires creating a separate repository instance that wraps
>> another, and hands out *copies* of definitions from the underlying
>> instance.
>>
>> We simply need a standard way to make such a copy, one that does not
>> require knowing the actual subtype.
>
> If I understand what you are trying to do, you want to construct a new
> repository instance with module definitions that are based on some
> module definitions in an existing repository instance. To do that, we
> could either go with the approach of constructing new ModuleDefinition,
> or as you suggested - cloning. However, I don't think cloning is the
> right general solution here - there are many module definitions that are
> unsuitable for cloning (e.g. platform module definitions). My assumption
> is that the developer creating the separate repository instance is
> possibly the one creating the original repository instance, so I don't
> understand why he can't simply construct a new ModuleDefinition with an
> existing ModuleDefinitionContent.
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.
>
> - Stanley
>
More information about the jsr277-eg-observer
mailing list