views:

664

answers:

7

Hi there!

I want to share some information between two classes (A and B), which are running in different java programs. Instead of writing a whole communication protocol I want to use the java build-in rmi classes for that purpose. Currently class B is able to run a method which belongs to class A remotely. Is it somehow possible to use the same "connection" within class A to call a method of class B? Otherwise I probably have to implement a second rmi service ...

BR,

Markus

A: 

How would class B know about class A without a second RMI server though? I think you are going to need two servers.

Gandalf
+2  A: 

It's been a while since I've used RMI, but IIRC if class B implements java.rmi.Remote and passes a reference to an instance of itself as a parameter to the method in class A, then class A should receive a stub and methods called on it will be called on the original instance.

However, if you have a lot of such RMI calls going back anf fro, you will probably encounter performance problems.

Michael Borgwardt
A: 

Both JVMs would need to implement RMI services. But that is really very easy look at the various classes in java.rmi.

What you can't do is somehow use one RMI connection and do two way communication.

Tom
+4  A: 

If B implements Remote, it can be export and passed as a parameter in an RMI call to A. In this scenario, there's no need to register B in an RMI registry, since the client is being passed a reference to it explicitly.

erickson
Mhhh, i think if I implement it that way there might occure some data inconsistencies between the "copied" and the "real" B, or?
Markus
No, there is no "copy". When A calls a method on B, it's really invoking a remote method call via a stub to the "real" B. It's identical to B invoking a remote method on A, except that instead of looking up the object in a registry, A received the remote object as a parameter in a method call.
erickson
+1  A: 

If you pass B as an argument to a method in A and then use that reference to call a method on B I am fairly certain that a reverse connection is established, and I am fairly certain that RMI Registry is created for the JVM where B resides. At some point this got us into a bit of trouble with particularly strict firewall rules. Our code looked a little something like

Web Server

public int uploadFile(FileItem fileItem){
    return ApplicationClassLoader
        .get(DocumentManager.class)
        .attachFile(new RemoteInputStreamImpl(fileItem.getInputStream());
    )
}

Application Server

public int attachFile(RemoteInputStream in){
    ...

    byte[] buffer;
    while((buffer = in.read(1024)) != null) // Would return null to indicate EOF
      // Do some stuff

    return documentId;       
}
Ambience
A: 

Some RMI service support callbacks or listeners which allow the server to asynchronous call the client down the same connection. (Sorry I don't remember the name of the open libraries which do this, a quick google wasn't very helpful) Standard RMI doesn't support this, instead you need to expose the client as an RMI service as well.

Peter Lawrey
A: 

RMI bidirectional:

SERVER:

import java.io.IOException; import java.rmi.Naming; import java.rmi.RemoteException; import java.util.logging.Level; import java.util.logging.Logger;

public class RMISERVER {

public RMISERVER() throws IOException {

   Thread t;
    try {
        t = new Prou_run();
        t.start();
    } catch (RemoteException ex) {
        Logger.getLogger(RMISERVER.class.getName()).log(Level.SEVERE, null, ex);
    }

}

public static void main(String args[]) throws IOException { new RMISERVER(); } }

import java.io.File; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.rmi.Naming; import java.rmi.Remote; import java.rmi.registry.Registry; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.tree.DefaultMutableTreeNode;

//extends java.rmi.server.UnicastRemoteObject

public class Prou_run extends Thread implements Runnable{

        New_Object  root = null,root2=null,root3=null,root4=null,root5;
          New_Object new_root=null;
        Object xt = null, xt2=null , xt3=null;
        Registry r1,r2;
        RMIClientSocketFactory csf,csf2;
        RMIServerSocketFactory ssf,sf2;


        new_Patryk npal;

public Prou_run() throws java.rmi.RemoteException, IOException {

     if (System.getSecurityManager() == null) {
        System.setSecurityManager(new SecurityManager());
              }

// csf = new RMIClientSocketFactory() { // // public Socket createSocket(String host, int port) throws IOException { // return new Socket("rmi://localhost/getchil",1080); // } // }; // csf2 = new RMIClientSocketFactory() { // // public Socket createSocket(String host, int port) throws IOException { // return new Socket("rmi://localhost/getchild",1081); // } // }; // ssf=new RMIServerSocketFactory() { // // public ServerSocket createServerSocket(int port) throws IOException { // return new ServerSocket(1099); // } // };// ssf.createServerSocket(1099); // sf2=new RMIServerSocketFactory() { // // public ServerSocket createServerSocket(int port) throws IOException { // return new ServerSocket(1098); // } // };//sf2.createServerSocket(1098); //

   try {
     r1=java.rmi.registry.LocateRegistry.createRegistry(1098);
             r2=java.rmi.registry.LocateRegistry.createRegistry(1099);//, csf2, ssf);
             java.rmi.registry.LocateRegistry.createRegistry(1097);
             java.rmi.registry.LocateRegistry.createRegistry(1095);
             java.rmi.registry.LocateRegistry.createRegistry(1096);
     System.out.println("RMI registry ready.");
  } catch (Exception e) {
     System.out.println("Exception starting RMI registry:");
     e.printStackTrace();
  }



    this.xt = null;this.xt2 = null;this.xt3 = null;
    npal = new new_Patryk();
    System.out.println("sdmmmfxxxxxxxx");

}

public void run() {

//while(true){

  try{

// root = new_root; // xt=npal.getChild((File)new_root.getob(), (int)new_root.geti()); New_ObjectIMPL sl = new New_ObjectIMPL(); sl.i=354; System.out.println("sdmmmf2"); //r2 Naming.rebind("rmi://localhost:1099/getchild",(New_Object) sl); System.out.println("sdmmmf3");

     }catch (Exception e) {
   System.out.println("Trouble: " + e);
 }

    while(new_root==null){
        try{
             //System.out.println("sdmmmf1"   +   new_root.geti());
     new_root = (New_Object) Naming.lookup("rmi://localhost:1080/getchil");
     System.out.println("sdmmmf1"   +   new_root.geti());
        }catch (Exception e) {
   System.out.println("Trouble: " + e);
 }
    }







}

}

/** * * @author austinchuma */ public interface New_Object extends java.rmi.Remote {

 public int geti() throws java.rmi.RemoteException;

 public Object getob() throws java.rmi.RemoteException;

 public Object getobchild() throws java.rmi.RemoteException;

  public boolean getbbol() throws java.rmi.RemoteException;

   public byte[] getb() throws java.rmi.RemoteException;

}

public class New_ObjectIMPL extends java.rmi.server.UnicastRemoteObject implements New_Object

{ Object ob = null,obchild = null; int i=0; boolean bol = false; byte[] b = null;

public New_ObjectIMPL() throws RemoteException{
    ob = null;obchild = null;
    i=0;
    bol = false;
    b = null;
}

public int geti() throws RemoteException {
   return i;
       }

public Object getob() throws RemoteException {

   return ob;
}

public Object getobchild() throws RemoteException {
   return obchild;
}

public boolean getbbol() throws RemoteException {
  return bol;
}

public byte[] getb() throws RemoteException {

    return b;

}

}

Austin Chukwuma