Alt om Java RMI-registret og hvordan du bruker det

Alt om Java RMI-registret og hvordan du bruker det / programmering

RMI står for ekstern metode påkalling og, som navnet antyder, er en protokoll for et Java-program for å påberope en metode for et objekt som kjører på en annen datamaskin. Det gir en API Hva er APIer, og hvordan er åpne APIer som endrer Internett Hva er APIer, og hvordan er åpne APIer som endrer Internett Har du noen gang lurt på hvordan programmer på datamaskinen din og nettstedene du besøker, snakker med hverandre? Les mer (Application Programming Interface) for å eksportere en gjenstand fra ett program (kalt serveren) og påberope metodene til objektet fra et annet program (kalt klienten), muligens kjører på en annen datamaskin.

Java RMI Registry er en nøkkelkomponent i Java RMI-systemet og gir en sentralisert katalog for servere å registrere tjenester og for kunder å lete opp disse tjenestene. I denne artikkelen lærer vi hvordan du implementerer en server for å avsløre et objekt og en klient for å påberope en metode på serveren, samt å registrere og se opp tjenesten i RMI-registret.

Deklarerer servergrensesnittet

For å lære om vanskelighetene med hvordan Java RMI-systemet fungerer, la oss implementere et enkelt serverobjekt som gir en metode for å akseptere et navn og returnere en hilsen. Her er definisjonen av objektgrensesnittet:

importer java.rmi.Remote; importer java.rmi.RemoteException; Offentlig grensesnitt Hilsen utvider Remote Public String greet (String Name) kaster RemoteException;  

Navnet på grensesnittet kalles Hilsen. Det gir en enkelt metode som kalles hilse på() som aksepterer et navn og returnerer en passende hilsen.

For å markere dette grensesnittet som eksporterbart, må det utvides java.rmi.Remote grensesnitt. Også metoden må deklarere a kaster klausul notering java.rmi.RemoteException i tillegg til eventuelle programspesifikasjoner unntatt Java unntak: håndterer du dem riktig? Java unntak: Håndterer du dem riktig? En unntak i programmering betyr en eksepsjonell tilstand i programgjennomføringen. Den brukes når tilstanden kan håndteres bedre andre steder. Vurder følgende eksempler på håndtering av Java-unntak. Les mer . Dette er slik at klientkoden kan håndtere (eller forplante) eksterne metodeinnkallingsfeil som vert-ikke-funnet, forbindelsesfeil, etc.

Implementere serverobjektet

Etter at du har oppgitt grensesnittet (som brukes av klientene), implementerer vi serversideobjektet, og gir hilse på() metode som vist. Den bruker en enkel formatstreng til å formatere hilsen.

offentlig klasse GreetingObject implementerer hilsen private String fmtString = "Hei,% s"; offentlig strenghilsen (Stringsnavn) return String.format (this.fmtString, navn);  

Serverens hovedmetode

La oss nå samle alle disse brikkene sammen og implementere hoved() metode for serveren. La oss gå gjennom hvert av de relevante trinnene.

  • Det første trinnet er å opprette serverobjektimplementeringen.
    Hilsen hilsen = ny GreetingObject (); 
  • Deretter får vi en stub for serverobjektet fra RMI-kjøretiden. Stubben implementerer det samme grensesnittet som serverobjektet. Metoden implementerer imidlertid den nødvendige kommunikasjonen med det eksterne serverobjektet. Denne stubben brukes av klienten til å åpne fremgangsmåten på serverobjektet transparent.
    Hilsen stub = (Hilsen) UnicastRemoteObject.exportObject (hilsen, 0); 
  • Når stubben er oppnådd, overfører vi denne stuben til RMI-registeret for å binde til en spesifisert navngitt tjeneste. Når klienten ber om en implementering av denne tjenesten, mottar den stubben som vet hvordan man kommuniserer med serverobjektet.I det følgende er den statiske metoden LocateRegistry.getRegistry () brukes til å oppnå den lokale registerreferansen. De bindingen på nytt () Metoden brukes da til å binde navnet til stubben.
    Strengenavn = "Hilsen"; Registerregister = LocateRegistry.getRegistry (port); registry.rebind (navn, stub); 

Den komplette hovedmetoden.

importer java.rmi.registry.LocateRegistry; importer java.rmi.registry.Registry; importer java.rmi.server.UnicastRemoteObject; offentlig klasse Hoved static public void main (String [] args) kaster Unntak hvis (args.length == 0) System.err.println ("bruk: java Main port #"); System.exit (1);  int indeks = 0; int port = Integer.parseInt (args [index ++]); Strengenavn = "Hilsen"; Hilsen hilsen = ny GreetingObject (); Hilsen stub = (Hilsen) UnicastRemoteObject.exportObject (hilsen, 0); Registerregister = LocateRegistry.getRegistry (port); registry.rebind (navn, stub); System.out.println ("Hilsen bundet til \" "+ navn +" \ "");  

Bygger serveren

La oss nå se på å bygge serveren. For å holde ting enkelt, bygger vi ved hjelp av kommandolinjen på Linux i stedet for å bruke et byggverktøy som Maven.

Følgende kompilerer kildefilene til klassefiler i en målkatalog.

rm -rf mål mkdir mål javac -d mål src / server / *. java 

Samle klassefilene i en JAR-fil for utførelse.

jar cvf target / rmi-server.jar -C mål server 

Vi samler også grensesnittfilene som kreves for å kompilere klienten i et bibliotek JAR.

jar cvf mål / rmi-lib.jar -C mål server / Greeting.class 

Gjennomføring av klienten

La oss nå se på å implementere klienten som brukes for å påkalle serverobjektmetodene.

  • Som med serveren, få en referanse til registret, angi vertsnavnet der registeret kjører, og portnummeret.
    Registerregister = LocateRegistry.getRegistry (vert, port); 
  • Deretter ser du tjenesten i registeret. De se opp() Metoden returnerer en stub som kan brukes til å påkalle tjenester.
    Hilsen hilsen = (Hilsen) registry.lookup (navn); 
  • Og påkall metoden som passerer de nødvendige argumentene. Her får vi hilsen ved å sende navnet og skrive ut det.
    System.out.println (navn + "rapportert:" + greeting.greet (myName)); 

Den komplette klientkoden:

pakke klient; importer java.rmi.registry.LocateRegistry; importer java.rmi.registry.Registry; import server.Greeting; offentlig klasseklient static public void main (String [] args) kaster Unntak hvis (args.length! = 3) System.err.println ("bruk: java Client host port myName"); System.exit (1);  int indeks = 0; Stringsverten = args [indeks ++]; int port = Integer.parseInt (args [index ++]); String myName = args [index ++]; Strengenavn = "Hilsen"; Registerregister = LocateRegistry.getRegistry (vert, port); Hilsen hilsen = (Hilsen) registry.lookup (navn); System.out.println (navn + "rapportert:" + greeting.greet (myName));  

RMI-registeret

La oss nå kjøre serverprogrammet slik at det kan begynne å betjene forespørsler.

java -cp target / rmi-server.jar server.Main 1099 # kaster Unntak i tråden "main" java.rmi.ConnectException: Connection nektet å være vert: xxx; nestet unntak er: java.net.ConnectException: Forbindelse nektet 

Hva er dette unntaket Hvordan du håndterer Java-unntak på riktig måte Hvordan håndtere Java-unntak på riktig måte I denne artikkelen lærer du hvilke Java-unntak, hvorfor de er viktige, hvordan du bruker dem, og vanlige feil å unngå. Les mer ? Tilkobling nektet.

Grunnen til at du får dette unntaket er fordi: notat fra serverkoden som den forsøker å koble til det lokale registeret i port 1099. Hvis det mislykkes, slutter du med dette unntaket.

Løsningen er å kjøre RMI-registeret. RMI-registret er et program som sendes med Java Virtual Machine og kalles rmiregistry. Det skal være plassert i bin katalog over installasjonen av Java Virtual Machine. Kjører det er så enkelt som:

/usr/lib/jvm/jdk1.8.0_71/bin/rmiregistry 

Som standard lytter registeret på port 1099. For å få det til å lytte på en annen port, spesifiser portnummeret som følger:

/usr/lib/jvm/jdk1.8.0_71/bin/rmiregistry 1100 

Kontroller at det faktisk er en lytter til den angitte porten med netstat-kommandoen. 8 CMD-kommandoer for å administrere (trådløse) nettverk i Windows 8 CMD-kommandoer for å administrere (trådløse) nettverk i Windows Hvis du vil ha full og absolutt kontroll over nettverket, må begynne å bruke kommandoprompt. Her er de mest nyttige kommandoene for å administrere og feilsøke hjemmenettverket. Les mer :

netstat -an -t tcp -p | grep LISTEN ... tcp6 0 0 ::: 1100 ::: * LISTEN 23450 / rmiregistry 

Kjører serveren

La oss nå prøve å kjøre serveren igjen.

java -cp target / rmi-server.jar server. Hoved 1100 # kaster java.rmi.UnmarshalException: feil unmarshalling argumenter ... Forårsaget av: java.lang.ClassNotFoundException: server.Greeting ... 

Et unntak igjen! Hva er det denne gangen?

Serveren kan ikke laste grensesnittet server.Greeting. Dette skjer fordi RMI-registret ikke klarer å laste den nødvendige klassen. Så du må spesifisere plasseringen av de nødvendige klassene. En måte å gjøre det på er å spesifisere CLASSPATH miljøvariabelen:

CLASSPATH = ... / ... /junk/target/rmi-lib.jar /usr/lib/jvm/jdk1.8.0_71/bin/rmiregistry 1100 

Å prøve å kjøre serveren igjen gir:

java -cp target / rmi-server.jar server.Main 1100 # utskrifter Hilsen bundet til "Hilsen" 

Nå kjører serveren.

Kjører kunden

Etter at alle delene er samlet og utført, er det enkelt å kjøre klienten. Den trenger de riktige JARene for utførelse. Disse inkluderer klassen som inneholder hoved() metode og grensesnittklassen. Den aksepterer argumenter som indikerer hvor RMI-registeret kjører, og et navn for hilsen.

java -cp target / rmi-client.jar: target / rmi-lib.jar client.Client localhost 1100 Peter # utskrifter Hilsen rapportert: Hei, Peter 

Sammendrag

Java RMI gir en API og verktøy for å gjøre ekstern kjøring av kode enklere. Du kan implementere en server som registrerer et tjenesteobjekt med Java RMI Registry. Klienter kan spørre registret og få serviceobjektstub for å påkalle servicemetoder. Som dette eksemplet illustrerer, er det alt ganske enkelt.

Bruker du Java RMI i prosjektet ditt? Hva har vært din erfaring? Er det noen alternativer du har undersøkt? Vennligst gi oss beskjed i kommentarene nedenfor.

Utforsk mer om: Java.