close

Java Remote Method Anrop

Gå till navigering Gå till sök

RMI ( Java Remote Method Invocation ) är en mekanism som erbjuds av Java för att anropa en metod på distans. Det är en del av standard Java-runtime-miljön och tillhandahåller en enkel mekanism för serverkommunikation i distribuerade Java-bara applikationer. Om kommunikation mellan andra teknologier krävs ska CORBA eller SOAP användas istället för RMI.

RMI kännetecknas av att det är lätt att använda i programmering eftersom det är speciellt utformat för Java; tillhandahåller objekt som passerar genom referens (inte tillåtet av SOAP), distribuerad sophämtning (Distributed Garbage Collector) och godtycklig typöverföring (funktionalitet tillhandahålls inte av CORBA).

Genom RMI kan ett Java-program exportera ett objekt , vilket gör objektet tillgängligt över nätverket och programmet väntar på förfrågningar på en TCP-port . Därefter kan en klient ansluta och anropa metoderna som tillhandahålls av objektet.

Anropet består av följande steg:

  • Parameterrangering (med Javas serialiseringsfunktion ).
  • Anropa metoden (av klienten på servern). Den som ringer väntar på svar.
  • När exekveringen är klar, serialiserar servern returvärdet (om något finns) och skickar det till klienten.
  • Klientkoden tar emot svaret och fortsätter som om anropet hade varit lokalt.

Sammanhang

Sedan JDK version 1.1 har Java sin egen ORB : RMI (Remote Method Invocation). Även om RMI är en ORB i allmän mening, är det inte en CORBA-kompatibel modell. RMI är inbyggt i Java, det vill säga det är en förlängning av kärnspråket. RMI förlitar sig helt och hållet på kärnan av Java Object Serialization, såväl som implementering av både portabilitet och mekanismer för att ladda och lossa objekt på andra system, etc.

Användningen av RMI är mycket naturligt för alla Java-programmerare eftersom han inte behöver lära sig en helt annan teknik än den han kommer att utveckla med. RMI har dock vissa begränsningar på grund av dess täta integration med Java, den viktigaste är att denna teknik inte tillåter interaktion med applikationer skrivna på ett annat språk.

RMI, som en förlängning av Java, är en programmeringsteknik designad för att lösa problem genom att skriva och organisera körbar kod. Således utgör RMI en specifik punkt i utrymmet för programmeringsteknologier tillsammans med C, C++, Smalltalk, etc.

Huvudskillnaden mellan att använda RPC och RMI är att RMI är en mekanism för fjärrproceduranrop baserad på Java-programmeringsspråket som stöder interaktion mellan objekt, medan RPC inte stöder denna funktion.

Arkitektur

RMI-arkitekturen kan ses som en modell i fyra nivåer.

Första lagret

Det första lagret är applikationslagret och motsvarar den faktiska implementeringen av klient- och serverapplikationerna. Anrop på hög nivå för att komma åt och exportera fjärrobjekt sker här. Alla program som vill att dess metoder ska vara tillgängliga för åtkomst av fjärrklienter måste deklarera dessa metoder i ett gränssnitt som utökar java.rmi.Remote. Ett sådant gränssnitt används i princip för att "markera" ett objekt som fjärråtkomligt. När metoderna har implementerats måste objektet exporteras. Detta kan göras implicit om objektet utökar UnicastRemoteObject-klassen (java.rmi.server-paketet), eller så kan det göras explicit genom att anropa exportObject()-metoden för samma paket.

Andra lagret

Lager 2 är proxyskiktet, eller stubskelettskiktet. Detta lager är det som direkt interagerar med applikationslagret. Alla anrop till fjärrobjekt och åtgärder tillsammans med deras parametrar och returobjekt sker i detta lager.

Tredje lagret

Lager 3 är fjärrreferensskiktet och ansvarar för att hantera den semantiska delen av fjärranrop. Det är också ansvarigt för att hantera objektreplikering och utföra implementeringsspecifika uppgifter med fjärrobjekt, som att etablera semantisk beständighet och korrekta strategier för att återhämta sig från förlorade anslutningar. I detta skikt förväntas en strömorienterad förbindelse från transportskiktet.

Fjärde lagret

Skikt 4 är transportskiktet. Den ansvarar för att göra nödvändiga anslutningar och hantera transporten av data från en maskin till en annan. Det underliggande transportprotokollet för RMI är Java Remote Method Protocol (JRMP), som bara "förstås" av Java-program.

Element

Varje RMI-applikation delas normalt upp i två delar:

  • En server som skapar några fjärrobjekt, skapar referenser för att göra dem tillgängliga och väntar på att klienten ska anropa dem.
  • En klient som hämtar en referens till fjärrobjekt på servern och anropar dem.

Exempel

En RMI-server består av att definiera ett fjärrobjekt som ska användas av klienter. För att skapa ett fjärrobjekt definieras ett gränssnitt och fjärrobjektet kommer att vara en klass som implementerar det gränssnittet. Låt oss se hur man skapar en exempelserver i tre steg:

  • Definiera fjärrgränssnittet. När ett fjärrgränssnitt skapas:
    • Gränssnittet måste vara offentligt.
    • Den måste ärva från java.rmi.Remote-gränssnittet för att indikera att den kan anropas från vilken virtuell Java-maskin som helst.
    • Varje fjärrmetod måste kasta java.rmi.RemoteException-undantaget i sin throws-sats, utöver alla undantag som den kan hantera.
offentligt  gränssnitt  MyRemoteInterface  utökar  java . rmi . Remote 
{ 
  public  void  myMethod1 ()  kastar  java . rmi . RemoteException ; 
  public  int  myMethod2 ()  kastar  java . rmi . RemoteException ; 
}
  • Implementera fjärrgränssnittet
public  class  MyRemoteClass  
 utökar  java . rmi . server . UnicastRemoteObject  
 implementerar  MyRemoteInterface 
{ 
 public  MyRemoteClass ()  kastar  java . rmi . RemoteException 
 { 
   super ();  //Anropa konstruktorn för basklassen (UnicastRemoteObject) 
   // Konstruktorkod 
 }
 
 public  void  myMethod1 ()  kastar  java . rmi . RemoteException 
 { 
   // Här lägger vi koden vi vill ha 
   System . ut . println ( "Jag är i minMethod1()" ); 
 }

 public  int  myMethod2 ()  kastar  java . rmi . RemoteException 
 { 
   return  5 ;  // Här lägger vi koden vi vill ha 
 }

 public  void  otherMethod () 
 { 
   // Om vi ​​definierar en annan metod kan den inte anropas 
   // på distans eftersom den inte kommer från fjärrgränssnittet 
 }
 
 public  static  void  main ( String []  args ) 
 { 
   try 
   { 
     MyRemoteInterface  mir  =  new  MyRemoteClass (); 
     java . rmi . Namngivning . rebind ( "rmi://"  +  java . net . InetAddress . getLocalHost (). getHostAddress ()  + 
                             ":"  +  args [ 0 ]  +  "/TestRMI" ,  mir ); 
   } 
   catch  ( Undantag  e ) 
   { 
     e . printStackTrace (); 
   } 
 } 
}
  • Som du kan se implementerar MyRemoteClass-klassen MyRemoteInterface-gränssnittet som vi tidigare har definierat. Den ärver också från UnicastRemoteObject, som är en Java-klass som vi kan använda som en superklass för att implementera fjärrobjekt.
  • Sedan, inuti klassen, definierar vi en konstruktor (som kastar RemoteException-undantaget eftersom det också kastas av superklassen UnicastRemoteObject), och metoderna för gränssnittet/gränssnitten som den implementerar.
  • Slutligen, i huvudmetoden, definierar vi koden för att skapa fjärrobjektet som vi vill dela och göra fjärrobjektet synligt för klienter, med hjälp av klassen Naming och dess rebind(...)-metod.

Obs: Vi har lagt in metoden main() i samma klass för enkelhets skull. En separat klass skulle kunna definieras som ansvarig för registrering av fjärrobjektet.

  • Kompilera och kör servern

Vi har redan definierat servern. Nu måste vi sammanställa dina klasser med följande steg:

    • Vi kompilerar fjärrgränssnittet. Dessutom grupperar vi den i en JAR-fil för att hålla den närvarande både på klienten och på servern:
javac MyRemoteInterface.java
jar cvf objRemotes.jar MyRemoteInterface.class
    • Därefter kompilerar vi klasserna som implementerar gränssnitten. Och för var och en av dem genererar vi Stub- och Skeleton-filerna för att upprätthålla referensen till fjärrobjektet, med hjälp av kommandot rmic:
set CLASSPATH=%CLASSPATH%;.\Remoteobj.jar;.
javac MyRemoteClass.java
rmic -d. MyRemoteClass

Vi kan se i vår arbetskatalog att två .class-filer har genererats automatiskt (MiClaseRemota_Skel.class och MiClaseRemota_Stub.class) motsvarande stub-skelettlagret i RMI-arkitekturen.

  • För att köra servern följer vi dessa steg:
    • RMI-loggning startas för att möjliggöra loggning och sökning av fjärrobjekt. Registret ansvarar för att hantera en uppsättning fjärrobjekt som ska delas och leta efter dem när kunderna begär det. Den körs med rmiregistry-applikationen distribuerad med Java, till vilken vi valfritt kan skicka porten att ansluta till (som standard, 1099).

I fallet med Windows måste det köras:

starta rmiregistry 1234

Och i fallet med Linux:

rmiregistry &
    • Slutligen startas servern:
java -Djava.rmi.server.hostname=127.0.0.1 MyRemoteClass 1234
  • Skapa en RMI-klient

Vi kommer nu att definiera en klient som kommer åt det eller de fjärrobjekt vi skapar. För detta följer vi följande steg:

    • Definiera klassen för att få de nödvändiga fjärrobjekten

Följande klass får ett objekt av typen MyRemoteInterface, implementerat på vår server:

offentlig  klass  MyRMIClient 
{

 privat  MyRMIClient (){}; 

 public  static  void  main ( String []  args ) 
 { 
   try 
   { 
     MyRemoteInterface  mir  =  ( MyRemoteInterface ) java . rmi . Namngivning . lookup ( "rmi://"  +  
                             args [ 0 ]  +  ":"  +  args [ 1 ]  +  "/RMITest" );
     
     // Skriv ut myMethod1() så många gånger som myMethod2() returnerar 
     för  ( int  i = 1 ; i <= myr . myMethod2 (); i ++ )  
         myr . myMethod1 (); 
   } 
   catch  ( Undantag  e ) 
   { 
     e . printStackTrace (); 
   } 
 } 
}

Som du kan se består det helt enkelt av att leta efter fjärrobjektet i fjärrmaskinens RMI-register. För att göra detta använder vi klassen Naming och dess lookup(...)-metod.

    • Kompilera och kör klienten

När vi redan har definierat klienten gör vi för att kompilera den:

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

Sedan, för att köra klienten, gör vi:

java MyClientRMI 127.0.0.1 1234

Fjärrklassens stubbfil måste vara tillgänglig. För att göra detta kopierar vi den antingen till klienten och inkluderar den i dess CLASSPATH, eller tar bort den från serverns CLASSPATH och inkluderar dess sökväg i serverns java.rmi.codebase (om den inte tas bort från serverns CLASSPATH, alternativet java. rmi.codebase, och klienten kommer inte att kunna komma åt stubben). Om vi ​​tittar på fönstret där RMI-servern körs kommer vi att se hur fjärrobjektet har hittats och dess metoder har exekveras:

Se även

Externa länkar