Module system notification mechanism

Bryan Atsatt bryan.atsatt at
Mon Jul 16 13:41:44 PDT 2007

Stanley M. Ho wrote:
> Hi Bryan,
> Bryan Atsatt wrote:
>>> 1. If a module's activator is executed before the module is fully
>>> initialized, it can safely register something into some service lookup
>>> mechanism in the system.
>>> 2. The service lookup mechanism will make sure the registered thing from
>>> that module is not usable by other modules unless that module becomes
>>> fully initialized.
>>> 3. If the module's activator fails to execute when the module is being
>>> initialized, the module system knows how to work with the service lookup
>>> mechanism to undo all the unregisterations automatically and correctly.
>> So do you expect that java.util.ServiceLoader will do this?
> No. Actually, the way java.util.ServiceLoader looks up service-providers
> is through the context classloader at runtime when a service is being
> requested. Unlike other service lookup mechanisms, it is not necessary
> to register service-providers with the java.util.ServiceLoader API at
> all, so the module's activator won't be useful in this case.
> The scenarios where using module's activator for registration might be
> applicable are for those modules that want to register with other
> service lookup mechanisms that are not based on java.util.ServiceLoader.
>> I agree that we shouldn't try to push a *service* mechanism into the
>> module layer.
>> But a generic *activator* certainly seems appropriate. Some modules will
>> need to perform initialization prior to use (e.g. process a config file,
>> check some environmental constraints, populate a JNDI context, etc,
>> etc). Successful initialization for such a module is then a
>> pre-condition for use, and any failure should be treated exactly as
>> seriously as a resolution failure.
> The solution does not have to tie to the module state. I think what we
> simply want is to support the use case that a module instance should not
> be handed out unless certain initialization code is executed
> successfully. As long as the API for obtaining such module instance
> supports this semantic, it's orthogonal to how the module state changes
> internally.
>> Yes, this *could* be done using the notification mechanism, but that
>> strikes me as a rather hackish approach. This use case is not limited to
>> "container" environments, so, IMO, should be made part of the spec.
> I'm not aware of use cases which are not in the "container"
> environments. Could you provide some examples?

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!

>> And it seems like a rather small addition:
>> 1. A simple interface that the module can implement, e.g.:
>>    interface ModuleActivator {
>>        public void start(Module module) throws Exception;
>>        public void release(Module module) throws Exception;
>>    }
>> 2. An annotation to declare the activator impl name.
>> 3. Module system instantiates and invokes activator (at end of
>> prep/validation or a new step). An exception here would put the module
>> into ERROR state.
>> Exactly what such an activator does is mostly irrelevant, though it
>> clearly cannot consume the thread; the usual precautions here should
>> suffice.
> I also think that the API impact is small. However, because the module
> system and the service lookup mechanisms are not integrated tightly
> together, a not-yet-fully-initialized Module instance might be leaked
> out to other service lookup callers after it is registered by the
> ModuleActivator through the service lookup mechanism but before it is
> fully initialized. Because of this, I don't think there is obvious
> benefit to provide built-in support for ModuleActivator since the same
> can be achieved using the notification mechanism, which we'll support
> anyway.

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

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.

> Another extreme approach is to design a very generic service lookup
> mechanism that is tightly integrated with the module system, and also
> requires all other service lookup mechanisms to be built on top of this
> generic one (if these mechanisms are ever used in the module's
> activator), so they will all provide the appropriate semantic w.r.t. the
> module system and no uninitialized module instance would be leaked out
> accidentally. That said, I don't think this is what we want to do. ;-)


> - Stanley

More information about the jsr277-eg-observer mailing list