10 Replies Latest reply: Jul 5, 2012 1:08 AM by gimbal2 RSS

    calling EJB method

    928518
      Hi All,
      I have never worked with EJBs so I am kind of stuck with one problem.

      I have to make use of one existing EJB project through my external standard java class. The existing EJB project makes use of some other packages which are also EJB projects and I am not allowed to change any functionality of the EJB project but to use them as it is.

      I am just initilizing the class object of the EJB project and calling its method. Within the EJB project there is a method which is calling another method of another EJB class.

      The problem is that I dont see this other EJB class object getting initilized first and then calling its method as it happens in a normal scenario, hence when that method gets called i get a null pointer execption.

      Let me give you some idea by posting some code snippet.
      @WebService(targetNamespace = "http://www.ttt.de/ota")
      @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.BARE)
      // standard EJB3 annotations
      @Local(AMSAgencyWSPortType.class)
      @Stateless
      @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
      // jboss propriatary annotations
      @WebContext(transportGuarantee = "NONE", secureWSDLAccess = false)
      
      public class AMSProfileServiceBean extends AbstractProfileBuilder implements AMSAgencyWSPortType
      {
        private static Log log = LogFactory.getLog(AMSMappingServiceBean.class);
      
        @EJB(mappedName = "PotsdamProfileService/local")
        private PotsdamProfileService profileService;
        
        private Security              security;
      
        @EJB
        private OTAProfileBuilder     otaProfileBuilder;
        
      ...
      ...
      
       @Override
        public OTATTProfileReadRS otaTTReadRQ(Holder<Security> wsseHeader, OTATTReadRQ request)
        {
                    
           security = wsseHeader.value;
           BigDecimal requestVersion = request.getVersion();
      
           OTATTProfileReadRS otaProfileReadRS = new OTATTProfileReadRS();
              
           otaProfileReadRS.setVersion(requestVersion);
          
           PotsdamInstanceKey profileIntanceKey;
          try
          {
                 
            profileIntanceKey = getKeyHandler(requestVersion).buildUserKey(wsseHeader);
      
            
            PotsdamInstance userInstance = loadProfileFromPotsdam(profileIntanceKey);
      
      ...
      ...
      
       private PotsdamInstance loadProfileFromPotsdam(PotsdamInstanceKey userCredentials) throws PotsdamException
        {
             
             PotsdamInstance potsdamInstance = null;
             try{
         
          Holder<com.ttt.potsdam.common.messages.Security> wsseHeader = buildWsseHeader(security);
         
          ProfileResponse potsdamInstanceRS = profileService.loadProfile(wsseHeader, userCredentials);
      
      ...
      I get an error message before the sequence reaches loadProfile(..), which in my sense is due to the fact that 'profileService' never was initilized in the EJB project.

      profileService is object of another EJB project, which looks somethign like this:
      @Stateless
      @LocalBinding(jndiBinding = "PotsdamProfileService/local")
      // jboss 4.2
      @org.jboss.annotation.ejb.LocalBinding(jndiBinding = "PotsdamProfileService/local")
      
      public class PotsdamProfileServiceBean implements PotsdamProfileService {
           private static Log log = LogFactory.getLog(PotsdamProfileServiceBean.class);
      
           @EJB
           private CacheProfileService cacheProfileService;
      
           @EJB(mappedName = "/PersistenceUnitsManagerBean/local")
           private PersistenceUnitsManager persistenceUnitsManager;
      
           @EJB
           private PotsdamService potsdamService;
      
           public ProfileResponse loadProfile(Holder<Security> wsseHeader,
                     PotsdamInstanceKey cacheInstanceKey) {
                
                 log.debug("inside  loadProfile"); 
      
      ...
      Now I am calling the main EJB like this:
      ...
      PotsdamotaTTReadRQ();
      ...
      public OTATTProfileReadRS PotsdamotaTTReadRQ()
        {
        
             AMSProfileServiceBean a = new AMSProfileServiceBean();
      
             Holder<Security> wsseHeader = new Holder<Security>();
       
      ...
      ...
             OTATTProfileReadRS response = a.otaTTReadRQ(wsseHeader, request);
             
             
             return response;
         
        }
      So my confusion is how can I make use of profileService.loadProfile(wsseHeader, userCredentials); ??

      I tried to initilize:
      PotsdamProfileServiceBean profileService = new PotsdamProfileServiceBean();
      but I get jndi binding and lots of other exception.

      Please help.

      Edited by: 925515 on 04.07.2012 06:40
        • 1. Re: calling EJB method
          r035198x
          Don't instantiate an EJB yourself in the client code.
          Either inject it into your client (if your client is managed) or look up the EJB using JNDI.
          • 2. Re: calling EJB method
            gimbal2
            "Enterprise Javabeans 3.1" is an excellent book to actually learn EJB technology so it is no longer necessary to guess, assume and hack.
            • 3. Re: calling EJB method
              928518
              Thanks for your pointer. Could you please help me out with a small code snippet example?

              I want to make use of this existing bean (AMSProfileServiceBean ):
              @WebService(targetNamespace = "http://www.ttt.de/ota")
              @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.BARE)
              // standard EJB3 annotations
              @Local(AMSAgencyWSPortType.class)
              @Stateless
              @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
              // jboss propriatary annotations
              @WebContext(transportGuarantee = "NONE", secureWSDLAccess = false)
              public class AMSProfileServiceBean extends AbstractProfileBuilder implements AMSAgencyWSPortType
              {
                private static Log log = LogFactory.getLog(AMSMappingServiceBean.class);
              
                @EJB(mappedName = "PotsdamProfileService/local")
                private PotsdamProfileService profileService;
                
                private Security              security;
              
                @EJB
                private OTAProfileBuilder     otaProfileBuilder;
                
                
              
                @EJB
                private OTAProfileUpdater     otaProfileUpdater;
              
              ...
              @Override
                public OTATTProfileReadRS otaTTReadRQ(Holder<Security> wsseHeader, OTATTReadRQ request)
                {
              
              ...
              in my soap-connector :
              @WebServiceProvider(wsdlLocation = "WEB-INF/wsdl/PotsdamAMSAgencyWS.wsdl", targetNamespace = "http://www.ttt.de/ota", serviceName = "PotsdamAMSAgencyWS", portName = "PotsdamAMSAgencyWSPortType")
              @ServiceMode(value = Service.Mode.MESSAGE)
              public class PotsdamAgencyWSProvider extends WSProvider implements Provider<SOAPMessage>
              {
                @Resource
                WebServiceContext     wsCtx;
              
              ...
              A small example would be really appreciated.

              Thanks.
              • 4. Re: calling EJB method
                r035198x
                First decide if you should call the service as an EJB or as a Webservice because it looks like it's also exposed as a webservice.
                If you have to call it as an EJB then decide if you are going to use injection to get the EJB reference or if you are going to use JNDI.
                You should read the tutorial here for more details: http://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html

                That link is for EE6 so look for the corresponding reference in the EE5 tutorial if you are using EE5 because there are quite a few differences.
                • 5. Re: calling EJB method
                  928518
                  Thanks for the info, I am goign to give it a detailed look. Could you also please tell how that Bean (AMSProfileServiceBean) is exposed or accessable via my client program as a webservice? Any example or some similar tutorial would be great.

                  Thanks.
                  • 6. Re: calling EJB method
                    r035198x
                    925515 wrote:
                    Could you also please tell how that Bean (AMSProfileServiceBean) is exposed or accessable via my client program as a webservice? Any example or some similar tutorial would be great.

                    Thanks.
                    The @Webservice annotation on the bean class is a hint. The same tutorial (or it's EE5 equivalent) linked to above has sections explaining how to call webservices as well.
                    • 7. Re: calling EJB method
                      928518
                      As per the Java EE 5 tutorial, i have tried 2 options in my PotsdamAgencyWSProvider.

                      @EJB
                      private static AMSProfileServiceBean a;

                      And

                      AMSProfileServiceBean a = (AMSProfileServiceBean)InitialContext.doLookup("java:module/AMSProfileServiceBean");


                      But each time i got the error: module not bound

                      on my calling a.otaTTReadRQ(wsseHeader, request); method of AMSProfileServiceBean.
                      • 8. Re: calling EJB method
                        928518
                        Even tried this:

                        @EJB(mappedName = "AMSProfileServiceBean/local")
                        private static AMSProfileServiceBean a;

                        And

                        @EJB(mappedName = "AMSAgencyWSPortType/local")
                        private static AMSAgencyWSPortType a;

                        And


                        @EJB(mappedName = "AMSProfileServiceBean")
                        private static AMSProfileServiceBean a;

                        And

                        @EJB(mappedName = "AMSAgencyWSPortType")
                        private static AMSAgencyWSPortType a;


                        But still the same error.
                        • 9. Re: calling EJB method
                          r035198x
                          1.) You should be using the EJB's interface on the client not the implementing class.
                          2.) If you are using EE5 the jndi name of the EJB will be decided by the container (or specified in a container specific way) so check your container's manual to find out which one it is rather than try to guess it.
                          • 10. Re: calling EJB method
                            gimbal2
                            Actually through the JBoss specific annotations the JNDI name is overridden in the code. But there are only local bindings; if this is done from some sort of client likely some remote bindings and interfaces will also need to be put on the EJBs.

                            The first thing I'd do is strip that unnecessary "mappedName" everywhere. There is nothing worse than paranoid code.