Hi Bryan,

Bryan Atsatt wrote:
...
I don't have a specific example in mind, but just consider libraries
targeted at SE that, before use, must:

- Validate a license key, or
- Establish a network connection, or
- Read a config file, or
- Validate the environment (e.g. java version, presence of some Class,
etc,), or
- Fork threads.

While these could all be done lazily, or with explicit calls by the
client, I've seen many cases of the "X must be initialized first"
problem. In my experience, many of these have been in the EE
environment, but only incidentally: some app bundles lib X, which itself
has no EE dependencies but must be initialized. I've seen many EE apps
that are configured with a servlet *only* so that they can get an init
call at startup!

If we take the service registration out of the picture, the module's
initialization could probably take place in the custom import policy
directly. Maybe in some situations the custom import policy would
require more security permissions for the initialization to succeed, but
we could work this out. Do you have examples that using custom import
policy is not sufficient for performing initialization?

The initialization issue around EE apps is a separate issue, and it
could be addressed if EE defines its own activation mechanism on top of
the module system's notification mechanism.

You are coupling the ideas of activation and services; I'm explicitly
trying to de-couple them here. Yes, service registration could be done
by an activator, but I'm focused on the more general problem of module
*initialization*.

My impression around the activation idea was to support the service
registration, and this is the primary use case I see how activation is
used in many existing systems. If we want to use this mechanism for
initialization, then I would like to better understand why using custom
import policy is not sufficient. ;-)

Maybe this would be clearer if we changed the interface name:

    interface ModuleInitializer {
        public void start(Module module) throws Exception;
        public void release(Module module) throws Exception;
    }

Seems to me that we can easily eliminate the leakage problem by:

1. Ensuring that initialization occurs before the module moves from
RESOLVED to READY state, and

2. Initialization failure moves the module to ERROR state, and

3. Module lifecycle events are only fired when the module enters either
READY or ERROR states (and STOPPING/STOPPED, if we add those).

If you intend to expose the states leading up to READY/ERROR as events,
then yes, leakage is a potential problem. We could get around this by
passing only the ModuleDefinition on these events, not the Module itself.

I agreed some modules might want to cleanup themselves when there is no
reference to their Module instances. On the other hand, the suggested
release() method is invoked after the reference of the Module instance
has been released from the module system, but other modules could still
hold references to that instance and continue accessing classes through
the module's classloader. In other words, it would be inappropriate to
trigger clean up when this release() method is invoked.

I believe what you really want is to clean up when the Module instance
is about to be GCed; however, this is already possible if the module
hooks into the garbage collector to trigger the cleanup code after the
Module instance becomes unreachable. It is unclear to me what purpose
the release() method really serves and if supporting this method is
useful. Unless of course, the clean up is performed when the module's
classloader is disabled at the same time so nobody else could use the
module, but we have already discussed that disabling the classloader is
a very special use case that should only happen in the EE container
environments. If this is something only needed by some containers, then
it is better to let the containers build their own activation mechanisms
on top of the module system's notification mechanism, rather than
pushing it down into the module system level.

Do you have specific examples where the release() method would be useful
outside the container environments?

- Stanley

Reply via email to