Re: Relationship to JSR 291 [was: Re: Bryan's comments]

2007-05-30 Thread Bryan Atsatt

Stanley M. Ho wrote:

Hi,

Glyn Normington wrote:


*Bryan Atsatt <[EMAIL PROTECTED]>* wrote on 30/05/2007 07:57:59:
...
 > 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.


I agreed with Glyn that this might be reaching too far. Before we dive
too much into how to implement interoperability, I think one of the
outstanding questions we should answer first is what degree of import
interoperability we want to offer. There are four possibilities:

1. JSR 277 module imports OSGi module by module name
2. OSGi module imports JSR 277 module by module name
3. OSGi module imports JSR 277 module by package name
4. JSR 277 module imports OSGi module by package name

Let's ignore the 294 issues and the module initialization issues for now
to simplify this discussion.

I think we all agreed #1 and #2 are important to support and the
reflective APIs already enable these (of course, there are minor issues
we still have to address as we evolve the APIs.)

That said, it is unclear to me how important it is to support #3 and #4,
so I think the first question for this EG is whether we want to support
#3 and #4 at all. However, let's pretend #3 and #4 are important for
this specific discussion.

I think #3 is already possible since the OSGi framework could look up
the appropriate module which exported the package in the repository,
using the reflective APIs. Afterwards, the OSGi framework can then do
the necessary wiring. Yes, the reflective APIs can be further refined to
make it easier for the OSGi framework to query modules by exported
package name from the repository, but this is a minor issue that we can
address easily.

#4 is a bit complicated, because there is no import-by-package semantic
in the current module layer's APIs and I think we all agreed that we
don't want to support this semantic directly in the module system
defined by JSR 277.


Not me.

I do understand your point that this is more difficult, but I don't
really care--it is our job to do the Right Thing here. Sure, if it is
not feasible in the time frame we have, then so be it. But we haven't
even tried!

If we're forced to make a choice between the two models, I'd pick
import-by-package with zero hesitation.

OSGi has a lot of experience here, and we shouldn't ignore it.
Import-by-name was added late in the game, and is now seriously
downplayed, for good reason.

And Oracle has a lot of relevant experience as well, since the shared
loader mechanism I created for our AS stack ("shared libraries")
supports only the import-by-name model. We have *lots* of
shared-libraries (I've seen 100+ running simultaneously), used by many
different components in the stack, in addition to customer applications.
It is a tremendous pain when refactoring or even simple renaming has to
be done (I hope to shift this implementation onto 277 to solve this
problem, rather than inventing an interim approach). And this kind of
change happens far more frequently than you probably expect.

I don't want to repeat the same mistake here. Nor do I think that
leaving a long trail of extraneous "view" modules behind for
compatibility is a good solution.

Worse still, if the 277 APIs don't support import-by-package, then the
compiler won't support it either. If the compiler doesn't support it,
then we've lost a golden opportunity to move to a better world, one in
which packaging is irrelevant.

We're supposed to be eliminating "jar-hell" here. Let's not simply
replace it with "module-hell".


In this context, the question is really about what
it would take to make #4 possible if we want to support it, and so far
there are two different approaches we have discussed:

a. Treat import-by-package separately from import-by-module in the
reflective APIs and make the module layer fully aware of the
import-by-package concept.

b. Expose exported-package using the ModuleDefinition abstraction, and
provide necessary hooks (e.g. consistency checking) for the module
system to resolve this kind of dependency appropriately. The module
layer is not aware of the import-by-package concept at all. New import
dependency granularity could also be introduced in a similar manner in
the future without requiring significant changes in the module layer.


As Richard and I discussed in previous emails, it seems to make the most
sense for JSR 277 to define the minimal set of features possible in the
module layer to accomplish what needs to be accomplished to

Re: Relationship to JSR 291 [was: Re: Bryan's comments]

2007-05-30 Thread Richard S. Hall

On May 30, 2007, at 5:55 PM, Stanley M. Ho wrote:


Glyn Normington wrote:


*Bryan Atsatt <[EMAIL PROTECTED]>* wrote on 30/05/2007
07:57:59:
...
 > 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.


I agreed with Glyn that this might be reaching too far. Before we dive
too much into how to implement interoperability, I think one of the
outstanding questions we should answer first is what degree of import
interoperability we want to offer. There are four possibilities:

1. JSR 277 module imports OSGi module by module name
2. OSGi module imports JSR 277 module by module name
3. OSGi module imports JSR 277 module by package name
4. JSR 277 module imports OSGi module by package name

Let's ignore the 294 issues and the module initialization issues
for now
to simplify this discussion.

I think we all agreed #1 and #2 are important to support and the
reflective APIs already enable these (of course, there are minor
issues
we still have to address as we evolve the APIs.)

That said, it is unclear to me how important it is to support #3
and #4,
so I think the first question for this EG is whether we want to
support
#3 and #4 at all. However, let's pretend #3 and #4 are important for
this specific discussion.

I think #3 is already possible since the OSGi framework could look up
the appropriate module which exported the package in the repository,
using the reflective APIs. Afterwards, the OSGi framework can then do
the necessary wiring. Yes, the reflective APIs can be further
refined to
make it easier for the OSGi framework to query modules by exported
package name from the repository, but this is a minor issue that we
can
address easily.


I am not so sure supporting #3 is as straight forward as you suggest
here. Specially, the OSGi modularity layer [for the most part]
assumes that packages are atomic units; there is no way to specify
that your export or import something smaller than a package. Since
277 modules declare exports in terms of classes, it is not clear how
we would know if a 277 module was exporting an entire package. This
would, at a minimum, require that we assume we can inspect the
contents of the module and see that the contents of a contained
package matches the module's export signature for that package.

-> richard



#4 is a bit complicated, because there is no import-by-package
semantic
in the current module layer's APIs and I think we all agreed that we
don't want to support this semantic directly in the module system
defined by JSR 277. In this context, the question is really about what
it would take to make #4 possible if we want to support it, and so far
there are two different approaches we have discussed:

a. Treat import-by-package separately from import-by-module in the
reflective APIs and make the module layer fully aware of the
import-by-package concept.

b. Expose exported-package using the ModuleDefinition abstraction, and
provide necessary hooks (e.g. consistency checking) for the module
system to resolve this kind of dependency appropriately. The module
layer is not aware of the import-by-package concept at all. New import
dependency granularity could also be introduced in a similar manner in
the future without requiring significant changes in the module layer.


As Richard and I discussed in previous emails, it seems to make the
most
sense for JSR 277 to define the minimal set of features possible in
the
module layer to accomplish what needs to be accomplished to provide
core
modularity support in the Java platform. I think (b) follows this
principle nicely while (a) does not. If we decide to support #3 and
#4,
then how we want to address #4 would impact our overall design
significantly.

Is there anyone in the EG provide good reasons why #3 and #4 are
important to be supported? If so, is there anyone in the EG think
(b) is
not feasible at all and we should do (a) instead to support #4? Can
you
explain your rationale?



 > 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.


In the existing module systems we are aware, e.g. OSGi and
NetBeans, we
alread

Re: Exported resources

2007-05-30 Thread Bryan Atsatt

Hey Stanley,

Sorry to be generating so much traffic while you're traveling! I'm not
in any rush here, so feel free to take your time responding...

Stanley M. Ho wrote:

Hi Bryan,

A module can use the ResourceBundle API to retrieve resources from other
resource modules, but it can also use the ResourceBundle API to retrieve
resources from the (target) module itself. In the latter case, the
resources are currently not required to be exported from the target module.

I don't think we want to force a module to export its own private
resources simply because it wants to use the ResourceBundle API in this
case, would you agree?


No, I don't agree. That's what I said before :^). I *really* don't like
the idea that I'm going to have to explicitly grant permission to some
module to access my resource. This *significantly* complicates
deployment. How will the grant occur, especially given that each
environment can use an entirely different permission storage mechanism?

Or are you thinking that the loaders in the module system will construct
ProtectionDomains pre-wired with permissions? If so, exactly which
entities will be blessed? Just the JRE code? What about all the existing
non-JRE frameworks in use?


Regarding there are differences in the access models between classes and
resources, I also prefer symmetry if possible. However, the access model
for classes and resources have always been different, and there are
built-in JVM support for classes while there is none for resources, so
it is unclear if we can completely eliminate this asymmetry after all.


Sure, resources have never had JVM access control applied to them. But I
don't think we should go to the other extreme (permissions) just so that
I can give "friend" access to private resources. I'd much prefer that
such resources simply be exported.

And I don't see this as a particular problem, either. We've gotten along
just fine without private resources so far (or maybe there is some big
demand for this that I'm missing?).

And what about the mismatch issue I brought up? Lots of existing
frameworks use the "services" pattern, in which:

1. A well known resource name is used in a getResource() call.
2. The resource contains a string naming a provider class.
3. The provider class is loaded using Class.forName().

This is a simple but very powerful pattern, but it requires that *both*
the resource and the named class be accessible to the framework. If we
require a permission grant for the resource, but not for the class, it
will be very easy to get access to one and not the other. Is it really
worth opening up this potential headache to enable a friend model for
resources?

// Bryan



- Stanley


Bryan Atsatt wrote:

I've been assuming that Module private resources should not be visible
to *any* class outside of the module. Including ResourceBundle, or any
other existing framework classes that do resource lookups (e.g.
ServiceLoader, JSF, etc). If resources need to be visible to these
existing classes, they must be exported. The very simple check I
proposed (immediate caller) is sufficient to make this assertion.

I believe your point is that if we used the permission model instead, it
would become possible for a module to invoke an external class (e.g.
ResourceBundle.getBundle()) and enable *it* to successfully load a
private resource from the module.

Aside from the permission *grant* mechanism this model would rely on, it
is an entirely different model than that used for classes! (Though we
haven't explicitly defined this in 294, it seems extremely unlikely that
we will rely on permissions--none of the other access modes do so.) Such
asymmetry is very disconcerting to me, and, I believe, just plain
wrong...

Consider that you could grant the ServiceLoader, for example, access to
a resource that names a class that it could not instantiate. That class
would have to be exported. I believe the resource should be as well.

// Bryan




Re: Service providers

2007-05-30 Thread Stanley M. Ho

Hi Richard,

Richard S. Hall wrote:

Hey Stanley,
...
To me, this sounds like what we call the "extender model" for the OSGi
framework. The way it works is that bundles that want to participate in
certain scenarios simply include some metadata inside of themselves,
then some infrastructure can probe for this metadata and automatically
do work on their behalf. This is how Declarative Services works in the
R4 spec and also how Spring-OSGi works...it is becoming a very common
model.

The benefit of this approach is that it doesn't push upper layer
concepts down into the modularity layer and keeps it simple. Off the top
of my head, I don't see a reason why the Service Loader couldn't use a
similar approach.

-> richard


Thanks. I will certainly check it out to see if this approach is feasible.

- Stanley


Re: Exported resources

2007-05-30 Thread Stanley M. Ho

Hi Bryan,

A module can use the ResourceBundle API to retrieve resources from other
resource modules, but it can also use the ResourceBundle API to retrieve
resources from the (target) module itself. In the latter case, the
resources are currently not required to be exported from the target module.

I don't think we want to force a module to export its own private
resources simply because it wants to use the ResourceBundle API in this
case, would you agree?

Regarding there are differences in the access models between classes and
resources, I also prefer symmetry if possible. However, the access model
for classes and resources have always been different, and there are
built-in JVM support for classes while there is none for resources, so
it is unclear if we can completely eliminate this asymmetry after all.

- Stanley


Bryan Atsatt wrote:

I've been assuming that Module private resources should not be visible
to *any* class outside of the module. Including ResourceBundle, or any
other existing framework classes that do resource lookups (e.g.
ServiceLoader, JSF, etc). If resources need to be visible to these
existing classes, they must be exported. The very simple check I
proposed (immediate caller) is sufficient to make this assertion.

I believe your point is that if we used the permission model instead, it
would become possible for a module to invoke an external class (e.g.
ResourceBundle.getBundle()) and enable *it* to successfully load a
private resource from the module.

Aside from the permission *grant* mechanism this model would rely on, it
is an entirely different model than that used for classes! (Though we
haven't explicitly defined this in 294, it seems extremely unlikely that
we will rely on permissions--none of the other access modes do so.) Such
asymmetry is very disconcerting to me, and, I believe, just plain wrong...

Consider that you could grant the ServiceLoader, for example, access to
a resource that names a class that it could not instantiate. That class
would have to be exported. I believe the resource should be as well.

// Bryan


Re: Relationship to JSR 291 [was: Re: Bryan's comments]

2007-05-30 Thread Stanley M. Ho

Hi,

Glyn Normington wrote:


*Bryan Atsatt <[EMAIL PROTECTED]>* wrote on 30/05/2007 07:57:59:
...
 > 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.


I agreed with Glyn that this might be reaching too far. Before we dive
too much into how to implement interoperability, I think one of the
outstanding questions we should answer first is what degree of import
interoperability we want to offer. There are four possibilities:

1. JSR 277 module imports OSGi module by module name
2. OSGi module imports JSR 277 module by module name
3. OSGi module imports JSR 277 module by package name
4. JSR 277 module imports OSGi module by package name

Let's ignore the 294 issues and the module initialization issues for now
to simplify this discussion.

I think we all agreed #1 and #2 are important to support and the
reflective APIs already enable these (of course, there are minor issues
we still have to address as we evolve the APIs.)

That said, it is unclear to me how important it is to support #3 and #4,
so I think the first question for this EG is whether we want to support
#3 and #4 at all. However, let's pretend #3 and #4 are important for
this specific discussion.

I think #3 is already possible since the OSGi framework could look up
the appropriate module which exported the package in the repository,
using the reflective APIs. Afterwards, the OSGi framework can then do
the necessary wiring. Yes, the reflective APIs can be further refined to
make it easier for the OSGi framework to query modules by exported
package name from the repository, but this is a minor issue that we can
address easily.

#4 is a bit complicated, because there is no import-by-package semantic
in the current module layer's APIs and I think we all agreed that we
don't want to support this semantic directly in the module system
defined by JSR 277. In this context, the question is really about what
it would take to make #4 possible if we want to support it, and so far
there are two different approaches we have discussed:

a. Treat import-by-package separately from import-by-module in the
reflective APIs and make the module layer fully aware of the
import-by-package concept.

b. Expose exported-package using the ModuleDefinition abstraction, and
provide necessary hooks (e.g. consistency checking) for the module
system to resolve this kind of dependency appropriately. The module
layer is not aware of the import-by-package concept at all. New import
dependency granularity could also be introduced in a similar manner in
the future without requiring significant changes in the module layer.


As Richard and I discussed in previous emails, it seems to make the most
sense for JSR 277 to define the minimal set of features possible in the
module layer to accomplish what needs to be accomplished to provide core
modularity support in the Java platform. I think (b) follows this
principle nicely while (a) does not. If we decide to support #3 and #4,
then how we want to address #4 would impact our overall design
significantly.

Is there anyone in the EG provide good reasons why #3 and #4 are
important to be supported? If so, is there anyone in the EG think (b) is
not feasible at all and we should do (a) instead to support #4? Can you
explain your rationale?



 > 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.


In the existing module systems we are aware, e.g. OSGi and NetBeans, we
already know their resolution logics are different from each other. Even
if they are migrated/re-based to JSR 277 in the future, I think we
should expect their resolution logic would remain the same to maintain
backward compatibility with their existing modules/bundles. In other
words, their resolution logic would still be different from each other.


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 sufficien

Re: Exported resources

2007-05-30 Thread Bryan Atsatt

I've been assuming that Module private resources should not be visible
to *any* class outside of the module. Including ResourceBundle, or any
other existing framework classes that do resource lookups (e.g.
ServiceLoader, JSF, etc). If resources need to be visible to these
existing classes, they must be exported. The very simple check I
proposed (immediate caller) is sufficient to make this assertion.

I believe your point is that if we used the permission model instead, it
would become possible for a module to invoke an external class (e.g.
ResourceBundle.getBundle()) and enable *it* to successfully load a
private resource from the module.

Aside from the permission *grant* mechanism this model would rely on, it
is an entirely different model than that used for classes! (Though we
haven't explicitly defined this in 294, it seems extremely unlikely that
we will rely on permissions--none of the other access modes do so.) Such
asymmetry is very disconcerting to me, and, I believe, just plain wrong...

Consider that you could grant the ServiceLoader, for example, access to
a resource that names a class that it could not instantiate. That class
would have to be exported. I believe the resource should be as well.

// Bryan




Stanley M. Ho wrote:

Hi Bryan,

Those resource-related methods in ClassLoader can be called by anyone,
including code that is part of the module, code that is from other
modules, or code that is part of the platform libraries (e.g.
ResourceBundle). The approach you described would require walking the
stack to get the caller's Module, but the real issue is that it is
difficult to determine who the actual caller is from the stack.

Treating the immediate caller on the stack as the actual caller wouldn't
be sufficient because the immediate caller could be called by someone
else who is the one actually making the call. On the other hand,
treating the originated caller on the stack as the actual caller would
be the right semantic, but this is basically the same as the security
permission approach.

- Stanley


Bryan Atsatt wrote:

Both solutions require stack walking (unless there is some new
implementation of the java security model I've not yet seen!).

The permission check does much more work than is necessary here. Take a
look at AccessController.checkPermission() to see what I mean.

And actually there is a very simple API to get the stack, which I've
used for years:

  private static class StackAccessor extends SecurityManager {
  public Class[] getStack() {
  return getClassContext();
  }
  }

  private static final STACK_ACCESSOR = new StackAccessor();

Now the enclosing class can simply call STACK_ACCESSOR.getStack().

// Bryan



Stanley M. Ho wrote:

Hi Bryan,

Bryan Atsatt wrote:

1. Definitely agree that resource search order should be identical to
class search order.


Glad to hear!


2. Using permissions to limit access to private resources seems like
overkill to me. The prototype implemented this in a very simple
fashion:

a. If resource is exported, return it, else
a. Get the caller's Module (get class from stack, get module from it)
b. If callerModule == this, return resource, else return null.


The issue is that this approach still requires stack walking and there
is no public API in the SE platform that let you implement this.

If stack walking is required for the check anyway, I think the security
permission approach is better that it is implementable with the existing
API in the SE platform.

- Stanley





Re: Service providers

2007-05-30 Thread Richard S. Hall

Hey Stanley,

Stanley M. Ho wrote:

Richard S. Hall wrote:

Hello Stanley,
...
I guess the addition of service-related concepts into the module layer
would be one example of feature creep for me. While I think it makes
perfect sense to figure out how the Service Loader stuff will work on
top of the module layer, pushing Service Loader concepts down into the
module layer doesn't make any sense to me at all.

It should be sufficient for the Service Loader to probe the installed
modules and perhaps examine module metadata to determine if a module
provides a service or not. From there, the Service Loader can create
module instances and provider instances as necessary.

If this is not possible in our current constructs, then we should
address these shortcomings rather than adding higher layer concepts into
the module layer.

-> richard


The current service provider strawman suggests a few changes in
ModuleDefinition/Query classes, and you basically suggest that these
changes could be eliminated if we have a more generic way to express
services and service-providers in the module metadata and a generic way
to examine the information from the module metadata, all without
service-related APIs in the module layer.

I think what you suggested makes sense, and I will look into this.


To me, this sounds like what we call the "extender model" for the OSGi
framework. The way it works is that bundles that want to participate in
certain scenarios simply include some metadata inside of themselves,
then some infrastructure can probe for this metadata and automatically
do work on their behalf. This is how Declarative Services works in the
R4 spec and also how Spring-OSGi works...it is becoming a very common model.

The benefit of this approach is that it doesn't push upper layer
concepts down into the modularity layer and keeps it simple. Off the top
of my head, I don't see a reason why the Service Loader couldn't use a
similar approach.

-> richard


Service providers (was: Richard's comments)

2007-05-30 Thread Stanley M. Ho

Hi Richard,

I have renamed the subject so we can discuss issues around the
service-provider strawman in its own thread.

Richard S. Hall wrote:

Hello Stanley,
...
I guess the addition of service-related concepts into the module layer
would be one example of feature creep for me. While I think it makes
perfect sense to figure out how the Service Loader stuff will work on
top of the module layer, pushing Service Loader concepts down into the
module layer doesn't make any sense to me at all.

It should be sufficient for the Service Loader to probe the installed
modules and perhaps examine module metadata to determine if a module
provides a service or not. From there, the Service Loader can create
module instances and provider instances as necessary.

If this is not possible in our current constructs, then we should
address these shortcomings rather than adding higher layer concepts into
the module layer.

-> richard


The current service provider strawman suggests a few changes in
ModuleDefinition/Query classes, and you basically suggest that these
changes could be eliminated if we have a more generic way to express
services and service-providers in the module metadata and a generic way
to examine the information from the module metadata, all without
service-related APIs in the module layer.

I think what you suggested makes sense, and I will look into this.

- Stanley


Re: Exported resources

2007-05-30 Thread Stanley M. Ho

Hi Bryan,

Those resource-related methods in ClassLoader can be called by anyone,
including code that is part of the module, code that is from other
modules, or code that is part of the platform libraries (e.g.
ResourceBundle). The approach you described would require walking the
stack to get the caller's Module, but the real issue is that it is
difficult to determine who the actual caller is from the stack.

Treating the immediate caller on the stack as the actual caller wouldn't
be sufficient because the immediate caller could be called by someone
else who is the one actually making the call. On the other hand,
treating the originated caller on the stack as the actual caller would
be the right semantic, but this is basically the same as the security
permission approach.

- Stanley


Bryan Atsatt wrote:

Both solutions require stack walking (unless there is some new
implementation of the java security model I've not yet seen!).

The permission check does much more work than is necessary here. Take a
look at AccessController.checkPermission() to see what I mean.

And actually there is a very simple API to get the stack, which I've
used for years:

  private static class StackAccessor extends SecurityManager {
  public Class[] getStack() {
  return getClassContext();
  }
  }

  private static final STACK_ACCESSOR = new StackAccessor();

Now the enclosing class can simply call STACK_ACCESSOR.getStack().

// Bryan



Stanley M. Ho wrote:

Hi Bryan,

Bryan Atsatt wrote:

1. Definitely agree that resource search order should be identical to
class search order.


Glad to hear!


2. Using permissions to limit access to private resources seems like
overkill to me. The prototype implemented this in a very simple fashion:

a. If resource is exported, return it, else
a. Get the caller's Module (get class from stack, get module from it)
b. If callerModule == this, return resource, else return null.


The issue is that this approach still requires stack walking and there
is no public API in the SE platform that let you implement this.

If stack walking is required for the check anyway, I think the security
permission approach is better that it is implementable with the existing
API in the SE platform.

- Stanley



Re: ClassLoader Deadlock fix

2007-05-30 Thread Stanley M. Ho

Hi JSR 277 experts,

Below are some comments from Jeff Nisewanger and Karen Kinnear who are
working on the ClassLoader API improvements for Java SE 7. If you are
interested in contributing to the ClassLoader API improvements as a
reviewer, you may contact Jeff and Karen at [EMAIL PROTECTED] and
[EMAIL PROTECTED]

- Stanley

 Original Message 
Hi,

Sun is working on the ClassLoader Deadlock fix. Our goal is to work
closely with the community, of which the 277 EG contains key members, in
coming up with small modifications to the current ClassLoader APIs to
resolve that issue.

As we've mentioned before, and Glyn even points out in his referenced
blog, we did add a temporary risky unstable workaround which only really
handles a small special case for WebSphere 6.1 which should be
supplanted by the new mechanism as that becomes available.

One of the key issues here is that a prerequisite for avoiding the
ClassLoader deadlocks is that the JVM must not hold the ClassLoader
Object lock when it calls out to LoadClass[Internal]. And presumably the
lock must not be held when the custom class loader's loadClass() is called.

As anyone who has written a custom class loader would immediately
recognize, changing that underlying assumption is inherently risky. It
is all too easy to break existing custom class loaders that were perhaps
unknowingly relying on that lock to protect critical data and
operations. Those are the kind of breakages that are extremely timing
dependent and can pass many test cases and then unexpectedly fail in the
field. I'm sure you all also remember when Unix user level libraries
were converted to being MT-safe. We didn't get them all right the first
time around. We don't want to put our customers in that position.

So a part of the ClassLoader API modifications would be for class
loaders to explicitly declare that they are safe for parallel class
loading, both for multiple classes in the same class loader, and for
multiple instances of the same class in the same class loader.

I have been assuming that this would be the default for JSR 277, but we
can work that issue in detail when we have a strawman ClassLoader API
proposal.

In the meantime, thank you very much to Adrian Brock for his
classcircularity example. I will be studying it in detail. If any other
EG member has a test scenario they would like to describe to us or even
better they have a test case for, we would very much appreciate it.

And if you are interested in contributing to the ClassLoader API
improvements as a reviewer, please let us know.

Thank you,
Jeff Nisewanger & Karen Kinnear


Re: Relationship to JSR 291 [was: Re: Bryan's comments]

2007-05-30 Thread Bryan Atsatt

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 <[EMAIL PROTECTED]>* 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?



 >
 > 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
 >

Re: Relationship to JSR 291 [was: Re: Bryan's comments]

2007-05-30 Thread Glyn Normington
Bryan Atsatt <[EMAIL PROTECTED]> 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.

>
> 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.

>
>
> (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 thi

Re: ClassLoader Deadlock fix was: Re: Relationship to JSR 291 [was: Re: Bryan's comments]

2007-05-30 Thread Glyn Normington
Adrian <[EMAIL PROTECTED]> wrote on 25/05/2007 12:44:54:

> On Thu, 2007-05-24 at 11:00 +0100, Glyn Normington wrote:
> > A better approach would be for the Java 7 platform to provide first
> > class support for JSR 291. This boils down to standardising the
> > experimental class loader deadlock fix ([1])
>
> Fixing the deadlock just moves the problem.
>
> You'll still get ClassCircularityErrors when competing threads
> try to load classes using locks other than the classloader
> synchronization or they don't synchronize on the loadClass()
> or they release the lock during the classloading request
> to let others have a go (again to avoid the deadlock).
>
> This is because of the way the dictionary class determines
> whether a circular load is occuring.
>
> Although I haven't tried it with OpenJDK so maybe the
> dictionary class contains some other fixes to workaround the
> problem?
>
> The simple form of the problem:
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4699981
> has been fixed in recent JDKs, but spurious CCEs
> still exist in other cases.
> e.g. the testAbstractFactoryConcurrent() here:
> http://viewvc.jboss.org/cgi-bin/viewvc.
>
cgi/jbossas/projects/microcontainer/trunk/classloader/src/tests/org/jboss/test/classloader/delegate/test/DelegateUnitTestCase.
> java?revision=62792&view=markup
> will show CCEs in the log if you enable TRACE logging.
>
> 1445 TRACE [ClassLoaderManager] Run failed with exception
> java.lang.ClassCircularityError:
> org/jboss/test/classloader/delegate/support/b/TestFactoryImplementation
> at java.lang.ClassLoader.defineClass1(Native Method)
> at java.lang.ClassLoader.defineClass(ClassLoader.java:620)

Some spurious CCEs were indeed fixed before the experimental deadlock fix
was introduced, but there may be more to do to make this fix robust and
complete. If you raise a sunbug for the above testcase, best to report it
here so that class loader rearchitecture folks can take it into
consideration for Java 7.

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: Relationship to JSR 291 [was: Re: Bryan's comments]

2007-05-30 Thread Bryan Atsatt

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.)

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...


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.

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.


(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.
pub