tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Brian Burch <>
Subject Re: problem using default Realm in new unit tests
Date Mon, 09 Jan 2012 14:02:46 GMT
On 06/01/12 11:47, Konstantin Kolinko wrote:
> 2012/1/6 Brian Burch<>:
>> I am developing some new unit tests to validate SingleSignOn and
>> Authenticator logic. I have used this existing test class as my template:
>> org.apache.catalina.authenticator.TestDigestAuthenticator
>> .. which extends org.apache.catalina.startup.TomcatBaseTest.
>> I noticed that TestDigestAuthenticator sets up its own MapRealm and assigns
>> it to its single Context. I thought this logic was unnecessary, and so my
>> own initial test logic simply used the default RealmBase provided by the
>> underlying Tomcat instance. I add my test user and role to that. It worked
>> fine with my simple cases, however...
>> To test SSO, I need to set up two Contexts under the same Realm. I see the
>> following message in the output log:
>> INFO: The start() method was called on component [Realm[Simple]] after
>> start() had already been called. The second call will be ignored.
>> I know it is an INFO message. I know the second start (and its associated
>> stop) are ignored and therefore are harmless. However, I am reluctant to
>> simply shrug and ignore it. My instincts tell me something isn't right.
>> I have done quite a lot of investigating, but the underlying logic is very
>> hard for me to follow. Here is what I am sure about:
>> 1. The message is ONLY emitted in tests that create two Contexts and each
>> have the same Realm assigned with setRealm.
>> 2. The message is NOT emitted at the time the Contexts are created and
>> defined (servlets, security constraints, etc).
>> 3. The message IS emitted after the Tomcat.start method is called.
>> 4. The message is emitted by one of the two threads which are started on
>> behalf of my two contexts. The messages are issued by the start and stop
>> methods in the abstract class org.apache.catalina.util.LifecycleBase.
>> 5. org.apache.catalina.realm.RealmBase extends
>> org.apache.catalina.util.LifecycleMBeanBase which extends LifecycleBase.
>> My currently unanswered questions are:
>> 1. Is this message normal? (I don't see it when I start multiple contexts
>> under a real tomcat server, but perhaps the logging properties are
>> different).
>> 2. Why isn't the redundant startup of the Realm detected earlier and simply
>> avoided (maybe the Threads are intended to race to be first with startup -
>> but then I think the message should be debug level and not sound so scary).
>> Please don't waste your time investigating this for me. I am only asking the
>> question because I don't want too get side-tracked if one of you already
>> knows the answers to my questions. I'd like to settle the matter quickly and
>> get back to my original task!
>> Thanks for listening,
> The message is expected. I would say that the configuration is wrong,
> or at least unusual.
> If you look at the default server.xml file you will note that the
> <Realm>  element there belongs to Engine. That is why it is started
> once.

I agree, and this is what the TomcatBaseTest expects. If you "tickle" 
tomcat with TomcatBaseTest.getTomcatInstance() and then with 
Tomcat.getDefaultRealm(), a new default RealBase (memory) instance is 
definitely created.

> When Contexts are created and their context.xml files are parsed, the
> Contexts always get distinct new Realm instances.
> Instead of assigning the same Realm instance to both Contexts you
> should assign it to an upper container (I have not looked at the API
> though).  Or maybe you can have different Realm instances, but which
> connect to the same backing storage?

When the StandardEngine (extending ContainerBase) thread starts, I would 
expect percolating getRealm calls (from Context to Host to Engine) to 
eventually arrive at the already-defined Tomcat default Realm. HOWEVER, 
StandardEngine overrides the ContainerBase.getRealm method and ensures 
that an unconfigured JAAS Realm is instantiated as the default for the 
Context, because it cannot locate its parent (the field is certainly 
null, not tomcat), so it decides to use this JAAS as the backstop.

This looks to me as if some refactoring between tomcat 5 and 6 left the 
Tomcat default memory realm orphaned from the StandardEngine, which now 
operates independently and establishes a completely different default 
realm. Perhaps the right hand no longer knows what the left hand is 

Funny thing is that I googled this:

... and your name (Konstantin) is all over it! Can you cast you mind 
back 4 months and try to give me a clue about the history of this change 
to the logic?

My feeling is that we need to stop StandardEngine from unilaterally 
creating an unconfigured JAAS default Realm... and help the poor thing 
find its true parent, i.e. tomcat, which has a perfectly serviceable 
default memory realm just waiting to be used!

(apologies for the mild sarcasm - I can see you are very busy on other 


To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message