Java Remote Method Invocation
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
- Enkelt RMI-eksempel
- Java RMI-veiledning Opplæring fra Sun Microsystems (på engelsk)
- Trail: RMI Java RMI Offisiell dokumentasjon
- En oversikt over RMI-applikasjoner Offisiell introduksjon til Java RMI-applikasjoner