9 Replies Latest reply on May 19, 2004 8:24 PM by David Budworth

    MBean JNDI Name: Alternative to RMIAdapter?

    Francis Xavier Newbie

      Hello All
      I've a situation where I've to deploy a MBean which is a config service (basically it is a startup class that gets the properties and configurations from database at the startup). One this is deployed, I'll have to lookup for this service to call methods on it. For example,

      configMBean.getConfigForTestServer()
      should get me the configuration details for my test server.

      I've followed the rules of SAR process and deployed with the following snip from jboss-service.xml
       <mbean code="playground.org.ms.mbeans.ConfigService"
       name=":service=ConfigService,name=ConfigService">
       <attribute name="JndiName">ConfigService</attribute>
       </mbean>
      


      My Question(s):
      1. After successful deployment, I'm unable to see this MBean bound to JNDI NamingService. I didn't find the ConfigService in JNDIView. Is there anything I've to do to reflect this service into JNDI NS? I don't want to use NonSerializableFactory methods to do this. Am I assuming that deploying the MBean with the above configuration will bind to JNDI? If yes, what is the way I can do this?

      2. If I know the JNDI Name, Is it right to lookup for this Bean as follows(JRun didn't have any problem for this kind of lookup and getter):
      Context ctx = ...
      Object obj = ctx.lookup("ConfigService");
      Object mbean = PortableRemoteObject.narrow(obj,ConfiService.class)
      // now I got the bean, I call the methods on this?
      Configuration conf = mbean.getConfigForTestServer();
      


      3. I understand I can use RMIAdaptor to invoke the methods on the MBean. The only disadvantage in this way is the client should import jboss class(RMIAdaptor) which is not an ideal way. So I'm tending to go the alternative suggested above.

      4. The alternative in question worked perfectly fine with JRun. I'm assuming there should be some way to do in JBoss as well.

      Advane Thanks to All
      X

        • 1. Re: MBean JNDI Name: Alternative to RMIAdapter?
          Raja Master

          Answers inline

          "xavieruk" wrote:
          Hello All
           <mbean code="playground.org.ms.mbeans.ConfigService"
           name=":service=ConfigService,name=ConfigService">
           <attribute name="JndiName">ConfigService</attribute>
           </mbean>
          


          My Question(s):
          1. After successful deployment, I'm unable to see this MBean bound to JNDI NamingService. I didn't find the ConfigService in JNDIView. Is there anything I've to do to reflect this service into JNDI NS? I don't want to use NonSerializableFactory methods to do this. Am I assuming that deploying the MBean with the above configuration will bind to JNDI? If yes, what is the way I can do this?

          The MBean would be bound when you deployed it successfully. You should be able to see a :service=ConfigService,name=ConfigService from http://localhost:8080/jmx-console. Binding to the JNDI is something that you need to do from within your Mbean(using the approach you specified or something else). Just setting up the attribute called jndiname doesnt do anything other than just setting up that value.



          "xavieruk" wrote:

          2. If I know the JNDI Name, Is it right to lookup for this Bean as follows(JRun didn't have any problem for this kind of lookup and getter):
          Context ctx = ...
          Object obj = ctx.lookup("ConfigService");
          Object mbean = PortableRemoteObject.narrow(obj,ConfiService.class)
          // now I got the bean, I call the methods on this?
          Configuration conf = mbean.getConfigForTestServer();
          


          Yes but if you are binding it to the JMX Tree, why do you want to still go the JNDI Route. You have your objectname which is unique for the server, so why not use it to invoke methods.


          "xavieruk" wrote:

          3. I understand I can use RMIAdaptor to invoke the methods on the MBean. The only disadvantage in this way is the client should import jboss class(RMIAdaptor) which is not an ideal way. So I'm tending to go the alternative suggested above.


          Well there is the HTTPAdaptor. So the client for all that could just create a HTTPConnection and call it (no extra libraries used). Check out the second reply on this thread
          http://www.jboss.org/index.html?module=bb&op=viewtopic&p=3817878

          • 2. Re: MBean JNDI Name: Alternative to RMIAdapter?
            Francis Xavier Newbie

            Thanks Raj for propmt reply.
            See the replies to your replies (they are not inline, sorry)

            1. I'm finding the service in jmx-console. That's fine.

            2. I could use the ObjectName, but still the problem of invoking methods using RMIAdapter! see 3.

            3. My client could be another Bean or statup class or singleton Object that could sit in the same App server or out of J2EE. So how can I invoke methods without using RMIAdapter? I guess I may have to do the following to invoke the method, in which case I'm coming back to square one: using RMIAdapter!!

            RMIAdaptor server = (RMIAdaptor) jndiContext.lookup("jmx/rmi/RMIAdaptor");
            ObjectName name = new ObjectName(":service=ConfigService");
            

            Or is there any other way of invoking methods?



            • 3. Re: MBean JNDI Name: Alternative to RMIAdapter?
              Raja Master

              As far the rmiadapter thing, did you check out the link that i had given above.?

              Assume that i need to invoke the flushCache method on
              jboss.j2ee:jndiName=com.yoyo.AddressJNDI,service=EJB

              i would create a urlconnection to the following URL
              http://localhost:8080/jmx-console/HtmlAdaptor?action=invokeOpByName&name=jboss.j2ee:jndiName=com.yoyo.AddressJNDI,service=EJB&methodName=flushCache

              where ur objectname would go in the name request and methodName would be the name that you want to call.

              • 4. Re: MBean JNDI Name: Alternative to RMIAdapter?
                Francis Xavier Newbie

                I had checked the mentioned post.

                In the URL, the name=jboss.j2ee:jndiName=com.yoyo.AddressJNDI you have quoted seems to have a Jndi Name bound in JNDI Tree. But as my MBean didn't have any JNDI Name (It's bound to JMX only), I'm unable to move forward with your tip. Infact I used the name exactly displayed in jmx-console!! I'm getting MethodNotFoundException (Method is there, I'm sure)

                Thanks
                Madhu

                • 5. Re: MBean JNDI Name: Alternative to RMIAdapter?
                  Kabir Khan Master

                  You have to bind it yourself. In your MBean you need something like:


                  
                  String jndiName;
                  
                  public void setJndiName(String name){
                   InitialContext ctx = new InitialContext();
                   this.jndiName=name;
                   ctx.bind(name, this);
                  }
                  
                  public String getJndiName(){
                   return jndiName;
                  }
                  
                  


                  If your name contains subcontexts (e.g. blah/something/ConfigService) you need to bing the blah and something subcontexts first.

                  Cheers,

                  Kab



                  • 6. Re: MBean JNDI Name: Alternative to RMIAdapter?
                    Raja Master

                    the jndiname in my objectname is just how jboss creates the objectname. Its an EJB and i dont really set any object for that. So having an jndiName or not in the objectname should make no difference.
                    Are you sure you included the domain(jboss.j2ee) as well as the name included in the HTTP URL?

                    • 7. Re: MBean JNDI Name: Alternative to RMIAdapter?
                      Francis Xavier Newbie

                      Kab, I can't do that:
                      ctx.bind(name, this) will throw an exception as "this" is not a Serializable source!!

                      All I need is to Bind the MBean to the JNDI Tree and lookup!!

                      • 9. Re: MBean JNDI Name: Alternative to RMIAdapter?
                        David Budworth Newbie

                        Unless something has changed recently, MBeans are *NOT* remote objects.

                        You can either
                        a) use RMIAdaptor to access things via the MBean server (which you would like to avoid)

                        b) Use HTML adaptor (not a good choice IMHO)

                        c) Bind an RMI stub for your service to the JNDI tree

                        My company does "c" (but in a clustered/load balanced way, so you'd need to adjust if you don't do clusters)

                        example

                         HARMIServerImpl server = new HARMIServerImpl(
                         haPartition, //your HA partition handle
                         "ReplicantName", // unique name for your service, call it anything
                         ServiceInterface.class, //exposed interface clients use
                         serviceInstance, // actual MBean instance you want to access
                         0, // RMI port, zero for automatic
                         null, //
                         null, //
                         null, //
                         callBackHandler //handler to be notified when other cluster members come/go
                        );
                        new InitialContext().bind("MyService",server.createHAStub(new RoundRobin()));
                        


                        Main classes to look at are:
                        org.jboss.ha.framework.server.HARMIServerImpl
                        org.jboss.ha.framework.interfaces.HARMIProxyCallback
                        org.jboss.ha.framework.interfaces.RoundRobin

                        We basically wrapped all the nastiness of creating HARMI stubs for load balanced / HA services in a simple wrapper class that takes care of the binding/rebinding as members come and go.

                        There may be regular non-HA versions of the HARMIServerImpl that will do the trick for ya, but i wouldn't know (we require 100% of our stuff to be HA)

                        Hope that helps, and wasn't too confusing.

                        oh, and in case you were not aware, the JNDI tree is basically just a big map of serialized data. There's no magic there. Trying to store your MBean's "this" in that map would not really work, when the client did the lookup they'd get the entire class down at their end in the client vm.

                        Think of it like Suspend mode on your laptop. You tell the JNDI server to store something, and he takes a snapshot in time and stores it in memory, then hands that back to all who ask. The fancy remote-magic type stuff is in the RMI (or any invoker) layer.

                        For this reason, any RMI type stub you store in JNDI for clients to use, must be re-bound if something changes about it. Otherwise the clients get the old snapshot in time.

                        Extremely important on HA services, as the old version might be holding a reference to a bunch of turned off servers, thereby making stuff not quite so HA.

                        ok, too much cafine, good luck with your project