Newsgroup: it.comp.java
Titolo: problemi con RMI

sto provando l'RMI scrivendo un'esempio dal libro "Distributed Programming
with Java" di Qusay Mahmoud
l'applicazione è un client che richiede al server la somma di due array e
riceve il risultato
// -------------- server
public interface Arith extends java.rmi.Remote {
  int[] add(int a[], int b[]) throws java.rmi.RemoteException;
}
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.net.*;
import java.net.UnknownHostException;
/**
 * Create a single, non-replicated, remote object
 */
public class ArithImpl extends UnicastRemoteObject implements Arith{
  private String objectName;
  private static String serviceURL; // Keep the service URL for the closing
method.
  public ArithImpl(String s) throws RemoteException {
    super();
    objectName = s;
  }
  public int[] add(int a[], int b[]) {
    int c[] = new int[10];
    for (int i = 0; i < 10; i++) {
      c[i] = a[i] + b[i];
    }
    return c;
  }
  public static void main(String[] args) {
    RMISecurityManager sm = new RMISecurityManager();
    System.setSecurityManager(sm);
    try {
      ArithImpl obj = new ArithImpl("ArithServer");
      InetAddress addr = null;
      try {
        addr = InetAddress.getLocalHost();
      }
      catch (UnknownHostException ex2) {
        ex2.printStackTrace();
      }
      String localHost = addr.getHostName();
      serviceURL = "//" + localHost + "/ArithServer";
      try {
        Naming.rebind(serviceURL, obj);
        System.out.println("Binded at: " + serviceURL);
      }
      catch (RemoteException ex1) {
      }
      catch (MalformedURLException ex1) {
      }
      System.out.println("ArithServer bound in registry");
    }
    catch (RemoteException ex) {
      System.out.println("Remote error: "+ex);
    }
  }
}
// ----------------------------- client
import java.rmi.*;
import java.net.*;
public class ArithClient {
  static int a[] = {1,2,3,4,5,6,7,8,9,10};
  static int b[] = {1,2,3,4,5,6,7,8,9,10};
  static int result[] = new int[10];
  public static void main(String[] args) {
    try {
      String hostName = "localhost";
      String serverName = "//" + hostName + "/ArithServer";
      Arith obj = (Arith) Naming.lookup(serverName);
      result = obj.add(a,b);
    }
    catch (RemoteException ex) {
      System.out.println("Remote error: "+ex);
    }
    catch (MalformedURLException ex) {
      System.out.println("Malformed error: "+ex);
    }
    catch (NotBoundException ex) {
      System.out.println("RMI not bound: "+ex); // <-- genera questa
eccezione
    }
  }
}
- compilo i file
- eseguo rmic dalla directory in cui ci sono i file .class
c:\jbuilderx\jdk1.4\bin\rmic ArithImpl
vengono creati i due file: ArithImpl_Skel.class e ArithImpl_Stub.class
- eseguo rmiregistry
- lancio il server  // ok   scrive "ArithServer bound in registry"
- lancio il client // eccezione
RMI not bound: java.rmi.NotBoundException: ArithServer
come mai?
PS: c'è un'esempio nella directory samples di JBuilder che funziona!!!
(è un'esempio su DataSet)
ho provato a usare le stesse impostazioni ma niente
1) come prima cosa mi generava un'eccezione il SecurityManager, allora
guardando
il file di esempio ho messo questa stringa nei parametri della VM:
-Djava.security.policy=file:C:/JBuilderX/samples/DataExpress/StreamableDataS
ets/SampleRMI.policy
in questo file c'è:
grant {
 // allows anyone to listen on un-privileged ports
 permission java.net.SocketPermission "*:1024-65535",
"listen,accept,connect";
};
come mai il libro non ne faceva menzione!?
(comunque l'esempio usa questo parametro ma non chiama mai la classe
RMISecurityManager...)
2) siccome non funzionava ho aggiunto alla VM anche questa riga (sempre
dall'esempio)
-Djava.rmi.server.codebase="file:C:/Documents and
Settings/Hannibal/jbproject/ProvaRMI/classes/ file:C:/JBuilderX/lib/dx.jar"
ma a che serve? bo
3) Infine ho provato a cambiare tutti i nomi, ma non ho ben capito:
nel server uso questa stringa:
        InetAddress addr = InetAddress.getLocalHost();
        String localHost = addr.getHostName();
        serviceURL = "//" + localHost + "/ArithServer";
alla fine serviceURL è: //Nebula/ArithServer  cioè ci mette il nome del mio
computer
nel client invece c'è
    String hostName = "localhost";
    String serverName = "//" + hostName + "/ArithServer";
    Arith obj = (Arith) Naming.lookup(serverName);
inutile dire che ho provato tutte le configurazioni!!!
nell'esempio di JBuilder funziona con queste impostazioni, mentre nel mio
caso
genera l'eccezione
Infine, uff, un'ultima domanda.
E' ovvio che il server fa il bind ma poi esce! come diavolo fa il client, se
il
Thread del server non esiste??? nel libro c'è scritto proprio così
Ovvio che nell'esempio il server è un JFrame e rimane in attesa...
allora ho provato a creare il server derivando da Thread e
"mantenendolo" in vita con un ciclo
run {
 while (true)
  sleep(1000)
}
ma non funziona nemmeno così!
scusate la lunghezza ma i dubbi sono tanti
PPS: grazie se mi rispondete (e siete riusciti a leggere tutto), a me sembra
arabo ma magari una volta capito il meccanismo non è poi cos'ì incasinato

ok, dopo aver perso un pomeriggio con il tutorial della sun su RMI e non
averci cavato un ragno dal buco, ho scoperto che c'è una semplicisssima
applicazione (SimpleRMI) con jbuilder che funziona e fa proprio al caso
mio!!!
(meglio tardi che mai...)