Invocazione del metodo remoto Java - Java remote method invocation

Image
Un tipico modello di implementazione di Java-RMI che utilizza oggetti stub e scheletro . Java 2 SDK, Standard Edition, v1.2 ha eliminato la necessità di uno scheletro.

In informatica , Java Remote Method Invocation ( Java RMI ) è un'API Java che esegue l'invocazione di metodi remoti , l'equivalente orientato agli oggetti delle chiamate di procedura remota (RPC), con supporto per il trasferimento diretto di classi Java serializzate e raccolta di rifiuti distribuita .

L'implementazione originale dipende dai meccanismi di rappresentazione della classe Java Virtual Machine (JVM) e quindi supporta solo l'esecuzione di chiamate da una JVM all'altra. Il protocollo alla base di questa implementazione solo Java è noto come Java Remote Method Protocol (JRMP). Per supportare il codice in esecuzione in un contesto non JVM, i programmatori hanno successivamente sviluppato una versione CORBA .

L'uso del termine RMI può denotare esclusivamente l'interfaccia di programmazione o può significare sia l'API che JRMP, IIOP o un'altra implementazione, mentre il termine RMI-IIOP (leggi: RMI su IIOP ) denota specificamente l'interfaccia RMI che delega la maggior parte delle funzionalità a il supporto all'implementazione di CORBA .

L'idea di base di Java RMI, il protocollo DGC (Distributed Garbage Collection) e gran parte dell'architettura alla base dell'implementazione originale di Sun, derivano dalla funzionalità degli "oggetti di rete" di Modula-3 .

Codice generalizzato

I programmatori dell'API RMI originale hanno in qualche modo generalizzato il codice per supportare diverse implementazioni, come un trasporto HTTP . Inoltre, è stata aggiunta a CORBA la possibilità di passare argomenti " per valore " per essere compatibile con l'interfaccia RMI. Tuttavia, le implementazioni RMI-IIOP e JRMP non hanno interfacce completamente identiche.

La funzionalità RMI è inclusa nel pacchetto java.rmi, mentre la maggior parte dell'implementazione di Sun si trova nel sun.rmipacchetto. Si noti che con le versioni Java precedenti a Java 5.0 gli sviluppatori dovevano compilare gli stub RMI in un passaggio di compilazione separato utilizzando rmic. La versione 5.0 di Java e successive non richiede più questo passaggio.

Versione Jini

Jini offre una versione più avanzata di RMI in Java. Funziona in modo simile ma fornisce sicurezza più avanzata, capacità di individuazione degli oggetti e altri meccanismi per applicazioni di oggetti distribuiti.

Esempio

Le classi seguenti implementano un semplice programma client-server utilizzando RMI che visualizza un messaggio.

RmiServerclass — ascolta le richieste RMI e implementa l'interfaccia utilizzata dal client per invocare metodi remoti.

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.*;

public class RmiServer extends UnicastRemoteObject implements RmiServerIntf {
    public static final String MESSAGE = "Hello World";

    public RmiServer() throws RemoteException {
        super(0); // required to avoid the 'rmic' step, see below
    }

    public String getMessage() {
        return MESSAGE;
    }

    public static void main(String args[]) throws Exception {
        System.out.println("RMI server started");

        try { //special exception handler for registry creation
            LocateRegistry.createRegistry(1099);
            System.out.println("java RMI registry created.");
        } catch (RemoteException e) {
            //do nothing, error means registry already exists
            System.out.println("java RMI registry already exists.");
        }
           
        //Instantiate RmiServer
        RmiServer server = new RmiServer();

        // Bind this object instance to the name "RmiServer"
        Naming.rebind("//localhost/RmiServer", server);
        System.out.println("PeerServer bound in registry");
    }
}

RmiServerIntfinterfaccia : definisce l'interfaccia utilizzata dal client e implementata dal server.

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RmiServerIntf extends Remote {
    String getMessage() throws RemoteException;
}

RmiClientclass — questo è il client che ottiene il riferimento (un proxy) all'oggetto remoto che vive sul server e invoca il suo metodo per ottenere un messaggio. Se l'oggetto server implementasse java.io.Serializable invece di java.rmi.Remote, verrebbe serializzato e passato al client come valore.

import java.rmi.Naming;

public class RmiClient {
    public static void main(String args[]) throws Exception {
        RmiServerIntf server = (RmiServerIntf)Naming.lookup("//localhost/RmiServer");
        System.out.println(server.getMessage());
    }
}

Prima di eseguire questo esempio, dobbiamo creare un file 'stub' per l'interfaccia che abbiamo usato. Per questo compito abbiamo il compilatore RMI - 'rmic'

  • Nota: creiamo un file stub dal file '*.class' con l'implementazione dell'interfaccia remota, non dal file '*.java'.
rmic RmiServer

Si noti che dalla versione 5.0 di J2SE è stato aggiunto il supporto per i file stub generati dinamicamente e l'rmic è fornito solo per la retrocompatibilità con i runtime precedenti o per i programmi che non forniscono un numero di porta esplicito (o zero) durante l'esportazione di oggetti remoti, che è necessario affinché gli stub generati siano possibili, come descritto in Javadoc per UnicastRemoteObject. Vedi il commento nel costruttore sopra.

Riferimenti

link esterno