Re: Module isolation

2007-06-14 Thread Stanley M. Ho

Resend.

Bryan Atsatt wrote:
>
> It seems to me that if we're going to follow this model, then:
>
> 1. There is a 1:1 relationship between ModuleDefinition instances and
> Module instances.

ModuleSystem is the one actually handling the module instances'
instantiation, initialization, and release. Typically, instantiating a
Module from a ModuleDefinition through the ModuleSystem will return the
same cached Module instance for sharing, and it's 1:1. That said, the
ModuleSystem also has a releaseModule() method (see Section 7.1.4 in the
spec) that allows Module instance to be released from the cache when
necessary, and that Module instance will be GCed eventually. If a
ModuleDefinition is instantiated multiple times and each time
ModuleSystem.releaseModule() is also called for that ModuleDefinition,
it is possible to have multiple Module instances in memory for a given
ModuleDefinition, although calling getModuleInstance() method on
ModuleDefinition will only return the Module instance in the
ModuleSystem's cache.

> 2. Given #1, why does the getModuleInstance() method on ModuleDefinition
> need to call through to the ModuleSystem? As it is, the ModuleSystem
> must keep a separate map, which seems like overkill. The definition type
> will be specific to the module system, so it can always instantiate the
> correct type, and simply cache it in a field.

That's because ModuleSystem does much more than instantiating a Module
instance from a ModuleDefinition. ModuleSystem is also responsible for
initializing the Module instance to interconnect the imported modules
(and resolve potential cyclic dependencies) and to perform type
consistency checking. To do module initialization properly, ModuleSystem
needs to be aware of all the cached Module instances (so they can be
reused for sharing) and all the Module instances that are in the process
of instantiation, initialization, and release.

The getModuleInstance() method on ModuleDefinition is simply a
convenience method to get to the Module instance from the ModuleSystem,
and ModuleDefinition does not keep track of any Module instance itself.
It is the ModuleSystem doing all the actual works.

> 3. The ModuleDefinition copy operation and semantics must be defined. We
> could simply implement Cloneable, or create a copy() operation. Either
> way, it needs to be clear *what* is copied; I would think we would copy
> all of the data *except* for the ModuleDefinitionContent.

It is unclear to me which use case you have in mind that requires
cloning of ModuleDefinition. At a high level, the information in
ModuleDefinition can be retrieved from ModuleDefinitionContent. If you
have a ModuleDefinitionContent instance, you could simply construct new
ModuleDefinition instances with it, and you don't need cloning.

- Stanley


Re: Module isolation

2007-06-14 Thread Stanley M. Ho

Hi Bryan,

Bryan Atsatt wrote:

...
It seems to me that if we're going to follow this model, then:

1. There is a 1:1 relationship between ModuleDefinition instances and
Module instances.


ModuleSystem is the one actually handling the module instances'
instantiation, initialization, and release. Typically, instantiating a
Module from a ModuleDefinition through the ModuleSystem will return the
same cached Module instance for sharing, and it's 1:1. That said, the
ModuleSystem also has a releaseModule() method (see Section 7.1.4 in the
spec) that allows Module instance to be released from the cache when
necessary, and that Module instance will be GCed eventually. If a
ModuleDefinition is instantiated multiple times and each time
ModuleSystem.releaseModule() is also called for that ModuleDefinition,
it is possible to have multiple Module instances in memory for a given
ModuleDefinition, although calling getModuleInstance() method on
ModuleDefinition will only return the Module instance in the
ModuleSystem's cache.


2. Given #1, why does the getModuleInstance() method on ModuleDefinition
need to call through to the ModuleSystem? As it is, the ModuleSystem
must keep a separate map, which seems like overkill. The definition type
will be specific to the module system, so it can always instantiate the
correct type, and simply cache it in a field.


That's because ModuleSystem does much more than instantiating a Module
instance from a ModuleDefinition. ModuleSystem is also responsible for
initializing the Module instance to interconnect the imported modules
(and resolve potential cyclic dependencies) and to perform type
consistency checking. To do module initialization properly, ModuleSystem
needs to be aware of all the cached Module instances (so they can be
reused for sharing) and all the Module instances that are in the process
of instantiation, initialization, and release.

The getModuleInstance() method on ModuleDefinition is simply a
convenience method to get to the Module instance from the ModuleSystem,
and ModuleDefinition does not keep track of any Module instance itself.
It is the ModuleSystem doing all the actual works.


3. The ModuleDefinition copy operation and semantics must be defined. We
could simply implement Cloneable, or create a copy() operation. Either
way, it needs to be clear *what* is copied; I would think we would copy
all of the data *except* for the ModuleDefinitionContent.


It is unclear to me which use case you have in mind that requires
cloning of ModuleDefinition. At a high level, the information in
ModuleDefinition can be retrieved from ModuleDefinitionContent. If you
have a ModuleDefinitionContent instance, you could simply construct new
ModuleDefinition instances with it, and you don't need cloning.

- Stanley


Re: Strawman: Services and service-providers support

2007-06-14 Thread Glyn Normington
"Stanley M. Ho" <[EMAIL PROTECTED]> wrote on 13/06/2007 07:19:10 PM:

> Since I have not heard any further input on the services and
> service-providers strawman, I suppose the EG is fine with the strawman
> overall except the issue raised by Richard. Unless I hear any objection,
> I will incorporate the appropriate portion of the strawman based on the
> feedback you have provided into the next revision of the specification.

I am very concerned that the scope of JSR 277 is being expanded
considerably without much attention being paid to the state of the art
(particularly Spring-OSGi and Declarative Services). If we could implement
good interoperation with JSR 291, we could delegate the complexities of
supporting services to JSR 291 and technologies like Spring-OSGi that
layer nicely on top of JSR 291.

Apart from that, the support for services in the strawman has some obvious
holes, so I don't think it is ready to be incorporated into the JSR 277
specification:

1. It seems to be lacking any form of dependency injection.

2. The namespace of services is global, but not partitioned by service
interface version. The effect of this is that a module could import v1 of
a service interface class and obtain an instance of the service that
implements v2 of the service interface and get a class cast exception.

3. There is no support for dynamic updates of service providers and
notification of service updates to service consumers. (This is consistent
with JSR 277's static nature, but I point it out as this is an obvious
future requirement based on our experience in OSGi.)

4. There seems to be some confusion in the strawman between loading of
service interfaces/implementations and construction and publication of
service instances.

I wonder what other Expert Group members think of this strawman. Silence
does not necessarily indicate happiness, so it would be good to have more
feedback.

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







Re: Module isolation

2007-06-14 Thread Stanley M. Ho

Resend.

Bryan Atsatt wrote:


It seems to me that if we're going to follow this model, then:

1. There is a 1:1 relationship between ModuleDefinition instances and
Module instances.


ModuleSystem is the one actually handling the module instances'
instantiation, initialization, and release. Typically, instantiating a
Module from a ModuleDefinition through the ModuleSystem will return the
same cached Module instance for sharing, and it's 1:1. That said, the
ModuleSystem also has a releaseModule() method (see Section 7.1.4 in the
spec) that allows Module instance to be released from the cache when
necessary, and that Module instance will be GCed eventually. If a
ModuleDefinition is instantiated multiple times and each time
ModuleSystem.releaseModule() is also called for that ModuleDefinition,
it is possible to have multiple Module instances in memory for a given
ModuleDefinition, although calling getModuleInstance() method on
ModuleDefinition will only return the Module instance in the
ModuleSystem's cache.


2. Given #1, why does the getModuleInstance() method on ModuleDefinition
need to call through to the ModuleSystem? As it is, the ModuleSystem
must keep a separate map, which seems like overkill. The definition type
will be specific to the module system, so it can always instantiate the
correct type, and simply cache it in a field.


That's because ModuleSystem does much more than instantiating a Module
instance from a ModuleDefinition. ModuleSystem is also responsible for
initializing the Module instance to interconnect the imported modules
(and resolve potential cyclic dependencies) and to perform type
consistency checking. To do module initialization properly, ModuleSystem
needs to be aware of all the cached Module instances (so they can be
reused for sharing) and all the Module instances that are in the process
of instantiation, initialization, and release.

The getModuleInstance() method on ModuleDefinition is simply a
convenience method to get to the Module instance from the ModuleSystem,
and ModuleDefinition does not keep track of any Module instance itself.
It is the ModuleSystem doing all the actual works.


3. The ModuleDefinition copy operation and semantics must be defined. We
could simply implement Cloneable, or create a copy() operation. Either
way, it needs to be clear *what* is copied; I would think we would copy
all of the data *except* for the ModuleDefinitionContent.


It is unclear to me which use case you have in mind that requires
cloning of ModuleDefinition. At a high level, the information in
ModuleDefinition can be retrieved from ModuleDefinitionContent. If you
have a ModuleDefinitionContent instance, you could simply construct new
ModuleDefinition instances with it, and you don't need cloning.

- Stanley


Re: Strawman: Services and service-providers support

2007-06-14 Thread Andy Piper
I share Glyn's concerns, but can someone remind me where the strawman is?!

Thanks!

andy

At 11:07 AM 6/14/2007, Glyn Normington wrote:

>"Stanley M. Ho" <[EMAIL PROTECTED]> wrote on 13/06/2007 07:19:10 PM:
>
> > Since I have not heard any further input on the services and
> > service-providers strawman, I suppose the EG is fine with the strawman
> > overall except the issue raised by Richard. Unless I hear any objection,
> > I will incorporate the appropriate portion of the strawman based on the
> > feedback you have provided into the next revision of the specification.
>
>I am very concerned that the scope of JSR 277 is being expanded
>considerably without much attention being paid to the state of the
>art (particularly Spring-OSGi and Declarative Services). If we could
>implement good interoperation with JSR 291, we could delegate the
>complexities of supporting services to JSR 291 and technologies like
>Spring-OSGi that layer nicely on top of JSR 291.
>
>Apart from that, the support for services in the strawman has some
>obvious holes, so I don't think it is ready to be incorporated into
>the JSR 277 specification:
>
>1. It seems to be lacking any form of dependency injection.
>
>2. The namespace of services is global, but not partitioned by
>service interface version. The effect of this is that a module could
>import v1 of a service interface class and obtain an instance of the
>service that implements v2 of the service interface and get a class
>cast exception.
>
>3. There is no support for dynamic updates of service providers and
>notification of service updates to service consumers. (This is
>consistent with JSR 277's static nature, but I point it out as this
>is an obvious future requirement based on our experience in OSGi.)
>
>4. There seems to be some confusion in the strawman between loading
>of service interfaces/implementations and construction and
>publication of service instances.
>
>I wonder what other Expert Group members think of this strawman.
>Silence does not necessarily indicate happiness, so it would be good
>to have more feedback.
>
>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
>
>
>
>
>



Notice:  This email message, together with any attachments, may contain 
information  of  BEA Systems,  Inc.,  its subsidiaries  and  affiliated 
entities,  that may be confidential,  proprietary,  copyrighted  and/or legally 
privileged, and is intended solely for the use of the individual or entity 
named in this message. If you are not the intended recipient, and have received 
this message in error, please immediately return this by email and then delete 
it.


Re: Strawman: Services and service-providers support

2007-06-14 Thread Glyn Normington
http://jcp.org/en/eg/download/jsr-277-service-provider-strawman-05222007.pdf?id=277&fileId=3438

Glyn

Andy Piper <[EMAIL PROTECTED]> wrote on 14/06/2007 12:43:45 PM:

> I share Glyn's concerns, but can someone remind me where the strawman
is?!
>
> Thanks!
>
> andy
>
> At 11:07 AM 6/14/2007, Glyn Normington wrote:
>
> >"Stanley M. Ho" <[EMAIL PROTECTED]> wrote on 13/06/2007 07:19:10 PM:
> >
> > > Since I have not heard any further input on the services and
> > > service-providers strawman, I suppose the EG is fine with the
strawman
> > > overall except the issue raised by Richard. Unless I hear any
objection,
> > > I will incorporate the appropriate portion of the strawman based on
the
> > > feedback you have provided into the next revision of the
specification.
> >
> >I am very concerned that the scope of JSR 277 is being expanded
> >considerably without much attention being paid to the state of the
> >art (particularly Spring-OSGi and Declarative Services). If we could
> >implement good interoperation with JSR 291, we could delegate the
> >complexities of supporting services to JSR 291 and technologies like
> >Spring-OSGi that layer nicely on top of JSR 291.
> >
> >Apart from that, the support for services in the strawman has some
> >obvious holes, so I don't think it is ready to be incorporated into
> >the JSR 277 specification:
> >
> >1. It seems to be lacking any form of dependency injection.
> >
> >2. The namespace of services is global, but not partitioned by
> >service interface version. The effect of this is that a module could
> >import v1 of a service interface class and obtain an instance of the
> >service that implements v2 of the service interface and get a class
> >cast exception.
> >
> >3. There is no support for dynamic updates of service providers and
> >notification of service updates to service consumers. (This is
> >consistent with JSR 277's static nature, but I point it out as this
> >is an obvious future requirement based on our experience in OSGi.)
> >
> >4. There seems to be some confusion in the strawman between loading
> >of service interfaces/implementations and construction and
> >publication of service instances.
> >
> >I wonder what other Expert Group members think of this strawman.
> >Silence does not necessarily indicate happiness, so it would be good
> >to have more feedback.
> >
> >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
> >
> >
> >
> >
> >
>
>
>
> Notice:  This email message, together with any attachments, may
> contain information  of  BEA Systems,  Inc.,  its subsidiaries  and
> affiliated entities,  that may be confidential,  proprietary,
> copyrighted  and/or legally privileged, and is intended solely for
> the use of the individual or entity named in this message. If you
> are not the intended recipient, and have received this message in
> error, please immediately return this by email and then delete it.






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







Re: Strawman: Services and service-providers support

2007-06-14 Thread Stanley M. Ho

Hi Glyn,

The existing service/service-provider model has been used in various SE
components for loading available providers from JARs in the installed
optional packages and classpath. Since JSR 277 will define a set of
repositories that allow multiple versions of modules to coexist and
these modules may define services and/or service-providers, what the
strawman describes is basically how JSR 277 will fit into this existing
service/service-provider model and provide support for it.

While I agreed with you that enhancing the existing
service/service-provider model is desirable (like #1 and #2 you pointed
out), it is outside the scope of JSR 277 (i.e. JSR 277 is not chartered
to change the service/service-provider model.) Therefore, I suggest we
should focus our discussion on issues around how to support the existing
service/service-provider model.

#3 you mentioned is somewhat related to another topic I would like to
bring up, and I will start the discussion in another thread. For #4, it
is unclear to me what the issues are, could you elaborate?

Thanks,
- Stanley


Glyn Normington wrote:


I am very concerned that the scope of JSR 277 is being expanded
considerably without much attention being paid to the state of the art
(particularly Spring-OSGi and Declarative Services). If we could
implement good interoperation with JSR 291, we could delegate the
complexities of supporting services to JSR 291 and technologies like
Spring-OSGi that layer nicely on top of JSR 291.

Apart from that, the support for services in the strawman has some
obvious holes, so I don't think it is ready to be incorporated into the
JSR 277 specification:

1. It seems to be lacking any form of dependency injection.

2. The namespace of services is global, but not partitioned by service
interface version. The effect of this is that a module could import v1
of a service interface class and obtain an instance of the service that
implements v2 of the service interface and get a class cast exception.

3. There is no support for dynamic updates of service providers and
notification of service updates to service consumers. (This is
consistent with JSR 277's static nature, but I point it out as this is
an obvious future requirement based on our experience in OSGi.)

4. There seems to be some confusion in the strawman between loading of
service interfaces/implementations and construction and publication of
service instances.

I wonder what other Expert Group members think of this strawman. Silence
does not necessarily indicate happiness, so it would be good to have
more feedback.

Glyn


Re: Module isolation

2007-06-14 Thread Bryan Atsatt

Stanley M. Ho wrote:

Hi Bryan,

Bryan Atsatt wrote:

...
It seems to me that if we're going to follow this model, then:

1. There is a 1:1 relationship between ModuleDefinition instances and
Module instances.


ModuleSystem is the one actually handling the module instances'
instantiation, initialization, and release. Typically, instantiating a
Module from a ModuleDefinition through the ModuleSystem will return the
same cached Module instance for sharing, and it's 1:1. That said, the
ModuleSystem also has a releaseModule() method (see Section 7.1.4 in the
spec) that allows Module instance to be released from the cache when
necessary, and that Module instance will be GCed eventually. If a
ModuleDefinition is instantiated multiple times and each time
ModuleSystem.releaseModule() is also called for that ModuleDefinition,
it is possible to have multiple Module instances in memory for a given
ModuleDefinition, although calling getModuleInstance() method on
ModuleDefinition will only return the Module instance in the
ModuleSystem's cache.


Apparently I don't understand the use case here. Though releaseModule()
is exactly like the detach() method I put in the prototype, I realized
long ago that this pattern does not work well for isolation, as you
cannot control access to the original instances *or* the subsequent
instances--there is no "transaction" model.

A separate, private, Repository instance, OTOH, does provide such a model.

Can you please explain the use case for releaseModule()?

If there is no strong case for this, I would much prefer to stick with
the very simple 1:1 model.




2. Given #1, why does the getModuleInstance() method on ModuleDefinition
need to call through to the ModuleSystem? As it is, the ModuleSystem
must keep a separate map, which seems like overkill. The definition type
will be specific to the module system, so it can always instantiate the
correct type, and simply cache it in a field.


That's because ModuleSystem does much more than instantiating a Module
instance from a ModuleDefinition. ModuleSystem is also responsible for
initializing the Module instance to interconnect the imported modules
(and resolve potential cyclic dependencies) and to perform type
consistency checking. To do module initialization properly, ModuleSystem
needs to be aware of all the cached Module instances (so they can be
reused for sharing) and all the Module instances that are in the process
of instantiation, initialization, and release.


Of course ModuleSystem must be involved, but that is orthogonal to
*where* the instance is cached.

Would you agree that if we did not support releaseModule(), caching the
Module instance in the ModuleDefinition would eliminate some complexity?



The getModuleInstance() method on ModuleDefinition is simply a
convenience method to get to the Module instance from the ModuleSystem,
and ModuleDefinition does not keep track of any Module instance itself.
It is the ModuleSystem doing all the actual works.


3. The ModuleDefinition copy operation and semantics must be defined. We
could simply implement Cloneable, or create a copy() operation. Either
way, it needs to be clear *what* is copied; I would think we would copy
all of the data *except* for the ModuleDefinitionContent.


It is unclear to me which use case you have in mind that requires
cloning of ModuleDefinition. At a high level, the information in
ModuleDefinition can be retrieved from ModuleDefinitionContent. If you
have a ModuleDefinitionContent instance, you could simply construct new
ModuleDefinition instances with it, and you don't need cloning.


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.



- Stanley



Re: Module isolation

2007-06-14 Thread Stanley M. Ho

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.

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.


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.

- Stanley


Re: Module isolation

2007-06-14 Thread Bryan Atsatt

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