wildfly - CDI typesafe resolution is not working in weld 2.2.6 when the the bean type parameter is a type variable -


the following code snipset works "weld-core-1.1.5.as71.final.jar" (the 1 used jboss 7.1.1), doesn't work "weld-core-impl-2.2.6.final.jar" (the 1 used wildfly 8.2).

public class client<t> {     public interface spi<t> {         t getsomething();     }      @inject     private spi<t> spi; // weld-001408: unsatisfied dependencies type spi<object>  }  public class spiimpl implements client.spi<integer> {     @override     public integer getsomething() {         return 5;     } } 

why? cdi 1.2 specification:

a parameterized bean type considered assignable parameterized required type if have identical raw type , each parameter:

  1. the required type parameter , bean type parameter actual types identical raw type, and, if type parameterized, bean type parameter assignable required type parameter according these rules, or
  2. the required type parameter wildcard, bean type parameter actual type , actual type assignable upper bound, if any, of wildcard , assignable lower bound, if any, of wildcard, or
  3. the required type parameter wildcard, bean type parameter type variable , upper bound of type variable assignable or assignable upper bound, if any, of wildcard , assignable lower bound, if any, of wildcard, or
  4. the required type parameter actual type, bean type parameter type variable , actual type assignable upper bound, if any, of type variable, or
  5. the required type parameter , bean type parameter both type variables , upper bound of required type parameter assignable upper bound, if any, of bean type parameter.

so, according item #4, above code should work, shouldn't it?

edit 1: <-- see edit 2 before. there noticed cdi implementation doing expected should do, mistakenly thought didn't.

antonin stefanutti answer right: item #4 of mentioned specification don't apply. but, if actual type of type variable t known when inyectión point resolved, possible proper instance of spi.

supouse client class abstract , implementation specifies type of type parameter in class definition. in case, actual type can discovered , item #4 of specification apply.

how can resolved? means of introspection, using class#getgenericinterfaces() operation, on actual class of client instance. this:

public class test {  @inject private clientimpl clientimpl;  public abstract static class client<t> {     public interface spi<t> {         t getsomething();     }      // @inject inject don't work because cdi doesn't require when actual type of t can discovered. so, instead, initialized programaticaly in postconstruct()     private spi<t> spi; // weld-001408: unsatisfied dependencies type spi<object> // not true, later, in "edit 2" noteced works fine. forget this. sorry.      @inject     private instance<spi<?>> spifinder;      /**initializes spi instance variable programaticaly */     @postconstruct     private void postconstruct(){         parameterizedtype clienttype = (parameterizedtype)this.getclass().getgenericsuperclass();         type clienttypeparamter = clienttype.getactualtypearguments()[0];         class<t> clientparameterclass = (class<t>)clienttypeparamter;          final iterator<spi<?>> iterator = spifinder.iterator();         while (iterator.hasnext()) {             spi<?> spicandidate = iterator.next();             parameterizedtype spicandidatetype = (parameterizedtype)spicandidate.getclass().getgenericinterfaces()[0];             type spicandidatetypeparameter = spicandidatetype.getactualtypearguments()[0];             class<?> spicandidateparameterclass = (class<?>)spicandidatetypeparameter;             if( clientparameterclass.isassignablefrom(spicandidateparameterclass)) {                 if( spi != null)                     throw new ambiguousresolutionexception();                 spi = (spi<t>)spicandidate;             }         }         if( spi == null)             throw new unsatisfiedresolutionexception();     } }  @dependent public static class spiimpl_1 implements client.spi<integer> {     @override     public integer getsomething() {         return 5;     } }  @dependent public static class spiimpl_2 implements client.spi<double> {     @override     public double getsomething() {         return 5.0;     } }  @dependent public static class clientimpl extends client<integer> {}  } 

the above code works (an instance of spiimpl_1 injected spi instance variable), so, why couldn't cdi job us? instrospection it's possible discover actual type of every type parameter declared in enclosing class/interface definition when concrete class specifies actual type of extended superclass's type parameter.

edit 2 sorry, forget have said. cdi inject proper instance of client in second example without need of programatic initialization added. doen't throw "weld-001408: unsatisfied dependencies type spi" said does. wrong. sorry again. should delete question?

in example, required type parameter type variable, t, , not actual type item #4 not apply. actually, of conditions mentioned in specification assignability of parameterized bean type parameterized required type met in example, implies conclusively dependency not satisfied.

this somehow related cdi-517, though not identical, yet clarification can explain behavioral changes between weld 1.x , weld 2.x specification has been clarified.

as mentioned in discussion, having spi<integer> assignable spi<t> incorrect java langage standpoint.


Popular posts from this blog

c# - ODP.NET Oracle.ManagedDataAccess causes ORA-12537 network session end of file -

matlab - Compression and Decompression of ECG Signal using HUFFMAN ALGORITHM -

utf 8 - split utf-8 string into bytes in python -