@ApplicationScoped beans get constructed more than once











up vote
1
down vote

favorite












I have two managed Java beans:



import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;

import javax.ws.rs.Path;

@Path("/sync")
@ManagedBean(name="syncService", eager=true)
@ApplicationScoped
public class SyncService {
@ManagedProperty(value="#{ldapDirectoryAccess}")
private DirectoryAccess directoryAccess;

public void setDirectoryAccess(DirectoryAccess directoryAccess) {
System.out.println("SyncService.setDirectoryAccess()");
this.directoryAccess = directoryAccess;
}

public SyncService() {
System.out.println("SyncService() - constructed: " + this);
}

@PostConstruct
public void init() {
System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
}
...
}

@ManagedBean(name="ldapDirectoryAccess", eager=true)
@ApplicationScoped
public class LdapDirectoryAccess implements DirectoryAccess {
public LdapDirectoryAccess() {
System.out.println("LdapDirectoryAccess constructed: " + this);
}
...
}


When I deploy the application in Tomcat, I get the following output in catalina.out:



SyncService() - constructed: ...SyncService@705ebb4d
...
LdapDirectoryAccess constructed: ...LdapDirectoryAccess@3c1fd5aa
SyncService.setDirectoryAccess()
DirectoryAccess injected: ...LdapDirectoryAccess@3c1fd5aa in:
...SyncService@705ebb4d
LdapDirectoryAccess constructed: ...LdapDirectoryAccess@59d6a4d1


So, first an instance of each bean is constructed as expected, and the second bean is injected into the first. But then, another instance of the second bean class is created. How is this possible? In this tutorial I found the following:




@ApplicationScoped



Bean lives as long as the web application lives. It gets created upon
the first HTTP request involving this bean in the application (or when
the web application starts up and the eager=true attribute is set in
@ManagedBean) and gets destroyed when the web application shuts down.




So I would expected that one instance of each bean is created when the application is started, and that both instances are destroyed when the application is shut down. But LdapDirectoryAccess is constructed twice.



Moreover, when I open the page that is served by SyncService I see:



SyncService() - constructed: ... SyncService@1cb4a09c


so a second instance of SyncService is built as well, and I cannot understand why. Also, no directoryAccess property is injected this time, and the service throws a null pointer exception.



This means that the first instance of SyncService is built correctly, but then




  1. A second instance of SyncService is created (why?)

  2. No LdapDirectoryAccess is injected into it (why?)

  3. This second instance of SyncService is used to serve the call to my REST API. Why this instance and not the first one that was created?


I have looked at this question and its answers, however:




  • I am using Mojarra 2.2.18

  • My application's web.xml does not contain any tag mentioning com.sun.faces.config.ConfigureListener


So I after several hours investigation I am completely out of ideas. Do you have any hints?










share|improve this question




























    up vote
    1
    down vote

    favorite












    I have two managed Java beans:



    import javax.annotation.PostConstruct;
    import javax.faces.bean.ApplicationScoped;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ManagedProperty;

    import javax.ws.rs.Path;

    @Path("/sync")
    @ManagedBean(name="syncService", eager=true)
    @ApplicationScoped
    public class SyncService {
    @ManagedProperty(value="#{ldapDirectoryAccess}")
    private DirectoryAccess directoryAccess;

    public void setDirectoryAccess(DirectoryAccess directoryAccess) {
    System.out.println("SyncService.setDirectoryAccess()");
    this.directoryAccess = directoryAccess;
    }

    public SyncService() {
    System.out.println("SyncService() - constructed: " + this);
    }

    @PostConstruct
    public void init() {
    System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
    }
    ...
    }

    @ManagedBean(name="ldapDirectoryAccess", eager=true)
    @ApplicationScoped
    public class LdapDirectoryAccess implements DirectoryAccess {
    public LdapDirectoryAccess() {
    System.out.println("LdapDirectoryAccess constructed: " + this);
    }
    ...
    }


    When I deploy the application in Tomcat, I get the following output in catalina.out:



    SyncService() - constructed: ...SyncService@705ebb4d
    ...
    LdapDirectoryAccess constructed: ...LdapDirectoryAccess@3c1fd5aa
    SyncService.setDirectoryAccess()
    DirectoryAccess injected: ...LdapDirectoryAccess@3c1fd5aa in:
    ...SyncService@705ebb4d
    LdapDirectoryAccess constructed: ...LdapDirectoryAccess@59d6a4d1


    So, first an instance of each bean is constructed as expected, and the second bean is injected into the first. But then, another instance of the second bean class is created. How is this possible? In this tutorial I found the following:




    @ApplicationScoped



    Bean lives as long as the web application lives. It gets created upon
    the first HTTP request involving this bean in the application (or when
    the web application starts up and the eager=true attribute is set in
    @ManagedBean) and gets destroyed when the web application shuts down.




    So I would expected that one instance of each bean is created when the application is started, and that both instances are destroyed when the application is shut down. But LdapDirectoryAccess is constructed twice.



    Moreover, when I open the page that is served by SyncService I see:



    SyncService() - constructed: ... SyncService@1cb4a09c


    so a second instance of SyncService is built as well, and I cannot understand why. Also, no directoryAccess property is injected this time, and the service throws a null pointer exception.



    This means that the first instance of SyncService is built correctly, but then




    1. A second instance of SyncService is created (why?)

    2. No LdapDirectoryAccess is injected into it (why?)

    3. This second instance of SyncService is used to serve the call to my REST API. Why this instance and not the first one that was created?


    I have looked at this question and its answers, however:




    • I am using Mojarra 2.2.18

    • My application's web.xml does not contain any tag mentioning com.sun.faces.config.ConfigureListener


    So I after several hours investigation I am completely out of ideas. Do you have any hints?










    share|improve this question


























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I have two managed Java beans:



      import javax.annotation.PostConstruct;
      import javax.faces.bean.ApplicationScoped;
      import javax.faces.bean.ManagedBean;
      import javax.faces.bean.ManagedProperty;

      import javax.ws.rs.Path;

      @Path("/sync")
      @ManagedBean(name="syncService", eager=true)
      @ApplicationScoped
      public class SyncService {
      @ManagedProperty(value="#{ldapDirectoryAccess}")
      private DirectoryAccess directoryAccess;

      public void setDirectoryAccess(DirectoryAccess directoryAccess) {
      System.out.println("SyncService.setDirectoryAccess()");
      this.directoryAccess = directoryAccess;
      }

      public SyncService() {
      System.out.println("SyncService() - constructed: " + this);
      }

      @PostConstruct
      public void init() {
      System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
      }
      ...
      }

      @ManagedBean(name="ldapDirectoryAccess", eager=true)
      @ApplicationScoped
      public class LdapDirectoryAccess implements DirectoryAccess {
      public LdapDirectoryAccess() {
      System.out.println("LdapDirectoryAccess constructed: " + this);
      }
      ...
      }


      When I deploy the application in Tomcat, I get the following output in catalina.out:



      SyncService() - constructed: ...SyncService@705ebb4d
      ...
      LdapDirectoryAccess constructed: ...LdapDirectoryAccess@3c1fd5aa
      SyncService.setDirectoryAccess()
      DirectoryAccess injected: ...LdapDirectoryAccess@3c1fd5aa in:
      ...SyncService@705ebb4d
      LdapDirectoryAccess constructed: ...LdapDirectoryAccess@59d6a4d1


      So, first an instance of each bean is constructed as expected, and the second bean is injected into the first. But then, another instance of the second bean class is created. How is this possible? In this tutorial I found the following:




      @ApplicationScoped



      Bean lives as long as the web application lives. It gets created upon
      the first HTTP request involving this bean in the application (or when
      the web application starts up and the eager=true attribute is set in
      @ManagedBean) and gets destroyed when the web application shuts down.




      So I would expected that one instance of each bean is created when the application is started, and that both instances are destroyed when the application is shut down. But LdapDirectoryAccess is constructed twice.



      Moreover, when I open the page that is served by SyncService I see:



      SyncService() - constructed: ... SyncService@1cb4a09c


      so a second instance of SyncService is built as well, and I cannot understand why. Also, no directoryAccess property is injected this time, and the service throws a null pointer exception.



      This means that the first instance of SyncService is built correctly, but then




      1. A second instance of SyncService is created (why?)

      2. No LdapDirectoryAccess is injected into it (why?)

      3. This second instance of SyncService is used to serve the call to my REST API. Why this instance and not the first one that was created?


      I have looked at this question and its answers, however:




      • I am using Mojarra 2.2.18

      • My application's web.xml does not contain any tag mentioning com.sun.faces.config.ConfigureListener


      So I after several hours investigation I am completely out of ideas. Do you have any hints?










      share|improve this question















      I have two managed Java beans:



      import javax.annotation.PostConstruct;
      import javax.faces.bean.ApplicationScoped;
      import javax.faces.bean.ManagedBean;
      import javax.faces.bean.ManagedProperty;

      import javax.ws.rs.Path;

      @Path("/sync")
      @ManagedBean(name="syncService", eager=true)
      @ApplicationScoped
      public class SyncService {
      @ManagedProperty(value="#{ldapDirectoryAccess}")
      private DirectoryAccess directoryAccess;

      public void setDirectoryAccess(DirectoryAccess directoryAccess) {
      System.out.println("SyncService.setDirectoryAccess()");
      this.directoryAccess = directoryAccess;
      }

      public SyncService() {
      System.out.println("SyncService() - constructed: " + this);
      }

      @PostConstruct
      public void init() {
      System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
      }
      ...
      }

      @ManagedBean(name="ldapDirectoryAccess", eager=true)
      @ApplicationScoped
      public class LdapDirectoryAccess implements DirectoryAccess {
      public LdapDirectoryAccess() {
      System.out.println("LdapDirectoryAccess constructed: " + this);
      }
      ...
      }


      When I deploy the application in Tomcat, I get the following output in catalina.out:



      SyncService() - constructed: ...SyncService@705ebb4d
      ...
      LdapDirectoryAccess constructed: ...LdapDirectoryAccess@3c1fd5aa
      SyncService.setDirectoryAccess()
      DirectoryAccess injected: ...LdapDirectoryAccess@3c1fd5aa in:
      ...SyncService@705ebb4d
      LdapDirectoryAccess constructed: ...LdapDirectoryAccess@59d6a4d1


      So, first an instance of each bean is constructed as expected, and the second bean is injected into the first. But then, another instance of the second bean class is created. How is this possible? In this tutorial I found the following:




      @ApplicationScoped



      Bean lives as long as the web application lives. It gets created upon
      the first HTTP request involving this bean in the application (or when
      the web application starts up and the eager=true attribute is set in
      @ManagedBean) and gets destroyed when the web application shuts down.




      So I would expected that one instance of each bean is created when the application is started, and that both instances are destroyed when the application is shut down. But LdapDirectoryAccess is constructed twice.



      Moreover, when I open the page that is served by SyncService I see:



      SyncService() - constructed: ... SyncService@1cb4a09c


      so a second instance of SyncService is built as well, and I cannot understand why. Also, no directoryAccess property is injected this time, and the service throws a null pointer exception.



      This means that the first instance of SyncService is built correctly, but then




      1. A second instance of SyncService is created (why?)

      2. No LdapDirectoryAccess is injected into it (why?)

      3. This second instance of SyncService is used to serve the call to my REST API. Why this instance and not the first one that was created?


      I have looked at this question and its answers, however:




      • I am using Mojarra 2.2.18

      • My application's web.xml does not contain any tag mentioning com.sun.faces.config.ConfigureListener


      So I after several hours investigation I am completely out of ideas. Do you have any hints?







      jsf dependency-injection managed-bean






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 19 at 14:44

























      asked Nov 19 at 14:02









      Giorgio

      2,62052857




      2,62052857
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote














          A second instance of SyncService is created (why?)




          Because two different frameworks, completely unaware of each other, are being instructed to manage (instantiate and use) it.




          1. JAX-RS, via @Path

          2. JSF, via @ManagedBean


          So, in effects, you have one instance of SyncService which is managed by JAX-RS, and you have another instance of SyncService which is managed by JSF, and only in this instance, the also JSF-specific @ManagedProperty is recognized. JAX-RS doesn't understand the @ManagedProperty and thus does nothing with it.



          Basically, you're here tight-coupling a JAX-RS resource and a JSF managed bean in the very same class. Tight-coupling is a bad programming practice. You need to split out SyncService into one independent JAX-RS resource and one independent JSF managed bean. And you'd need to convert the LdapDirectoryAccess to use another bean management framework which is recognized by both JAX-RS and JSF, so that a single instance can be injected in both. In modern Java EE 8, that would be a bean managed by CDI's @javax.enterprise.context.ApplicationScoped. In legacy Java EE 6/7, you could abuse EJB's @javax.ejb.Singleton for that.



          Given that you're still using the deprecated @ManagedBean instead of its replacement @Named, I'll assume that you're still on legacy Java EE, so I'll show only the EJB approach.



          import javax.annotation.PostConstruct;
          import javax.ejb.Singleton;

          @Singleton
          public class LdapDirectoryAccessService implements DirectoryAccess {

          @PostConstruct
          public void init() {
          System.out.println("LdapDirectoryAccess constructed: " + this);
          }
          }




          import javax.annotation.PostConstruct;
          import javax.ejb.EJB;
          import javax.ws.rs.Path;

          @Path("/sync")
          public class SyncResource {

          @EJB
          private DirectoryAccess directoryAccess;

          @PostConstruct
          public void init() {
          System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
          }
          }




          import javax.annotation.PostConstruct;
          import javax.ejb.EJB;
          import javax.faces.bean.RequestScoped;
          import javax.faces.bean.ManagedBean;

          @ManagedBean
          @RequestScoped
          public class SyncBacking {

          @EJB
          private DirectoryAccess directoryAccess;

          @PostConstruct
          public void init() {
          System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
          }
          }


          Note that being able to inject an EJB in a JAX-RS resource might require additional configuration in Java EE 6/7, for that see the first link of the list below. And, in case you want to LdapDirectoryAccessService to eagerly initialize during server's startup, add the @javax.ejb.Startup annotation.



          See also:




          • Inject an EJB into JAX-RS (RESTful service)

          • JSF Controller, Service and DAO

          • Backing beans (@ManagedBean) or CDI Beans (@Named)?


          • How to choose the right bean scope?






          share|improve this answer























          • Thanks for the thorough explanation. We are working on a new project and I am learning the technologies along the way. We have been advised to use JSF and I did not know that the @Path annotation was part of another framework. Also, I did not know that @ManagedBean was deprecated since searching for dependency injection in JSF I mostly found examples using this annotation. Anyway, thanks for the explanation and all the links: I will try to pick one framework and use it consistently.
            – Giorgio
            Nov 20 at 6:36












          • @Giorgio: Google does a very bad job in this regard since if everybody keeps clicking on only articles, they keep getting higher in searchengines. I more and more try to find a common authoritive human maintained site (like e.g. jsf.zeef.com) and use that. Yes for that I use google but look for recent (version wise and date wise) links) I do that for other interesting subjects too like solar power etc...
            – Kukeltje
            Nov 20 at 10:06











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53376320%2fapplicationscoped-beans-get-constructed-more-than-once%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote














          A second instance of SyncService is created (why?)




          Because two different frameworks, completely unaware of each other, are being instructed to manage (instantiate and use) it.




          1. JAX-RS, via @Path

          2. JSF, via @ManagedBean


          So, in effects, you have one instance of SyncService which is managed by JAX-RS, and you have another instance of SyncService which is managed by JSF, and only in this instance, the also JSF-specific @ManagedProperty is recognized. JAX-RS doesn't understand the @ManagedProperty and thus does nothing with it.



          Basically, you're here tight-coupling a JAX-RS resource and a JSF managed bean in the very same class. Tight-coupling is a bad programming practice. You need to split out SyncService into one independent JAX-RS resource and one independent JSF managed bean. And you'd need to convert the LdapDirectoryAccess to use another bean management framework which is recognized by both JAX-RS and JSF, so that a single instance can be injected in both. In modern Java EE 8, that would be a bean managed by CDI's @javax.enterprise.context.ApplicationScoped. In legacy Java EE 6/7, you could abuse EJB's @javax.ejb.Singleton for that.



          Given that you're still using the deprecated @ManagedBean instead of its replacement @Named, I'll assume that you're still on legacy Java EE, so I'll show only the EJB approach.



          import javax.annotation.PostConstruct;
          import javax.ejb.Singleton;

          @Singleton
          public class LdapDirectoryAccessService implements DirectoryAccess {

          @PostConstruct
          public void init() {
          System.out.println("LdapDirectoryAccess constructed: " + this);
          }
          }




          import javax.annotation.PostConstruct;
          import javax.ejb.EJB;
          import javax.ws.rs.Path;

          @Path("/sync")
          public class SyncResource {

          @EJB
          private DirectoryAccess directoryAccess;

          @PostConstruct
          public void init() {
          System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
          }
          }




          import javax.annotation.PostConstruct;
          import javax.ejb.EJB;
          import javax.faces.bean.RequestScoped;
          import javax.faces.bean.ManagedBean;

          @ManagedBean
          @RequestScoped
          public class SyncBacking {

          @EJB
          private DirectoryAccess directoryAccess;

          @PostConstruct
          public void init() {
          System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
          }
          }


          Note that being able to inject an EJB in a JAX-RS resource might require additional configuration in Java EE 6/7, for that see the first link of the list below. And, in case you want to LdapDirectoryAccessService to eagerly initialize during server's startup, add the @javax.ejb.Startup annotation.



          See also:




          • Inject an EJB into JAX-RS (RESTful service)

          • JSF Controller, Service and DAO

          • Backing beans (@ManagedBean) or CDI Beans (@Named)?


          • How to choose the right bean scope?






          share|improve this answer























          • Thanks for the thorough explanation. We are working on a new project and I am learning the technologies along the way. We have been advised to use JSF and I did not know that the @Path annotation was part of another framework. Also, I did not know that @ManagedBean was deprecated since searching for dependency injection in JSF I mostly found examples using this annotation. Anyway, thanks for the explanation and all the links: I will try to pick one framework and use it consistently.
            – Giorgio
            Nov 20 at 6:36












          • @Giorgio: Google does a very bad job in this regard since if everybody keeps clicking on only articles, they keep getting higher in searchengines. I more and more try to find a common authoritive human maintained site (like e.g. jsf.zeef.com) and use that. Yes for that I use google but look for recent (version wise and date wise) links) I do that for other interesting subjects too like solar power etc...
            – Kukeltje
            Nov 20 at 10:06















          up vote
          3
          down vote














          A second instance of SyncService is created (why?)




          Because two different frameworks, completely unaware of each other, are being instructed to manage (instantiate and use) it.




          1. JAX-RS, via @Path

          2. JSF, via @ManagedBean


          So, in effects, you have one instance of SyncService which is managed by JAX-RS, and you have another instance of SyncService which is managed by JSF, and only in this instance, the also JSF-specific @ManagedProperty is recognized. JAX-RS doesn't understand the @ManagedProperty and thus does nothing with it.



          Basically, you're here tight-coupling a JAX-RS resource and a JSF managed bean in the very same class. Tight-coupling is a bad programming practice. You need to split out SyncService into one independent JAX-RS resource and one independent JSF managed bean. And you'd need to convert the LdapDirectoryAccess to use another bean management framework which is recognized by both JAX-RS and JSF, so that a single instance can be injected in both. In modern Java EE 8, that would be a bean managed by CDI's @javax.enterprise.context.ApplicationScoped. In legacy Java EE 6/7, you could abuse EJB's @javax.ejb.Singleton for that.



          Given that you're still using the deprecated @ManagedBean instead of its replacement @Named, I'll assume that you're still on legacy Java EE, so I'll show only the EJB approach.



          import javax.annotation.PostConstruct;
          import javax.ejb.Singleton;

          @Singleton
          public class LdapDirectoryAccessService implements DirectoryAccess {

          @PostConstruct
          public void init() {
          System.out.println("LdapDirectoryAccess constructed: " + this);
          }
          }




          import javax.annotation.PostConstruct;
          import javax.ejb.EJB;
          import javax.ws.rs.Path;

          @Path("/sync")
          public class SyncResource {

          @EJB
          private DirectoryAccess directoryAccess;

          @PostConstruct
          public void init() {
          System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
          }
          }




          import javax.annotation.PostConstruct;
          import javax.ejb.EJB;
          import javax.faces.bean.RequestScoped;
          import javax.faces.bean.ManagedBean;

          @ManagedBean
          @RequestScoped
          public class SyncBacking {

          @EJB
          private DirectoryAccess directoryAccess;

          @PostConstruct
          public void init() {
          System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
          }
          }


          Note that being able to inject an EJB in a JAX-RS resource might require additional configuration in Java EE 6/7, for that see the first link of the list below. And, in case you want to LdapDirectoryAccessService to eagerly initialize during server's startup, add the @javax.ejb.Startup annotation.



          See also:




          • Inject an EJB into JAX-RS (RESTful service)

          • JSF Controller, Service and DAO

          • Backing beans (@ManagedBean) or CDI Beans (@Named)?


          • How to choose the right bean scope?






          share|improve this answer























          • Thanks for the thorough explanation. We are working on a new project and I am learning the technologies along the way. We have been advised to use JSF and I did not know that the @Path annotation was part of another framework. Also, I did not know that @ManagedBean was deprecated since searching for dependency injection in JSF I mostly found examples using this annotation. Anyway, thanks for the explanation and all the links: I will try to pick one framework and use it consistently.
            – Giorgio
            Nov 20 at 6:36












          • @Giorgio: Google does a very bad job in this regard since if everybody keeps clicking on only articles, they keep getting higher in searchengines. I more and more try to find a common authoritive human maintained site (like e.g. jsf.zeef.com) and use that. Yes for that I use google but look for recent (version wise and date wise) links) I do that for other interesting subjects too like solar power etc...
            – Kukeltje
            Nov 20 at 10:06













          up vote
          3
          down vote










          up vote
          3
          down vote










          A second instance of SyncService is created (why?)




          Because two different frameworks, completely unaware of each other, are being instructed to manage (instantiate and use) it.




          1. JAX-RS, via @Path

          2. JSF, via @ManagedBean


          So, in effects, you have one instance of SyncService which is managed by JAX-RS, and you have another instance of SyncService which is managed by JSF, and only in this instance, the also JSF-specific @ManagedProperty is recognized. JAX-RS doesn't understand the @ManagedProperty and thus does nothing with it.



          Basically, you're here tight-coupling a JAX-RS resource and a JSF managed bean in the very same class. Tight-coupling is a bad programming practice. You need to split out SyncService into one independent JAX-RS resource and one independent JSF managed bean. And you'd need to convert the LdapDirectoryAccess to use another bean management framework which is recognized by both JAX-RS and JSF, so that a single instance can be injected in both. In modern Java EE 8, that would be a bean managed by CDI's @javax.enterprise.context.ApplicationScoped. In legacy Java EE 6/7, you could abuse EJB's @javax.ejb.Singleton for that.



          Given that you're still using the deprecated @ManagedBean instead of its replacement @Named, I'll assume that you're still on legacy Java EE, so I'll show only the EJB approach.



          import javax.annotation.PostConstruct;
          import javax.ejb.Singleton;

          @Singleton
          public class LdapDirectoryAccessService implements DirectoryAccess {

          @PostConstruct
          public void init() {
          System.out.println("LdapDirectoryAccess constructed: " + this);
          }
          }




          import javax.annotation.PostConstruct;
          import javax.ejb.EJB;
          import javax.ws.rs.Path;

          @Path("/sync")
          public class SyncResource {

          @EJB
          private DirectoryAccess directoryAccess;

          @PostConstruct
          public void init() {
          System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
          }
          }




          import javax.annotation.PostConstruct;
          import javax.ejb.EJB;
          import javax.faces.bean.RequestScoped;
          import javax.faces.bean.ManagedBean;

          @ManagedBean
          @RequestScoped
          public class SyncBacking {

          @EJB
          private DirectoryAccess directoryAccess;

          @PostConstruct
          public void init() {
          System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
          }
          }


          Note that being able to inject an EJB in a JAX-RS resource might require additional configuration in Java EE 6/7, for that see the first link of the list below. And, in case you want to LdapDirectoryAccessService to eagerly initialize during server's startup, add the @javax.ejb.Startup annotation.



          See also:




          • Inject an EJB into JAX-RS (RESTful service)

          • JSF Controller, Service and DAO

          • Backing beans (@ManagedBean) or CDI Beans (@Named)?


          • How to choose the right bean scope?






          share|improve this answer















          A second instance of SyncService is created (why?)




          Because two different frameworks, completely unaware of each other, are being instructed to manage (instantiate and use) it.




          1. JAX-RS, via @Path

          2. JSF, via @ManagedBean


          So, in effects, you have one instance of SyncService which is managed by JAX-RS, and you have another instance of SyncService which is managed by JSF, and only in this instance, the also JSF-specific @ManagedProperty is recognized. JAX-RS doesn't understand the @ManagedProperty and thus does nothing with it.



          Basically, you're here tight-coupling a JAX-RS resource and a JSF managed bean in the very same class. Tight-coupling is a bad programming practice. You need to split out SyncService into one independent JAX-RS resource and one independent JSF managed bean. And you'd need to convert the LdapDirectoryAccess to use another bean management framework which is recognized by both JAX-RS and JSF, so that a single instance can be injected in both. In modern Java EE 8, that would be a bean managed by CDI's @javax.enterprise.context.ApplicationScoped. In legacy Java EE 6/7, you could abuse EJB's @javax.ejb.Singleton for that.



          Given that you're still using the deprecated @ManagedBean instead of its replacement @Named, I'll assume that you're still on legacy Java EE, so I'll show only the EJB approach.



          import javax.annotation.PostConstruct;
          import javax.ejb.Singleton;

          @Singleton
          public class LdapDirectoryAccessService implements DirectoryAccess {

          @PostConstruct
          public void init() {
          System.out.println("LdapDirectoryAccess constructed: " + this);
          }
          }




          import javax.annotation.PostConstruct;
          import javax.ejb.EJB;
          import javax.ws.rs.Path;

          @Path("/sync")
          public class SyncResource {

          @EJB
          private DirectoryAccess directoryAccess;

          @PostConstruct
          public void init() {
          System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
          }
          }




          import javax.annotation.PostConstruct;
          import javax.ejb.EJB;
          import javax.faces.bean.RequestScoped;
          import javax.faces.bean.ManagedBean;

          @ManagedBean
          @RequestScoped
          public class SyncBacking {

          @EJB
          private DirectoryAccess directoryAccess;

          @PostConstruct
          public void init() {
          System.out.println("DirectoryAccess injected: " + directoryAccess + " in: " + this);
          }
          }


          Note that being able to inject an EJB in a JAX-RS resource might require additional configuration in Java EE 6/7, for that see the first link of the list below. And, in case you want to LdapDirectoryAccessService to eagerly initialize during server's startup, add the @javax.ejb.Startup annotation.



          See also:




          • Inject an EJB into JAX-RS (RESTful service)

          • JSF Controller, Service and DAO

          • Backing beans (@ManagedBean) or CDI Beans (@Named)?


          • How to choose the right bean scope?







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 19 at 18:00

























          answered Nov 19 at 17:46









          BalusC

          835k29430973182




          835k29430973182












          • Thanks for the thorough explanation. We are working on a new project and I am learning the technologies along the way. We have been advised to use JSF and I did not know that the @Path annotation was part of another framework. Also, I did not know that @ManagedBean was deprecated since searching for dependency injection in JSF I mostly found examples using this annotation. Anyway, thanks for the explanation and all the links: I will try to pick one framework and use it consistently.
            – Giorgio
            Nov 20 at 6:36












          • @Giorgio: Google does a very bad job in this regard since if everybody keeps clicking on only articles, they keep getting higher in searchengines. I more and more try to find a common authoritive human maintained site (like e.g. jsf.zeef.com) and use that. Yes for that I use google but look for recent (version wise and date wise) links) I do that for other interesting subjects too like solar power etc...
            – Kukeltje
            Nov 20 at 10:06


















          • Thanks for the thorough explanation. We are working on a new project and I am learning the technologies along the way. We have been advised to use JSF and I did not know that the @Path annotation was part of another framework. Also, I did not know that @ManagedBean was deprecated since searching for dependency injection in JSF I mostly found examples using this annotation. Anyway, thanks for the explanation and all the links: I will try to pick one framework and use it consistently.
            – Giorgio
            Nov 20 at 6:36












          • @Giorgio: Google does a very bad job in this regard since if everybody keeps clicking on only articles, they keep getting higher in searchengines. I more and more try to find a common authoritive human maintained site (like e.g. jsf.zeef.com) and use that. Yes for that I use google but look for recent (version wise and date wise) links) I do that for other interesting subjects too like solar power etc...
            – Kukeltje
            Nov 20 at 10:06
















          Thanks for the thorough explanation. We are working on a new project and I am learning the technologies along the way. We have been advised to use JSF and I did not know that the @Path annotation was part of another framework. Also, I did not know that @ManagedBean was deprecated since searching for dependency injection in JSF I mostly found examples using this annotation. Anyway, thanks for the explanation and all the links: I will try to pick one framework and use it consistently.
          – Giorgio
          Nov 20 at 6:36






          Thanks for the thorough explanation. We are working on a new project and I am learning the technologies along the way. We have been advised to use JSF and I did not know that the @Path annotation was part of another framework. Also, I did not know that @ManagedBean was deprecated since searching for dependency injection in JSF I mostly found examples using this annotation. Anyway, thanks for the explanation and all the links: I will try to pick one framework and use it consistently.
          – Giorgio
          Nov 20 at 6:36














          @Giorgio: Google does a very bad job in this regard since if everybody keeps clicking on only articles, they keep getting higher in searchengines. I more and more try to find a common authoritive human maintained site (like e.g. jsf.zeef.com) and use that. Yes for that I use google but look for recent (version wise and date wise) links) I do that for other interesting subjects too like solar power etc...
          – Kukeltje
          Nov 20 at 10:06




          @Giorgio: Google does a very bad job in this regard since if everybody keeps clicking on only articles, they keep getting higher in searchengines. I more and more try to find a common authoritive human maintained site (like e.g. jsf.zeef.com) and use that. Yes for that I use google but look for recent (version wise and date wise) links) I do that for other interesting subjects too like solar power etc...
          – Kukeltje
          Nov 20 at 10:06


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53376320%2fapplicationscoped-beans-get-constructed-more-than-once%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          404 Error Contact Form 7 ajax form submitting

          How to know if a Active Directory user can login interactively

          TypeError: fit_transform() missing 1 required positional argument: 'X'