On Wed, 1 Aug 2001, Christopher Cain wrote:
> I followed the whole startup routine from Tomcat.startTomcat() all the
> way through where the ContextManager calls the
> ServerXMLReader.addInterceptor(). That's where the whole hairy-chested
> XML parsing begins, and my brain started hurting :-) Up to the point, I
> have a pretty good grasp of the process.
That's where the fun starts :-)
ServerXmlReader is just a normal interceptor. When the addInterceptor hook
is called ( telling ServerXmlReader it has been added to tomcat), it'll
read server.xml file and process it ( in general any module can add other
modules or contribute to the configuration process - in previous versions
the configuration was hardcoded, now it's just another module ).
The processing is very simple. First, modules.xml is read - like taskdefs
in ant, it associates a tag name with a java class.
The for every line in server.xml, the tag is used to construct a class,
then with introspection we set all the properties ( each attribute
coresponds to a setter ).
So if you have
class MyModule extends BaseInterceptor {
public void setFoo(String s ) {
}
...
}
You do a:
<module name="my" classname="my.MyModule" />
and in server.xml:
<my foo="bar" />
That's all. XmlMapper will do all the magic.
> So basically, the only part of the entire process that I'm missing is
> the one that I need: How we get from a <RequestInterceptor> tag in
> server.xml to an instantiated class that extends BaseInterceptor. I have
> the following knowledge:
<RequestInterceptor > is "old style", basically it uses the class=".."
attribute to construct the class.
I prefer the new ant-like style, but both should work.
> - The PoolTCPConnector has an "attributes" hashtable
> - It also has a "setKeyspass()" method which sets a "keypass" value in
> the hashtable (which a grep of the source tree turned up no specific
> calls to)
Yes, flexibility syndrome.
The idea is that XmlMapper can take <propery name="foo" value="bar" />
and call SetAttribute.
The attributes are passed to the SocketFactory, so this allows to pass
arbitrary atributes without changing the code. For the common keypass,
etc we have explicit setters ( much cleaner ).
> So my question to you is, can you fill in the last piece of the puzzle
> for me? I know, I know ... I really should be smart enough to follow the
> startup code through the XMLMapper jungle, and I feel stupid for asking.
I know, XmlMapper is a very bad hack. I'm working on a replacement ( as a
3.3 module, of course :-).
The main benefit is that's very flexible ( but you can reach it's limits,
and the speed can be improved significantely - the original reason to do
XmlMapper was speed, as it was much faster then using DOM ).
Until the replacement is ready, just treat it like a black box that
creates objects and calls setters for each attribute, and don't try to
hard to look into details.
> Finally, is the right answer to create a class that extends
> Http10Interceptor? It would inherit everything as-is, then adds a calls
> out to my (self-contained for portability) "prompt getter" class,
> calling the existing PoolTCPConnector.setKeypass() method with the
I don't think it's a good idea - just write a class that extends
BaseInterceptor, with all the attributes you need, then search for the
Http10Interceptor and set the property.
I hope I can extended a bit your module, after you're done, to
check if the admin password and ajp12 passwords are set - and if not to
prompt the user. Far too many users forget this.
I think what you want is a configuration module, not a http ( connector )
module.
Even if it would work if you extend Http10Interceptor, it would not be
very clean.
Costin