You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mailet-api@james.apache.org by "Andrew C. Oliver" <ac...@apache.org> on 2006/11/05 18:41:39 UTC

On Global vs Local jndi naming WAS: Re: mailet-refactorings - JNDI

Danny Angus wrote:
> Yesterday I made some refactorings to the fork in the sandbox to play
> with JNDI instead of avalon for service location.
> Sadly I had to rush off with my changes uncomitted, but I thought I'd
> give you an update anyway.
>
> First of all on a practical level it works a treat (means "very well")
> with o.a.naming from the directory sandbox (jars checked in to the
> fork).
> It works seamlessly with Avalon, because the services and datasources
> can be made to bind themselves using a configured name in configure()
> or a class constant in initialize() and unbind themselves in dispose().
>
Is this supplemental or instead of injection.  I can see them being used 
together.
> at the moment I think there should be three or four contexts as follows:
>
.. snip ..
> I'm trying to decide whether we need to mirror the J2EE idea of global 
> and
> local contexts, and mappings between global and local bindings. I'm not
> convinced, but not 100% sure that it isn't necessary to have local 
> contexts
> either.
>
In order to avoid the predetermined "well-known" name situation that you 
described
above.  That is exactly why you want local contexts.  Otherwise we have 
the same kind
of issue that we have with "well known" ports.  With names you can use 
conventions
(name spaces) to avoid some of this, but collision is possibly 
problematic.  Generally
the prefix: part should not be a requirement.  Usually this is used via 
assignment (with
the exception of the java: which is the well understood local) via 
configuration (aka jndi.properties)
to deal with multiple name servers.  It just complicates configuration 
unnecessarily.  With
a separation between global and local the code stays independent of this 
and other namespacing
issues anyhow.

For a demonstration of this look to EJB 2.1 and porting between JEE 
appservers.  Say you wanted
you JBoss app to also run on weblogic and you used the "well known" 
defaults for where EJBs were
bound.  On JBoss a bean with ejb-name "FooBean" would be bound as 
"FooBean" where on web logic
it would be bound as ejb/FooBean.  If you had one EJB looking it up by 
the "well-known" name on JBoss
the same code would fail on WebLogic.  If that same code were configured 
so that it always looked up
in the local context, the code would succeed with configuration on 
either appserver.

This is less clear of an analogy here at this point, but supposing there 
are a number of mailets and services
and that in some cases they can be swapped, or in the case of multiple 
instances with different configuration
or location independence, the separation becomes more clearly advantageous.


-Andy


Re: On Global vs Local jndi naming WAS: Re: mailet-refactorings - JNDI

Posted by "Andrew C. Oliver" <ac...@apache.org>.
> Its certainly my goal Andy, to the extent that I'd be prepared to
> release the API in advance of James implementing it, so long as we
> also had an RI or SDK to release which could be used to support
> container independant mailet development.
cool
> that's the nicest thing anyone has said to me on this list ever. (sad
> but probably true too)
>
> :-)
>
Yes I know. 
>> I guess if you can explain how you would provision two instances of a
>> service otherwise
>> then I might be able to wrap my head around it.
>
> Not sure, which is why I suspect we *will* need them.
>
>> Local namepaces are generally used for configuration settings ala (which
>> I don't particularly like JNDI for, preferring
>> to inject into individual setters), portability and instance separation.
>
> I'm not mad on the idea of using JNDI for config either, but its
> always going to be available to vendors and developers via
> context.bind unless we lock it down, which I'm not crazy about either,
> so I guess we can only sneer about it and attempt to cover the bases
> with a well designed API.
>
> That said the indirection provided by mapping global to local is a
> good thing, its just that the means of doing it isn't easy to trace or
> debug (debug errors in the mappings I mean, not the things which are
> bound and mapped). I'm 99% sure we're a long way from needing to make
> a decision about deployment descriptors, I'm happy to let this remain
> undecided until we actually do need an answer, none of the PoC stuff
> would be invalid in either case.
yes.  Once other have had time to sound of on this particular issue we 
should start
specing it out on the wiki as well.  I prefer your code-first method but 
think some level
of specification is also required.  Mainly because I'm way to lazy to 
search mail archives
when it comes time to implement.

-Andy
>
> d.
>
>
>
>> > d.
>>
>>
>>



Re: On Global vs Local jndi naming WAS: Re: mailet-refactorings - JNDI

Posted by Stefano Bagnara <ap...@bago.org>.
Danny Angus wrote:
> On 11/8/06, Serge Knystautas <sk...@gmail.com> wrote:
> 
>> I prefer dependency injection to service lookups, so much of what you
>> guys are discussing seems moot to me.  Since you (one or both of you)
>> have expressed preference for dependency injection as well, I'm
>> struggling to picture the use cases for when JNDI lookup is necessary.
>>  Can you guys give some examples to help me understand this
>> requirement?
> 
> You invent a new service (which depend upon other services) and a
> mailet which uses it, your service is instantiated then your mailet &
> matcher require a reference to it. Do you:
> 
> a) have it injected by declaring all of your dependancies in configuration

imho you declare the dependencies (dependency on service interfaces) in 
the mailet (either via annotation or via descriptor) and then you use 
configuration to let it know the real implementation you want to provide 
for that dependency. This is vendor/container specific: some container 
could use autowiring, someone else xml based wiring and so on.

Stefano

> b) look it up yourself from a configured name
> c) none of the above - discuss
> 
> 
> d.
> 



Re: On Global vs Local jndi naming WAS: Re: mailet-refactorings - JNDI

Posted by Danny Angus <da...@gmail.com>.
On 11/8/06, Serge Knystautas <sk...@gmail.com> wrote:

> I prefer dependency injection to service lookups, so much of what you
> guys are discussing seems moot to me.  Since you (one or both of you)
> have expressed preference for dependency injection as well, I'm
> struggling to picture the use cases for when JNDI lookup is necessary.
>  Can you guys give some examples to help me understand this
> requirement?

You invent a new service (which depend upon other services) and a
mailet which uses it, your service is instantiated then your mailet &
matcher require a reference to it. Do you:

a) have it injected by declaring all of your dependancies in configuration
b) look it up yourself from a configured name
c) none of the above - discuss


d.

injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by "Andrew C. Oliver" <an...@superlinksoftware.com>.
>>
>> yes.  Once other have had time to sound of on this particular issue we
>> should start
>> specing it out on the wiki as well.  I prefer your code-first method but
>> think some level
>> of specification is also required.  Mainly because I'm way to lazy to
>> search mail archives
>> when it comes time to implement.
>
> I prefer dependency injection to service lookups, so much of what you
> guys are discussing seems moot to me.  Since you (one or both of you)
> have expressed preference for dependency injection as well, I'm
> struggling to picture the use cases for when JNDI lookup is necessary.
> Can you guys give some examples to help me understand this
> requirement?
>

Whether dependency injection is used is orthogonal to whether JNDI is 
used or available.  I do not object
to a strict dependency injection scenario either.  I simply stated that 
if JNDI is used that local namespaces
are probably needed as well.  I do prefer dependency injection to raw 
name lookup code.

This is an example of them used together:
http://docs.jboss.org/ejb3/app-server/tutorial/injection/injection.html
http://docs.jboss.org/ejb3/app-server/tutorial/jndibinding/jndi.html

(I do not presuppose EJB3 or this form of attribute based configuration, 
just it was what immediately came to mind
when you asked for an example)

I prefer something as POJO as possible with as few implicit contracts as 
possible except where exceptionally pragmatic (EJB3
has many implicit contracts).  I prefer what is reasonably easy to 
implement, maintain and support.   I prefer something that
supports configuration with as little complexity as possible but favor 
brevity to the exceptionally verbose.

I can be convinced in either direction as to whether JNDI is redundant 
or assists in portability here.  On one hand with field and
setter injection based on attributes with JNDI the code is very simple 
and the implementation could probably be common, on the
other hand with no jndi its simple and reduces a requirement on 
implementors of mailets and mailet containers.  In either case the
descriptor can be divergent (though some standardization could happen as 
well). 

I do have an opinion on this:  I like attribute based metadata for 
*standard* injection pathways, its useful, portable, easy.  However 
regardless
XML (or similar) based descriptors must be available in addition or at 
least as overrides in order to allow multiple instances with divergent
configuration.

-Andy



Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by Stefano Bagnara <ap...@bago.org>.
I agree with Andrew.

1) Imho we can target java 5 for next mailet apis (so we can use 
annotations)
2) Mailets dependencies/configurability *declaration* must be defined by 
the api
3) Mailets configuration and deployment wiring are vendor specific and 
anyone will decide how to provide this.

If we don't want to require java 5 then we have to define a mean for the 
mailet to declare their dependencies: an xml file (maybe xdoclet 
generated) or the implementation of specific declaring interfaces are 
two alternative solutions. My personal idea is that we are discussing a 
future api while sun is releasing java 6 and java 2 1.4 will be probably 
EOLed soon.

Stefano

Andrew C. Oliver wrote:
> (sorry if there are two I fat fingered)
>> I'm still waiting for someone to give a sensible DI example that would
>> show how we deal with the fact that there can be an unlimited number
>> of unknown dependancies. 
> [...]
> CONTRACTS:
> Constructors are called in any order.  Each mailet has a method called 
> start.
> Each mailet has a method called stop.
> Attributes are "set" after construction but before "start".
> Interfaces are proxies (ala java.lang.reflect.Proxy) and thus can be 
> passed before the service is started
> Start is then called once dependencies are satisfied (below).
> Mailets with no <depends>true</depends> are started first.
> Mailets whose dependencies are satisfied are started next (loop).
> Mutual and circular dependencies are not allowed (error).
> JNDI dependencies are satisfied when the jndi lookup exists and the 
> service has been started.
> stops are called in reverse order that starts were called.
> 
> Notes:
> attribute annotations can be either on the implementation or the 
> interface.  constructor annotations must be on the implementation (duh)
> annotations and/or XML are equivalent
> annotations should not be used for configuration (vendor specific 
> example in xml above)
> 
> This is more or less the same idea used for JBoss XMBeans, Geronimo 
> GBeans, and EJB3.


Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by Norman Maurer <nm...@byteaction.de>.
I think java5 whould be great...

bye
Norman

Stefano Bagnara schrieb:
> I agree with Andrew.
>
> 1) Imho we can target java 5 for next mailet apis (so we can use
> annotations)
> 2) Mailets dependencies/configurability *declaration* must be defined
> by the api
> 3) Mailets configuration and deployment wiring are vendor specific and
> anyone will decide how to provide this.
>
> If we don't want to require java 5 then we have to define a mean for
> the mailet to declare their dependencies: an xml file (maybe xdoclet
> generated) or the implementation of specific declaring interfaces are
> two alternative solutions. My personal idea is that we are discussing
> a future api while sun is releasing java 6 and java 2 1.4 will be
> probably EOLed soon.
>
> Stefano
>
> Andrew C. Oliver wrote:
>> (sorry if there are two I fat fingered)
>>> I'm still waiting for someone to give a sensible DI example that would
>>> show how we deal with the fact that there can be an unlimited number
>>> of unknown dependancies. 
>> [...]
>> CONTRACTS:
>> Constructors are called in any order.  Each mailet has a method
>> called start.
>> Each mailet has a method called stop.
>> Attributes are "set" after construction but before "start".
>> Interfaces are proxies (ala java.lang.reflect.Proxy) and thus can be
>> passed before the service is started
>> Start is then called once dependencies are satisfied (below).
>> Mailets with no <depends>true</depends> are started first.
>> Mailets whose dependencies are satisfied are started next (loop).
>> Mutual and circular dependencies are not allowed (error).
>> JNDI dependencies are satisfied when the jndi lookup exists and the
>> service has been started.
>> stops are called in reverse order that starts were called.
>>
>> Notes:
>> attribute annotations can be either on the implementation or the
>> interface.  constructor annotations must be on the implementation (duh)
>> annotations and/or XML are equivalent
>> annotations should not be used for configuration (vendor specific
>> example in xml above)
>>
>> This is more or less the same idea used for JBoss XMBeans, Geronimo
>> GBeans, and EJB3.
>
> !EXCUBATOR:1,4558701f53074833495395!



Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by "Andrew C. Oliver" <ac...@apache.org>.
(sorry if there are two I fat fingered)
> I'm still waiting for someone to give a sensible DI example that would
> show how we deal with the fact that there can be an unlimited number
> of unknown dependancies. 

mailet.xml
<mailets>
<mailet>
   <name>MyMailet</name>
   <class>org.foo.MyMailetImpl</class>
   <interface>org.foo.MyMailet</interface>
   <constructors>
     <constructor/>
     <constructor>
       <arguments>
         <argument>java.lang.String</argument>
       </arguments>
     </constructor>
   </constructors>
   <attributes>
      <attribute>
         <name>foo</name>
         <type>java.lang.String</type>
         <getter>getFoo</getter>
         <setter>setFoo</setter>
      </attribtue>
      <attribute>  
         <name>MyOtherMailet</name>
         <type>org.foo.MyOtherMailet</type>
         <setter>getMyOtherMailet</setter>
         <depends>true</depends>
      </attribute>
      <attribute>  
         <name>YetAnotherMailet</name>
         <type>org.foo.YetAnotherMailet</type>
         <setter>setYetAnotherMailet</setter>
         <jndi>true</jndi>
         <depends>true</depends>
      </attribute>
   </attributes>
</mailet>
</mailets>

OR 

@org.apache.mailet.Mailet(name="MyMailet"
                          class="org.foo.MyMailet)
public class MyMailetImpl implements MyMailet {
  ... public members snipped ...
  @org.apache.mailet.Constructor
  public MyMailetImpl() {}   

  @org.apache.mailet.Constructor
  public MyMailetImpl(String bar) {
     this.bar = bar;
  }

  @org.apache.mailet.Attribute
  public void setFoo(String foo) {
      this.foo = foo;
  }

  public String getFoo() {
      return this.foo;
  }

  @org.apache.mailet.Attribute(depends=true)
  public void setMyOtherMailet(MyOtherMailet mailet) {
     this.mom = mailet;
  }

  @org.apache.mailet.Attribute(depends=true jndi=true)
  public void setYetAnotherMailet(YetAnotherMailet yam) {
      this.yam = yam;
  }

  public void start() {
  }

  public void stop() {
  }
}


myserver-specific-config.xml (unspecified but example)

<mailet-instance>
  <mailet>
     <name>MyMailet</name>
     <instance-name>MyMailet1</instance-name>
     <constructor>
        <arguments>
          <argument type="java.lang.String">Hi man</argument>
        </arguments>
     </constructor>
     <attributes>
        <attribute name="foo">Hello</attribute>
        <attribute name="MyOtherMailet">MyOtherMailet1</attribute>
        <attribute name="YetAnotherMailet">java://yam</attribute>
     </attributes>
  </mailet>
</mailet-instance>

CONTRACTS:
Constructors are called in any order.  
Each mailet has a method called start.
Each mailet has a method called stop.
Attributes are "set" after construction but before "start".
Interfaces are proxies (ala java.lang.reflect.Proxy) and thus can be 
passed before the service is started
Start is then called once dependencies are satisfied (below).
Mailets with no <depends>true</depends> are started first.
Mailets whose dependencies are satisfied are started next (loop).
Mutual and circular dependencies are not allowed (error).
JNDI dependencies are satisfied when the jndi lookup exists and the 
service has been started.
stops are called in reverse order that starts were called.

Notes:
attribute annotations can be either on the implementation or the 
interface.  
constructor annotations must be on the implementation (duh)
annotations and/or XML are equivalent
annotations should not be used for configuration (vendor specific 
example in xml above)

This is more or less the same idea used for JBoss XMBeans, Geronimo 
GBeans, and EJB3.


Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by Joachim Draeger <jd...@gmx.de>.
Am Samstag, den 11.11.2006, 09:14 +0000 schrieb Danny Angus:

> In what way is injection preferable to lookup?

Sorry, I forgot one important point in my previous posting:

Security. When using DI I have full and easy control which services a
Mailet is allowed to use. 
A commercial mailet may come in a binary form without source code.

Joachim



Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by "Andrew C. Oliver" <ac...@apache.org>.
Danny Angus wrote:
> On 11/11/06, Serge Knystautas <sk...@gmail.com> wrote:
>
>> Yeah, I'm biased, but I like think this is part of the advantages of
>> just dependency injection.
>
> I'm still waiting for someone to give a sensible DI example that would
> show how we deal with the fact that there can be an unlimited number
> of unknown dependancies.
>
I posted one but for some reason it didn't make it to the list.  I will 
post it again
when I get motivation on Monday.

> Service location allows the consumer of the services to look them up
> as needed, DI requires that the container be made aware of the
> dependance and invoke some mechanism to inject an instance which
> satisfies it.
>
> In what way is injection preferable to lookup?
Lookup doesn't necessarily help with dependence at all.  Meaning you 
just get NPEs all
over the place because the other service isnt' start.  Dependence, 
injection and lookup are
all orthogonal. 
>
> d.



Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by Stefano Bagnara <ap...@bago.org>.
100% agreed! I quote it all because this deserve better indexing by 
search engine ;-)

This is one of the most comprehensive list of JNDI (and service locator 
pattern in general) issues I don't like.

And that is to be completed with what Joachim already replied to 
himselft: security. Managing security with JNDI is much harder because 
you need nested contexts and complex containers.

Stefano

Joachim Draeger wrote:
> Am Samstag, den 11.11.2006, 09:14 +0000 schrieb Danny Angus:
>> On 11/11/06, Serge Knystautas <sk...@gmail.com> wrote:
>>
>>> Yeah, I'm biased, but I like think this is part of the advantages of
>>> just dependency injection.
>> I'm still waiting for someone to give a sensible DI example that would
>> show how we deal with the fact that there can be an unlimited number
>> of unknown dependancies.
> 
> IMO exactly "unlimited number of *unknown* dependencies" is a strong
> argument for DI. 
> In a big application it is important to know the dependencies exactly.
> 
>> Service location allows the consumer of the services to look them up
>> as needed, DI requires that the container be made aware of the
>> dependance and invoke some mechanism to inject an instance which
>> satisfies it.
> 
> Making aware a container of dependencies means mostly xml. This is just
> like a formal documentation of the dependencies. You should probably do
> that even when you using a service locator.
> I don't consider it as problematic that the format differs in different
> frameworks. They are quite similar and the process is not error prone. 
> 
> Invoking some mechanism means just calling setters. Likely inside some
> kind of factory. I don't see any magic there. :-) The whole procedure is
> probably just as easy as dealing with JNDI.
> IMO even when using JNDI the Bean should be configured through setters
> by calling a corresponding method or using a factory. 
> (Funny enough: This could even be done by using a generic factory and
> xml ;-)
> This way the consumer had full control and could decide whether to use
> DI or JNDI. 
> 
> 
> Also lookup up services as needed is more flexible I think it is more
> save to check dependencies at initialization. With DI you can do that
> even without creating any instances.
> 
>> In what way is injection preferable to lookup?
> 
> e.g.
>  -  who is affected when I change service A?
>  -  using a wrapper when Mailet X needs a special behavior of service B
>  -  different implementions/instances of Service C for Mailet Y and Z.
>  -  defined, full control of lifecycle: who is instantiated when?
>  -  possibility of adding support for different service locators.
>  -  Testing: being able to make use of Mocks
>  -  If you just want to use very few Mailets in a small tool you could
> wire up deps yourself. 
> 
> Another point is that a Mailet should concentrate on it's own business.
> Looking up and checking dependencies is IMO out of scope.
> If you do that in every single component it is not very DRY.
> 
> Conclusion:
> 
> I would not like to see service locator pattern as the default for
> looking up services in James. 
> 
> If it is really wanted/needed it could be a compromise to publish James
> services supplementary by JNDI and extend Mailet implementations with
> the ability of using JNDI for looking up dependencies.
> (I'm convinced this could be done in a clean, separate way without
> blowing up existing code)
> Following the trends we should keep OSGi in mind which offers another
> service locator mechanism.
> 
> Joachim



Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by Joachim Draeger <jd...@gmx.de>.
Am Samstag, den 11.11.2006, 09:14 +0000 schrieb Danny Angus:
> On 11/11/06, Serge Knystautas <sk...@gmail.com> wrote:
> 
> > Yeah, I'm biased, but I like think this is part of the advantages of
> > just dependency injection.
> 
> I'm still waiting for someone to give a sensible DI example that would
> show how we deal with the fact that there can be an unlimited number
> of unknown dependancies.

IMO exactly "unlimited number of *unknown* dependencies" is a strong
argument for DI. 
In a big application it is important to know the dependencies exactly.

> Service location allows the consumer of the services to look them up
> as needed, DI requires that the container be made aware of the
> dependance and invoke some mechanism to inject an instance which
> satisfies it.

Making aware a container of dependencies means mostly xml. This is just
like a formal documentation of the dependencies. You should probably do
that even when you using a service locator.
I don't consider it as problematic that the format differs in different
frameworks. They are quite similar and the process is not error prone. 

Invoking some mechanism means just calling setters. Likely inside some
kind of factory. I don't see any magic there. :-) The whole procedure is
probably just as easy as dealing with JNDI.
IMO even when using JNDI the Bean should be configured through setters
by calling a corresponding method or using a factory. 
(Funny enough: This could even be done by using a generic factory and
xml ;-)
This way the consumer had full control and could decide whether to use
DI or JNDI. 


Also lookup up services as needed is more flexible I think it is more
save to check dependencies at initialization. With DI you can do that
even without creating any instances.

> In what way is injection preferable to lookup?

e.g.
 -  who is affected when I change service A?
 -  using a wrapper when Mailet X needs a special behavior of service B
 -  different implementions/instances of Service C for Mailet Y and Z.
 -  defined, full control of lifecycle: who is instantiated when?
 -  possibility of adding support for different service locators.
 -  Testing: being able to make use of Mocks
 -  If you just want to use very few Mailets in a small tool you could
wire up deps yourself. 

Another point is that a Mailet should concentrate on it's own business.
Looking up and checking dependencies is IMO out of scope.
If you do that in every single component it is not very DRY.

Conclusion:

I would not like to see service locator pattern as the default for
looking up services in James. 

If it is really wanted/needed it could be a compromise to publish James
services supplementary by JNDI and extend Mailet implementations with
the ability of using JNDI for looking up dependencies.
(I'm convinced this could be done in a clean, separate way without
blowing up existing code)
Following the trends we should keep OSGi in mind which offers another
service locator mechanism.

Joachim









Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by "Andrew C. Oliver" <ac...@apache.org>.
> I'm still waiting for someone to give a sensible DI example that would
> show how we deal with the fact that there can be an unlimited number
> of unknown dependancies. 

mailet.xml
<mailets>
<mailet>
   <name>MyMailet</name>
   <class>org.foo.MyMailetImpl</class>
   <interface>org.foo.MyMailet</interface>
   <constructors>
     <constructor/>
     <constructor>
       <arguments>
         <argument>java.lang.String</argument>
       </arguments>
     </constructor>
   </constructors>
   <attributes>
      <attribute>
         <name>foo</name>
         <type>java.lang.String</type>
         <getter>getFoo</getter>
         <setter>setFoo</setter>
      </attribtue>
      <attribute>  
         <name>MyOtherMailet</name>
         <type>org.foo.MyOtherMailet</type>
         <setter>getMyOtherMailet</setter>
         <depends>true</depends>
      </attribute>
      <attribute>  
         <name>YetAnotherMailet</name>
         <type>org.foo.YetAnotherMailet</type>
         <setter>setYetAnotherMailet</setter>
         <jndi>true</jndi>
         <depends>true</depends>
      </attribute>
   </attributes>
</mailet>
</mailets>

OR 

@org.apache.mailet.Mailet(name="MyMailet"
                          class="org.foo.MyMailet)
public class MyMailetImpl implements MyMailet {
  ... public members snipped ...
  @org.apache.mailet.Constructor
  public MyMailetImpl() {}   

  @org.apache.mailet.Constructor
  public MyMailetImpl(String bar) {
     this.bar = bar;
  }

  @org.apache.mailet.Attribute
  public void setFoo(String foo) {
      this.foo = foo;
  }

  public String getFoo() {
      return this.foo;
  }

  @org.apache.mailet.Attribute(depends=true)
  public void setMyOtherMailet(MyOtherMailet mailet) {
     this.mom = mailet;
  }

  @org.apache.mailet.Attribute(depends=true jndi=true)
  public void setYetAnotherMailet(YetAnotherMailet yam) {
      this.yam = yam;
  }

  public void start() {
  }

  public void stop() {
  }
}


myserver-specific-config.xml (unspecified but example)

<mailet-instance>
  <mailet>
     <name>MyMailet</name>
     <instance-name>MyMailet1</instance-name>
     <constructor>
        <arguments>
          <argument type="java.lang.String">Hi man</argument>
        </arguments>
     </constructor>
     <attributes>
        <attribute name="foo">Hello</attribute>
        <attribute name="MyOtherMailet">MyOtherMailet1</attribute>
        <attribute name="YetAnotherMailet">java://yam</attribute>
     </attributes>
  </mailet>
</mailet-instance>

CONTRACTS:
Constructors are called in any order.  
Each mailet has a method called start.
Each mailet has a method called stop.
Attributes are "set" after construction but before "start".
Interfaces are proxies (ala java.lang.reflect.Proxy) and thus can be 
passed before the service is started
Start is then called once dependencies are satisfied (below).
Mailets with no <depends>true</depends> are started first.
Mailets whose dependencies are satisfied are started next (loop).
Mutual and circular dependencies are not allowed (error).
JNDI dependencies are satisfied when the jndi lookup exists and the 
service has been started.
stops are called in reverse order that starts were called.

Notes:
attribute annotations can be either on the implementation or the 
interface.  
constructor annotations must be on the implementation (duh)
annotations and/or XML are equivalent
annotations should not be used for configuration (vendor specific 
example in xml above)

This is more or less the same idea used for JBoss XMBeans, Geronimo 
GBeans, and EJB3.


Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by "Andrew C. Oliver" <an...@superlinksoftware.com>.
Danny Angus wrote:
> On 11/11/06, Serge Knystautas <sk...@gmail.com> wrote:
>
>> Yeah, I'm biased, but I like think this is part of the advantages of
>> just dependency injection.
>
> I'm still waiting for someone to give a sensible DI example that would
> show how we deal with the fact that there can be an unlimited number
> of unknown dependancies.
>
I posted one but for some reason it didn't make it to the list.  I will 
post it again
when I get motivation on Monday.

> Service location allows the consumer of the services to look them up
> as needed, DI requires that the container be made aware of the
> dependance and invoke some mechanism to inject an instance which
> satisfies it.
>
> In what way is injection preferable to lookup?
Lookup doesn't necessarily help with dependence at all.  Meaning you 
just get NPEs all
over the place because the other service isnt' start.  Dependence, 
injection and lookup are
all orthogonal. 
>
> d.



Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by Danny Angus <da...@gmail.com>.
On 11/11/06, Serge Knystautas <sk...@gmail.com> wrote:

> Yeah, I'm biased, but I like think this is part of the advantages of
> just dependency injection.

I'm still waiting for someone to give a sensible DI example that would
show how we deal with the fact that there can be an unlimited number
of unknown dependancies.

Service location allows the consumer of the services to look them up
as needed, DI requires that the container be made aware of the
dependance and invoke some mechanism to inject an instance which
satisfies it.

In what way is injection preferable to lookup?

d.

Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by Serge Knystautas <sk...@gmail.com>.
On 11/11/06, Danny Angus <da...@gmail.com> wrote:
> On 11/11/06, Serge Knystautas <sk...@gmail.com> wrote:
>
> > Yeah, I'm biased, but I like think this is part of the advantages of
> > just dependency injection.
>
> I'm still waiting for someone to give a sensible DI example that would
> show how we deal with the fact that there can be an unlimited number
> of unknown dependancies.
>
> Service location allows the consumer of the services to look them up
> as needed, DI requires that the container be made aware of the
> dependance and invoke some mechanism to inject an instance which
> satisfies it.
>
> In what way is injection preferable to lookup?

I think we're considering different scenarios since in my ears, your
points support my view.  When I hear unlimited number of unknown
dependencies, that rules out service lookup since it's impossible to
come up with an unlimited number of unknown names for the lookups.
It's all explicit and clear.  It makes a huge ugly XML, but it's much
more rigorous and scales better IMHO.

I haven't used attributes to define DI, but my first reaction is to
not like it since to me it seems that I would have to recompile my
Java classes to change the dependency relationship in some cases.
Actually, studying your example, it seems like it's just removing some
verbosity that I haven't had to deal with with Spring since it excels
at sensible defaults.

-- 
Serge Knystautas
Lokitech >> software . strategy . design >> http://www.lokitech.com
p. 301.656.5501
e. sergek@lokitech.com

Re: injection and/or JNDI WAS Re: On Global vs Local jndi naming

Posted by Serge Knystautas <sk...@gmail.com>.
On 11/9/06, Andrew C. Oliver <an...@superlinksoftware.com> wrote:
> (I do not presuppose EJB3 or this form of attribute based configuration,
> just it was what immediately came to mind
> when you asked for an example)

Thanks.

> on the
> other hand with no jndi its simple and reduces a requirement on
> implementors of mailets and mailet containers.

Yeah, I'm biased, but I like think this is part of the advantages of
just dependency injection.

I guess I'm in the same boat as you though Andy... I'm not absolutely
against JNDI, and if there are some conventions that can be
standardized, so be it.

-- 
Serge Knystautas
Lokitech >> software . strategy . design >> http://www.lokitech.com
p. 301.656.5501
e. sergek@lokitech.com

Re: On Global vs Local jndi naming WAS: Re: mailet-refactorings - JNDI

Posted by Serge Knystautas <sk...@gmail.com>.
On 11/9/06, Danny Angus <da...@gmail.com> wrote:
> You invent a new service (which depend upon other services) and a
> mailet which uses it, your service is instantiated then your mailet &
> matcher require a reference to it. Do you:
>
> a) have it injected by declaring all of your dependancies in configuration
> b) look it up yourself from a configured name
> c) none of the above - discuss

a)
-- 
Serge Knystautas
Lokitech >> software . strategy . design >> http://www.lokitech.com
p. 301.656.5501
e. sergek@lokitech.com

Re: On Global vs Local jndi naming WAS: Re: mailet-refactorings - JNDI

Posted by Serge Knystautas <sk...@gmail.com>.
On 11/6/06, Andrew C. Oliver <ac...@apache.org> wrote:
> >> Local namepaces are generally used for configuration settings ala (which
> >> I don't particularly like JNDI for, preferring
> >> to inject into individual setters), portability and instance separation.
> >
> > I'm not mad on the idea of using JNDI for config either, but its
> > always going to be available to vendors and developers via
> > context.bind unless we lock it down, which I'm not crazy about either,
> > so I guess we can only sneer about it and attempt to cover the bases
> > with a well designed API.
> >
> > That said the indirection provided by mapping global to local is a
> > good thing, its just that the means of doing it isn't easy to trace or
> > debug (debug errors in the mappings I mean, not the things which are
> > bound and mapped). I'm 99% sure we're a long way from needing to make
> > a decision about deployment descriptors, I'm happy to let this remain
> > undecided until we actually do need an answer, none of the PoC stuff
> > would be invalid in either case.
> yes.  Once other have had time to sound of on this particular issue we
> should start
> specing it out on the wiki as well.  I prefer your code-first method but
> think some level
> of specification is also required.  Mainly because I'm way to lazy to
> search mail archives
> when it comes time to implement.

I prefer dependency injection to service lookups, so much of what you
guys are discussing seems moot to me.  Since you (one or both of you)
have expressed preference for dependency injection as well, I'm
struggling to picture the use cases for when JNDI lookup is necessary.
 Can you guys give some examples to help me understand this
requirement?

-- 
Serge Knystautas
Lokitech >> software . strategy . design >> http://www.lokitech.com
p. 301.656.5501
e. sergek@lokitech.com

Re: On Global vs Local jndi naming WAS: Re: mailet-refactorings - JNDI

Posted by Danny Angus <da...@gmail.com>.
On 11/6/06, Andrew C. Oliver <ac...@apache.org> wrote:

> I'm not really particularly interested in James specific needs.  I am
> interested in a standardized
> portable Mailet API.  I would like to participate in mailet API
> specifically so long as there is a
> consensus that the same mailet running on different implementations
> without code changes is
> a desirable goal.

Its certainly my goal Andy, to the extent that I'd be prepared to
release the API in advance of James implementing it, so long as we
also had an RI or SDK to release which could be used to support
container independant mailet development.

Your involvement would obviously help to promote it as a goal of the
group, and would enhance its credibility precisely because of your
distance from James.


<sniped a lot of my own drivel/>

> I don't entirely disagree.

that's the nicest thing anyone has said to me on this list ever. (sad
but probably true too)

:-)


> I guess if you can explain how you would provision two instances of a
> service otherwise
> then I might be able to wrap my head around it.

Not sure, which is why I suspect we *will* need them.

> Local namepaces are generally used for configuration settings ala (which
> I don't particularly like JNDI for, preferring
> to inject into individual setters), portability and instance separation.

I'm not mad on the idea of using JNDI for config either, but its
always going to be available to vendors and developers via
context.bind unless we lock it down, which I'm not crazy about either,
so I guess we can only sneer about it and attempt to cover the bases
with a well designed API.

That said the indirection provided by mapping global to local is a
good thing, its just that the means of doing it isn't easy to trace or
debug (debug errors in the mappings I mean, not the things which are
bound and mapped). I'm 99% sure we're a long way from needing to make
a decision about deployment descriptors, I'm happy to let this remain
undecided until we actually do need an answer, none of the PoC stuff
would be invalid in either case.

d.



> > d.
>
>
>

Re: On Global vs Local jndi naming WAS: Re: mailet-refactorings - JNDI

Posted by "Andrew C. Oliver" <ac...@apache.org>.
> Yeah, Ijust wonder how much James really nees it, but I think it may
> be unavoidable
>
I'm not really particularly interested in James specific needs.  I am 
interested in a standardized
portable Mailet API.  I would like to participate in mailet API 
specifically so long as there is a
consensus that the same mailet running on different implementations 
without code changes is
a desirable goal.
>>  If you had one EJB looking it up by
>> the "well-known" name on JBoss
>> the same code would fail on WebLogic.
>
> yeah, what I'd propose would be that instead of using "well known"
> names that the API actually constrains the namespaces which can be
> used for portability.
>
> Frameworks allow development to achieve benefits because they contain
> pre-determined decisions which suit developments which don't challenge
> the scope of the framework.
> I think J2EE missed a trick by omitting to mandate namespaces more
> thoroughly. After all I struggle to see why anyone would care what the
> namespace is, so long as it is appropriately granular.
> Vendor specific deployment descriptors and namespace mappings always
> look like a kind of fudge, as if sun threw up its hands and said
> "enough" because there was too much variability in too many
> parameters. I understand that there needs to be extensibility at the
> edges to allow a framework to accept new technology and new thinking,
> and to evolve, and I understand  that ther are benefits to vendor
> specific extensions. What I don't accept is that those requirements
> necessarily mean that a framework cannot mandate the things which are
> comfortably in scope.
>
I don't entirely disagree.
>
>> This is less clear of an analogy here at this point, but supposing there
>> are a number of mailets and services
>> and that in some cases they can be swapped, or in the case of multiple
>> instances with different configuration
>> or location independence, the separation becomes more clearly 
>> advantageous.
>
> I agree that if you want to have two provisions of a single service
> type you need to map a provision to satisfy a dependance. What I'm
> asking is is that scenario a requirement for this API, or can we
> reason that it'll be so rare that we can ignore it providing that we
> don't actually exclude the possibility of satisfying it later?
>
I guess if you can explain how you would provision two instances of a 
service otherwise
then I might be able to wrap my head around it.

Local namepaces are generally used for configuration settings ala (which 
I don't particularly like JNDI for, preferring
to inject into individual setters), portability and instance separation. 
> d.



Re: On Global vs Local jndi naming WAS: Re: mailet-refactorings - JNDI

Posted by Danny Angus <da...@gmail.com>.
> In order to avoid the predetermined "well-known" name situation that you
> described
> above.  That is exactly why you want local contexts.
...snip ..

> With
> a separation between global and local the code stays independent of this
> and other namespacing
> issues anyhow.

Yeah, Ijust wonder how much James really nees it, but I think it may
be unavoidable

>  If you had one EJB looking it up by
> the "well-known" name on JBoss
> the same code would fail on WebLogic.

yeah, what I'd propose would be that instead of using "well known"
names that the API actually constrains the namespaces which can be
used for portability.

Frameworks allow development to achieve benefits because they contain
pre-determined decisions which suit developments which don't challenge
the scope of the framework.
I think J2EE missed a trick by omitting to mandate namespaces more
thoroughly. After all I struggle to see why anyone would care what the
namespace is, so long as it is appropriately granular.
Vendor specific deployment descriptors and namespace mappings always
look like a kind of fudge, as if sun threw up its hands and said
"enough" because there was too much variability in too many
parameters. I understand that there needs to be extensibility at the
edges to allow a framework to accept new technology and new thinking,
and to evolve, and I understand  that ther are benefits to vendor
specific extensions. What I don't accept is that those requirements
necessarily mean that a framework cannot mandate the things which are
comfortably in scope.


> This is less clear of an analogy here at this point, but supposing there
> are a number of mailets and services
> and that in some cases they can be swapped, or in the case of multiple
> instances with different configuration
> or location independence, the separation becomes more clearly advantageous.

I agree that if you want to have two provisions of a single service
type you need to map a provision to satisfy a dependance. What I'm
asking is is that scenario a requirement for this API, or can we
reason that it'll be so rare that we can ignore it providing that we
don't actually exclude the possibility of satisfying it later?

d.