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();
}
}
I think that this will lead to recursive injection (and OOME) if the
bean is not normal scoped (and by default it wouldn't be). I think that
the best way to sort this out is to provide an extension in the form of
a distinct qualifier e.g. @Self.
And trying to infer things ala "if the injection target is of the same
class as the the bean itself, inject the intercepted instance" may not
hold, since we may be required to inject an @Alternative.
txs and LieGrue,
strub
--- On Mon, 5/17/10, Marius Bogoevici<marius.bogoevici(a)gmail.com> wrote:
> From: Marius Bogoevici<marius.bogoevici(a)gmail.com>
> Subject: Re: [weld-dev] interceptors expected to be implemented via proxying or via
subclassing?
> To: "Kenneth Saks"<ken.saks(a)oracle.com>
> Cc: "Pete Muir"<pmuir(a)redhat.com>, "Mark
Struberg"<struberg(a)yahoo.de>, "Kenneth
Saks"<Kenneth.Saks(a)sun.com>, "Weld-Dev
List"<weld-dev(a)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(a)redhat.com>
>>>>
> wrote:
>
>>>>
>>>>
>>>>> From: Pete Muir<pmuir(a)redhat.com>
>>>>> Subject: Re: [weld-dev] interceptors
>>>>>
> expected to be implemented via proxying or via subclassing?
>
>>>>> To: "Marius Bogoevici"<marius.bogoevici(a)gmail.com>
>>>>> Cc: "Mark Struberg"<struberg(a)yahoo.de>,
>>>>>
> weld-dev(a)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(a)lists.jboss.org
>>>>>>>
https://lists.jboss.org/mailman/listinfo/weld-dev
>>>>>>>
>>>>>>>
>>>>>>>
>
>
>>>>>>
> _______________________________________________
>
>>>>>> weld-dev mailing list
>>>>>> weld-dev(a)lists.jboss.org
>>>>>>
https://lists.jboss.org/mailman/listinfo/weld-dev
>>>>>>
>>>>>>
>
>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>>
> _______________________________________________
>
>>>> weld-dev mailing list
>>>> weld-dev(a)lists.jboss.org
>>>>
https://lists.jboss.org/mailman/listinfo/weld-dev
>>>>
>>>>
>>>
>>>
>>
>>
>
>