Fieber, Cameron C FOR:EX wrote:

Hi Stephen,

I think I see where you are going with this.  As a first step, what do you
think if I implement the <specification> section of the <service>
declaration, but basically just read the artifact entries from the
specification section and promote them up the classloader chain?  After that
is working, then we could tackle the classloader relocation and extension
resolving.

I was chatting to Niclas about this subject a day or two ago and he basically came up with a bunch of issues none of which I can reasonably summarize at 5 in the morning. However - it did get me thinking about the difference in scope of specification between the block and a service.


If we take the http facility as an example block - we basically have a specification of system represented by the set of services provided by the block - i.e. the "http facility specification". If we look at the specification dependencies at this level we see things like the Servlet 2.1 specification. However - if we look down at the services that are exported - the specifications are much more fine grain.

My conclusion is that the specification I'm describing below should declared at the block level - and not at the service level - e.g.:

  <classloader>
    <specifications>
      <specification>
        <name>urn:apache:widget</name>
        <version>2.1</version>
        <artifact>apache/widget#2.1</artifact>
        </specification>
      </specification>
    </specifications>
    <classpath>
      <!-- as per current approach -->
    </classpath
  <classloader>

From this - we simply merge the spec artifact as an entry in the classloader classpath.

I still think that the notion of including specification details in the service element is a good idea - but I think its a scope related to service usage as distinct from the structural specification presented in the classloader.

Cheers, Stephen.



-Cameron


-----Original Message-----
From: Stephen McConnell
To: Avalon framework users
Sent: 4/24/04 10:30 AM
Subject: Re: [merlin] separate api and impl sections in classloader section
of      block.xml?


Cameron:


The declaration of an <api> classloader set (under the classloader or under a service export directive) is basically stating to the container that to use service X, you need to have in you classloader jar files A, B and C. Problem here is that the your going to express A, B and C in terms of jar artifact references as opposed to specification references.

What we want to be able to say - for a particular service export - is ... "to use this service the consumer's classloader needs to provide support for specification X". If we look at the consumer's classloader we can check manifest entries for the Extension-Name combined with a compatibility check relative to Specification-Version.

Example Manifest:

   Extension-Name: urn:apache:widget
   Specification-Version: 2.1

Example <service> declaration.

    <services>
      <service type="org.apache.Widget>
        <specification>
          <name>urn:apache:widget</name>
          <version>2.1</version>
          <artifact>apache/widget#2.1</artifact>
        </specification>
      </service>
    </services>

In the above example the <specification> elements is basically saying:

   1. any consumer of this service should exist within a classloader
      that provides support for the "urn:apache:widget" specification
      version 2.1.

   2. when constructing the classloader, if the parent classloader
      does not provide support for the specification, then add the
      supplied artifact to the classloader.

This also implies that the "apache/widget#2.1" artifact should not be declared in the <classloader> declaration.

The above becomes possible *if* (a) the repository maintains a cache or extension ids and versions, (b) container classloader construction is moved to the repository code, (c) optional extension management that is currently handled in the classloader model is moved to the repository classloader builder implementation, and (d) packages actually declare specification versions.

Taking the approach of declaring specific artifacts as in the service definition is IMO the wrong approach because this ties the block definition to a particular artifact (e.g. "apache/widget#2.1") when for example the actual artifact in a parent classloader could be "apache/widget#2.1.2".

WDYT?

Cheers, Stephen.


Cameron Fieber wrote:


I was thinking about a new feature to partition the classpath into
public and private (or api and impl) sections in the block.xml.  This
would allow a block.xml that is exporting one or more services to

define


the jars for its service's APIs in a public section of the classpath. Then, if that block.xml or jar was included in a higher level

container,


that container would include the public section of the included

block's


classpath in it's classpath.

This would ensure is that the classes for a service API would be

defined


in the correct classloader so that any client of that service would be
able to access it without running into classloader grief.

A potential complication could arise if a container includes a block,
then exports services from that included block.  I haven't fully

thought


through how that would work, but it doesn't seem too bad to solve.

My main motivation is to allow me to define groups of components in
jars, and be able to include them into higher level containers without
(preferably) having to modify the classpath of that higher level
container.

Any thoughts or opinions? I'll try to take a stab at an

implementation


this weekend to flesh out my example a bit better.

Example:  A FooService is specified in the block.xml included in
foo-impl-1.0.jar.  FooService's interface is defined in

foo-api-1.0.jar,


and it uses a data object defined in foo-bean-1.0.jar. Since these

are


defined in the api section of the block's classpath, when the block is
included in the the root container, those artifacts are promoted to

the


root container's classpath.

root-block.xml:
<container name="root">

 <classpath>
   <impl>
     <repository>
       <resource id="bar:foouser-impl" version="1.0"/>
       <!-- ... -->
     </repository>
   </impl>
 </classpath>

<include name="fooService" id="bar:foo-impl" version="1.0"/>

<component name="fooUser" class="com.bar.foouser.impl.FooUserImpl"/>

</container>

nested-block.xml:
<container name="nested">
 <services>
   <service type="com.bar.foo.FooService">
     <source>fooService</source>
   </service>
 </services>

 <classloader>
   <api>
     <repository>
       <resource id="bar:foo-api" version="1.0"/>
       <resource id="bar:foo-bean" version="1.0"/>
     </repository>
   </api>
   <impl>
     <repository>
       <resource id="bar:foo-impl" version="1.0"/>
       <!-- ... -->
     </repository>
   </impl>
 </classloader>

<component name="fooService"

class="com.bar.foo.impl.FooServiceImpl"/>


</container>


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]







--

|---------------------------------------|
| Magic by Merlin                       |
| Production by Avalon                  |
|                                       |
| http://avalon.apache.org              |
|---------------------------------------|

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to