You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by Joel Gluth <jo...@ping.net> on 2001/02/15 00:26:28 UTC

[LONGISH] the thorny problem of MailetConfig.getInitParameterNames()

Hi list.

In my travels today, I found myself alternately cursing the names of the
JAMES team, then taking it back on further reflection. Sorry. It
actually turns out to be minor, but I'm interested.

I've found myself writing a Mailet to use JAMES as a frontend to an
application server. I like it, and the oft-mentioned lack of docs hasn't
really been an issue. One of the core server components takes as its
constructor argument a java.util.Properties object (and I can hear you
guys snickering already, by the way, because you know what's coming).

After swearing at the JAMES MailetConfig interface for not doing
something sensible like extending java.util.Map, I shrugged and wrote a
subclass of Properties that could take a MailetConfig, iterate over its
parameters, and copy them. Apart from the fact that the JavaDoc claimed
that getInitParameterNames() returns a Collection (glad to see this is
fixed in 1.2.1, BTW), it compiled OK.

However, it didn't run OK. My AvalonRunner crashed during init with
vaguely threatening RuntimeExceptions. I soon tracked this down to my
little utility class, and to the getInitParameterNames() call. It throws
the RuntimeException, with the simple message, "Not yet implemented".

Leaving aside for the moment that this is a release candidate, and such
(undocumented!) behaviour is of questionable appropriateness to say the
least, I had a look to see if I could just write it myself. This is
where things got worrying. It turns out that MailetConfig is a wrapper
for org.apache.avalon.Configuration. The thing about Configuration is,
there is AFAICT *no way* to retrieve a list of keys at a particular
level of the tree (or at all, for that matter). You have to know what
the potential options are beforehand, and retrieve them explicitly.

So. org.apache.james.core.MailetConfigImpl is left with a contract it is
unable to fulfill, namely the MailetConfig interface. Since using Avalon
to do configuration is pretty deeply rooted in the design of JAMES,
there are two options: convince the (seemingly heavily Pattern-oriented)
Avalon team to change their interface, or to change MailetConfig.

The former is possibly not such a battle, since the main point of
avalon.Configuration is to be read-only. The latter is certainly less
so. But my question is, what's the plan?

Regards,
-- 
Joel Gluth \\ Disintegration Engineer, Ping.Net     http://www.ping.net
                              Any technology distinguishable from magic 
                                            is insufficiently advanced.

Valid XML config file in Avalon (was Re: [LONGISH] the thorny problem of MailetConfig.getInitParameterNames())

Posted by Joel Gluth <jo...@ping.net>.
Federico Barbieri wrote:
> 
> Joel Gluth wrote:
<SNIP/>
> > I know this is strictly an Avalon question now, but is there a reason
> > you're allowed to specify config parameters that way, other than the
> > fact that it's a neat DOM hack?
> 
> ?... miss the question...

Sorry. For example, I can configure my Mailet through Avalon's XML file
like this:

<mailet match="All" class="Prototype">
                        
    <driver>org.postgresql.Driver</driver>
    <url>jdbc:postgresql://test01/rweiler</url>
    <username>rweiler</username>
    <password>rweiler</password>
    <port>1235</port>
    <debug>true</debug>
    <nConnections>2</nConnections>

</mailet>

The problem is, the document containing such an element can't be valid
XML without knowing all the names of the configuration options of all
the subcomponents, because it's impossible to write a DTD for.

Right now, it works because you can make a DOM tree from a well-formed
but invalid XML document, and then do
Element.getElementsByTagName("nConnections").item(1), for example, to
get the value of the nConnections option. Which is cute, but it's a hack
(BTW, I have to admit that I haven't looked at the Avalon code to see if
this is what happens). The convention

<mailet match="All" class="Prototype">
                        
    <param name="driver" value="org.postgresql.Driver"/>
    <!-- ... -->

</mailet>

Means that you can write a DTD for JAMES' .conf.xml file. As well as
satisfying our need to be able to do discovery on a list of parameters
;)

Having said all that, I understand that being able have
sub-Configurations with arbitrary names, like <mailet></mailet> is
pretty nice, and would be much harder to do if you enforced valid XML on
the Avalon config as a whole.

So. We're back with JAMES. Since JAMES' MailetConfig interface is
basically a very simple map of String keys to String values, it doesn't
need (or even allow) all the flexibility of its underlying
avalon.Configuration. It would be a good thing, I think, if JAMES
enforced the second kind of <mailet> tag layout.

Is such a thing acceptable to the JAMES team?
-- 
Joel Gluth \\ Disintegration Engineer, Ping.Net     http://www.ping.net
TCL - what a misnomer that is. For a language with such a fun name,
                                           it's pretty damn humourless.

Re: [LONGISH] the thorny problem of MailetConfig.getInitParameterNames()

Posted by Federico Barbieri <sc...@betaversion.org>.

Joel Gluth wrote:
> 
> Federico Barbieri wrote:
> 
> > Yes I am pattern oriented and proud to be! :-)
> 
> Absolutely. Didn't mean that to sound like a bad thing :)
> 
> > The idea about Configuration is "you know what you're doing" so if you
> > need a value you should know the name of the element containing that
> > value. Makes sense doen't it?
> 
> Yes... if all you're doing is initalizing an application from the ground
> up. When you want to unify configuration for disparate components, some
> of whom aren't written to deal with Avalon, interoperability becomes
> something of an issue.
> 
> > But don't worry there is an alternative.
> <SNIP content="alternative"/>
> 
> Aha. Thanks. I'll modify my copy of JAMES accordingly. Although, it
> doesn't really solve MailetConfig's basic problem.
> 
> Actually, this <param name="something" value="somethingelse"/> is
> better, XML-wise, since you can actually describe the format of the
> config.xml file with a DTD that way. If, of course, proper XML is a
> concern :p

well the idea of a configuration validator could be nice... 

> 
> Even if it's not, enforcing it does allow JAMES to have a working
> MailetConfigImpl.

and nicely decouple Mailet from Configuration 

> 
> I know this is strictly an Avalon question now, but is there a reason
> you're allowed to specify config parameters that way, other than the
> fact that it's a neat DOM hack?

?... miss the question... 
Configuration are supposed to be very generic so that you are allow to
do whatever you want. The <param attributes/> is already used in James
for the mailet processor:
<mailet match="" class=""> 

We had the same problem... discovery of a piece of conf at run time. in
these situation the pattern <conftype attributes/> is elegant and fit
the role. In other situation you don't want discovery at run time... so
the absence of getChildren() force you to explicitely define a contract
to allow or denay discovery.


Fede

Re: [LONGISH] the thorny problem of MailetConfig.getInitParameterNames()

Posted by Joel Gluth <jo...@ping.net>.
Federico Barbieri wrote:

> Yes I am pattern oriented and proud to be! :-)

Absolutely. Didn't mean that to sound like a bad thing :)

> The idea about Configuration is "you know what you're doing" so if you
> need a value you should know the name of the element containing that
> value. Makes sense doen't it?

Yes... if all you're doing is initalizing an application from the ground
up. When you want to unify configuration for disparate components, some
of whom aren't written to deal with Avalon, interoperability becomes
something of an issue.

> But don't worry there is an alternative.
<SNIP content="alternative"/>

Aha. Thanks. I'll modify my copy of JAMES accordingly. Although, it
doesn't really solve MailetConfig's basic problem.

Actually, this <param name="something" value="somethingelse"/> is
better, XML-wise, since you can actually describe the format of the
config.xml file with a DTD that way. If, of course, proper XML is a
concern :p

Even if it's not, enforcing it does allow JAMES to have a working
MailetConfigImpl.

I know this is strictly an Avalon question now, but is there a reason
you're allowed to specify config parameters that way, other than the
fact that it's a neat DOM hack?

Cheers,
-- 
Joel Gluth \\ Disintegration Engineer, Ping.Net     http://www.ping.net
"Emily rocks."                           -- http://www.emilystrange.com

Re: [LONGISH] the thorny problem of MailetConfig.getInitParameterNames()

Posted by Federico Barbieri <sc...@betaversion.org>.
Joel Gluth wrote:
> 
> Hi list.
> 
> So. org.apache.james.core.MailetConfigImpl is left with a contract it is
> unable to fulfill, namely the MailetConfig interface. Since using Avalon
> to do configuration is pretty deeply rooted in the design of JAMES,
> there are two options: convince the (seemingly heavily Pattern-oriented)
> Avalon team to change their interface, or to change MailetConfig.
> 

Yes I am pattern oriented and proud to be! :-) 
The idea about Configuration is "you know what you're doing" so if you
need a value you should know the name of the element containing that
value. Makes sense doen't it?
So from my point of view the getInitailParamenteNames is kinda wrong
pattern. 

But don't worry there is an alternative. if you spec mailet
configuration to be in the form:

<param name="" value=""/> 

or like you can then conf.getChildren("param") in the MailetConfigImpl
and get things running. 
This means (from a pattern oriented point of view) Configuration do not
allow discovery, Parameters do, so you enforce a contract on conf to be
able to write an adapter between the two. 

Is that accetable?

Federico
fede@apache.org