8 Replies Latest reply on Mar 2, 2004 12:50 PM by michael.daleiden

    lookup mbean on other node in the cluster through jndi

    f_kasper

      Hi I want to get a connection to a mbean from one jboss node to another.
      I have a mbean with some service which i want to access from the other service.
      The MBean is bound like this:

      InitialContext rootCtx = new InitialContext();
      NonSerializableFactory.rebind(rootCtx, "customMBean", this);
      


      and on the other jboss i try to look ip up with this:
      InitialContext ctx = new InitialContext();
      ctx.lookup("customMBean");
      

      I also tried ctx.lookupLink and the InitialContext with this props:
      prop.put(Context.INITIAL_CONTEXT_FACTORY,
       "org.jnp.interfaces.NamingContextFactory");
      prop.put(Context.URL_PKG_PREFIXES,
       "jboss.naming:org.jnp.interfaces");
      prop.put(Context.PROVIDER_URL,
       "jnp://172.16.0.3:1100,jnp://172.16.0.7:1100");
      


      It seams as i actually access the InitialContext on the other jboss, but it just returns null. If I write some other name in the lookup I get a NameNotBound exception.

      Can anyone tell me what I am doing wrong, ore if I can access my mbeans in some other way?

      Thanks in advantage
      Kasper

        • 1. Re: lookup mbean on other node in the cluster through jndi
          bramr

          Use

          prop.put(Context.URL_PKG_PREFIXES,
          "org.jboss.naming:org.jnp.interfaces");


          instead of

          prop.put(Context.URL_PKG_PREFIXES,
          "jboss.naming:org.jnp.interfaces");


          This might fix your problem.
          regards,
          Bram


          • 2. Re: lookup mbean on other node in the cluster through jndi
            f_kasper

            Thanks for the answer but it doesn't seem to solve my problem. The properties set in:

            Properties prop = new Properties();
            prop.put(Context.INITIAL_CONTEXT_FACTORY,
             "org.jnp.interfaces.NamingContextFactory"); prop.put(Context.URL_PKG_PREFIXES,
             "org.jboss.naming:org.jnp.interfaces");
            prop.put(Context.PROVIDER_URL,
             "jnp://172.16.0.3:1100,jnp://172.16.0.7:1100");


            just seams to append the proberties set in jndi.properties. The InitaialContext getEnviroment gives my folowing:
            {java.naming.provider.url=jnp://172.16.0.3:1100,jnp://172.16.0.7:1100, java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces:org.jboss.naming:org.jnp.interfaces}


            The jndi lookup in localhost gives my a object, but lookup on another node just gives me a null object.

            In my configuration i have changed the HANamingService BindAddress to hardcoded ip because the ${jboss.bind.address} resulted in an error (no such device).
            Should I also change to hardcoded ip in JRMPInvokerHA (have tried but no effect), ore is the anything else I have to change from the default configuration.
            I am running the all configuration of jboss-3.2.3, where I have remowed the jms folder, and the farm-service.xml in deploy.last

            Am i doing something wrong here or have anyone any idea to how to solve my problem

            Kasper


            • 3. Re: lookup mbean on other node in the cluster through jndi
              f_kasper

              Isn't there anybody out there who can telle me what I am doing wrong, I think it is just som fundamentatal stuf I am missing, but i just don't get it.

              Is it posible to look up a mbean on another node in the cluster, via jndi (HAJNDI) and the invoke this mbeans functions? (I can find it, but don't get any object back?)

              I will be thanksfull for any answer, also if it is just som basic about the clustering teknolygy.
              (I have read the paid for documentation without any luck :-S)

              /Kasper

              My cluster-service.xml:

              <?xml version="1.0" encoding="UTF-8"?>
              
              <!-- ===================================================================== -->
              <!-- -->
              <!-- Sample Clustering Service Configuration -->
              <!-- -->
              <!-- ===================================================================== -->
              
              <server>
              
               <classpath codebase="lib" archives="jbossha.jar"/>
              
               <!-- ==================================================================== -->
               <!-- Cluster Partition: defines cluster -->
               <!-- ==================================================================== -->
              
               <mbean code="org.jboss.ha.framework.server.ClusterPartition"
               name="jboss:service=DefaultPartition">
              
               <!-- Name of the partition being built -->
               <attribute name="PartitionName">DefaultPartition</attribute>
               <!-- Determine if deadlock detection is enabled -->
               <attribute name="DeadlockDetection">False</attribute>
               <!-- The JGroups protocol configuration -->
               <attribute name="PartitionConfig">
               <Config>
               <!-- UDP: if you have a multihomed machine,
               set the bind_addr attribute to the appropriate NIC IP address -->
               <!-- UDP: On Windows machines, because of the media sense feature
               being broken with multicast (even after disabling media sense)
               set the loopback attribute to true -->
               <UDP mcast_addr="228.1.2.3" mcast_port="45566"
               ip_ttl="64" ip_mcast="true"
               mcast_send_buf_size="150000" mcast_recv_buf_size="80000"
               ucast_send_buf_size="150000" ucast_recv_buf_size="80000"
               loopback="false" />
               <PING timeout="2000" num_initial_members="3"
               up_thread="true" down_thread="true" />
               <MERGE2 min_interval="5000" max_interval="10000" />
               <FD shun="true" up_thread="true" down_thread="true"
               timeout="2500" max_tries="5" />
               <VERIFY_SUSPECT timeout="3000" num_msgs="3"
               up_thread="true" down_thread="true" />
               <pbcast.NAKACK gc_lag="50" retransmit_timeout="300,600,1200,2400,4800"
               up_thread="true" down_thread="true" />
               <pbcast.STABLE desired_avg_gossip="20000"
               up_thread="true" down_thread="true" />
               <UNICAST timeout="5000" window_size="100" min_threshold="10"
               down_thread="true" />
               <FRAG frag_size="8192"
               down_thread="true" up_thread="true" />
               <pbcast.GMS join_timeout="5000" join_retry_timeout="2000"
               shun="true" print_local_addr="true" />
               <pbcast.STATE_TRANSFER up_thread="true" down_thread="true" />
               </Config>
               </attribute>
               </mbean>
              
               <!-- ==================================================================== -->
               <!-- HA Session State Service for SFSB -->
               <!-- ==================================================================== -->
              
               <mbean code="org.jboss.ha.hasessionstate.server.HASessionStateService"
               name="jboss:service=HASessionState">
               <depends>jboss:service=DefaultPartition</depends>
               <!-- Name of the partition to which the service is linked -->
               <attribute name="PartitionName">DefaultPartition</attribute>
               <!-- JNDI name under which the service is bound -->
               <attribute name="JndiName">/HASessionState/Default</attribute>
               <!-- Max delay before cleaning unreclaimed state.
               Defaults to 30*60*1000 => 30 minutes -->
               <attribute name="BeanCleaningDelay">0</attribute>
               </mbean>
              
               <!-- ==================================================================== -->
               <!-- HA JNDI -->
               <!-- ==================================================================== -->
              
               <mbean code="org.jboss.ha.jndi.HANamingService"
               name="jboss:service=HAJNDI">
               <depends>jboss:service=DefaultPartition</depends>
               <!-- Name of the partition to which the service is linked -->
               <attribute name="PartitionName">DefaultPartition</attribute>
               <!-- bind address of HA JNDI RMI endpoint -->
               <attribute name="BindAddress"></attribute>
               <!-- RmiPort to be used by the HA-JNDI service
               once bound. 0 => auto. -->
               <attribute name="RmiPort">0</attribute>
               <!-- Port on which the HA-JNDI stub is made available -->
               <attribute name="Port">1100</attribute>
               <!-- Backlog to be used for client-server RMI
               invocations during JNDI queries -->
               <attribute name="Backlog">50</attribute>
              
               <!-- Multicast Address and Group used for auto-discovery -->
               <attribute name="AutoDiscoveryAddress">230.0.0.4</attribute>
               <attribute name="AutoDiscoveryGroup">1102</attribute>
              
               <!-- IP Address to which should be bound: the Port, the RmiPort and
               the AutoDiscovery multicast socket. -->
               <!-- Client socket factory to be used for client-server
               RMI invocations during JNDI queries -->
               <!--attribute name="ClientSocketFactory">custom</attribute-->
               <!-- Server socket factory to be used for client-server
               RMI invocations during JNDI queries -->
               <!--attribute name="ServerSocketFactory">custom</attribute-->
               </mbean>
              
               <mbean code="org.jboss.invocation.jrmp.server.JRMPInvokerHA"
               name="jboss:service=invoker,type=jrmpha">
               <attribute name="ServerAddress"></attribute>
               <!--
               <attribute name="RMIObjectPort">0</attribute>
               <attribute name="RMIClientSocketFactory">custom</attribute>
               <attribute name="RMIServerSocketFactory">custom</attribute>
               -->
               </mbean>
              
               <!-- ==================================================================== -->
               <!-- Distributed cache invalidation -->
               <!-- ==================================================================== -->
              
               <mbean code="org.jboss.cache.invalidation.bridges.JGCacheInvalidationBridge"
               name="jboss.cache:service=InvalidationBridge,type=JavaGroups">
               <depends>jboss:service=DefaultPartition</depends>
               <depends>jboss.cache:service=InvalidationManager</depends>
               <attribute name="InvalidationManager">jboss.cache:service=InvalidationManager</attribute>
               <attribute name="PartitionName">DefaultPartition</attribute>
               <attribute name="BridgeName">DefaultJGBridge</attribute>
               </mbean>
              
              </server>
              

              Also I have the default iiop-service.xml and jbossha-httpsession to enabel clustering.
              Anything missing or should be changed?

              • 4. Re: lookup mbean on other node in the cluster through jndi
                gcarrokc

                I am running into problems just calling ejbs using HAJNDI. So I can't help you, but if I find a fix for my problem, I will also try to solve yours. Good Luck.


                (I have read the paid for documentation without any luck :-S) me too!

                The paid for gives little into what you need to actually get it to work. All I find is that it works right out of the box. Well session replication, that does, but the EJB lookup...Not!

                • 5. Re: lookup mbean on other node in the cluster through jndi
                  gcarrokc

                  Rock On!

                  Kasper you made my day. I didn't have the jnp:// in front of my servers. All I did was add that after seeing it in your code and now it works. Thanks.

                  I will get online monday and try to help resolve your problem.

                  • 6. Re: lookup mbean on other node in the cluster through jndi
                    gcarrokc

                    Kasper:

                    I have been using EJBs and I can call them from any server I want.
                    Here is what I did to call them from a specific server. I have left all the cluster
                    setting the default, my ejb-jar and jboss xml files, use the defaults, I am also
                    using the full version of clustering, using the all server directory, with the farm
                    as my cluster deploy directory. Our network king, set it up and is using the
                    apache JK?mod for the session managment.

                    Hope this helps, you sure helped me "jnp://" !
                    Six small characters, but they made it work!


                     // show message on the server that is used,, this will help to show us how the
                     // clustering is working, should see this message on all servers if round-robin
                     // is used and this sevlet is called repeatedly.
                     System.err.println("[FYI] - The cluster test servlet was initialized on this server");
                    
                     int days=0;
                    
                     //dateofhire is passed into this as a valid date, it is used to calculate the days employeed
                    
                     try
                     {
                     Properties p = new Properties();
                     p.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
                     p.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
                    
                     // to lookup on all servers, if apps2 goes down, it will lookup on apps3.
                     //p.put(Context.PROVIDER_URL,"jnp://apps2:1100,jnp://apps3:1100");
                    
                     // to lookup on a specific server, not recommended as this does not make use
                     // of the clustering (unless you have different groups of server that serve different
                     // functions, and then you would still lookup on more than 1)
                     p.put(Context.PROVIDER_URL,"jnp://apps3:1100");
                    
                    
                     InitialContext jndiContext = new InitialContext(p);
                    
                    
                     Object ref = jndiContext.lookup("java:comp/env/ejb/employee");
                    
                     empHome = (employeeHome) PortableRemoteObject.narrow(ref, employeeHome.class);
                    
                     employeeRemote bean = empHome.create();
                    
                     bean.setdaysEmployeed(dateofhire);
                     days=bean.getdaysEmployeed();
                     bean.remove();
                     System.err.println("Days employed = " + days);
                     }
                     catch(Exception e)
                     {
                     throw new ServletException("Failed due to : ", e);
                     }
                    
                     }
                    



                    • 7. Re: lookup mbean on other node in the cluster through jndi
                      f_kasper

                      Thanks, for the reply
                      But it still doesn't seem to work for me.
                      The object returned from the jndiContext.lookup is still null, så i think i maybe do something wrong in the rmi providing the stub externaly.

                      For now I had bean forced to boost my hardware instead of clustering, and then hoping to change to cluster at a later time.


                      /Kasper

                      • 8. Re: lookup mbean on other node in the cluster through jndi
                        michael.daleiden

                        From your code examples, it appears that you are binding the MBean into the LOCAL JNDI of the server then trying to fetch it using the LOCAL JNDI of the other server.

                        If you want to place the MBean in the HA-JNDI, you will need to create the initial context on that server as follows:

                        Properties prop = new Properties();
                        prop.put(Context.INITIAL_CONTEXT_FACTORY,
                         "org.jnp.interfaces.NamingContextFactory");
                        prop.put(Context.URL_PKG_PREFIXES,
                         "org.jboss.naming:org.jnp.interfaces");
                        prop.put(Context.PROVIDER_URL,
                         "");
                        InitialContext jndiContext = new InitialContext(prop);


                        Then, store the MBean into the context.

                        On the other server, you will need to do the same InitialContext setup, then you should be able to perform the lookup via HA-JNDI.

                        The other problem you will run into with this is that MBeans on a remote server need to be accessed via a RMIAdaptor, so that the actual calls go across the network and run against the MBean that is actually running on the remote server. I have found that it is better to lookup the RMIAdaptor on the remote server via the remote server's local JNDI, then use that RMIAdaptor to call the MBean functions:

                        Properties props = new Properties();
                         props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
                         props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
                         props.put(Context.PROVIDER_URL, "jnp://myserver:1099");
                         InitialContext ctx = new InitialContext(props);
                         Object obj = ctx.lookup("jmx/rmi/RMIAdaptor");
                         if (!(obj instanceof RMIAdaptor)) {
                         throw new ClassCastException
                         ("Object not of type: RMIAdaptorImpl, but: " +
                         (obj == null ? "not found" : obj.getClass().getName()));
                         }
                         RemoteMBeanServer server = new RMIConnectorImpl((RMIAdaptor)obj);


                        The RemoteMBeanServer instance provides all of the same functionality as the standard MBeanServer, with additional infrastructure to support RMI.