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?

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.

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

Reply via email to