You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hivemind.apache.org by James Carman <ja...@carmanconsulting.com> on 2004/10/21 13:38:02 UTC

RE: AOPAlliance interceptor factory (WAS: Reflection vs. Javassist)

We could use a hybrid approach.  We could create an abstract base class
which has all the logic of the MethodInterceptorFactory, but also implements
MethodInterceptor, so that when it constructs the service interceptor it
uses itself as the MethodInterceptor implementation.  That's fine for new
method interceptor logic, but if you want to use something that has already
been written (3rd party stuff), the other approach is more appropriate.

Or, we could make BuilderFactory a bit smarter.  We could allow it to call
itself to build objects which will be set as properties.  Does that make
sense?  Something like this...

<implementation 
  service-id="TransactionInterceptorFactory">
  <invoke-factory service-id="hivemind.BuilderFactory">
    <construct class="example.interceptor.factory.MethodInterceptorFactory">
      <set-factory 
        service-id="hivemind.BuilderFactory" 
        property="methodInterceptor">
          <construct 
            class="example.interceptor.TransactionInterceptor"/>
      </set-factory>
    </construct>
  </invoke-factory>
</implementation>

We need a generalized mechanism for building POJO objects which can be tied
to other services within the registry.  Thus far, that role has been filled
by BuilderFactory, but BuilderFactory is meant to be a core service
implementation object builder, not necessarily a generalized POJO builder
service.  That's what we need IMHO.  Any thoughts?


-----Original Message-----
From: Dyson, Jimmi [mailto:dysonj@quindell.com] 
Sent: Thursday, October 21, 2004 4:26 AM
To: hivemind-user@jakarta.apache.org
Subject: RE: AOPAlliance interceptor factory (WAS: Reflection vs. Javassist)

That's a very good point that I hadn't thought of...

Can anyone think of another way to get around having to declare a factory
and an interceptor for each MethodInterceptor interceptor?

Even using Knut's ObjectProvider technique (which I never knew about!) means
that you have to declare 2 services for each MethodInterceptor, unless you
don't want to wire the interceptor implementation together with anything.
Please let me know if I've misunderstood something about ObjectProviders,
but in order to wire services to your interceptor, wouldn't you need to use
the service: prefix in the set-object, meaning that then that service would
also need to be declared?

Having to declare both the factory and the implementation is over the top
when you've already created a generic factory for MethodInterceptor
interceptors.

-----Original Message-----
From: James Carman [mailto:james@carmanconsulting.com] 
Sent: 20 October 2004 13:27
To: hivemind-user@jakarta.apache.org
Subject: RE: AOPAlliance interceptor factory (WAS: Reflection vs. Javassist)

Sorry, man.  It's early.  No coffee yet!  :-)  Anyway, I think my original
did just what you're doing here, give or take.  The problem I ran into was
that if you wanted to use multiple method interceptors, you have no way of
ordering them (security first, then logging, then transactions, etc.),
because the service-id of the service interceptor factory is always "
cendil.lib.AOPAllianceMethodInterceptorFactory." 

-----Original Message-----
From: Dyson, Jimmi [mailto:dysonj@quindell.com] 
Sent: Wednesday, October 20, 2004 8:23 AM
To: hivemind-user@jakarta.apache.org
Subject: RE: AOPAlliance interceptor factory (WAS: Reflection vs. Javassist)

The MethodInterceptor implementation is actually a service so what stops you
wiring that service with other services?

For example, the TransactionInterceptor (in fact, your
TransactionInterceptor!):

<implementation service-id="TransactionInterceptor">
  <invoke-factory service-id="hivemind.BuilderFactory">
    <construct
class="com.quindell.hivemind.transaction.TransactionInterceptor">
      
      <set-configuration configuration-id="rollbackOnlyExceptions"
property="rollbackOnlyExceptions"/>
    </construct>
  </invoke-factory>
</implementation>

As you know, this uses autowiring to wire the TransactionService
implementation to it.

Is that what you were getting at or have I missed something?

-----Original Message-----
From: James Carman [mailto:james@carmanconsulting.com] 
Sent: 20 October 2004 13:06
To: hivemind-user@jakarta.apache.org
Subject: RE: AOPAlliance interceptor factory (WAS: Reflection vs. Javassist)

I originally did it similar to that, but what if you want to wire your
method interceptor together with other services?  You're not using
BuilderFactory to build the method interceptor instance, so you can't do
that.

-----Original Message-----
From: Dyson, Jimmi [mailto:dysonj@quindell.com] 
Sent: Wednesday, October 20, 2004 5:23 AM
To: hivemind-user@jakarta.apache.org
Subject: AOPAlliance interceptor factory (WAS: Reflection vs. Javassist)

Firstly, apologies for the long post!

I have taken James Carman's AOPAlliance method interceptor factory and
altered it a bit to take a MethodInterceptor as a parameter when declaring
an interceptor. I felt that this was worth doing as otherwise we would have
to declare a 2 services for each MethodInterceptor service (one for the
MethodInterceptor factory and one for the MethodInterceptor itself). This
way it needs only 1 declaration for the MethodInterceptor factory and one
for each MethodInterceptor.

I am having a problem declaring multiple interceptors for the same service
point ("Interceptor contribution
'cendil.lib.AOPAllianceMethodInterceptorFactory' duplicates previous value
and is being ignored.").

The service-point looks like this:

<service-point id="AOPAllianceMethodInterceptorFactory"
interface="org.apache.hivemind.ServiceInterceptorFactory">
  <parameters-schema>
    <element name="method-interceptor">
      <attribute name="service-id" required="true" translator="service">The
id of the service implementing the MethodInterceptor interface</attribute>
        <rules>
          <create-object
class="com.cendil.hivemind.aopalliance.impl.MethodInterceptorParameter"/>
          <read-attribute attribute="service-id"
property="methodInterceptor"/>
          <invoke-parent method="addElement"/>
        </rules>
    </element>      
  </parameters-schema>
  <create-instance
class="com.cendil.hivemind.aopalliance.impl.MethodInterceptorFactory"
model="primitive"/>
</service-point>

This can then be used like below to add a method interceptor like below:

<interceptor service-id="cendil.lib.AOPAllianceMethodInterceptorFactory">
  <method-interceptor service-id="cendil.lib.LoggingInterceptor"/>
</interceptor>

Where the LoggingInterceptor is declared like this:

<service-point id="LoggingInterceptor"
  interface="org.aopalliance.intercept.MethodInterceptor"/>
	
<implementation service-id="LoggingInterceptor">
  <invoke-factory service-id="hivemind.BuilderFactory">
    <construct
class="com.quindell.hivemind.aopalliance.impl.LoggingInterceptor"/>
  </invoke-factory>
</implementation>

The problem I'm having is that if I want to add a second AOPAlliance
MethodInterceptor like this:

<interceptor service-id="cendil.lib.AOPAllianceMethodInterceptorFactory">
  <method-interceptor
service-id="cendil.transaction.TransactionInterceptor"/>
</interceptor>
<interceptor service-id="cendil.lib.AOPAllianceMethodInterceptorFactory">
  <method-interceptor service-id="cendil.lib.LoggingInterceptor"/>
</interceptor>

I get the message that:

Interceptor contribution 'cendil.lib.AOPAllianceMethodInterceptorFactory'
duplicates previous value and is being ignored.

Does anyone have any ideas as to how to get around this? This really does
simplify a lot of things (e.g. LoggingInterceptor is only 45 lines of code
rather than over 200).

Thanks,
Jim Dyson

-----Original Message-----
From: James Carman [mailto:james@carmanconsulting.com] 
Sent: 21 September 2004 15:18
To: hivemind-user@jakarta.apache.org; 'Knut Wannheden'
Subject: RE: Reflection vs. Javassist

Well, that's the beauty of it.  The class implementation has a setter for an
object of type MethodInterceptor, so you can set that property however you
want.  I chose to use a service, because my interceptor relied upon other
services and I wanted to use BuilderFactory to autowire everything for me.
I wasn't familiar with object providers, so I just stuck with what I knew.
:-)

-----Original Message-----
From: Knut Wannheden [mailto:knut.wannheden@gmail.com] 
Sent: Tuesday, September 21, 2004 10:14 AM
To: hivemind-user@jakarta.apache.org
Subject: Re: Reflection vs. Javassist

Can't this be simplified by using the HiveMind ObjectProviders? Then
you wouldn't need the first service anymore:

<service-point
  id="RollbackOnlyInterceptorFactory"
  interface="org.apache.hivemind.ServiceInterceptorFactory">
  <invoke-factory service-id="hivemind.BuilderFactory">
    <construct
      class="example.interceptor.factory.MethodInterceptorFactory">
      <set-object
        value="instance:example.interceptor.RollbackOnlyInterceptor"
        property="methodInterceptor"/>
    </construct>
  </invoke-factory>
</service-point>

--knut

On Tue, 21 Sep 2004 10:04:19 -0400, James Carman
<ja...@carmanconsulting.com> wrote:
> I can do you one better.  I can include the source code for a
> MethodInterceptorFactory class that I wrote.  Now, this class is dependent
> upon the AOP Alliance (http://sourceforge.net/projects/aopalliance) jar
> file, but it makes creating interceptors EASY!  All you have to do is
> implement the MethodInterceptor interface (from AOP Alliance).  This class
> (or some version similar to it) may make it into the hivemind-lib module
in
> version 1.1, so make sure you switch over to the "official" one once it
> arrives.
> 
> Here's an example of how to use it in a hivemodule.xml file...
> 
> <service-point
>   id="RollbackOnlyInterceptor"
>   interface="org.aopalliance.intercept.MethodInterceptor">
>   <invoke-factory service-id="hivemind.BuilderFactory">
>     <construct class="example.interceptor.RollbackOnlyInterceptor" />
>   </invoke-factory>
> </service-point>
> 
> <service-point
>   id="RollbackOnlyInterceptorFactory"
>   interface="org.apache.hivemind.ServiceInterceptorFactory">
>   <invoke-factory service-id="hivemind.BuilderFactory">
>     <construct
>       class="example.interceptor.factory.MethodInterceptorFactory">
>       <set-service
>         service-id="RollbackOnlyInterceptor"
>         property="methodInterceptor"/>
>     </construct>
>   </invoke-factory>
> </service-point>
> 
> <implementation service-id="ProjectServices">
>   <interceptor service-id="RollbackOnlyInterceptorFactory"/>
> </implementation>
> 
> Here, we declared the actual interceptor itself as a service and told the
> factory which service to call to intercept the methods.
>

---------------------------------------------------------------------
To unsubscribe, e-mail: hivemind-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-user-help@jakarta.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: hivemind-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-user-help@jakarta.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: hivemind-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-user-help@jakarta.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: hivemind-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-user-help@jakarta.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: hivemind-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-user-help@jakarta.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: hivemind-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-user-help@jakarta.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: hivemind-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-user-help@jakarta.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: hivemind-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-dev-help@jakarta.apache.org