5 Replies Latest reply on Feb 24, 2007 6:52 PM by Andrew Rubinger

    How to look up one of the many interfaces that a bean implem

    Anne Forumer Newbie

      JBoss 4.0.4CR2 EJB3:

      I'd like a bean to implement multiple interfaces:

      @Remote(MyBean.class)
      @RemoteBinding(jndiBinding="Company/MyBean/remote")
      MyBean implements Interface1, Interface2, Interface3


      Is there a way that a client can look up only, say Interface2?

      I tried looking up "Company/MyBean/remote#Interface2"

      but it didn't work. I got the error saying:

      javax.naming.NameNotFoundException: remote#Interface2 not bound

      Yes, the earlier part of the lookup string was lost!

      I'd appreciate any help as I'd rather not have a separate bean for each interface. Any examples would be good too.

      Thanks

        • 1. Re: How to look up one of the many interfaces that a bean im
          Andrew Rubinger Master

          The value stored in JNDI is an object - a proxy object that implements the interfaces you define.

          So...no, you can't pull out an object that only implements one of the interfaces you've defined.

          However, you should be casting the proxy from JNDI into the interface you want...

          Interface1 myBean = (Interface1)PortableRemoteObject.narrow(
           new InitialContext(props).lookup("address"),
           Interface1.class);


          ...and that way, you'll have compile-time constraints to only invoke operations defined by Interface1.

          (Code above only for remote lookup; local can skip the "PortableRemoteObject.narrow()) step)

          S,
          ALR

          • 2. Re: How to look up one of the many interfaces that a bean im
            Anne Forumer Newbie

            This will do what I want - only easier!

            Thank you!

            • 4. Re: How to look up one of the many interfaces that a bean im
              Anne Forumer Newbie

              If I may revisit this again, this is what I am doing:

              Interface MyRemoteIF extends Interface1, Interface2
              
              @Remote(MyRemoteIF.class)
              @RemoteBinding(JndiBinding="MyCompany/MySessionBean/remote")
              public Class MySessionBean implements MyRemoteIF
              
              



              At the client:

              Interface1 myInterface = (Interface1)context.lookup("MyCompany/MySessionBean/remote"));
              


              The problem is that in two of the three cases, I am getting ClassNotFoundException for MyRemoteIF.class! Classes and interfaces are different in each of the three cases. I am trying to locate the cause of this inconsistency.

              Does this arrangement require MyRemoteIF.class to be present at the client? I am hoping that only Interface1 is required.

              Thanks

              • 5. Re: How to look up one of the many interfaces that a bean im
                Andrew Rubinger Master

                Right...so the proxy object is going to be created by JBoss and will implement all the interfaces you designate.

                When your client does a lookup for this object, it's going to get loaded by the classloader, along with all dependencies it has.

                So if the definition in the classfile is something like (I'm making up some JBoss classnames for simplicity's sake) "Proxy$1 extends JbossRemoteProxy implements MyRemoteIF", then your client must have MyRemoteIF on its classpath (even though you just want the functionality defined in the superclass Interface1 at compile time, the actual object you're working with at runtime is what's most important here).

                So, I propose you do something like the following:

                public abstract class MyClassBase {
                
                ... all your business logic defined by Interface1 and Interface2...
                }


                @Remote
                public interface Interface1{}


                @Remote
                public interface Interface2{}


                @Stateless
                @RemoteBinding(JndiBinding="MyCompany/MySessionBean1/remote")
                public class MyClass1 extends MyClassBase implements Interface1{}


                @Stateless
                @RemoteBinding(JndiBinding="MyCompany/MySessionBean2/remote")
                public class MyClass2 extends MyClassBase implements Interface2{}


                ..this way, you'll have centralized your logic into one base class, and deployed the Stateless Beans separately such that one need not have any knowledge of the other.

                S,
                ALR