-
1. Re: Interception question
ljnelson Mar 13, 2019 12:34 AM (in response to ljnelson)Oh, this is interesting.
This is slightly different from the case above, but I think I've found some strange behavior in Weld 3.0.5.Final. I'm not sure which of the two scenarios below is supposed to work and which is not.
In a test case I have that hopefully I'll be able to package up and redistribute shortly, this works:
@ApplicationScoped
public class Foo {
@Inject
private UserTransaction userTransaction;
// Note final:
private final void onStartup(@Observes @Initialized(ApplicationScoped.class) final Object event)
throws SystemException {
assertNotNull(event);
this.frobnicate();
}
@Transactional(Transactional.TxType.REQUIRED)
public void frobnicate() throws SystemException {
assertNotNull(this.userTransaction);
assertEquals(Status.STATUS_ACTIVE, this.userTransaction.getStatus());
}
}
This does not:
@ApplicationScoped
public class Foo {
@Inject
private UserTransaction userTransaction;
// Note not final:
private void onStartup(@Observes @Initialized(ApplicationScoped.class) final Object event)
throws SystemException {
assertNotNull(event);
this.frobnicate();
}
@Transactional(Transactional.TxType.REQUIRED)
public void frobnicate() throws SystemException {
assertNotNull(this.userTransaction);
assertEquals(Status.STATUS_ACTIVE, this.userTransaction.getStatus());
}
}
Note the lack of final on the onStartup method. Of course private methods should be final effectively anyway.
On OpenWebBeans both constructs work.
Best,
Laird
-
2. Re: Interception question
mkouba Mar 13, 2019 2:32 AM (in response to ljnelson)Hi Laird,
I believe that the interceptor should not be invoked because
this.frobnicate()
is not a business method invocation. However, it's not explicitly defined neither in CDI nor in the Interceptors spec. There is an open spec issue: https://issues.jboss.org/browse/CDI-414. -
3. Re: Interception question
manovotn Mar 13, 2019 3:45 AM (in response to ljnelson)My understanding is same as Martin's.
It shouldn't be invoked because you are not going through a contextual reference, hence it won't be a business method invocation.
This, to me, seems fairly well defined in CDI spec 7.2 Container invocations and interception. Although the aforementioned CDI issue has various takes on the interpretation.
-
4. Re: Interception question
ljnelson Mar 13, 2019 11:29 AM (in response to mkouba)mkouba wrote:
Hi Laird,
I believe that the interceptor should not be invoked because
this.frobnicate()
is not a business method invocation. However, it's not explicitly defined neither in CDI nor in the Interceptors spec. There is an open spec issue: https://issues.jboss.org/browse/CDI-414.Thanks, Martin. Since control has entered the ApplicationScoped bean by way of a lifecycle event observer, isn't the this pointer a contextual reference and hence a client proxy? I think that's OpenWebBeans' position. Romain Manni-Bucau was emphatic on this point.
Regardless, it sounds like you're saying any usage of this.frobnicate() is by definition not a business method invocation, and that if interception occurs it is merely by chance, and I understand why you would say this. So one of the cases above would be a bug in Weld, namely the case that "works". Should I file an issue to track this?
Certainly given that I can just inject a self in a static observer method instead, obviously that's the safest thing to do and I understand that.
Nevertheless, I am still curious why the mere presence of final on a private instance method serving as an observer method makes this work, whereas removing final makes it not work. One would think this change should not make any difference, as all private methods are effectively final anyway.
-
5. Re: Interception question
mkouba Mar 13, 2019 11:29 AM (in response to ljnelson)Thanks, Martin. Since control has entered the ApplicationScoped bean by way of a lifecycle event observer, isn't the this pointer a contextual reference and hence a client proxy? I think that's OpenWebBeans' position. Romain Manni-Bucau was emphatic on this point.
Invocations of observer methods are business method invocations and thus are intercepted. But you would have to annotate the onStartup() method with Transactional to make it work.
Nevertheless, I am still curious why the mere presence of final on a private instance method serving as an observer method makes this work, whereas removing final makes it not work. One would think this change should not make any difference, as all private methods are effectively final anyway.
I have no idea but I'd guess it works by coincidence... Hm, it would be really interesting to find out more manovotn
-
6. Re: Interception question
manovotn Mar 14, 2019 3:59 AM (in response to mkouba)mkouba wrote:
Thanks, Martin. Since control has entered the ApplicationScoped bean by way of a lifecycle event observer, isn't the this pointer a contextual reference and hence a client proxy? I think that's OpenWebBeans' position. Romain Manni-Bucau was emphatic on this point.
Invocations of observer methods are business method invocations and thus are intercepted. But you would have to annotate the onStartup() method with Transactional to make it work.
Nevertheless, I am still curious why the mere presence of final on a private instance method serving as an observer method makes this work, whereas removing final makes it not work. One would think this change should not make any difference, as all private methods are effectively final anyway.
I have no idea but I'd guess it works by coincidence... Hm, it would be really interesting to find out more manovotn
It's got to be some magic around how proxies handle invocations of methods that are marked final. Dumping generated bytecode will be the starting point I suppose.
ljnelson feel free to create a JIRA, I'll look into it.
-
7. Re: Interception question
manovotn Mar 19, 2019 2:58 AM (in response to manovotn)FYI, I have created [WELD-2571] Investigate self-invocation of intercercepted private final method - JBoss Issue Tracker to track this.
-
8. Re: Interception question
manovotn May 2, 2019 8:43 AM (in response to ljnelson)ljnelson FYI there is a PR up that aligns the behaviour of private final observer methods with the rest of what Weld does in regards to self-invocation and interception.
Thanks for reporting it!