After read chapter "11.7. The InterceptionFactory interface" of "CDI 2.0 Spec", I think that it could be an unexpected behavior or bug for Interfaces support in InterceptionFactory.
I know that CDI spec says that "If an injection point of type InterceptionFactory has a type parameter that is not a Java class, nonportable behavior results." but if Weld will support Interface proxies I think that all methods from interface should be returned unless you call "ignoreFinalMethods()" method.
first of all, CDI doesn't require any support for InterceptionFactory on interfaces, this is, at the moment, purely Weld feature.
It is also stated in Weld docs - here.
Now, the actual point of allowing it on interfaces is to bypass unproxyable implementations that user cannot control/change.
As WELD-2550 issue says in description, it behaves slightly differently from standard interception factory in a way that it only takes into consideration annotations directly on the interface. E.g if you have a class-level interceptor binding on the interceptor (or add it via configurator), it will only intercept methods this interface has; it will completely ignore any methods added by implementing class. This is what allows us to create a proxy from interface as all interface methods are by definition proxyable (non-final to start with).
I am not sure I understand your use case, could you put together a simple reproducer? Ideally just with CDI, showing what you expect to have intercepted for certain hierarchy of classes and interfaces?
Hello Matěj, it's correct, as you say I know that the support of Interfaces with InterceptionFactory is a functionality of Weld and the behavior is not portable.
I understand that this functionality is targeted to bypass unproxyable implementations that user can not control / change.
After read Weld core and with a minimum set of tests I also understand why it only includes the "default" methods of the interface since otherwise it would end in an InvocationTargetException or similar.
Now, in certain situations the object that is wanted to put in the context of CDI is an object that is already a dynamic proxy (jdk, javassist / cglib, etc ...) as it happens with spring AOT objects.
In my case I try to integrate a JavaEE project with "Spring Data Jpa". Spring Data Jpa is built with a CDI extension but it does not provide support for Transactions, fully delegating the transactions to the service layer and that is cumbersome.
If CDI or Weld would support to intercept this kind of objects completely, the integration with this type of technologies could be easy.
In this case I was able to solve the problem without using a CDI proxy, modifying the code of the Spring extension to allow me to add my own transaction interceptor, but this takes a greater effort compared to with the creation of a new CDI proxy (often the penalty is supported).
Added to this, in many opportunities the third party code is not modifiable so it's not a viable alternative and you ends up implementing a custom proxy.
I have two projects on github that you can check:
- The first one has weld / cdi tests and interceptors https://github.com/arielcarrera/cdi-interception-factory-test
- The second has weld / cdi tests with jta, jpa and spring data jpa. https://github.com/arielcarrera/cdi-spring-data-jpa-test
In the first one you can run the tests of the class "InterceptionDynamicProxyTest" and you will see two tests that already fail when the proxy interface has annotated methods or when they are added through the InterceptionFactory.
In the second project you can see how I had to solve the problem by creating my own interceptor, replicating transactional interceptor logic (:S), making it compatible with Spring's proxy and adding it to the CDI Extension. It also include some minor changes to Spring Data to discuss with they.