9 Replies Latest reply on Jun 19, 2012 12:40 AM by jaikiran

    Is InitialContext.close neccessary in JBoss 7.1?

    shadowcreeper

      InitialStateException is always thrown when calling a remote bean's method if InitialContext was closed first (when bean was looked up using PROVIDER_URL).

       

      Here is the context setup:

      {code}// stand-alone integration test (not run from within JBoss, and no jboss-ejb-client.properties available in the class path)

      Properties jndiProperties = new Properties();

      jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");

      jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");

      jndiProperties.put("jboss.naming.client.ejb.context", true);

      jndiProperties.put(Context.SECURITY_PRINCIPAL, "login");

      jndiProperties.put(Context.SECURITY_CREDENTIALS, "password");

      InitialContext context = new InitialContext( jndiProperties );{code}

       

      This works:

      {code}// stand-alone integration test (not run from within JBoss, and no jboss-ejb-client.properties available in the class path)

      try

      {

         MyRemoteBean myRemoteBean = (MyRemoteBean)context.lookup( "my-ear/my-jar/MyBeanEJB!my.bean.MyRemoteBean" );

         myRemoteBean.doSomething();

      }

      finally

      {

         context.close();

      }{code}

       

      This does not work (IllegalStateException gets thrown):

      {code}// stand-alone integration test (not run from within JBoss, and no jboss-ejb-client.properties available in the class path)

      MyRemoteBean myRemoteBean;

      try

      {

         myRemoteBean = (MyRemoteBean)context.lookup( "my-ear/my-jar/MyBeanEJB!my.bean.MyRemoteBean" );

      }

      finally

      {

         context.close();

      }

      myRemoteBean.doSomething(); // IllegalStateException gets thrown here{code}

       

      Previously (in JBoss5, and also in JBoss 7.1.1.Final when using the jboss-ejb-client.properties method) I would always close the Context after bean lookup (in the finally block as you can see above). Apparently, using the PROVIDER_URL method, this causes the bean to disconnect causing the following log entry:

      INFO [org.jboss.as.naming] (Remoting "tribble" task-4) JBAS011806: Channel end notification received, closing channel Channel ID 682e6420 (inbound) of Remoting connection 43c9b57e to /127.0.0.1:50152

       

      Is this a bug or is this expected?

       

      I have also noticed that none of the examples I have seen ever show the context being closed. I generally see: return new InitialContext(props).lookup(bean);

       

      Do we even need to close the context?

      Is there any risk of leaks if we don't close the context?

        • 1. Re: Is InitialContext.close neccessary in JBoss 7.1?
          jaikiran

          Shadow Creeper wrote:

           

          Here is the context setup:

          // stand-alone integration test (not run from within JBoss, and no jboss-ejb-client.properties available in the class path)
          Properties jndiProperties = new Properties();
          jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
          jndiProperties.put(Context.PROVIDER_URL, "remote://localhost:4447");
          jndiProperties.put("jboss.naming.client.ejb.context", true);
          ...
          InitialContext context = new InitialContext( jndiProperties );

           

           

          This works:

          // stand-alone integration test (not run from within JBoss, and no jboss-ejb-client.properties available in the class path)
          try
          {
             MyRemoteBean myRemoteBean = (MyRemoteBean)context.lookup( "my-ear/my-jar/MyBeanEJB!my.bean.MyRemoteBean" );
             myRemoteBean.doSomething();
          }
          finally
          {
             context.close();
          }

           

           

          This does not work (IllegalStateException gets thrown):

          // stand-alone integration test (not run from within JBoss, and no jboss-ejb-client.properties available in the class path)
          MyRemoteBean myRemoteBean;
          try
          {
             myRemoteBean = (MyRemoteBean)context.lookup( "my-ear/my-jar/MyBeanEJB!my.bean.MyRemoteBean" );
          }
          finally
          {
             context.close();
          }
          myRemoteBean.doSomething(); // IllegalStateException gets thrown here

           

           

          You are using the jboss.naming.client.ejb.context property while creating the JNDI context and as explained here https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project that property if set to true implies that the connection that was used by the InitialContext (the PROVIDER_URL specific the connection URI), will also be used for the EJB invocation communication. When you issue a context.close(), that internally closes the connection to the remote server and effectively your EJB invocations won't be able to proceed subsequently.
          If you want the EJB invocations to proceed after you close the JNDI context, then don't let the remote-naming JNDI context manage the EJB client context for you. You can do that by removing the jboss.naming.client.ejb.context property from those JNDI properties and then placing a jboss-ejb-client.properties in your classpath with relevant configurations. This way the EJB client context won't be managed by the JNDI initial context lifecycle.

          Shadow Creeper wrote:

           

          Do we even need to close the context?

          Is there any risk of leaks if we don't close the context?

          Yes, closing the context is a good thing to do. Closing the context internally will close the remote connection which is a good thing. If you don't close the context, then the connection will stay around till either the application is shutdown or the GC kicks in for the JNDI context instance that created the connection.

          • 2. Re: Is InitialContext.close neccessary in JBoss 7.1?
            shadowcreeper

            Unfortunately, in order to use PROVIDER_URL we must set "jboss.naming.client.ejb.context" to true. So we must not close the context or we cannot use the bean.

             

            It sounds like this is a bug (unintended consequence of intended behavior)?

            • 3. Re: Is InitialContext.close neccessary in JBoss 7.1?
              wdfink

              This is not a bug, it is the behaviour of the AS7 ejb-client.

              • 4. Re: Is InitialContext.close neccessary in JBoss 7.1?
                shadowcreeper

                So you are saying this is not a bug, and JBoss expects us to never close the context. Correct?

                • 5. Re: Is InitialContext.close neccessary in JBoss 7.1?
                  jaikiran

                  Shadow Creeper wrote:

                   

                  So you are saying this is not a bug, and JBoss expects us to never close the context. Correct?

                  No, that's not what Wolf is saying. Please read my previous reply in this thread again. It already explains what the close does and why it behaves the way it does. It even tell you the other approach to use if the current one isn't what you are looking for.

                  • 6. Re: Is InitialContext.close neccessary in JBoss 7.1?
                    shadowcreeper

                    Yes, I read it. It said that we *should* close our context (with a good reason why). Yet Wolf said that we *cannot* close our context. Hence why I thought that was a bug. He then said it was *not* a bug, implying that we should *not* close our context (since we cannot). Hence the above reply asking for clarification.

                     

                    I understand there is an alternative way to lookup an EJB. But as I understand it, that way requires hard-coded values in a property file which gives the set of all possible servers that can be connected to. It gives us no control over which server a particular bean is looked up on nor which credentials are used and is thus not an option. Is there another alternative that I am unaware of?

                     

                    Although, when we lookup a bean, it is usually then used throughout the lifetime of the application, with cleanup only required upon application shutdown. So, when you say the context remains open til the application is shutdown, does that mean it is pro-actively closed at that time, or does it wait for garbage collection?

                     

                    Thank you for adding the section on remote naming by the way. Perhaps this caveat should be mentioned in there? An explanation as to why you should/shouldn't close the context and the dangers associated with that would be nice too.

                    • 7. Re: Is InitialContext.close neccessary in JBoss 7.1?
                      jaikiran

                      Shadow Creeper,

                      Shadow Creeper wrote:

                       

                      Yes, I read it. It said that we *should* close our context (with a good reason why). Yet Wolf said that we *cannot* close our context. Hence why I thought that was a bug. He then said it was *not* a bug, implying that we should *not* close our context (since we cannot). Hence the above reply asking for clarification.

                       

                       

                      I do understand your usecase and I do understand why you are using the remote-naming approach (remote://) for EJB invocations, but each time your question was along the lines of:

                       

                      So you are saying this is not a bug, and JBoss expects us to never close the context. Correct?

                      One of the reasons why I have been repeatedly saying that we do recommend closing the context is because others reading this thread or whoever stumbles upon this thread via a google search should not get the feeling that not closing the context is a good thing.

                       

                      I'm not blaming you for asking for clarification though. So here's what exactly should be done in cases/application like yours where you use remote:// naming approach with jboss.naming.client.ejb.context = true:

                       

                      1) The jboss.naming.client.ejb.context = true, forces the EJB client API to let the remote-naming API take control of the remote connection(s) to the server(s)

                      2) What #1 means is that the lifecycle of the connection (i.e. connect, disconnect) is now fully controlled by the InitialContext constructed by the remote-naming API.

                      3) InitialContext creation creates a connection to the server and context.close() closes the connection.

                      4) EJB invocations require a connection to the server (obviously)

                      5) Because of #2, #3 and #4, it implies that you should close the intialcontext only after you are done with all your EJB invocations. Not closing the InitialContext is not a good thing. Closing it at an "appropriate" time is the right thing.  It ultimately depends on the client application to know/decide what the "appropriate" time is.

                       

                      I hope that clears up the confusion. If you still have questions feel free to ask.

                      • 8. Re: Is InitialContext.close neccessary in JBoss 7.1?
                        jaikiran

                        Shadow Creeper wrote:

                         

                         

                        I understand there is an alternative way to lookup an EJB. But as I understand it, that way requires hard-coded values in a property file which gives the set of all possible servers that can be connected to. It gives us no control over which server a particular bean is looked up on

                        There are ways to direct the invocation to a specific server. It ultimately depends on your usecase. Here's one way using the distinct name https://community.jboss.org/thread/200470?tstart=0. If you tell me why exactly you want to pick/select a specific server from a list of servers which can handle the same EJB, then maybe I can tell you a better way to get what you want. For instance, why does it matter if server A is used for handling the invocation instead of server B, if both the servers have the same implementation of the same EJB in the same application? I know of one reason, but I don't want to mention it here and derail the discussion. I want to understand your use case first.

                        • 9. Re: Is InitialContext.close neccessary in JBoss 7.1?
                          jaikiran

                          Shadow Creeper wrote:

                           

                          Thank you for adding the section on remote naming by the way. Perhaps this caveat should be mentioned in there? An explanation as to why you should/shouldn't close the context and the dangers associated with that would be nice too.

                          Yes, I hadn't thought of this while writing that article. I'll add include a section on this, soon.