Calling EJB in JBoss from Tomcat and passing object as argument

I have the following EJB class generated in an application running in JBoss 5



public interface ISlaveServer {

    public  String getId();

    public  String getName();
}

@Remote
public interface IMasterServer {

    public String getId();

    public void addSlave(ISlaveServer slaveServer);

    public  void removeSlave(ISlaveServer slaveServer);

}

@Stateless
@RemoteBinding(jndiBinding = "MasterServer")
public class MasterServer implements IMasterServer, Serializable {

    UUID id = UUID.randomUUID().toString();

    public String getId() { return id.toString(); }

    public void addSlave(ISlaveServer slaveServer) { ... }

    public void removeSlave(ISlaveServer slaveServer) { ... }

}

      

code>

I have the following class created in an application running in Tomcat 6



public static class SlaveServer implements ISlaveServer, Serializable {


    UUID id = UUID.randomUUID().toString();

    public String getId() { return id.toString(); }

    public String getName() { return "SlaveServer"; }

}

      

code>

Finally, I have the following code which also works in a Tomcat based application ...

    Properties properties = new Properties();
    properties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
    properties.put("java.naming.factory.url.pkgs", "org.jboss.naming.client");
    properties.put("java.naming.provider.url", "jnp://localhost:1099");

    try {
        Context ctx = new InitialContext(properties);
        IMasterServer masterServer = (IMasterServer) ctx.lookup("MasterServer");
        String masterId = masterServer.getId();
        masterServer.addVideoServer(new SlaveServer());
    }
    catch(NamingException e) {
        e.printStackTrace();
    }

      

code>

Everything works fine before calling



masterServer.addVideoServer(new SlaveServer());

      

code>

when i get the following exception ...

java.lang.ClassNotFoundException: org.test.SlaveServerTest $ SlaveServer (no security manager: RMI class loader disabled)

From what I can tell, this exception may be originating from the remote JBoss server, because remote calls are working (masterServer.getId () works fine). Just the call where I pass the locally implemented object fails.

What do I need to do to make this work?

+2


source to share


3 answers


The SlaveServer class is Serializable. This means that this class must be available to both the client (JNDI snippet) and the server (MasterServer). When a class cannot be found on the server, RMI can load code from a remote location. However, executing code downloaded from a remote client is a potentially dangerous operation and is only allowed if a security manager is installed.



You either need to include the SlaveServer class in the application that contains the MasterServer (or some path to the server), or you need to stop using Serializable.

+2


source


"Static" was there because the original SlaveServer class was a nested class.

I moved the class to the top level (thus removing the static one) and it still doesn't go; I am getting the same exception.



I think I need to do something like activating CORBA on my SlaveServer. This way the JBoss server should be able to get stubs for my SlaveServer inside Tomcat.

/ Edit There is no ISlaveServer implementation in the JBoss application. I want it to pass a "remote link" from Tomcat app to JBoss app, so it doesn't have to serialize it at all (just a link to it).

0


source


To get this working, I needed to implement the ISlaveServer interface as a remote RMI interface.



public interface ISlaveServer extends java.rmi.Remote {

   ...

}

      

code>

and make sure the SlaveServer class is the proper remote object ...



public class SlaveServer extends java.rmi.RemoteObject implements ISlaveServer {

}

      

code>

Finally, I had to make sure the SlaveServer was exported via RMI before using it ...



    static SlaveServer slaveServer = new SlaveServer();
    Properties properties = new Properties();
    properties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
    properties.put("java.naming.factory.url.pkgs", "org.jboss.naming.client");
    properties.put("java.naming.provider.url", "jnp://localhost:1099");

    try {
            Context ctx = new InitialContext(properties);
            IMasterServer masterServer = (IMasterServer) ctx.lookup("MasterServer");
            String masterId = masterServer.getId();
            masterServer.addVideoServer((ISlaveServer)UnicastRemoteObject.exportObject(slaveServer, 0));
    }
    catch(NamingException e) {
            e.printStackTrace();
    }

      

code>

This binds to the remote EJB correctly and passes a reference to my SlaveServer object, which the EJB can use to communicate with the calling VM.

FYI SlaveServer is static because in RMI you are responsible for binding to a real object, since RMI contains only weak references. If you do not, you will receive "Object not in table" errors from RMI.

0


source







All Articles