james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefano Bagnara <apa...@bago.org>
Subject Re: [mailets] POJOs (and in particular SieveToMultiMailbox)
Date Wed, 03 Sep 2008 10:36:42 GMT
Robert Burrell Donkin ha scritto:
> On Tue, Sep 2, 2008 at 9:53 AM, Stefano Bagnara <apache@bago.org> wrote:
>> IN past we discussed about what IoC style we prefer and SDI was the
>> "winner":
>> http://issues.apache.org/jira/browse/JAMES-494
>> Here you can find the biggest poll we've ever had ;-)
>> http://markmail.org/message/rfagbuq6t3au7uia
>> "G" questions was about dependency injection.
> i did remark that setting injection is more popular but i don't intend
> to set a president, just take one more step forward. it may give some
> pointers towards more general solutions

I agree. I just wanted to share with you what we discussed in past.

>> Removing the default constructor will also make my new mailet report maven
>> module to fail obtaining the getMailetInfo/getMatcherInfo answer. It have to
>> get a newInstance in order to invoke that method.
>> Not a big deal, and if you go with CDI it will anyway be easy to refactor to
>> SDI in any moment.
> setter injection would work best with annotations or interfaces
> paired interfaces could be retrofitted easily. for example
> interface Mailbox
> interface MailboxAware
> {
>    public void setMailbox(Mailbox mailbox)
> }

I call this "enabling interfaces", and I love them.

>>> 2. no conventions need to be established or explained. as a temporary
>>> measure, it's easy to check and inject a limited number of SPIs
>>> through reflection.
>>> i would prefer to avoid major changes before moving IMAP out
>> We have a "store" method in MailetContext and we deprecated it because it
>> was not clear how to proceed and we simply discouraged it's usage to feel
>> more free to change it later :-)
> IMHO MailetContext suffers from doing both too much and too little

I agree.

>>>> I don't understand if you are proposing something to be added to the
>>>> mailet
>>>> specification
>>> ATM AIUI the mailet specification is silent on assembly and service
>>> acquisition. one advantage of this strategy is that it's possible to
>>> alter these characteristics without altering the mailet specification.
>> True and False... there was not support anything using services will not
>> work on current containers. So let's say "there's no way to be backward
>> compatible, so we can do whatever we want" ;-)
>> Every existing container will fail to load a mailet without a default
>> constructor.
> i'm not sure how you know that's true

I know of some mailet containers: James, MailCatcher. All of them use 
class.newInstance() to load a mailet.

If you know of an existing *mailet* container not doing so and 
leveraging more flexible containers to instantiate mailets I would be 
happy to know this.

>> [...]
>> When I refactored this in my mind there was the idea to bring as many
>> components to a top level. The idea is that StateAwareProcessorList could be
>> a component itself and the SpoolManager could simply depend on a
>> MailProcessor component.
>> This should be easy to do now. I didn't do that before simply because when I
>> worked on this everyone was worried about backward compatibility, so no
>> change was allowed to break config.xml and db content compatibility. There
>> are many hacks in the code to deal with this.
> i'm not sure why factoring out the processor would break configuration
> compatibility

Because of the way "Configuration" object works in Phoenix.
The SpoolProcessor contains the Configuration for 
StateAwareProcessorList so if you move StateAwareProcessorList to an 
external component phoenix will initialize it before the spoolmanager 
and there is no way to get the configuration from SpoolManager. You 
should let phoenix instantiate the StateAwareProcessorList 
"unconfigured" and then manually configure it when it will "service" the 
SpoolManager. Indeed an hack.

If you instead don't like of config.xml compatibility then you simply 
take the xml tree for the StateAwareProcessorList and move it outside 
from the <spoolmanager> block.

>>>> or simply you are proposing to change the way james specific
>>>> mailets are written so to not require avalon knowledge to the james
>>>> specific
>>>> mailets.
>>> IMHO JAMES specific mailets are an anti-pattern. we need to work
>>> towards decoupling minimal SPIs for mailets from the large APIs used
>>> internally by JAMES. i prefer to think about mailet loaders and
>>> processor assemblers indepedently. avalon is not a good match for this
>>> problem. more modern IoC containers like pico or spring as *much*
>>> better.
>> I agree that james specific mailets are antipattern.
>> To make them generic you have to define services at the mailet level.
>> And make the services generic.
>> To change the service lookup method without publicizing the services does
>> not make the mailets portable to other services.
>> If a Mailet depends on SpoolRepository interface we can remove avalon and
>> the service manager by using simple CDI/SDI, but in the end the mailet will
>> be only usable where SpoolRepository implementations are available.
>> SpoolRepository is james specific.
>> MailboxSPI is james specific until we make it part of a generic API
>> supported by compliant containers.
>> I don't understand what is your idea about this? Do you want to make an
>> mailet-spi package with optional services to be supported by advanced
>> containers?
> yep
>>> i strongly dislike the use of the magic avalon service attribute. IMHO
>>> if a mailet is coupled to avalon then it should implement the standard
>>> servicable interface. the container could then recognize this and
>>> configure the mailet appropriately.
>> I agree that the context and the service lookup are a bad idea for mailets.
>> IMHO this is a necessary change, but this alone won't change the fact that
>> mailets are james specific.
>> In http://issues.apache.org/jira/browse/JAMES-494 you can see the easiest
>> approach is to add setters for dependencies and make the "service" method
>> lookup the services and set them via setters. This way the avalon container
>> will keep working while non avalon containers can simply use setters.
> i'm not sure i agree with this being the easiest approach. there are
> known issues when trying to implement good setter injection frameworks
> and conventions would have to be established for setter names unless
> annotations are used.
> the simplest approach would be to use constructor injection and
> exclude optional dependencies
> IMO the best approach for setter injection would be to create an
> alternative spring processor loader
> i'd like to be able to deploy a self contained jar'd mail application
> eg (sketching somewhat):
> META-INF/org/apache/james/list-processor.xml
> <procesor loader='org.apache.james.mailet.container.Spring'>
>    <mailet name='ListManager'>
> ....
>    </mailet>
> </processor>
> META-INF/org/apache/james/spring-mailets.xml
> <beans>
>  <bean id='ListManager' class=...>
> ....
>  </bean>
> </beans>

Currently it is not the Processor loading the mailets but the 
MailetLoader and MatcherLoader services. YOu have to create new 
implementations of that services.

In StateAwareProcessorList each processor can optionally declare an 
alternative implementation via the "class" attribute, defaulting to 

As you can see the LinearProcessor uses the MailetLoader and 
MatcherLoader services to load the mailets given their name and their 

Do you want to implementa LinearProcessor that simply ignore the 
MailetLoader/MatcherLoader service and use it's own loading mechanism?

I'm not sure I like this, but it can be a PoC.

>>>> Another doubt is about the use of "String url": can you give more details
>>>> on
>>>> the allowed values for url and the way it works (a couple of examples
>>>> would
>>>> suffice, I guess)?
>>> i've been thinking for a long while that there might be a lot to gain
>>> in flexibility by moving towards APIs using URIs
>>> but it's still hazy...
>>>> Last point, and the least important, I don't like the SPI postfix.
>>>> The same interface could be used by SMTPServer/Fetchmail to store
>>>> messages
>>>> to the spool. In fact a spool repository could expose this interface
>>>> (ignoring the url) or we could expose it via the Store by looking up the
>>>> appropriate spool repository and storing the message to it.
>>> i have been thinking about that direction
>>> for example, POSTing to "mailto://joe@example.org" is an elegant and
>>> concise way to express the idea of forwarding a mail. this can be used
>>> for delivery as well. for example "mailet://joe@localhost".
>>> the advantage of using URLs is that it's easier to present interfaces
>>> which work ok for a wider variety of protocols. for example POSTing to
>>> "imap://joe@localhost/INBOX" could be distringuished from
>>> "james://joe@localhost/INBOX" and "mailbox://joe@localhost/INBOX".
>>> might be possible to do some interesting stuff this way.
>> I like this stuff very much. I discussed a similar thing in past. I named it
>> "destinations":
>> http://markmail.org/message/xkcttgyqmfwpieew
>> In my 2005 idea "destinations" was particular email addresses because email
>> address is more "mail" oriented than url, but mail is moving to different
>> transport and everyone probably better understand urls than email addresses.
>> But I think it would be a very interesting paradigm to use urls for anything
>> from local spool management, to remote delivery to forward and anything
>> else.
>> The issue I see here is that we should understand how they works before
>> starting to add interfaces using this urls.
> the sieve mailet is still experiement: it's a good opportunity just to
> give it a go and take the chance to live with it for a while

As long as it is clear that this can be dropped at any time and it is 
only an experiment, and that there is no agreement yet that it is the 
correct solution, I'm fine with it. Go ahead.


To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org

View raw message