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@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@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<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-37...
_______________________________________________
weld-dev mailing list
weld-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/weld-dev
--
Martin Kouba
Senior Software Engineer
Red Hat, Czech Republic