4 Replies Latest reply on Mar 12, 2015 9:23 AM by mkouba

    WELD-001408: Unsatisfied dependencies with parameterized type having dependencies

    stessy.delcroix

      Hi,

       

      we are experiencing a problem when we try to use a producer with parameterized types having dependencies between them.

       

      The following two interfaces represent the Entity and DAO as we would like to type them. Our entity specifies the type of its primary key. The DAO is typed with the entity and the primary key. Under CDI 1.0 (we are using Weld contained in Glassfish 3.1.2.2) we are able to inject instances of the DAO using a producer method, where we use the injection point to determine the generic parameter values at runtime.

       

      public interface BaseEntity<PK> {

       

       

      }

       

      public interface DAO<K extends BaseEntity<PK>, PK> {

       

       

          List<K> findAll();

       

       

      }

       

      Using Weld 2.2.6 (contained in WildFly 8.2.1), the injection does not work anymore. Here is the producer which works using CDI 1.0 but not using Weld 2.2.6.

      @ApplicationScoped

      public class DAOProducer {

       

       

       

       

          @Produces

          public <K extends BaseEntity<PK>, PK> TestDAO<K, PK> createDAO() {

              return (TestDAO<K, PK>) new TestDAOImpl();

          }

       

       

      }

       

      On the other hand a producer where the parameterized types are not related is correctly injected. This works when deployed in WildFly. The only difference between the working version and the broken version is that we replaced the generic parameter on BaseEntity with a wildcard.

       

      public interface BaseEntity<?> {

       

       

      }

       

       

      public interface DAO<K extends BaseEntity<?>, PK> {

       

       

          List<K> findAll();

       

       

      }

       

      @ApplicationScoped

      public class DAOProducer {

       

       

       

          @Produces

          public <K extends BaseEntity<?>, PK> TestDAO<K, PK> createDAO() {

              return (TestDAO<K, PK>) new TestDAOImpl();

          }

       

       

      }

       

      Is there anything that we missed regarding the CDI 1.2 spec, especially this part Contexts and Dependency Injection for the Java EE platform ?

       

      Is it possible to inject beans having a relationship between parameterized type ?

       

      Thanks for your help.

        • 1. Re: WELD-001408: Unsatisfied dependencies with parameterized type having dependencies
          mkouba

          Hi,

          I think it should be possible. How does the injection point look like?

          • 2. Re: WELD-001408: Unsatisfied dependencies with parameterized type having dependencies
            stessy.delcroix

            Hi Martin,

             

            thanks for your reply.

             

            Here is the service where the bean is injected and the entity used for testing

            @Stateless

            @LocalBean

            @Local(TestService.class)

            public class TestServiceImpl implements TestService {

             

                @Inject

                private TestDAO<TestEntity, Long> workingDAO;

             

                @Override

                public void testCdiRawType() {

                    this.workingDAO.findAll();

                }

             

             

            }

             

            @Entity

            @Table(name = "TEST_ENTITY")

            public class TestEntity implements BaseEntity<Long> {

             

                @Id

                @GeneratedValue(strategy = GenerationType.AUTO)

                private Long id;

             

                @Column(name = "STR")

                private String str;

             

                public String getStr() {

                    return this.str;

                }

             

                public void setStr(final String str) {

                    this.str = str;

                }

             

            }

            • 3. Re: WELD-001408: Unsatisfied dependencies with parameterized type having dependencies
              mkouba

              Hm, it seems that it shouldn't work according to the spec and Weld 2.2.x is correct. Actually, it has nothing to do with the relation between the type variables. It's more related to how covariance works in Java. Let's go through the resolution process step by step:

               

              Injection point: @Inject private TestDAO<TestEntity, Long> workingDAO

              Producer bean: @Produces public <K extends BaseEntity<PK>, PK> TestDAO<K, PK> createDAO()

               

              Now, we can identify the required type and the bean type which we would like to test:

               

              Required type: TestDAO<TestEntity, Long>

              Bean type: TestDAO<K extends BaseEntity<PK>, PK>

               

              Here, the following bullet from 5.2.4. Assignability of raw and parameterized types applies:

              • the required type parameter and the bean type parameter are actual types with identical raw type, and, if the type is parameterized, the bean type parameter is assignable to the required type parameter according to these rules, or

               

              Let's test the first parameter:

               

              Required type: TestEntity

              Bean type: K extends BaseEntity<PK>

               

              The spec rule:

              • the required type parameter is an actual type, the bean type parameter is a type variable and the actual type is assignable to the upper bound, if any, of the type variable, or

               

              And this rule does not match because in Java generic types are invariant, i.e. you can't assign TesEntity to BaseEntity<PK>.

              • 4. Re: WELD-001408: Unsatisfied dependencies with parameterized type having dependencies
                mkouba

                Also note that wildcard types are covariant in their upper bounds.