[weld-dev] interceptors expected to be implemented via proxying or via subclassing?

Mark Struberg struberg at yahoo.de
Mon May 17 12:36:13 EDT 2010


Thanks Marius!

That sums it up pretty well. My main concern is not _that_ we (OWB + Weld) currently work that way, but that this behaviour is not really explicitly stated.

I can well live with the behaviour because there are ways to work around it. But those ways should get clearly documented, otherwise we would confuse users pretty heavily.

For example:

public class MyService {
  private @Inject MyService self;

  @Secured(role=Admin)
  public doA(){..}
  
  @Secured(role=User)
  public doU(){
    self.doA();
  }
}

txs and LieGrue,
strub


--- On Mon, 5/17/10, Marius Bogoevici <marius.bogoevici at gmail.com> wrote:

> From: Marius Bogoevici <marius.bogoevici at gmail.com>
> Subject: Re: [weld-dev] interceptors expected to be implemented via proxying or via subclassing?
> To: "Kenneth Saks" <ken.saks at oracle.com>
> Cc: "Pete Muir" <pmuir at redhat.com>, "Mark Struberg" <struberg at yahoo.de>, "Kenneth Saks" <Kenneth.Saks at sun.com>, "Weld-Dev List" <weld-dev at lists.jboss.org>
> Date: Monday, May 17, 2010, 4:18 PM
> Well ... I'm not considering
> interception of calls to 'this' an 
> ideological issue, so I think the discussion is still open,
> but I want 
> to add a few more elements to the discussion:
> 
> Not only EJBs behave in this way (calls to "this" are not
> intercepted), 
> but this is, for example, the case for Spring beans as well
> (notably, 
> even when using subclassing via CGLib). The only case when
> Spring beans 
> behave differently (and apply aspects on calls to "this")
> is when 
> applying AspectJ load-time-weaving (which is a completely
> different kind 
> of beast altogether).
> 
> Of course that there is room for treating JSR-299 and EJBs
> differently 
> wrt interception/decoration. The main question is whether
> we want to go 
> that way or not. Now, there are plenty of cases when the
> invocation on 
> an otherwise intercepted method will not be
> intercepted/decorated, like 
> for example:
> 
> public class SelfIntercepting {
> 
>     void method A() {
>      }
> 
>      void method B() {
>      }
> 
>      @AroundInvoke
>      public void
> aroundInvoke(InvocationContext ctx) {
>         ((SelfIntercepting)
> ctx.getTarget()).methodA();
>      }
> }
> 
> In this case a call to methodB does not go twice through
> methodA() - we 
> know that getTarget() returns a non-intercepted instance
> (it's the 
> spec). However, if we had this.methodA(), would be expect
> that to be 
> intercepted?
> 
> or, for example, if a decorator invokes a different method
> (B) on a 
> delegate than the one it decorates (A), we do not apply the
> whole 
> decorator chain on the new invocation, we just start at the
> next 
> delegate. But, if the method (B) on the target class had an
> interceptor, 
> will we expect it to be intercepted as well? Well ...
> 
> I would be all for doing things as Mark says, as I
> recognize a lot of 
> situations where that is useful and I understand some of
> the confusion, 
> however, my considerations are that the price to be paid in
> 
> inconsistency and need to clarify things on a case-per-case
> basis 
> overweigh by far the benefits of a clear-cut explanation,
> albeit not 
> satisfactory in all cases. I'd rather simply say: these are
> managed 
> objects, therefore only contextual references are
> intercepted/decorated. 
> There is a boundary that the container sets and we sort of
> have to live 
> with that.
> 
> Perhaps we could find a way to do something similar to what
> EJB does, 
> i.e. ala
> @Inject @SelfDelegate SomeClasss contextualThis;
> 
> I have to say it - this will not win an aesthetics contest,
> but I find 
> it overall cleaner than dealing with the whole mess of
> "when is the 
> method intercepted, when is it not".
> 
> 
> On 10-05-17 9:19 AM, Kenneth Saks wrote:
> > On May 17, 2010, at 5:45 AM, Pete Muir wrote:
> >
> >    
> >> Hi Ken,
> >>
> >> Could you tell us where the EJB spec(s) says that
> you only don't have to intercept references to this?
> >>      
> > Hi Pete,
> >
> > An EJB invocation is by definition an invocation on an
> EJB reference object.  That's the only way to get the
> additional services  (CMT, method authorization,
> special exception handling, interceptors, etc.) offered by
> the container.  The caller never holds a direct
> reference to a bean instance.
> >
> > The case where code within a bean class method makes a
> direct Java invocation of another method in the bean class
> using "this" is just a plain Java SE method
> invocation.  There's no container interposition
> involved.    SessionContext.getBusinessObject()
> was defined in part to allow one business method to make a
> 1st class EJB invocation on its own bean.
> >
> >   --ken
> >
> >    
> >> Thanks!
> >>
> >> On 16 May 2010, at 09:36, Mark Struberg wrote:
> >>
> >>      
> >>> Hoi!
> >>>
> >>> Sorry, only came back yesterday night, so I
> had no time to answere Marius' post before.
> >>>
> >>> Actually I don't really know if I should agree
> or not.
> >>>
> >>> I would not really argue with the EJB spec,
> because 299 and EJB are still different. For example in the
> EJB spec Interceptors doesn't need to be Serializable
> whereas in 299 they certainly do for passivatable scopes.
> >>>
> >>> Also, EJB-3.1 is coming from the EJB-2 mindset
> where you really have separated remotes and stubs and many
> people are _used_ that only remote calles get intercepted.
> But I actually didn't find that backed in the EJB-3.1 spec
> (4.3.12), any? Imo the spec does NOT say that interception
> only happens if business methods get invoked from external!
> It's only that _old_ EJB users got _used_ to that
> behaviour.
> >>>
> >>> Let's make a small example:
> >>>
> >>> public class MyService() {
> >>>
> >>> @Secured(role=Admin)
> >>> public void doThingA() {
> >>> }
> >>>
> >>> @Secured(role=User)
> >>> public void doThingU() {
> >>>    ...
> >>>    if (veryRareCase) {
> >>>      doThingA()
> >>>    }
> >>> }
> >>>
> >>> }
> >>>
> >>> Clearly we would allow to call doThingA
> without checking for admin rights. I don't like to split my
> classes depending on the interceptors I'd like to apply.
> That sounds _really_ dumb. Even more if you look at
> interceptors which get applied without annotating the
> classes in the code but from external like e.g. @Trace,
> @Statistics, etc.
> >>>
> >>> This also happens if you have services where
> not all methods share must be e.g. @Transactional or even
> worse, use @Transactional with different payload.
> >>>
> >>> WE know WHY this behaves that way, but for 99%
> of all users, this will get reported as bug (as seen on the
> OpenEJB list lot of times).
> >>>
> >>> I'm sure we can do better!
> >>>
> >>> LieGrue,
> >>> strub
> >>>
> >>>
> >>> --- On Wed, 5/12/10, Pete Muir<pmuir at redhat.com> wrote:
> >>>
> >>>        
> >>>> From: Pete Muir<pmuir at redhat.com>
> >>>> Subject: Re: [weld-dev] interceptors
> expected to be implemented via proxying or via subclassing?
> >>>> To: "Marius Bogoevici"<marius.bogoevici at gmail.com>
> >>>> Cc: "Mark Struberg"<struberg at yahoo.de>,
> weld-dev at lists.jboss.org
> >>>> Date: Wednesday, May 12, 2010, 1:46 PM
> >>>> Agreed.
> >>>>
> >>>> On 11 May 2010, at 10:31, Marius Bogoevici
> wrote:
> >>>>
> >>>>          
> >>>>> Mark,
> >>>>>
> >>>>> I asked a similar  question
> here:
> >>>>> http://lists.jboss.org/pipermail/weld-dev/2010-April/002485.html
> >>>>>
> >>>>> Gurkan answered here:
> >>>>> http://lists.jboss.org/pipermail/weld-dev/2010-April/002490.html
> >>>>>
> >>>>> So based on what I think, and also on
> my understanding
> >>>>>         
>   
> >>>> of what Gurkan
> >>>>          
> >>>>> says: one should not expect that
> invocations to 'this'
> >>>>>         
>   
> >>>> are
> >>>>          
> >>>>> intercepted/decorated - that doesn't
> happen in EJB and
> >>>>>         
>   
> >>>> it is not
> >>>>          
> >>>>> expected to happen for decorators.
> >>>>>
> >>>>> Marius
> >>>>>
> >>>>> On 10-05-11 2:24 AM, Mark Struberg
> wrote:
> >>>>>         
>   
> >>>>>> Hi!
> >>>>>>
> >>>>>> There is a subtle difference
> between implementing
> >>>>>>         
>     
> >>>> interceptors via proxy or via subclasses.
> >>>>          
> >>>>>> I have the following service which
> imports data
> >>>>>>         
>     
> >>>> from a legacy system into my db. Since
> commits are very
> >>>> performance intense, they should get
> imported in packages of
> >>>> 100. So I'll get 100 'Employees' from my
> legacy system and
> >>>> then call a @Transactional method to store
> them in my own
> >>>> database.
> >>>>          
> >>>>>> public void ImportService() {
> >>>>>>    public void
> importEmployee() {
> >>>>>>
> >>>>>>         
>     
> >>>>   
> List<LegacyEmployee>   les;
> >>>>          

> >>>>>>      while ((les =
> >>>>>>         
>     
> >>>> getNext100EmployeesFromLegacy()) != nul)
> {
> >>>>          
> >>>>>>         
>     
> >>>>    importLegacyEmployees(le);
> >>>>          
> >>>>>>      }
> >>>>>>    }
> >>>>>>
> >>>>>>    @Transactional
> >>>>>>    protected
> >>>>>>         
>     
> >>>>
> importLegacyEmployees(List<LegacyEmployee>   les)
> >>>> {
> >>>>          
> >>>>>>      for
> (LegacyEmployee le:
> >>>>>>         
>     
> >>>> les) {
> >>>>          
> >>>>>>         
>     
> >>>>    employeeService.store(le);
> >>>>          
> >>>>>>      }
> >>>>>>    }
> >>>>>> }
> >>>>>>
> >>>>>> This would actually _not_ work
> when using proxies
> >>>>>>         
>     
> >>>> for the interceptor handling, because
> calling a method on an
> >>>> own class doesn't invoke the
> proxyhandler.
> >>>>          
> >>>>>> So is this expected to work?
> >>>>>>
> >>>>>> I remember that the old spec
> explicitly says that
> >>>>>>         
>     
> >>>> we need to use subclassing, but cannot
> find this paragraph
> >>>> anymore. So what does the spec require us
> to do? And what is
> >>>> Weld going to do?
> >>>>          
> >>>>>> txs and LieGrue,
> >>>>>> strub
> >>>>>>
> >>>>>>
> >>>>>>         
>     
> >>>>>         
>   
> >>>>>>
> _______________________________________________
> >>>>>> weld-dev mailing list
> >>>>>> weld-dev at lists.jboss.org
> >>>>>> https://lists.jboss.org/mailman/listinfo/weld-dev
> >>>>>>
> >>>>>>         
>     
> >>>>>
> _______________________________________________
> >>>>> weld-dev mailing list
> >>>>> weld-dev at lists.jboss.org
> >>>>> https://lists.jboss.org/mailman/listinfo/weld-dev
> >>>>>         
>   
> >>>>
> >>>>          
> >>>
> >>>
> >>>
> >>>
> _______________________________________________
> >>> weld-dev mailing list
> >>> weld-dev at lists.jboss.org
> >>> https://lists.jboss.org/mailman/listinfo/weld-dev
> >>>        
> >>      
> >    
> 
> 


      



More information about the weld-dev mailing list