IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

4. diel - Java RMI - Vysvetlenie pojmov a opis tried

V minulej lekcii o volanie vzdialených metód v Jave sme si ukázali použitie portu 2020. Dnes si vysvetlíme ďalšie pojmy a triedy spojené s problematikou RMI.

RMI - Vzdialené volanie metód

Tu na obrázku si abstraktne nakreslíme o čo vlastne ide. Existujú prakticky dve triedy (príp. Projekty, programy) ako u socketu, a to klient a server. Zdieľaná referenčná vrstva prevedie svoje napojenie cez localhost / LAN / MAN / WAN. Samozrejme je nutné poznať adresu IPv4, IPv6 alebo URL. Serverová trieda si vyrobí inštanciu (zdieľaný referenčný objekt) a nasdílí ho do zdieľanej referenčnej vrstvy (RMI registra). Zdieľaný referenčný objekt musí mať implementované rozhranie java.rmi.Remote. Akonáhle ho server nasdílí (zaregistruje) cez RMI registre vzniká tzv. Skeleton.

Klientska trieda sa pripojí cez na RMI registre servera. Ak disponuje identifikátorom zdieľaného referenčného objektu, potom si daný objekt môže vytvoriť. Týmto vzniká tzv. Stub. Tento stub má k dispozícii metódy definované rozhraním. Transportná vrstva je už riešená priamo JVM bez našej možnosti ovplyvňovať ju.

Takto to však funguje v tom najjednoduchšom prípade. Ako sme videli v príklade č.2, nie je problém, aby aj server mal ako skeleton aj stub a to isté aj klient. To svojím spôsobom urobilo z klienta server a zo servera klienta. Samozrejme je nutné si uvedomiť aj bezpečnostné hľadisko. Ktokoľvek kto bude poznať IP a port, na ktorom RMI registre pobeží. Veľmi ľahko získa výpis všetkých RMI objektov (viď. Java.rmi.Namin­g.list (String name)) a môže si teda potom metódy zavolať. Možno si na konci seriálu predvedieme nejaké verzie zabezpečenia rmiregistrů.

Schéma RMI komunikácie v Jave - RMI - Remote Method Invocation

Java.rmi. * balíčky (knižnice)

Najdôležitejšími balíčky tried pre RMI sú:

  • java.rmi
  • java.rmi.registry
  • java.rmi.server

RMI Menná služba (Naming service)

Naming trieda ( java.rmi.Naming) poskytuje metódy pre ukladanie a získavanie vzdialených objektov (tvorbu Stube / Skeleton) z RMI registrov. Každá metóda Naming triedy berie parameter typu java.lang.String vo formáte URL a v tvare rmi://host:port/jmenoRMIobjektu.

Časti adresy sú nasledovné:

  • hosť - IP adresa alebo URL, lokálne alebo vzdialených RMI registrov
  • port - Port, na ktorom RMI registre beží (defaultne 1099)
  • jmenoRMIobjektu - Meno zdieľaného objektu na serveri. (Tzv. Identifikátor skeletonu)

Metódy máme k dispozícii nasledujúce:

package java.rmi.server;
public final class Naming {
    public static Remote lookup(String name) throws NotBoundException,MalformedURLException, UnknownHostException, RemoteException;
    public static void bind(String name,Remote obj) throws AlreadyBoundException,MalformedURLException, UnknownHostException, RemoteException;
    public static void rebind(String name,Remote obj) throws MalformedURLException, UnknownHostException, RemoteException;
    public static void unbind(String name) throws NotBoundException,MalformedURLException, UnknownHostException, RemoteException;
    public static String[] list(String name) throws MalformedURLException, UnknownHostException, RemoteException;
}

Jedná sa o najdôležitejšie aplikačné rozhranie RMI k mennej službe (Naming service) v RMI registroch. Metódy si popíšme:

  • lookup (String name) - Vracia referenciu na stub objektu (vzdialený objekt). V prípade, že vzdialený objekt tohto mena nie je na danom počítači registrovaný, je vyhodená výnimka.
  • bind (String name, Remote obj) - Zaregistruje vzdialený objekt (skeleton) so zadaným menom a prevezme odkaz na objekt, ktorý ju reprezentuje. Parameter obj je teda inštancia vzdialeného rozhrania. Ak už služba tohto mena existuje, vyhodí výnimku java.rmi.AlreadyBoundException.
  • REBIND (String name, Remote obj) - Od metódy bind() sa líši tým, že ak už vzdialený objekt tohto mena existuje, je staršia registrácia prepísaná touto novou.
  • String [] list (String name) - Vracia pole s menami registrovaných vzdialených objektov.
  • unbind (String name) - Zruší registráciu vzdialeného objektu daného mena.

Vzdialené objekty

Triedy používané pre vytvorenie vzdialených objektov sú nasledovné:

UnicastRemoteObject

java.rmi.serve­rUnicastRemote­Object trieda sa používa pre export vzdialených objektu, pre získavanie Stube, ktoré komunikujú so vzdialeným objektom. Stub je prakticky zrkadlový obraz objektu skeletonu. Generovanie Stub je vykonávané rmic nástrojom. Existuje celkom 6 spôsobov ako exportovať vzdialené objekty (viac viď. API).

package java.rmi.server;
public class UnicastRemoteServer extends RemoteServer {
    // Protected konstruktory
    protected UnicastRemoteObject() throws java.rmi.RemoteException;
    protected UnicastRemoteObject(int port) throws java.rmi.RemoteException;
    protected UnicastRemoteObject(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws java.rmi.RemoteException;
    // Veřejné metody
    public Object clone() throws java.lang.CloneNotSupportedException;
    public static void exportObject(java.rmi.Remote obj) throws java.rmi.RemoteException;
    //Deprecated
    public static void exportObject(Remote obj, int port) throws java.rmi.RemoteException;
    public static void exportObject(Remote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws java.rmi.RemoteException;
    public static boolean unexportObject(Remote obj, boolean force) throws java.rmi.RemoteException;
}

RemoteObject

java.rmi.server­.RemoteObject je trieda národné implementačné java.lang.Object správania pre vzdialené objekty. RemoteObject reimplementuje kľúčové metódy z typu Object, konkrétne hashCode(), equals(), a toString().

package java.rmi.server;
public abstract class RemoteObject implements Remote, java.io.Serializable {
    // Protected konstruktory
    protected RemoteObject();
    protected RemoteObject(RemoteRef newref);
    // Protected proměnná třídy
    transient protected RemoteRef >ref;
    // Veřejné metody
    public boolean equals(Object obj);
    public int hashCode();
    public String toString();
    public RemoteRef getRef();
    public static Remote toStub(Remote obj);
}

RemoteServer

java.rmi.server­.RemoteServer je trieda, ktorá dedí od RemoteObjekt a prakticky má slúžiť a poskytovať podporu metódy na získanie informácií cez stub z klienta RMI.

package java.rmi.server;
public class RemoteServer extends RemoteObject {
    // Protected konstruktory
    protected RemoteServer();
    protected RemoteServer(RemoteRef newref);
    // Veřejné metody
    public static String getClientHost() throws ServerNotActiveException;
    public static void setLog(java.io.OutputStream out);
    public static java.io.PrintStream getLog();
}

RMI registre služba

Ak chceme vykonávať RMI komunikáciu, je nutné spustiť RMI registre na serveri aj na klientovi. Spustenie RMI registrov je nutné vykonať skôr, ako začneme pracovať s RMI. Služba beží štandardne na porte 1099, ale port možno pri spustení zmeniť. Spustenie možno vykonávať cez príkazový riadok (cmd u Windows), priamo v IDE alebo programovo cez JAVA API, napr. Cez statickú metódu z java.rmi.regis­try.LocateRegis­try.createRegis­try (int port).

Program (služba RMIregistry) sa nachádza v adresári "adresár inštalácie Java \ bin \ rmiregistry.exe".

Trieda LocateRegistry mám nasledujúce rozhranie:

package java.rmi.registry;
public final class LocateRegistry {
    // Veřejné metody
    public static Registry createRegistry(int port) throws RemoteException;
    public static Registry createRegistry(int port,RMIClientSocketFactory csf,RMIServerSocketFactory ssf) throws RemoteException;
    public static Registry getRegistry() throws RemoteException;
    public static Registry getRegistry(int port) throws RemoteException;
    public static Registry getRegistry(String host) throws RemoteException;
    public static Registry getRegistry(String host, int port) throws RemoteException;
    public static Registry getRegistry(String host, int port, RMIClientSocketFactory csf) throws RemoteException;
}

V budúcej lekcii si pred spustenie exportu a spustenie RMI server / klienta cez príkazový riadok.


 

Predchádzajúci článok
Java RMI - Volanie zo servera na porte 2020
Všetky články v sekcii
RMI - Remote Method Invocation
Preskočiť článok
(neodporúčame)
Java RMI - Spustenie RMI Server / Klient cez CMD
Článok pre vás napísal Robert Michalovič
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Programuji převážně v Javě SE,EE a trochu nativním C a CUDA. více viz.https://cz.linkedin.com/in/robert-michalovic
Aktivity