Relationship to JSR 291 [was: Re: Bryan's comments]
Glyn Normington
glyn_normington at UK.IBM.COM
Fri Jun 1 02:43:27 PDT 2007
After writing:
>I think ResolutionContext doesn't need any detail
I remembered the class in the interoperation kernel prototype did have a
little detail (but not much):
public interface ResolutionContext extends KernelRelated {
/**
* Notify completion.
*/
void complete();
}
I blogged ([1]) the README and class diagrams from the prototype for ease
of reference.
Glyn
[1]
http://underlap.blogspot.com/2007/06/module-system-interoperation-kernel.html
glyn_normington at uk.ibm.com wrote on 31/05/2007 17:15:19:
>
> Bryan Atsatt <bryan.atsatt at ORACLE.COM> wrote on 30/05/2007 19:11:02:
>
> > Responses inline, and a few clarifications here (I was a bit tired
when
> > I finished this last night :^)...
> >
> > The main point I was trying to make is that resolution must occur
within
> > a specific context, but I don't think my example APIs showed that
well.
> > I was assuming that ImportResolver had a ModuleContext as a field, but
> > we can make this much cleaner and easier to understand by passing it
as
> > an argument:
> >
> > public abstract class ImportResolver {
> > public abstract Module resolve(ModuleDefinition def,
> > ModuleContext ctx);
> > }
> >
> > And we can really tie this together by adding a convenience method to
> > ModuleContext:
> >
> > public abstract class ModuleContext {
> > ...
> > public Module resolve(ModuleDefinition def) {
> > return getImportResolver().resolve(def, this);
> > }
> > }
> >
> > Now resolution becomes simply:
> >
> > context.resolve(definition);
> >
> >
> > (I also left out any use of the ImportPolicy, as it isn't yet clear to
> > me that it should remain a separate type in this model.)
> >
> > // Bryan
> >
> > Glyn Normington wrote:
> > >
> > > *Bryan Atsatt <bryan.atsatt at ORACLE.COM>* wrote on 30/05/2007
07:57:59:
> > >
> > > > Andy Piper wrote:
> > > > > At 23:19 25/05/2007, Stanley M. Ho wrote:
> > > > >> Anyway, it seems the EG consensus so far is to not add
> import package
> > > > >> support. If any EG member disagrees, please speak up.
> > > > >
> > > > > Well, it depends on what the solution for enabling
interoperation
> > > > > with JSR 291 is.
> > > > > Our requirement is that there must be a solution, if that
requires
> > > > > import package, so be it. If not then not.
> > > >
> > > > Exactly.
> > > >
> > > > I think we can all agree that, at minimum, interoperation means
that
> > > > classes and resources are sharable *across* ModuleSystems at
runtime.
> > > >
> > > > Which implies that *import dependencies must be resolvable across
> > > > multiple ModuleSystem instances*. (BTW, I think we should change
the
> > > > state name "PREPARING" to "RESOLVING" in 7.2.1.)
> > >
> > > Agreed. We must avoid the trap of thinking that module system
interop.
> > > can be achieved by exposing class loaders (as loadClass will happily
> > > load unexported classes).
> > >
> > > >
> > > > So the open issue is the richness of the import "language": must
we
> > > > support only lowest-common-denominator, or can we do better
without
> > > > over-complicating the design?
> > > >
> > > > I for one would like to be able to have a single module express
> > > > dependencies on modules from both the same and different
ModuleSystems,
> > > > *using the standard semantics of each*. This may be reaching too
far,
> > > > but we should at least explore it seriously while we figure out
what
> > > > interop means here...
> > >
> > > At this point, I feel that is likely to be reaching too far, but I'm
> > > happy to play along and see what we can learn along the way.
> > >
> > > >
> > > >
> > > > BASICS
> > > >
> > > > So far, we only know of two different import semantics:
> module-name, and
> > > > package-name. For discussion, let's call these:
> > > >
> > > > a. import-module
> > > > b. import-package
> > > >
> > > > So, to start, we could:
> > > >
> > > > 1. Support declaration of both import types. If 294 supports
imports at
> > > > all, it should be relatively easy to support both, since a
superpackage
> > > > name is a module name, and it contains member package
> names. (Compiler
> > > > support is clearly the critical issue here, but it will obviously
> > > > require use of the 277 runtime, so the import *type* should be
> > > > transparent to it.) At worst, we'd need two new annotation types.
> > >
> > > A superpackage name is a deployment module name in the JSR 277 model
of
> > > one superpackage per deployment module, but I don't see any reason
why a
> > > JSR 291 deployment module should not contain more than one
superpackage.
> > > So if 294 were to support import, then its import-module would
really be
> > > a superpackage import rather than a development module import.
> >
> > If we end up with nested superpackages, might it make sense to model
> > multiple superpackages by enclosing them in a single top-level one?
>
> That is an option, but of course each nested superpackage has to
> name its parent, so it wouldn't be possible to combine superpackages
> from independent groups or sources without either modifying their
> superpackage declarations or getting them to agree on the name of
> the parent superpackage and code it themselves.
>
> >
> > >
> > > >
> > > > 2. Provide API for both import types (e.g. ImportDependency has
> > > > getModuleName() and getPackageName() methods, one of which will
return
> > > > null on a given instance).
> > > >
> > > > However, we know these are necessary but not sufficient. Leaving
aside
> > > > the resolution issue for a moment, support for import-package
also
> > > > suggests that we:
> > > >
> > > > 3. Enable a single module to declare different versions for each
of its
> > > > member packages.
> > > >
> > > > 4. Enable efficient Repository lookup by package name.
> > > >
> > > > I think these are relatively easy (but *could* be considered
optional).
> > > >
> > > > We also need:
> > > >
> > > > 5. Standard Query types for lookup by module and package name.
> > > >
> > > >
> > > > EXISTING DEPENDENCY RESOLUTION MODEL
> > > >
> > > > The more interesting issue is dependency resolution. But this
hasn't
> > > > been discussed in any real detail, so lets do so before talking
further
> > > > about import-package. To simplify this discussion, I'm ignoring
> > > > bundled/custom import policies for now...
> > > >
> > > > Resolution in the current spec is delegated to the associated
> > > > ModuleSystem instance (7.2.2 #8). While the details are not
> spelled out,
> > > > the expectation appears to be that
> > > > ModuleSystem.getModule(ModuleDefinition) must:
> > > >
> > > > - Select an initial repository. Call getRepository() on the input
> > > parameter.
> > > >
> > > > Then, for each ImportDependency of the definition:
> > > >
> > > > - Select a matching definition. Construct a Query from the
> > > > ImportDependency and use Repository.find() to lookup a matching
> > > > ModuleDefinition.
> > > >
> > > > - Get an instance. Use def.getModuleSystem().getModule(def). The
> > > > ModuleSystem is expected to return a cached instance if
available, or
> > > > create/cache/return one if not.
> > >
> > > I think there also needs to be some 'resolution context' object
which
> > > explicitly denotes a particular resolution so that each module
system
> > > can keep track of the state of a resolution. This is required when
two
> > > or more imports of a given module from another module system need to
> > > resolve to the same module instance. A resolution context may also
be
> > > needed for back-tracking when a set of module instances created
earlier
> > > in resolution turn out not to satisfy all the necessary constraints.
> >
> > Yes. I had (briefly :^) thought that we need only a List<Module> as
> > field in the ImportResolver to hold the resolved modules as we go. But
> > probably we need to keep some additional state along with each Module,
> > so a new type may be required. Let's call it ResolutionContext, and
> > create one at the start of each resolution:
> >
> > public abstract class ImportResolver {
> >
> > public Module resolve(ModuleDefinition def, ModuleContext modCtx)
{
> > ResolutionContext resCtx = createResolutionContext();
> > return resolve(def, modCtx, resCtx);
> > }
> >
> > protected abstract ResolutionContext createResolutionContext();
> >
> > protected abstract Module resolve(ModuleDefinition def,
> > ModuleContext modCtx,
> > ResolutionContext resCtx);
> > }
> >
> > Does this approach make sense? Any thoughts on details for
> > ResolutionContext?
>
> Seems reasonable. I think ResolutionContext doesn't need any detail
> - it can simply be used as the key of a map recording the
> resolutions that a module system is currently aware of.
>
> >
> > >
> > > >
> > > >
> > > > (TBD: The PlatformBinding must be taken into account somehow
during
> > > > selection. ModuleDefinition must include an accessor for it, and
either
> > > > Repository.find() should implicitly filter them, or the caller
must
> > > > construct a Query which will do so. I think we should add a
> > > > CURRENT_PLATFORM constant to Query, which will evaluate to true
if no
> > > > binding is present in a definition.)
> > > >
> > > > (The spec also talks about Repository as the mechanism of
isolation
> > > > (6.4). This was the case in the prototype, where the repository
itself
> > > > provided caching. It doesn't appear to work with the current
design.
> > > > There is no need that I can see to isolate ModuleDefinition
> > > > instances--it is Module instances with their associated
> loaders that may
> > > > require isolation.)
> > > >
> > > > (Also note that if ImportDependency was itself a Query subclass,
there
> > > > would be no need to do any mapping. And since the
ModuleDefinition
> > > > subclass must produce ImportDependency instances, it can even
produce
> > > > more specialized Query instances if desired.)
> > > >
> > > >
> > > > REFINEMENT
> > > >
> > > > I think we can improve on the existing model in several ways:
> > > >
> > > > A. Provide a model for Module isolation (e.g. for EE, Applets,
etc).
> > > >
> > > > B. Encapsulate all selection logic in a single mechanism.
> > > >
> > > > C. Eliminate the overhead of the repository lookup when a cached
> > > > instance exists.
> > > >
> > > > Let me propose a new class that encapsulates the caching logic,
enables
> > > > lookup using Query, and supports multiple instances for
isolation:
> > > >
> > > > public abstract class ModuleContext {
> > > >
> > > > // Get the context used to define JRE modules.
> > > > public static ModuleContext getBootstrapContext(){...};
> > > >
> > > > // Get the context used to define the main module.
> > > > public static ModuleContext getSystemContext(){...};
> > > >
> > > > // Get all contexts.
> > > > public static List<ModuleContext> getContexts() {...};
> > > >
> > > > // Add a new context.
> > > > public static void addContext(ModuleContext ctx) {...}
> > > >
> > > > // Remove a context (error if == default).
> > > > public static boolean removeContext(ModuleContext ctx) {...}
> > > >
> > > > // Get the parent context (null if bootstrap).
> > > > public ModuleContext getParentContext(){...}
> > > >
> > > > // Get the name of this context.
> > > > public String getContextName() {...}
> > > >
> > > > // Create a new Module instance and store it in the cache.
> > > > public abstract Module createModule(ModuleDefinition def);
> > > >
> > > > // Find cached Module instances. Must check parent first.
> > > > public abstract List<Module> findModules(Query query);
> > > >
> > > > // Set the context used for JRE modules.
> > > > static void setBootstrapContext(ModuleContext ctx){...}
> > > >
> > > > // Set the context used to define the main module.
> > > > static void setSystemContext(ModuleContext ctx){...}
> > > > }
> > > >
> > > > The JVM will create an appropriate subtype and call
> > > > setBootstrapContext(). The launcher will create a child
> context and call
> > > > setSystemContext(). An EE (or similar) environment can
> create/remove new
> > > > contexts as needed for application isolation.
> > > >
> > > > And the resolution algorithm can now check the cache *first*,
before
> > > > doing a repository lookup, using the same mechanism in both.
Query
> > > > should be used to express *all* selection criteria (including
> > > > attributes, which we have not yet directly supported).
> > > >
> > > > Caches are no longer tied to ModuleSystem instances.
> > > > ModuleSystem.getModule() can become simply createModule(). The
normal
> > > > implementation of ModuleContext.createModule() just calls
> > > > ModuleSystem.createModule() and caches/returns the result.
> > > >
> > > >
> > > > This class could easily be made concrete, but it may be useful to
> > > > support subtypes for specialization (e.g. event generation,
lifecycle
> > > > management, specialized diagnostics, etc).
> > > >
> > > >
> > > > RESOLUTION MODELS
> > > >
> > > > The current design requires that each ModuleSystem provide its
own
> > > > resolution logic, and that each definition will be resolved by
its
> > > > owning ModuleSystem. This model appears to provide flexibility
for
> > > > significant differences in implementation, but we really don't
know
> > > > enough at this point. Perhaps only an actual second
implementation will
> > > > tell us if this provides useful flexibility.
> > > >
> > > > It wouldn't surprise me if we have to keep tightening the
> spec as we go,
> > > > in order to remove inconsistencies that arise from the separate
> > > > algorithms. And this may eliminate flexibility to the point where
it is
> > > > no longer useful. Much worse, we may not even discover this until
after
> > > > the spec and RI are released, if that second implementation (e.g.
OSGi)
> > > > is not completed beforehand.
> > > >
> > > > We should at least consider the obvious alternative: one
algorithm (to
> > > > rule them all :^). And I don't mean one hard-coded algorithm,I
mean one
> > > > replaceable, extensible class, such as:
> > > >
> > > > public abstract class ImportResolver {
> > > > public abstract Module resolve(ModuleDefinition def);
> > > > }
> > > >
> > > > And we add a method to ModuleContext to retrieve an instance:
> > > >
> > > > public abstract class ModuleContext {
> > > > ...
> > > > public abstract ImportResolver getImportResolver();
> > > > }
> > > >
> > > > (Note that ImportResolver is now in a position to subsume the
> > > > functionality of both VisibilityPolicy and ImportOverridePolicy.)
> > > >
> > > > Repository usage is encapsulated within the implementation of the
> > > > resolve() method. The full resolution algorithm becomes:
> > > >
> > > > context.getImportResolver().resolve(definition);
> > > >
> > > > The launcher uses the "system" context for this. EE, Applets,etc.
make
> > > > and use their own distinct, isolated instances.
> > > >
> > > >
> > > > RESOLUTION WITH IMPORT-NAME AND IMPORT-PACKAGE
> > > >
> > > > With this scaffolding in place we can easily take a phased
approach to
> > > > supporting import-package: the initial implementation simply does
not
> > > > support it at runtime.
> > >
> > > A phased approach would be particularly beneficial if the initial
phase
> > > could be delivered as part of Java 7 and subsequent phases
implemented
> > > strictly on top of Java 7. But getting the API right up front might
be
> > > tricky unless we can spot some really good abstractions or prototype
the
> > > later phases sufficiently well. Is that the kind of phasing you had
in
> > > mind?
> >
> > Yes. It would be *extremely* useful to have an OSGi
> > implementation/prototype well under way before Java 7 is completed, so
> > that we can fine tune the model as we learn.
> >
> > >
> > > >
> > > > A subsequent implementation may support import-package, but only
within
> > > > the boundaries of the same ModuleSystem.
> > > >
> > > > And a full blown implementation may support import-package across
> > > > ModuleSystems.
> > > >
> > > > We can build in support for selecting/configuring the
ImportResolver as
> > > > a service, just as we plan to do with ModuleSystem (and
Repository, I
> > > > presume).
> > > >
> > > >
> > > > And maybe, just maybe, we can find a way to abstract and re-use
the
> > > > mature resolution logic from the OSGi reference implementation
*as* the
> > > > one implementation to rule them all.
> > > >
> > > > // Bryan
> > >
> > > Glyn
> > >
> > >
> > >
------------------------------------------------------------------------
> > >
> > > /
> > > /
> > >
> > > /Unless stated otherwise above:
> > > IBM United Kingdom Limited - Registered in England and Wales with
number
> > > 741598.
> > > Registered office: PO Box 41, North Harbour, Portsmouth,
> Hampshire PO6 3AU/
> > >
> > >
> > >
> > >
> > >
> > >
>
> Glyn
>
>
>
> Unless stated otherwise above:
> IBM United Kingdom Limited - Registered in England and Wales with
> number 741598.
> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6
3AU
>
>
>
>
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/jsr277-eg-observer/attachments/20070601/2ffb304f/attachment.html
More information about the jsr277-eg-observer
mailing list