close

Java Remote Method Invocation

Gå til navigasjon Gå til søk

RMI ( Java Remote Method Invocation ) er en mekanisme som tilbys av Java for å påkalle en metode eksternt. Det er en del av standard Java runtime-miljø og gir en enkel mekanisme for serverkommunikasjon i distribuerte Java-bare applikasjoner. Hvis kommunikasjon mellom andre teknologier er nødvendig, bør CORBA eller SOAP brukes i stedet for RMI.

RMI er preget av sin brukervennlighet i programmering da den er spesielt utviklet for Java; gir objektoverføring ved referanse (ikke tillatt av SOAP), distribuert søppelinnsamling (Distributed Garbage Collector) og vilkårlig type overføring (funksjonalitet leveres ikke av CORBA).

Gjennom RMI kan et Java-program eksportere et objekt , noe som gjør objektet tilgjengelig over nettverket og programmet venter på forespørsler på en TCP-port . Deretter kan en klient koble til og påkalle metodene gitt av objektet.

Påkallelsen består av følgende trinn:

  • Parameter rangering (ved hjelp av Javas serialiseringsfunksjonalitet ).
  • Påkalling av metoden (av klienten på serveren). Den som ringer venter på svar.
  • Ved fullføring av kjøringen serialiserer serveren returverdien (hvis noen) og sender den til klienten.
  • Klientkoden mottar svaret og fortsetter som om påkallingen hadde vært lokal.

Kontekst

Siden JDK versjon 1.1 har Java sin egen ORB : RMI (Remote Method Invocation). Selv om RMI er en ORB i generell forstand, er det ikke en CORBA-kompatibel modell. RMI er innfødt til Java, det vil si at det er en utvidelse til kjernespråket. RMI er helt avhengig av kjernen i Java Object Serialization, samt implementering av både portabilitet og mekanismer for lasting og lossing av objekter på andre systemer, etc.

Bruken av RMI er veldig naturlig for enhver Java-programmerer siden han ikke trenger å lære en ny teknologi helt forskjellig fra den han skal utvikle seg med. Imidlertid har RMI noen begrensninger på grunn av sin tette integrasjon med Java, den viktigste er at denne teknologien ikke tillater interaksjon med applikasjoner skrevet på et annet språk.

RMI, som en utvidelse av Java, er en programmeringsteknologi utviklet for å løse problemer ved å skrive og organisere kjørbar kode. Dermed utgjør RMI et spesifikt punkt i rommet for programmeringsteknologi sammen med C, C++, Smalltalk, etc.

Hovedforskjellen mellom å bruke RPC og RMI er at RMI er en mekanisme for ekstern prosedyreanrop basert på Java-programmeringsspråket som støtter interaksjon mellom objekter, mens RPC ikke støtter denne funksjonen.

Arkitektur

RMI-arkitekturen kan sees på som en firelagsmodell.

Første lag

Det første laget er applikasjonslaget og tilsvarer den faktiske implementeringen av klient- og serverapplikasjonene. Anrop på høyt nivå for å få tilgang til og eksportere eksterne objekter finner sted her. Enhver applikasjon som ønsker at metodene skal være tilgjengelige for tilgang for eksterne klienter, må deklarere disse metodene i et grensesnitt som utvider java.rmi.Remote. Et slikt grensesnitt brukes i utgangspunktet til å "merke" et objekt som eksternt tilgjengelig. Når metodene er implementert, må objektet eksporteres. Dette kan gjøres implisitt hvis objektet utvider UnicastRemoteObject-klassen (java.rmi.server-pakken), eller det kan gjøres eksplisitt ved å kalle opp exportObject()-metoden til samme pakke.

Andre lag

Lag 2 er proxy-laget, eller stubbeskjelettlaget. Dette laget er det som samhandler direkte med applikasjonslaget. Alle anrop til eksterne objekter og handlinger sammen med deres parametere og returobjekter finner sted i dette laget.

Tredje lag

Lag 3 er det eksterne referanselaget, og er ansvarlig for å håndtere den semantiske delen av eksterne påkallinger. Den er også ansvarlig for å administrere objektreplikering og utføre implementeringsspesifikke oppgaver med eksterne objekter, for eksempel å etablere semantisk utholdenhet og riktige strategier for å gjenopprette fra tapte tilkoblinger. I dette laget forventes det en strømorientert forbindelse fra transportlaget.

Fjerde lag

Lag 4 er transportlaget. Den er ansvarlig for å lage nødvendige tilkoblinger og administrere transporten av data fra en maskin til en annen. Den underliggende transportprotokollen for RMI er Java Remote Method Protocol (JRMP), som bare "forstås" av Java-programmer.

Elementer

Hver RMI-applikasjon deles vanligvis inn i 2 deler:

  • En server, som lager noen eksterne objekter, lager referanser for å gjøre dem tilgjengelige, og venter på at klienten skal påkalle dem.
  • En klient, som henter en referanse til eksterne objekter på serveren, og påkaller dem.

Eksempel

En RMI-server består av å definere et eksternt objekt som skal brukes av klienter. For å lage et eksternt objekt, er et grensesnitt definert , og det eksterne objektet vil være en klasse som implementerer det grensesnittet. La oss se hvordan du lager en eksempelserver i 3 trinn:

  • Definer det eksterne grensesnittet. Når et eksternt grensesnitt opprettes:
    • Grensesnittet må være offentlig.
    • Den må arve fra java.rmi.Remote-grensesnittet, for å indikere at den kan kalles fra hvilken som helst virtuell Java-maskin.
    • Hver ekstern metode må kaste java.rmi.RemoteException-unntaket i sin throws-klausul, i tillegg til eventuelle unntak den kan håndtere.
offentlig  grensesnitt  MyRemoteInterface  utvider  java . rmi . Remote 
{ 
  public  void  myMethod1 ()  kaster  java . rmi . RemoteException ; 
  public  int  myMethod2 ()  kaster  java . rmi . RemoteException ; 
}
  • Implementer det eksterne grensesnittet
public  class  MyRemoteClass  
 utvider  java . rmi . server . UnicastRemoteObject  
 implementerer  MyRemoteInterface 
{ 
 public  MyRemoteClass ()  kaster  java . rmi . RemoteException 
 { 
   super ();  //Kall konstruktøren til basisklassen (UnicastRemoteObject) 
   // Konstruktørkode 
 }
 
 public  void  myMethod1 ()  kaster  java . rmi . RemoteException 
 { 
   // Her legger vi koden vi ønsker 
   System . ut . println ( "Jeg er i minMethod1()" ); 
 }

 public  int  myMethod2 ()  kaster  java . rmi . RemoteException 
 { 
   return  5 ;  // Her legger vi koden vi vil ha 
 }

 public  void  otherMethod () 
 { 
   // Hvis vi definerer en annen metode, kan den ikke kalles 
   // eksternt siden den ikke er fra det eksterne grensesnittet 
 }
 
 public  static  void  main ( String []  args ) 
 { 
   try 
   { 
     MyRemoteInterface  mir  =  new  MyRemoteClass (); 
     java . rmi . Navngivning . rebind ( "rmi://"  +  java . net . InetAddress . getLocalHost (). getHostAddress ()  + 
                             ":"  +  args [ 0 ]  +  "/TestRMI" ,  mir ); 
   } 
   catch  ( Unntak  e ) 
   { 
     e . printStackTrace (); 
   } 
 } 
}
  • Som du kan se, implementerer MyRemoteClass-klassen MyRemoteInterface-grensesnittet som vi tidligere har definert. Dessuten arver den fra UnicastRemoteObject, som er en Java-klasse som vi kan bruke som en superklasse for å implementere eksterne objekter.
  • Deretter, inne i klassen, definerer vi en konstruktør (som kaster RemoteException-unntaket fordi det også kastes av UnicastRemoteObject-superklassen), og metodene til grensesnittet(e) den implementerer.
  • Til slutt, i hovedmetoden, definerer vi koden for å lage det eksterne objektet som vi ønsker å dele og gjøre det eksterne objektet synlig for klienter, ved å bruke Naming-klassen og dens rebind(...)-metode.

Merk: Vi har plassert main()-metoden i samme klasse for enkelhets skyld. En egen klasse kan defineres som ansvarlig for registrering av det eksterne objektet.

  • Kompiler og kjør serveren

Vi har allerede serveren definert. Nå må vi kompilere klassene dine ved å bruke følgende trinn:

    • Vi kompilerer det eksterne grensesnittet. I tillegg grupperer vi den i en JAR-fil for å holde den til stede både på klienten og på serveren:
javac MyRemoteInterface.java
jar cvf objRemotes.jar MyRemoteInterface.class
    • Deretter kompilerer vi klassene som implementerer grensesnittene. Og for hver av dem genererer vi Stub- og Skeleton-filene for å opprettholde referansen til det eksterne objektet, ved å bruke rmic-kommandoen:
sett CLASSPATH=%CLASSPATH%;.\Remoteobj.jar;.
javac MyRemoteClass.java
rmic -d. MyRemoteClass

Vi kan se i arbeidskatalogen vår at to .class-filer er automatisk generert (MiClaseRemota_Skel.class og MiClaseRemota_Stub.class) som tilsvarer stub-skjelettlaget til RMI-arkitekturen.

  • For å kjøre serveren følger vi disse trinnene:
    • RMI-logging startes for å tillate logging og søking av eksterne objekter. Registeret er ansvarlig for å administrere et sett med eksterne objekter som skal deles, og lete etter dem når klienter ber om det. Den kjører med rmiregistry-applikasjonen distribuert med Java, som vi eventuelt kan sende porten for å koble til (som standard, 1099).

Når det gjelder Windows, må det utføres:

start rmiregistry 1234

Og når det gjelder Linux:

rmiregistry &
    • Til slutt startes serveren:
java -Djava.rmi.server.hostname=127.0.0.1 MyRemoteClass 1234
  • Opprett en RMI-klient

Vi skal nå definere en klient som vil få tilgang til de eksterne objektene vi oppretter. For dette følger vi følgende trinn:

    • Definer klassen for å få de nødvendige eksterne objektene

Følgende klasse får et objekt av typen MyRemoteInterface, implementert på serveren vår:

offentlig  klasse  MyRMIClient 
{

 privat  MyRMIClient (){}; 

 public  static  void  main ( String []  args ) 
 { 
   prøv 
   { 
     MyRemoteInterface  mir  =  ( MyRemoteInterface ) java . rmi . Navngivning . oppslag ( "rmi://"  +  
                             args [ 0 ]  +  ":"  +  args [ 1 ]  +  "/RMITest" );
     
     // Skriv ut myMethod1() så mange ganger som minMethod2() returnerer 
     for  ( int  i = 1 ; i <= myr . myMethod2 (); i ++ )  
         myr . minMethod1 (); 
   } 
   catch  ( Unntak  e ) 
   { 
     e . printStackTrace (); 
   } 
 } 
}

Som du kan se, består det ganske enkelt av å lete etter det eksterne objektet i RMI-registeret til den eksterne maskinen. For å gjøre dette bruker vi Naming-klassen og dens oppslagsmetode (...).

    • Kompiler og kjør klienten

Når vi allerede har definert klienten, gjør vi for å kompilere den:

sett CLASSPATH=%CLASSPATH%;.\Remoteobj.jar;.
javac MyRMIClient.java

Deretter, for å kjøre klienten, gjør vi:

java MyClientRMI 127.0.0.1 1234

Den eksterne klassens stubbefil må være tilgjengelig. For å gjøre dette, kopierer vi den enten til klienten og inkluderer den i CLASSPATH, eller fjerner den fra serverens CLASSPATH og inkluderer banen i serverens java.rmi.codebase (hvis den ikke fjernes fra serverens CLASSPATH, alternativet java. rmi.codebase, og klienten vil ikke kunne få tilgang til stubben.) Hvis vi ser på vinduet der RMI-serveren kjører, vil vi se hvordan det eksterne objektet er funnet og dets metoder er utført:

Se også

Eksterne lenker