The main reason why EJB will eventually prevail over COM+ is that Microsoft
does not let any vendor compete since all the COM+ infraestructure is given
away for free when you buy Windows 2000, i.e. MTS, MSMQ, IIS etc are free
so companies cannot expect to make business offering alternative
implementations.
So every vendor will offer EJB products as we are seeing everyday, and none
will
ever offer an MTS-like product.
Regards
Javier Borrajo
www.tid.es
>Some of you might have seen the latest issue of ObjectWatch issue 20, in
>which Roger Sessions makes a lengthy evaluation of the EJB1.1
>specification. My evaluation of his critique follow below.
>
>As I will only quote snippets there is a chance that some vital context
>is lost. For completeness you should read the whole critique yourself
>at:
>www.objectwatch.com/issue20.htm
>www.objectwatch.com/issue20a.htm
>www.objectwatch.com/issue20b.htm
>www.objectwatch.com/issue20c.htm
>www.objectwatch.com/issue20d.htm (this has not been released yet)
>
>All comments are IMHO, AFAIK, FWIW, etc.
>
>Note: this is an *extremely* long post. Normally I wouldn't be this
>talkative, but since this is part of a book that lots of people are
>gonna read and (*shudder*) believe I feel that it is of vital importance
>that the content is scrutinized closely.
>
>As always, second opinions are important. In issue20b mr Sessions says
>that Anne Thomas will be posting a rebuttal article (similar to this I'd
>presume). Read that too and see if I have a clue or not.
>
>Ok, let's go!
>
>Part 1 of 5 of the article
>
>"Any so-called persistent object can be implemented as either bean type.
>In fact, as I will discuss in this chapter,
>most persistent objects would be better off implemented as a session
>bean. The real difference between these bean types is how you will
>manage the database ID for that persistent
>object. For entity beans, the system will manage the database ID for
>you. For session beans, you are responsible for managing the database ID
>yourself. "
>
>IMHO this is the age-old "assembler vs. OO"-argument: "any program you
>can do in Java with OO I can do just as well in assembler". Sure, but it
>is a matter of using the right tool for the job, specifically one wants
>to minimize the effort needed to implement application X. Assembler is
>good for some things and Java/OO for others. Since EntityBeans where
>designed with a specific use in mind, why not use them for that?
>
>The definition of EntityBean and SessionBean is not really from the
>client perspective but from the bean developer perspective. If a bean
>developer needs to choose which type of bean he should use to solve a
>specific problem the definition given in the EJB spec. is useful.
>
>He then proceeds to describe how a bean developer might implement a
>Customer (the usual stuff: getName, getAddrress, but also
>getCreditLimit(??)):
>"Should Bernice make Customer a session bean or an entity bean? It's
>hard to say. Maybe Customer is an entity bean. Based on its update and
>retrieval functionality, and the
>specification's admonition that an entity bean is "an object view of
>transactional data in the database," the entity choice would be logical.
>Customer is also "long-lived;" we don't expect
>to lose the customer when the client program goes away. But on the other
>hand, credit limit calculations do not represent any direct view of data
>in the database, so maybe we are
>dealing with a session bean. And this functionality seems to "execute on
>behalf of a single client," whatever that means."
>
>The above problem has nothing to do with EJB, but rather that his
>OO-"design" is bad. Typically when designing systems such as this one
>would try to use the metaphor of a reallife bank. When was the last time
>you asked a customer "so, what is your credit limit?". Duh. The given
>problem warrants the introduction of Accounts and Tellers, as one would
>expect to find in a real bank. Then, it would be simple to ask a Teller:
>"Given this Customers Accounts, can you tell me his credit limit?".
>Customer is an Entity, Account is an Entity and Teller is a Session.
>
>He then starts to explain about EJB homes:
>"Bernice starts implementing Customer as an entity bean. She first thing
>she does is create the Enterprise Bean's home interface. A home is a
>special type of component, a kind of
>finder/creator component, that knows how to create and/or find an
>instance of the bean we care about, a Customer in Bernice's case."
>
>and continues with
>
>"Notice that I am using slightly different language than I have used in
>previous chapter. I'm trying to use the terminology of EJB, so it won't
>be too confusing for those of you in the home
>audience trying to follow along with your own EJB specification."
>
>Anyone who has read the EJB specification, or been in this list long
>enough, would be somewhat confused with the first statement that a home
>is a special type of component. It is not a component. It is something
>which is associated with a component, hence his desire to use EJB lingo
>has already failed.
>
>Next paragraph:
>"Back to our home bean story. Each bean type has one and only one home
>in each component process. Component processes, by the way, are referred
>to as containers in EJB lingo.
>Strictly speaking, a container could be something other than a component
>process, but this is unlikely in many EJB implementations. So in EJB
>lingo, each container has a Customer
>home object."
>
>Anyone familiar with operating systems theory has a pretty good idea of
>what a process is, and a EJB-container will not fit that description
>very well. An EJB-container is nothing more than a (really) advanced
>part of a server, which is a program. A server can contain several
>EJB-containers. An executing program is a process. To claim that each
>component has its own process is not correct. Also, the statement that
>each container has *a* Customer home object is incorrect. A container
>can contain one *or more* beans(/homes) as illustrated in EJB1.1 spec.
>section 5.2.2.
>
>"The rules for creating a CustomerHome interface say that it must be
>derived from the EJBHome interface, which is provided as part of the
>Java platform."
>Strictly speaking this is not correct. Since EJB is a Java2 extension
>the EJBHome interface is not part of the Java platform. It is part of
>the Java2 Enterprise Edition platform however. (ok, it's a minor point,
>but anyway..)
>
>"She must
>define one or more create methods and she must define one or more find
>methods."
>Again, strictly speaking this is not correct. There is no *need* to
>implement create methods. They are optional. Details, dude...
>
>Next sentence:
>"The create methods are used for creating a Customer bean and the find
>methods are used for finding
>an existing Customer bean."
>Here he diverges from his above claim to use EJB lingo. In EJB lingo
>this would be "..creating a Customer object..". The terms used in EJB1.0
>was somewhat confusing as the term "bean" could refer to "instance of
>bean class", "the bean component" (as a whole), "the EJBObject", and
>lastly (what Sessions is referring to) "an object with an identity".
>This has been clarified in EJB1.1.
>
>So to clean up the next paragraph:
>"The create methods are actually misnamed. They are not used for
>creating the Customer bean, rather they are used for initializing an
>already created bean. The bean will be created
>using a default constructor on the CustomerBean class."
>Yes and no: create methods are for creating Entity objects, not
>instances, but Customer objects are indeed "created". The server will
>call the default constructor to create CustomerBean class *instances*.
>In EJB lingo one would stay as far away as possible from the term
>"bean".
>
>And he goes on to say that:
>"Once Bernice has created the CustomerHome interface and generated the
>ABCCustomerHome class using the ABC code generator, she is ready for the
>next step: defining the
>Customer interface. In our case, Bernice will define four methods in
>this interface. One of these will be the retrieve method, which returns
>the information related to a customer. One of
>these will be the update method, which is used to change information
>related to a customer. One of these will be the credit limit method,
>which is used to find out how much more
>money we can sucker out of our customer before our system starts
>worrying about whether or not that customer can actually pay. And
>finally one of these will be the default
>constructor, which is used to actually instantiate a Customer."
>Actually, he was almost home free here. Disregarding his crappy
>OO-design it is "possible" to have retrieve and update methods, and also
>a credit limit method, but interfaces cannot have default constructors.
>Nope, no way. And this aint no EJB thing, this is a Java thing.
>
>"The rules for creating a Customer Interface tell Bernice she must
>derive it from the EJBObject Interface, which is itself derived from
>java.rmi.Remote. It is this last derivation that defines
>for Java RMI an interface that can be treated as a remote component.
>Once Bernice has defined the Customer Interface, she does something
>quite remarkable. She doesn't have to
>implement any of the methods! Not only was the ABC code generator smart
>enough to automatically generate code for the ABCCustomerHome object, it
>can also automatically
>implement all the code for the actual Customer object to whom Curly's
>reference will eventually be speaking. This automatic code generator may
>seem more and more unbelievable, but
>we shall soon see exactly what the code generator has up its sleeves.
>The overall inheritance relationship between the different Customer
>related interfaces (and the methods they
>define) and classes (and the methods they implement) are shown in Figure
>3."
>
>Yes and no: Bernice doesn't have to create the proxy that implements the
>Customer interface, *BUUUUUT* she most certainly will have to provide
>the implementation that actually does what the methods are supposed to
>do on the object. He here wants the reader to think that (in EJB lingo)
>the code generator implements the CustomerBean, which it obviously will
>not do.
>
>"Poor Bernice. Just when she thought she was getting off easy with the
>ABC code generator, she gets to the last step (implementing the
>CustomerBean) and she finds that all the hard
>work has been left for her."
>
>Ehm.. out of curiosity.. in COM, is it only necessary to define the
>interface of a component, or do you actually have to implement the
>functionality of the component?
>
>(Divine voice from out of the blue: "Yes you have to implement what you
>want to happen")
>
>You have to do that in COM as well? Ok, so why is it that we should feel
>sorry for "poor" Bernice here? Uhm.. yeah...
>
>Just checking...
>
>Ok, on with the show. He sums it up with a list of required steps:
>"Define the Customer interface.
> Define the CustomerHome interface.
> Include in the above interface at least one create method and at
>least one find method.
> Generate the ABCCustomerHome class.
> Implement the CustomerBean class (this is where all the real work
>comes in).
> Generate the ABCCustomerBean class.
> Implement the CustomerKey class."
>* You don't *have to* make create methods
>* You don't *have to* generate classes. Easy-to-use containers will
>create these on the fly when the bean is deployed, or some might have
>generic implementations that can handle all beans...I mean all
>EJB-components
>* You don't *have to* implement a CustomerKey class. This was one of the
>new (and really good) features in EJB1.1
>Makes you wonder if he has ever read the EJB1.1-specification...
>
>A little note on internationalization:
>"Commerce systems and databases go together like peanut butter and
>jelly."
>As a non-US citizen I have no idea if this is good or bad. Is this book
>only intended for US readers? Somewhat limited then IMHO.
>
>On CMP:
>"This works
>great if Bernice isn't too fussy about how or where her Customer's data
>is being stored. In most real life situations, Bernice will care a lot,
>and will probably have data storage
>requirements that exceed the ability of these tools to cope. She will
>have specific databases she must use and specific, and often complex,
>data formats she must follow to maintain
>compatibility with non-JB applications (yes, I know it's hard to
>believe, but there still are some non EJB applications around!). So the
>usefulness of container managed persistence is
>limited to a few rare situations, at least until these tools improve."
>The last sentence is extremely important. This limitation has *nothing*
>to do with EJB1.1, and since its EJB1.1 we're talking about it's
>completely irrelevant. If he wants to put this remark in an evaluattion
>of an EJB-server, fine, but this aint the case here.
>
>This kind of confusion between design and implementation is something
>that most COM-people seem to have, and they seem to do the same mistake
>over and over again... when will they ever learn...
>
>"Client side find requests will be sent through to the EJBFind method
>which is also in CustomerBean. The parameter to this method
>takes a primary key from the client."
>The correct name is ejbFindByPrimaryKey.
>
>On finder return values:
>"Curly the client asked the
>CustomerHome object to create the Customer bean. He must have, or he
>couldn't now be finding it. When he did that, the create method returned
>the primary key of the newly created
>object."
>Wrong. The create method, from Curly the clients perspective, returns a
>EJBObject reference.
>
>Ok, moving on to part 3 of 5 in his article.
>
>EJB lingo again:
>"And once he has found the home object, he can use it to either create
>or find entity components, such as a Customer."
>Now he says that home objects are for finding and creating entity
>*components*. Again, the correct term is Entity object, as defined and
>used in the EJB1.1 specification.
>
>Names, names, names...:
>"Where is the point of interception in EJB? It is in the
>ABCRemoteCustomer class, the one to which Curly's reference naively
>points."
>Curiously enough Sessions have never mentioned the ABCRemoteCustomer
>class before. OTOH he has has mentioned the ABCCustomerBean class
>however, which is what he really means.
>
>"But what happens between when the ABCRemoteCustomer gets
>the request from Curly and passes it on to the CustomerBean is entirely
>up to the container."
>
>This is not entirely true, of course. The container must follow the
>semantic rules for method invocation as defined in the
>EJB1.1-specification. This is what it's all about: having rules that we
>as bean developers and users know that the component server environment
>will follow. The container is in complete charge of the implementation,
>but not the semantics.
>
>He then talks a bit about COM:
>"Not having database access code anyplace is not an option; it must be
>there and it must be there in such a way that its
>usage is coordinated with the overall transaction boundaries (as
>discussed in Chapter 4, "COMWare")."
>
>Well, I got news for you: in EJB there is no need to have any database
>access code at all. And this is one of the core reasons to use EJB:
>since there's no need to do db access there's no place to mess things
>up, and db access is (in my experience) one of the most error-prone
>things one can program. So many things to do wrong, can only mean that
>in the end it *will* go wrong. Since we don't have to bother with that
>in EJB, we're off the hook.
>
>This it completely confused:
>"It is possible to tell an EJB EntityBean that its database ID has
>changed. You can do that by changing its EntityContext. And in fact,
>this happens quite regularly in EJB as a natural side
>effect of the instance management algorithms. But only the container is
>allowed to reset an EntityContext; this is not an option available to
>clients. The client doesn't even have access to
>the EntityContext. The client model is that once a database ID has been
>associated with a bean, it can't be changed."
>
>What Sessions have not seemed to grasp is that we are in a world of
>objects, not data. The client requests objects, which are named with
>primary keys. If an object changes key it is essentially not the same
>object. In EJB we use instance pooling to fake this, because allowing
>all objects to have one physical instance each is not practical. It's
>the same reason as for having database connection pooling really. It is
>a known fact that if all clients have their own database connections the
>database server breaks down pretty fast. The same thing goes with entity
>objects.
>
>He then explains the steps required to access entities:
>"The potential problem with all this is that the creation of a reference
>to an entity bean is a very time consuming operation in EJB. It requires
>the following:
>
> 1.A call to find a remote name context to the Java Naming and
>Directory Interface (JNDI).
> 2.A remote method call to that name context to find the Home object
>and get a reference to it.
> 3.A distributed method call to the Home object to get a reference to
>the bean.
> 4.A search in the database to find the appropriate object data and
>load the data, requiring a transaction.
>
>Step 4 is by far the most expensive of all of these, because it requires
>a database search and a transaction.
>"
>1 and 2 are typically done once. Once you have the Home you can keep it
>and use it as many times as you wish. 4 is expensive, but then this is
>why most advanced EJB implementation uses caching for this: if an entity
>object corresponding to a particular primary key is already loaded the
>database wont be accessed *at all*. Yes! In the best case the database
>is never accessed at all, and *that* is a performance boost that COM can
>never have.
>
>Oh, and I just realized: 4 is typically never done. His use case is to
>acquire a *reference* to an entity object.. hehe.. well, just acquiring
>a reference to an entity object does not require that its data is
>actually loaded and activated in a live instance. The cost comes when
>you start *using* the reference. Very very very important difference.
>
>The above point totally invalidates the next three paragraphs where he
>whines about how costly it is to acquire entity references. Disregard
>them completely.
>
>"Oddly enough, even though the EJBSessionEntity does not support
>getPrimaryKey, the ABCRemoteCustomer object, the object to which Curly
>the client's reference points, does
>support getPrimaryKey. How can this be? Simple. If Curly invokes
>getPrimaryKey on a session bean, it returns an exception. It is unclear
>why the ABCRemoteCustomer's derivation
>pattern (as shown in Figure 3) doesn't parallel the derivation pattern
>of the CustomerBean (as shown in Figure 4) which would have solved this
>problem. Perhaps this is one of the
>problems some future release of the specification will fix."
>
>The reason for having one EJBObject interface which contains
>getPrimaryKey and throws exception for Sessions has been discussed
>extensively on this list. The reaon is simplicity. Three interfaces
>(EJBObject, EntityEJBObject (containing only getPrimaryKey) and
>SessionEJBObject (containing nothing)) would perhaps make sense as
>Sessions notes, but it is way overkill.
>
>On Customer as a SessionBean:
>"The getCustomerInformation method needs to read the customer's
>information from the database, and to do so, it must have a primary key
>for that customer. How will it get it? Since it
>isn't available any other way, Bernice must design the method so that it
>accepts another parameter, which is the database ID.
>
>The updateCustomerInformation method needs to update the customer's
>information in the database, and to do so, it also must have a primary
>key for that customer. How will it get it?
>The same way the getCustomerInformation method got it, through a
>parameter.
>
>The checkCreditLimit method needs to find all kinds of records in the
>database related to that customer. It also needs a database key. Are we
>seeing a pattern here? Where is it going
>to get that key? THROUGH A PARAMETER."
>Is it just me, or isn't it kinda awkward to have that parameter fly back
>and forth all the time. In his thinking this is good it seems. Ehm..
>yeah...right...
>
>On state:
>"There is a variant on the session bean that is called a stateful
>session bean. This is a misnomer, since the Customer session bean I have
>just been discussing is also stateful, it's just that its
>state is stored in a database, as you would expect from any self
>respecting commerce component."
>
>No, it's not stateful, it's just the OO-design that is so bad that you
>think that it is stateful. If I instead had a Teller component to do the
>credit checking, would he be stateful? No, because any Teller in a bank
>could be replaced with any other Teller in the bank, hence the Teller
>does not have any important state which is needed to complete a given
>task. What if I gave the Teller a list of tasks to perform, and wanted
>to check back later how he was doing? Then it would implement Teller as
>a stateful session bean. As simple as that.
>
>And we're now off to part 4 of the article.
>
>Entity references revisited:
>"Which of these is better? Most EJB folks would recommend the former, as
>the customer seems to fit the general notion of a bean that will outlast
>the client's process. But the entity
>implementation has a problem. It is much less efficient than the session
>implementation. This is because the cost of the reference creation is
>much higher for the entity bean than for the
>session bean. The reason it is higher is because it, unlike the session
>reference creation, requires a database lookup. It requires a database
>lookup to make sure the "find" has actually
>"found" an existing customer. There is no way to tell this without going
>to the database."
>
>Again, the reference creation is not an issue. He does have a point when
>he says that "It requires a database lookup to make sure the "find" has
>actually "found" an existing customer.". This is almost true. If the
>instance is already alive the server wont access the database, it will
>instead simply return a reference to the live instance. However, if it
>is not alive the server would have to ask the database.
>
>The real issue is that when you then start using the entity object it
>will have to be loaded from the database, i.e. there are two database
>accesses:
>* find it
>* load it
>But here comes two vital implementation details: databases typically
>caches the data, so the overhead of the last call will be minimal if the
>time between them is low, and it is also possible for a server to
>retrieve the data during the find, cache it internally and then reuse it
>when the load request comes. I.e., in real-life this will not be a big
>problem. As always, remember that "Cache is king" :-)
>
>On data integrity:
>"If we try to avoid the second lookup, we risk the transactional
>integrity of the bean; someone else might have come in
>and changed the bean's data since we did the find. "
>This is only true if the statements are not performed in a transaction.
>If it is then the EJB-server will typically block any other client
>trying to access it until the transaction has finished. This is what
>transactions all are about. If you want transactions, use them.
>
>Additionally:
>"As I discussed back in Chapter 4, all COMWare, including EJB, requires
>that transactional boundaries be the same as method
>boundaries. This means the bean's data has no protection between the
>find and the display. The display must therefore reread the data from
>the database."
>*IF* the code is not performed in a transaction *OF COURSE*, but that's
>the whole point of transactions, innit? If you need data integrity
>between the two calls then use a *TRANSACTION*.
>
>And to make this even worse his code example is as follows:
>"customer = CustomerHome.find("1234");
>display (customer.limit());"
>As you can see he is not reliant on the data integrity between the two
>calls so even if the data is actually changed between the two calls, SO
>WHAT? Since any changes done by any other client will be made to the
>same live physical instance in main memory (typically at least. There
>are other scenarios, but the end result is the same) it will simply
>display the latest known limit of the customers credit. No problemo.
>
>And the following example remark:
>"The cost for the entity reference is now much more expensive than the
>session reference. Not only is the cost of the first reference higher
>(as it was in the pattern one usage), but we
>must create three times as many references to do the same job."
>.. is incorrect. Since his discussion of the reference acquisition costs
>are inaccurate, the foundation for this remark is invalid. However, it
>is not entirely without merit. If all customer have to be found, loaded
>and subsequently stored this might cause nine separate calls to the
>database in a worst case scenario. However, if deployed well, and with a
>clever server implementation and some luck it requires *0* (zero, zip,
>nil) database calls for the entire example. (I wont detail how this is
>possible, just take my word for it, ok).
>
>And now he wants to finish off with a example to show how pathetic
>EntityBeans are and how good stateless is, and comments it with:
>"For this pattern, the initialization costs for the session bean is
>actually higher than for the entity bean since it includes the customer
>reference creation as well as the Customer home
>reference creation. But initialization costs are usually not important
>in this type of scenario. Initialization occurs very infrequently. The
>much more important cost is the cost of executing
>the main body, which happens over and over, perhaps thousands of times
>for every one initialization. The main body using the session bean will
>execute much faster than the main body
>using the entity bean. The session code completely eliminates the cost
>of the reference creation."
>
>First he contradicts himself with "initialization costs are usually not
>important in this type of scenario" and "...much faster than the main
>body
>using the entity bean. The session code completely eliminates the cost
>of the reference creation". Hello???? Houston calling, R U still there!?
>
>In reality: for sessions, each main body call requires that the code
>accesses the database through JDBC. This is typically expensive, but a
>clever database will have optimizied this somewhat if the primary key
>"1234" is used all the time (caching, caching and caching). For
>entities, after the first call the entity object will be loaded and
>happy in main memory so all subsequent calls does not require the server
>to go to the database. And it wont become stale if EJB is the only way
>to interact with the database (which will be the most common scenario
>IRL, or otherwise much of the gains with using EJB, or any
>componenttechnology are kinda lost).
>
>He then makes a summary and evaluation of the scenario, which is based
>on his completely f*d up view of how things work. Comletely disregard
>those paragraphs.
>
>And finishes off with:
>"Given this analysis, I make the following claim. While entity beans may
>seem to offer a more attractive programming model in some scenarios,
>that aesthetic advantage is more than
>outweighed by performance considerations. Given the increasing
>importance of thin (pattern three) clients, for whom entity beans do the
>absolute worse, it is difficult to imagine that
>anybody will implement any business logic using this inefficient
>model.."
>Given the above description of why mr Sessions is completely wrong I
>would advise you to disregard this remark.
>
>Finally, he makes a lame attempt at being funny, and also explains that
>there are five bean types:
>"Notice something strange about all this. EJB offers five bean types.
>Four of them have limited, if any, value. One of them is very useful and
>also happens to be the one that is supported
>today by COM+ and has been supported by since MTS 1996. Spooky, isn't
>it?"
>
>Keep in mind that there are many views here. From a EJB client
>programmers point of view there are three types: EntityBeans, Stateless
>SessionBeans and Stateful SessionBeans. From the EJB bean programmers
>point of view there are some implementation choices to be made, but
>there are really still only three basic types of EJB's.
>
>And that's as far as the article has come. Part 5 (of 5) is not out yet,
>but I will "happily" digest it too.
>
>I remember saying (on this list, a year or so ago) that the "EJB vs MTS"
>WhitePaper from David Chappell (available from www.microsoft.com) was
>the worst piece of crap I had ever read. Well, mr Chappell has been
>completely beaten by Sessions.
>
>I hope you have understood by now that this article is way off,
>completely inaccurate, and (IMHO) not even well-written. But people are
>allowed to have "opinions" on everything, including me.
>
>BUT, what makes this article a little different is that it is actually
>part of a book that mr Sessions will release through O'Wiley. Yes, you
>will be able to buy this crap in bookshops. And people will probably do
>that. And this is where it gets dangerous: on the web people say stuff,
>and others can easily respond to it and set things right, but when one
>reads stuff in a book one usually assumes that the content is somewhat
>accurate. This is certainly not the case here. If I were the publisher I
>would be *very* careful about this book. I don't know about the COM
>parts, they might be all fine and dandy, but this chapter is not
>finished. In fact, it should either be completely rewritten or scrapped.
>IMHO etc.
>
>Comments? :-)
>
>/Rickard
>
>--
>Rickard �berg
>
>@home: +46 13 177937
>Email: [EMAIL PROTECTED]
>Homepage: http://www-und.ida.liu.se/~ricob684
>
>===========================================================================
>To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
>of the message "signoff EJB-INTEREST". For general help, send email to
>[EMAIL PROTECTED] and include in the body of the message "help".
>
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".