12 Replies Latest reply on Aug 29, 2003 7:04 AM by Adrian Brock

    ClassCastException, standalone client JNDI lookup

    madcoder Newbie

      I have a custom mbean that registers an object in the jndi tree. This object extends PortableRemoteObject and implements a Remote interface. The mbean registers the object using NonSerializableFactory.rebind( parentCtx, "ObjName", object ) where the parentCtx is the root of the JNDI tree.
      I would like to get a reference to that object from a java standalone client application. The client application is able to lookup the object, and obtain a valid reference... however, when I attempt to narrow and cast the object to the remote interface it throws a ClassCastException. The client's classpath has jbossall-client.jar and the path to the remote stubs/ties. I am compiling the stubs/ties via sun's rmic compiler with the -iiop option. I am able to lookup the object and cast it without any problems with a client that is inside the container; i.e. a servlet. I only run into problems when I venture outside the container.

      Any ideas as to why I am unable to cast the object to its remote type on a standalone client?

      I am fairly new to j2ee and jboss. Even if you're not sure about a solution, I would welcome any advice on how to troubleshoot the problem.

      I am using jboss-3.2.1_tomcat-4.1.24 and jdk version 1.4.2

      Thanks for any help you might provide.

        • 1. Re: ClassCastException, standalone client JNDI lookup
          Adrian Brock Master

          The NonSerializableFactory is used for inVM work.
          If your object really is a remote object, just bind
          it directly.

          Regards,
          Adrian

          • 2. Re: ClassCastException, standalone client JNDI lookup
            madcoder Newbie

            Thanks for the reply. I have stopped using NonSerializableFactory, and instead just use the initial context's rebind method.

            Now I have another question: When the mbean is initialized, and it attempts to bind the object, I get a CommunicationException with a root cause telling me that the Remote object is not serializable.

            1. Why do I need to implement the remote interface and implement Serializable? In the majority of the examples I've seen, you create an interface that extends java.rmi.Remote, and an object that implements that remote interface which also extends PortableRemoteObject.

            2. I modified the remote object code so that it does implement Serializable, and the mbean successfully binds the object into the JNDI tree. Also, the external client is able to lookup the object and perform operations on the object. The problem: It seems that the lookup operation passed a copy of the remote object instead of a reference. This is because any changes I make to the object do not appear on the server side copy of the object. Any ideas?

            Thanks again for your help.

            • 3. Re: ClassCastException, standalone client JNDI lookup
              Adrian Brock Master

              Have you run it through rmic?

              Regards,
              Adrian

              • 4. Re: ClassCastException, standalone client JNDI lookup
                madcoder Newbie

                Yes, I am using rmic that is bundled with the jdk.

                • 5. Re: ClassCastException, standalone client JNDI lookup
                  Adrian Brock Master

                  Did you use PortableRemoteObject?
                  This allows you to use the RemoteObject without specifically
                  binding it to a port.

                  What are you doing anyway? If you just want remote
                  access to the MBean, you can use the RMIAdapter.

                  Regards,
                  Adrian

                  • 6. Re: ClassCastException, standalone client JNDI lookup
                    madcoder Newbie

                    Essentially, I am trying to get an example from BEA's site to work with jboss - then work from there. I want to use client-side callbacks using RMI. You can find the example here:
                    http://edocs.bea.com/wle/wle50/rmi/callbak.htm

                    I took the server side of the code (CallbackImpl) and placed it into a jboss mbean where upon mbean startup, it attempts to register the CallbackImpl into the JNDI tree. I modified the CallbackImpl class to extend PortableRemoteObject, then call super() in its c-tor.

                    The problem is, that when I try to bind the CallbackImpl object into the JNDI tree, jboss wants it to be Serializable. I cannot figure out why?

                    Thanks for all your help.

                    • 7. Re: ClassCastException, standalone client JNDI lookup
                      Adrian Brock Master

                      In what way is this different from UnicastRemoteObject?

                      e.g. In JMS we bind a server object into jndi. When this
                      is passed over JRMP through the jndi lookup it actually
                      returns the stub. The client then invokes a method to
                      pass another UnicastRemoteObject for callbacks again it
                      is the stub that gets passed.

                      At no point are either RemoteObject explicity bound to any port.

                      See the package org.jboss.mq.il.rmi

                      We use the same trick for the JRMPInvoker that handles
                      EJB (it can do JMX as well) invocations over JRMP

                      See org.jboss.invocation.jrmp

                      Regards,
                      Adrian

                      • 8. Re: ClassCastException, standalone client JNDI lookup
                        madcoder Newbie

                        The problem is that when a client attempts to lookup the CallbackImpl object, I believe they are getting a copy, not a reference.

                        For instance, the client will lookup the Callback object then call a method that increments an integer. Meanwhile the server is outputting the value of the integer every 5 seconds from its copy of the object. The value never changes - so the method that the client called was not invoked remotely.

                        I believe its because I had to make the CallbackImpl object implement Serializable so that jboss could register the object in its JNDI tree. Since its a Serializable object, its no longer seen as remote. Is there a way I can determine whether the object that is returned from a JNDI lookup is the remote stub versus a serialized copy?

                        If I use UnicastRemoteObject instead of PortableRemoteObject, I am no longer going to be using rmi over iiop. I'm not sure that this is a big deal in this case... but why is jboss trying to serialize a remote object when binding it into the JNDI tree ? I thought only the stubs need be serializable.

                        -BS

                        • 9. Re: ClassCastException, standalone client JNDI lookup
                          Adrian Brock Master

                          It is RMI that will swap it for the stub.
                          We just wrap it in a MarshelledObject which will just
                          Serialize it if there is no stub.

                          System.out.print(object.getClass());

                          Regards,
                          Adrian

                          • 10. Re: ClassCastException, standalone client JNDI lookup
                            madcoder Newbie

                            I used the getClass() method, and found that it was not the stub object, instead it was the object itself - so it must've serialized instead of rmi taking over.

                            I had been compiling the stubs/ties using rmic -iiop. I decided to try compiling without the iiop option - and now everything works! I do not understand why though... I though that if you extend PortableRemoteObject you had to use iiop?

                            Thanks for all your patience and help.

                            • 11. Re: ClassCastException, standalone client JNDI lookup
                              madcoder Newbie

                              I used the getClass() method, and found that it was not the stub object, instead it was the object itself - so it must've serialized instead of rmi taking over.

                              I had been compiling the stubs/ties using rmic -iiop. I decided to try compiling without the iiop option - and now everything works! I do not understand why though... I though that if you extend PortableRemoteObject you had to use iiop?

                              Thanks for all your patience and help.

                              • 12. Re: ClassCastException, standalone client JNDI lookup
                                Adrian Brock Master

                                -iiop is for when you are using an ORB

                                Regards,
                                Adrian