4 Replies Latest reply on Nov 24, 2017 10:22 AM by mkouba

    CDI injection into servlet not working in Wildfly.

    swbrenneis

      I am having problems with CDI injection into a couple of servlets. I find mention on Google that people have problems with it, but I can't find anywhere that it is prohibited.

       

      What I have:

       

      @Qualifier

      @Retention(RUNTIME)

      @Target({ TYPE, FIELD, METHOD })

      public @interface MyAnnotation {

      }

       

      public interface MyInterface {

      ...

      }

       

      @MyAnnotation

      @ApplicationScoped

      public class MyBean implements MyInterface {

      ...

      }

       

      @WebServlet("MyResource")

      public class MyServlet extends HttpServlet {

       

      @Inject @MyAnnotation

      private MyInterface bean;

      ...

      }

       

      public class AnotherClass {

       

         @Inject @MyAnnotation

         private MyInterface bean;

      ...

      }

       

      This is packaged in an ear file with the annotation, interface, and bean in an EJB archive and the servlet in a war file. The EJB archive has an empty beans.xml with bean discover mode = all.

       

      The problem is that bean (in the servlet) is always null in the doGet method. I can't tell if it is null in AnotherClass because the null pointer exception in the servlet prevents execution from ever getting there. If I remove the interface and change MyBean to a singleton no-interface bean and use @EJB injection in the servlet, Wildfly complains that there is already a MyBean implementation in the module. If I remove the @Singleton annotation from the bean, Wildfly is happy, but obviously the bean isn't application scoped and the expected state is not present. I have solved this problem in another place by creating an EJB proxy class, but that is less than optimal.

       

      All help is appreciated.

        • 1. Re: CDI injection into servlet not working in Wildfly.
          swbrenneis

          I found the answer, so hopefully this will help someone else.

           

          In numerous places, I see comments and documentation to the effect that a beans.xml file is no longer necessary. That is not the case. According to the JSR, a bean archive must have a beans.xml file. Additionally, any archive that contains classes that use injected beans must also have a beans.xml file, even if it is empty. In my case, my EJB archive had a beans.xml, but the web application war file did not. Adding the beans.xml file to the war solved the problem.

          • 2. Re: CDI injection into servlet not working in Wildfly.
            mkouba

            Hi Steve,

            what version of WildFly do you use?

            I numerous places, I see comments and documentation to the effect that a beans.xml file is no longer necessary.

            Well, it's a little bit more complicated, especially when speaking about EARs. Anyway, in WildFly CDI injection into Java EE components should work in any bean archive, i.e. either in an explicit bean archive (has beans.xml either empty OR with bean-discovery-mode=all) or in an implicit bean archive (has no beans.xml but contains at least one bean class annotated with a bean defining annotation, e.g. scope OR has beans.xml with bean-discovery-mode=annotated). See also http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bean_archive.

            • 3. Re: CDI injection into servlet not working in Wildfly.
              swbrenneis

              Hi Martin.

               

              I am using Wildfly 10.1. I have encountered this problem in a couple of places, and wherever it occurs, the solution is to put a beans.xml file in the archive. When I say the file is empty, that might be a bit misleading. What I mean is that there are no bean mappings. It is simply the opening and closing bean tag with the bean discovery mode set to all. I also encountered a similar problem trying to create a custom extension in which all bean discovery failed until I added the beans.xml file. I think there might be some general misunderstanding of the function of the file, but so far, other than a very simple case, it seems the beans.xml file is necessary in every archive containing a CDI bean.

              • 4. Re: CDI injection into servlet not working in Wildfly.
                mkouba

                When I say the file is empty, that might be a bit misleading. What I mean is that there are no bean mappings.

                Yes, in CDI there is nothing like "bean mappings". In CDI 1.1+ beans.xml is mostly used to mark a bean archive or to specify discovery mode.

                I also encountered a similar problem trying to create a custom extension in which all bean discovery failed until I added the beans.xml file.

                Yes, some CDI extensions do not support implicit bean archives (and annotated bean discovery) or even require explicit bean archives.

                I think there might be some general misunderstanding of the function of the file, but so far, other than a very simple case, it seems the beans.xml file is necessary in every archive containing a CDI bean.

                No, it does work even without the beans.xml file (even in Java SE). But you're right that sometimes it's really confusing. Anyway, I think it's always good to add the descriptor to an archive which should be considered a bean archive.