[weld-dev] Class#getGenericInterfaces() on a CDI proxy

Martin Kouba mkouba at redhat.com
Thu Mar 15 03:21:40 EDT 2018


Hi Marko,

I don't think Class#getGenericInterfaces() is defined for CDI proxies. 
In any case, there are some generics-related problems with proxies (see 
for example WELD-1539 and WELD-1914). So I would recommend to detect 
client proxies and subclasses and inspect the superclass (i.e. the 
original class, DefaultRepeater in your case) via reflection. Since 
2.3.0.Beta1 and 3.0.0.Alpha11 classes generated by Weld are marked with 
the SYNTHETIC modifier. And the name of the proxy class should always 
contain "$Proxy$". In Weld 3.0.1+ you can even use 
org.jboss.weld.proxy.WeldConstruct and 
org.jboss.weld.proxy.WeldClientProxy interfaces to distinguish such classes.

Martin

Dne 13.3.2018 v 14:38 Marko Bekhta napsal(a):
> Hi all!
> 
> While working on an issue [1] in Hibernate Validator, We've stumbled on, 
> what
> seems to be, a bug in Weld. We have a generic interface:
> 
> @ValidateOnExecution(type = { ExecutableType.NON_GETTER_METHODS, 
> ExecutableType.GETTER_METHODS })
> public interface Repeater<T> {
> String repeat(@NotNull String in);
> 
> @NotNull
> T reverse(T in);
> 
> @NotNull
> String getHelloWorld();
> }
> 
> and then it's impl:
> 
> @ValidateOnExecution
> public class DefaultRepeater implements Repeater<String> {
> 
> @Override
> public String repeat(String in) {
> return in;
> }
> 
> @Override
> public String reverse(String in) {
> return null;
> }
> 
> @Override
> public String getHelloWorld() {
> return null;
> }
> }
> 
> In the internals of HV we need to make a call to 
> `Class#getGenericInterfaces()`.
> In case of calling it on `DefaultRepeater` class we will get something 
> similar
> to:
> 
> result = {Type[1]@4948}
>   0 = {ParameterizedTypeImpl at 4863} 
> "org.hibernate.validator.test.cdi.internal.methodvalidation.Repeater<java.lang.String>"
> 
> But in case when validation run in CDI context we receive a proxy instead
> (something like 
> org.hibernate.validator.test.cdi.internal.methodvalidation.DefaultRepeater$Proxy$_$$_WeldSubclass). 
> 
> And if we call `Class#getGenericInterfaces()` on such proxy we'd get 
> next results:
> 
>   result = {Class[6]@4880}
>   0 = {Class at 3049} "interface 
> org.hibernate.validator.test.cdi.internal.methodvalidation.Repeater"
>   1 = {Class at 327} "interface java.io.Serializable"
>   2 = {Class at 4636} "interface org.jboss.weld.proxy.WeldConstruct"
>   3 = {Class at 4638} "interface 
> org.jboss.weld.interceptor.util.proxy.TargetInstanceProxy"
>   4 = {Class at 4637} "interface 
> org.jboss.weld.interceptor.proxy.LifecycleMixin"
>   5 = {Class at 4639} "interface org.jboss.weld.bean.proxy.ProxyObject"
> 
>   The only line of interest here is 0. As you can see it gives a raw, 
> non-generic
>   type, while `ParameterizedType` was expected (Repeater<java.lang.String>).
> 
>   Is that expected/intended behavior of `Class#getGenericInterfaces()`
>   (returning raw types) for CDI proxies?
> 
>   Have a nice day,
>   Marko
> 
>   [1]https://github.com/hibernate/hibernate-validator/pull/931#issuecomment-372619324 <https://github.com/hibernate/hibernate-validator/pull/931#issuecomment-372619324>
> 
> 
> 
> _______________________________________________
> weld-dev mailing list
> weld-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/weld-dev
> 

-- 
Martin Kouba
Senior Software Engineer
Red Hat, Czech Republic


More information about the weld-dev mailing list