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

Kenneth Saks ken.saks at oracle.com
Mon May 17 09:19:02 EDT 2010


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