0 Replies Latest reply on Sep 20, 2002 10:33 AM by Marcus Eriksson

    CommunicationException with EJB gateway

    Marcus Eriksson Newbie

      Hello all!

      We're having problems using our EJB gateway on JBoss (works on WebLogic).

      The idea is to have a EJB gateway with no knowledge of bean remote/home interfaces that can call any deployed bean as long as the bean implements a special method.

      Clients call EJBs by calling a gateway method and passing three arguments:
      * JNDI-name of bean to call
      * Method name on bean
      * Argument to method

      The gateway looks up the desired bean and calls the method in the interface extended by all remote interfaces. The gateway should not need access to any bean home/remote interface classes (only the common interface class).

      I've attached my files below.

      Description:

      MyInterface:

      All remote interfaces extends this interface.
      The gateway always calls the callOperation method.

      TestBeanRemote:

      In addition to the callOperation method, this particular bean have to methods.

      TestBeanHome:

      Standard home

      TestBeanImpl:

      Bean class. Implementation of all three methods. The callOperation-method calls the correct operation based on arguments.

      BeanClient:

      The bean client knows only of MyInterface.
      Standard jndi lookup, but narrow to EJBHome.class.
      Use reflection to call create() on home interface and typecast to MyInterface. Now, it is possible to call the callOperation method.

      This works perfectly on WebLogic 7.0 but not on Jboss 3.0.2. Why? Is there any other way to accomplish what we want?

      Exception is:

      javax.naming.CommunicationException. Root exception is java.lang.ClassNotFoundException: com.marcus.TestBeanHome
      at java.net.URLClassLoader$1.run(Unknown Source)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.net.URLClassLoader.findClass(Unknown Source)
      at java.lang.ClassLoader.loadClass(Unknown Source)
      at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
      at java.lang.ClassLoader.loadClass(Unknown Source)
      at java.lang.ClassLoader.loadClassInternal(Unknown Source)
      at java.lang.Class.forName0(Native Method)
      at java.lang.Class.forName(Unknown Source)
      at sun.rmi.server.MarshalInputStream.resolveProxyClass(Unknown Source)
      at java.io.ObjectInputStream.inputProxyClassDescriptor(Unknown Source)
      at java.io.ObjectInputStream.readObject(Unknown Source)
      at java.io.ObjectInputStream.readObject(Unknown Source)
      at java.io.ObjectInputStream.inputObject(Unknown Source)
      at java.io.ObjectInputStream.readObject(Unknown Source)
      at java.io.ObjectInputStream.readObject(Unknown Source)
      at java.rmi.MarshalledObject.get(Unknown Source)
      at org.jnp.interfaces.MarshalledValuePair.get(MarshalledValuePair.java:30)
      at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:460)
      at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:440)
      at javax.naming.InitialContext.lookup(Unknown Source)
      at com.client.BeanClient.main(BeanClient.java:24)


      MyInterface.java:

      package com.ifsworld;

      import javax.ejb.*;
      import java.rmi.*;

      public interface MyInterface extends EJBObject {

      public String callOperation(String operationName, String argument) throws RemoteException;
      }

      TestBeanHome.java:

      package com.marcus;

      import java.rmi.*;
      import javax.ejb.*;

      public interface TestBeanHome extends EJBHome {

      TestBeanRemote create() throws RemoteException, CreateException;
      }

      TestBeanRemote.java:

      package com.marcus;

      import com.ifsworld.MyInterface;
      import java.rmi.RemoteException;

      public interface TestBeanRemote extends MyInterface {

      public String TestBeanOp1(String argument) throws RemoteException;

      public String TestBeanOp2(String argument) throws RemoteException;

      }


      TestBeanImpl.java:

      package com.marcus;

      import java.rmi.*;
      import javax.ejb.*;

      public class TestBeanImpl implements SessionBean {

      private SessionContext sessionContext;

      /** Implement method from MyInterface
      */
      public String callOperation(String operationName, String argument) {
      if (operationName.equals("TestBeanOp1"))
      return TestBeanOp1(argument);
      else if (operationName.equals("TestBeanOp2"))
      return TestBeanOp2(argument);
      else
      throw new EJBException("Invalid operation " + operationName);
      }

      /** Implementation of TestBeanRemote operation
      */
      public String TestBeanOp1(String argument) {
      return "TestBeanOp1 called with argument = " + argument;
      }

      /** Implementation of TestBeanRemote operation
      */
      public String TestBeanOp2(String argument) {
      return "TestBeanOp2 called with argumant = " + argument;
      }

      public void ejbCreate() throws CreateException, RemoteException {
      }

      public void ejbPostCreate() throws CreateException, RemoteException {
      }

      public void ejbRemove() {
      }

      public void ejbActivate() {
      }

      public void ejbPassivate() {
      }

      public void setSessionContext(SessionContext sessionContext) {
      this.sessionContext = sessionContext;
      }

      public void unsetSessionContext() {
      this.sessionContext = null;
      }

      }


      BeanClient.java:

      package com.client;

      import com.ifsworld.MyInterface;
      import javax.naming.*;
      import javax.rmi.PortableRemoteObject;
      import java.lang.reflect.*;
      import javax.ejb.*;
      import java.rmi.*;
      import java.util.*;

      public class BeanClient {

      public BeanClient() {
      }

      public static void main(String[] args) throws RemoteException {
      try {
      Hashtable env = new Hashtable();
      env.put(Context.INITIAL_CONTEXT_FACTORY,
      weblogic.jndi.WLInitialContextFactory.class.getName());
      env.put(Context.PROVIDER_URL, "t3://lkprnd25:7001");

      InitialContext ctx = new InitialContext(env);
      Object o = ctx.lookup("ifs/remote/TestBean");
      EJBHome home = (EJBHome)PortableRemoteObject.narrow(o, EJBHome.class);
      Method m = home.getClass().getDeclaredMethod("create", new Class[0]);
      MyInterface handler = (MyInterface) m.invoke(home, new Object[0]);

      String result = handler.callOperation("TestBeanOp2", "Hello!");
      System.out.println(result);
      }
      catch (NamingException e) {
      e.printStackTrace();
      }
      catch (NoSuchMethodException e) {
      e.printStackTrace();
      }
      catch (IllegalAccessException e) {
      e.printStackTrace();
      }
      catch (InvocationTargetException e) {
      e.printStackTrace();
      }
      }

      }


      ejb-jar.xml:

      <?xml version="1.0"?>

      <!DOCTYPE ejb-jar PUBLIC
      '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN'
      'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>

      <ejb-jar>
      <enterprise-beans>

      <ejb-name>TestBean</ejb-name>
      com.marcus.TestBeanHome
      com.marcus.TestBeanRemote
      <ejb-class>com.marcus.TestBeanImpl</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>

      </enterprise-beans>
      <assembly-descriptor>
      <container-transaction>

      <ejb-name>TestBean</ejb-name>
      <method-name>*</method-name>

      <trans-attribute>Required</trans-attribute>
      </container-transaction>
      </assembly-descriptor>
      </ejb-jar>


      jboss.xml:

      <?xml version="1.0" encoding="UTF-8"?>

      <enterprise-beans>

      <ejb-name>TestBean</ejb-name>
      <jndi-name>ifs/remote/TestBean</jndi-name>

      </enterprise-beans>



      Regards,

      Marcus