cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leo Simons <lsim...@jicarilla.org>
Subject Re: [Kernel22] How to develop a component?
Date Thu, 08 Apr 2004 15:42:54 GMT
Leo Sutic wrote:
>>From: news [mailto:news@sea.gmane.org] On Behalf Of Leo Simons
 >>
>>write a failing testcase that doens't require me to understand every 
>>little detail of cocoon internals and I could try.
> 
> Easy.
<snip/>

made that into an actual testcase :-D:

public abstract class ReloadingProxyTestCase extends TestCase
{
   ServiceManager manager;
   ProxyInvalidator invalidator;
   Client client;

   public void setUp() throws Exception
   {
     super.setUp();

     manager = getManager();
     invalidator = getInvalidator();
     client = getClient();
   }

   protected abstract ServiceManager getManager();
   protected abstract ProxyInvalidator getInvalidator();
   protected abstract Client getClient();

   public void testCacheInvalidationDoesntWork()
   {
     client.login();
     invalidator.invalidate();

     try
     {
       client.attemptOperation();
     }
     catch( InvalidatedReferenceException ire )
     {
       fail( "client doesn't catch InvalidatedReferenceException!" );
     }
   }

   public interface StatefulComponent
   {
     public void login (); // never throws any exception, ever.
     public void doOperation (); // never throws any exception, ever.
     public void logout (); // never throws any exception, ever.
   }

   public class AvalonStatefulComponent
       extends AbstractLogEnabled,
       implements Serviceable, StatefulComponent
   {
     public void login () {}
     public void doOperation () {}
     public void logout () {}
   }

   public interface Client
   {
     public void attemptLogin();
     public void attemptOperation();
   }

   public class OldStyleClient implements Serviceable, Client
   {
     private StatefulComponent comp;

     public void service( ServiceManager sm )
     {
       comp = (StatefulComponent)
         sm.lookup(StatefulComponent.ROLE);
     }

     public void attemptLogin()
     {
       comp.login();
     }
     public void attemptOperation()
     {
       comp.doOperation();
     }
   }
}

> This is contrary to Avalon semantics, where a component reference,
> once obtained, remains valid until it is released.

right. It's contrary to java semantics, even. I'll try to withhold most 
of my opinion as to how smart a design like this is in the interest of 
keeping the discussion on-topic ;)

If you provide a component that has this kind of behaviour to an 
avalon-framework-compatible component through that component its 
servicemanager, it will not catch the InvalidatedReferenceException and 
it will lead to unexpected results. Acked.

 > Of course there are ways to code around this (or ignore it) in
 > the vast majority of cases.

Yep. Nothing to do with avalon-framework, though. I would say you'd have 
to mark components up with

   /** @@SupportsInvalidationOfReferences() */

and have the container print a big fat warning if the tag is missing but 
the ServiceManager (or anything which can lead to a reference that can 
be invalidatied) being provided to the component contains components 
that may invalidate.

Agreed, its not very clean.

All this, however, does not mean:

"If you have two blocks in the avalon sandbox, you could share them 
between them, but there is no (easy? elegant?) way you can pass them 
arond *OUTSIDE* the sandbox and still allow blocks to be hotswappable 
and runtime polymorphic."

your test case shows that there is no easy or elegant way you can pass a 
new style cocoon block into an old-style avalon component. Which will of 
course be true for the majority of code in this world, because the 
majority of software doesn't check for the not-yet-existant 
InvalidatedReferenceException. You have major headache to deal with 
there anyway, regardless of whether you have an avalon component or a 
javabean or an EJB.

But the test case doesn't show that there is no easy or elegant way to 
pass an old style avalon component into a new style cocoon block. After 
all, the block is not going to be disfunctional if the reference to the 
avalon component *doesn't invalidate*.

You could write a testcase for that. The testcase would be saying "all 
code inside cocoon must be prepared for references to anything to 
invalidate at any point in time". Ugh.

IOW, What you have shown here is that new-style cocoon blocks are 
incompatible with a standard assumption in most java code, namely, that 
references will remain references. You have not shown that these kinds 
of components cannot be used in an application where you violate that 
assumption, only that it will result in headache.

I can't see how it is relevant whether a reference is obtained through 
the avalon ServiceManager or through any other means.

-- 
cheers,

- Leo Simons

-----------------------------------------------------------------------
Weblog              -- http://leosimons.com/
Component Community -- http://componentplanet.org/
Component Glue      -- http://jicarilla.org/
-----------------------------------------------------------------------
"We started off trying to set up a small anarchist community, but
  people wouldn't obey the rules."
                                                         -- Alan Bennett


Mime
View raw message