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

2018-03-15 Thread Martin Kouba
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 {
> String repeat(@NotNull String in);
> 
> @NotNull
> T reverse(T in);
> 
> @NotNull
> String getHelloWorld();
> }
> 
> and then it's impl:
> 
> @ValidateOnExecution
> public class DefaultRepeater implements Repeater {
> 
> @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@4863} 
> "org.hibernate.validator.test.cdi.internal.methodvalidation.Repeater"
> 
> 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@3049} "interface 
> org.hibernate.validator.test.cdi.internal.methodvalidation.Repeater"
>   1 = {Class@327} "interface java.io.Serializable"
>   2 = {Class@4636} "interface org.jboss.weld.proxy.WeldConstruct"
>   3 = {Class@4638} "interface 
> org.jboss.weld.interceptor.util.proxy.TargetInstanceProxy"
>   4 = {Class@4637} "interface 
> org.jboss.weld.interceptor.proxy.LifecycleMixin"
>   5 = {Class@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).
> 
>   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
>  
> 
> 
> 
> 
> ___
> weld-dev mailing list
> weld-dev@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/weld-dev
> 

-- 
Martin Kouba
Senior Software Engineer
Red Hat, Czech Republic
___
weld-dev mailing list
weld-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/weld-dev

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

2018-03-13 Thread Marko Bekhta
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 {
String repeat(@NotNull String in);

@NotNull
T reverse(T in);

@NotNull
String getHelloWorld();
}

and then it's impl:

@ValidateOnExecution
public class DefaultRepeater implements Repeater {

@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@4863} "org.hibernate.validator.test.
cdi.internal.methodvalidation.Repeater"

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@3049} "interface org.hibernate.validator.test.
cdi.internal.methodvalidation.Repeater"
 1 = {Class@327} "interface java.io.Serializable"
 2 = {Class@4636} "interface org.jboss.weld.proxy.WeldConstruct"
 3 = {Class@4638} "interface org.jboss.weld.interceptor.util.proxy.
TargetInstanceProxy"
 4 = {Class@4637} "interface org.jboss.weld.interceptor.
proxy.LifecycleMixin"
 5 = {Class@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).

 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
___
weld-dev mailing list
weld-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/weld-dev