Soketové připojení Klient InetAddress getbyname() UnknowHostException SecurityException Socket getinputstream() getoutputstream() IOException Server



Podobné dokumenty
Remote Method Invocation RMI

RMI Remote Method Invocation

Jini (pronounced GEE-nee) Cvičení 8 - DS 2006

JAVA V RMI Java, letní semestr

RMI - Distribuované objekty v Javě

java remote method invocation Kateřina Fricková, Matouš Jandek

JAVA RMI Java, letní semestr 2018

Katedra měřicí a řídicí techniky, VŠB - Technická univerzita v Ostravě, tř. 17. listopadu, Ostrava-Poruba, Česká republika

RMI - Remote Method Invocation

Bezpečnost v Javě. Architektura zabezpečení jazyka Java.

Soubor jako posloupnost bytů

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Class loader. každá třída (java.lang.class) obsahuje referenci na svůj class loader. Implementace class loaderu

Výčtový typ strana 67

Zadání Vytvoříme jednoduchý multithread HTTP server v jazyce Java Spustíme si ho na lokálním počítači A otestujeme ho Zdrojový kód je v

Bridge. Známý jako. Účel. Použitelnost. Handle/Body

8. přednáška: Soubory a proudy

Se vznikem internetu se můžeme na síťovou komunikaci v Javě (komunikace mezi více JVM) dívat dvěma pohledy-způsoby:

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

7. přednáška - třídy, objekty třídy objekty atributy tříd metody tříd

Generické programování

Vytváření a použití knihoven tříd

Z. Kotala, P. Toman: Java ( Obsah )

Abstraktní třída a rozhraní

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Java - výjimky. private void vstup() throws IOException {... }

17. Projekt Trojúhelníky

Seminář Java II p.1/43

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Definice třídy. úplná definice. public veřejná třída abstract nesmí být vytvářeny instance final nelze vytvářet potomky

InputStream. FilterInputStream

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Úvod do programovacích jazyků (Java)

SOUBORY, VSTUPY A VÝSTUPY POKRAČOVÁNÍ

3. Třídy. Základní pojmy objektového programování. Třídy

Osnova. GIOP a IIOP IDL IOR POA. IDL Klient Server. 2 Historie. 3 Princip a základní pojmy. 4 Implementace. 5 Aplikace CORBA

1. Programování proti rozhraní

20. Projekt Domácí mediotéka

Java aplety. Předávání parametrů z HTML

Při studiu tohoto bloku se předpokládá, že student je zvládá základy programování v jazyce Java s využitím vývojového prostředí NetBeans.

Programování v Javě I. Leden 2008

Programovací jazyk Java

TŘÍDY POKRAČOVÁNÍ. Události pokračování. Příklad. public delegate void ZmenaSouradnicEventHandler (object sender, EventArgs e);

Úvod do programovacích jazyků (Java)

Programování v Javě I. Únor 2009

IRAE 07/08 Přednáška č. 7. Začátek (head)

8 Třídy, objekty, metody, předávání argumentů metod

Obsah přednášky 9. Skrývání informací. Skrývání informací. Zapouzdření. Skrývání informací. Základy programování (IZAPR, IZKPR) Přednáška 9

Počítačové laboratoře bez tajemství aneb naučme se učit algoritmizaci a programování s využitím robotů CZ.1.07/1.3.12/

Úvod do programování - Java. Cvičení č.4

Algoritmizace a programování

Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost rozhraním a výjimkám.

Textové soubory. alg9 1

10 Balíčky, grafické znázornění tříd, základy zapozdření

Testování. Zadání příkladu. Vytvoření kostry třídy. Obsah:

KTE / ZPE Informační technologie

11 Diagram tříd, asociace, dědičnost, abstraktní třídy

IRAE 07/08 Přednáška č. 2. atr1 atr2. atr1 atr2 -33

Úvod Třídy Rozhraní Pole Konec. Programování v C# Hodnotové datové typy, řídící struktury. Petr Vaněček 1 / 39

Úvod Virtuální kanál TCP Datagramová služba UDP URL TCP, UDP, URL. Fakulta elektrotechnická

Platforma.NET 11.NET Framework 11 Visual Basic.NET Základní principy a syntaxe 13

Základy objektové orientace I. Únor 2010

Výjimky. v C# a Javě

typová konverze typová inference

Algoritmizace a programování

Java Výjimky Java, zimní semestr

1 Správce licencí Správce licencí Správce licencí Start > Všechny programy > IDEA StatiCa > Správce licencí Soubor > Správce licencí Licence

Více o konstruktorech a destruktorech

PŘETĚŽOVÁNÍ OPERÁTORŮ

Využití OOP v praxi -- Knihovna PHP -- Interval.cz

PREPROCESOR POKRAČOVÁNÍ

Od CGI k FastCGI. Uvedené dílo podléhá licenci Creative Commons Uved te autora 3.0 Česko.

Abstraktní datové typy: zásobník

Třídy, polymorfismus. A0B36PR2-Programování 2 Fakulta elektrotechnická České vysoké učení technické

Semin aˇr Java V yjimky Radek Ko ˇc ı Fakulta informaˇcn ıch technologi ı VUT Unor 2008 Radek Koˇc ı Semin aˇr Java V yjimky 1/ 25

Java a XML. 10/26/09 1/7 Java a XML

Předmluva k aktuálnímu vydání Úvod k prvnímu vydání z roku Typografické a syntaktické konvence... 20

UJO Framework. revoluční architektura beans. verze

29. Výjimky, jejich vznik, vyhození, odchyt a zpracování. (A7B36PVJ)

PB161 Programování v jazyce C++ Přednáška 7

PB161 Programování v jazyce C++ Přednáška 7

Common Object Request Broker Architecture

Příklad aplikace Klient/Server s Boss/Worker modelem (informativní)

7. Statické prvky třídy

7. Datové typy v Javě

Vlákna. První jednoduchý program s vlákny:

Vaše jistota na trhu IT. Balíčky. Rudolf Pecinovský

X-komponenty 3.1. Uživatelská příručka. J. Kocman, V. Trojan

Dědění, polymorfismus

Dědičnost (inheritance)

Iterator & for cyklus

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

Programování v C++ 3, 3. cvičení

Principy objektově orientovaného programování

6. PRÁCE S DATOVÝMI PROUDY

1. Dědičnost a polymorfismus

NetBeans platforma. Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti

Ing. Michal Martin. MQTT na zařízeních Weintek

Transkript:

Soketové připojení Při socketovém připojení spolu komunikují dvě nezávislé JVM pomocí streamů odpovídajících typů. Po síti můžete posílat textové i binární informace, je možno posílat i objekty, které byly do streamů převedeny pomocí serializace. Pro zvýšení bezpečnosti komunikace je možno použít další javovské knihovny a komunikovat např, přes SSL. Pomocí bezpečnostních politik je možno zajistit i další bezpečnostní omezení, např. klienty mohou být pouze ze zadané domény atd. Třídy potřebné pro připojení pomocí socketu najdete v balíčku java.net. Klient Pro vytvoření spojení potřebujete instanci třídy InetAddress, která obsahuje informaci internetové adrese serveru. Tato třída nemá veřejný konstruktor a její instance se vytvářejí pomocí statické metody getbyname(). Instanci této třídy lze vytvořit buď pomocí IP adresy nebo logického jména, např. : InetAddress adresa = InetAddress.getByName( 146.102.64.82 ); Tato metoda může vyvolat výjimku UnknowHostException a případně i výjimku SecurityException. Na straně klienta je třeba vytvořit instanci třídy Socket, která má v konstruktoru dva parametry. První parametr je typu InetAddress s adresou serveru a druhý typu int udává číslo portu, na který se klient u serveru připojí. Číslo portu by mělo být vyšší než 1025. Po připojení je nutné vytvořit komunikační streamy pomocí metod instance Socketu getinputstream() a getoutputstream(). Na konci komunikace je třeba zavřít socket metodou close() a to i v případě, že při spojení došlo k chybě. Všechny tyto činnosti mohou vyvolat výjimku IOException. Server Na straně serveru je třeba nejdříve vytvořit instanci třídy ServerSocket, která má v konstruktoru číslo portu. Toto číslo se musí shodovat s číslem portu uvedeným v socketu klienta. Pak spustíme metodu instance ServerSocketu accept(), která vrací instanci třídy Socket po připojení nějakého klienta. Na straně serveru pak opět vytvoříme streamy pro čtení a zápis. Na konci komunikace je třeba uzavřít socket i server socket metodami close(). Všechny tyto činnosti mohou vyvolat výjimku IOException. Takto vytvořený server je pouze jednouživatelský a při každém spuštění použitelný pouze jednou. Aby měl server smysl, musíte vytvořit podporu pro víceuživatelský přístup. Díky podpoře vláken v Javě to není takový problém. Server bude ve smyčce čekat na připojení klienta, obslouží ho v samostatném vláknu.,toto vlákno se vytvoří odpovídající streamy a po skončení komunikace s klientem je uzavře, uzavře socket a ukončí se. Pokud potřebuje aplikace, aby o sobě jednotliví klienti věděli, je třeba vlákna zařazovat do skupin. Pokud jednotlivý klienti využívají na serveru omezený zdroj např. soubor, je nutná synchronizace.

Remote Method Invocation RMI Java TM Remote Method Invocation (RMI) umožňuje objektu na jedné Java virtual Mashine(JVM) jednoduše spustit metodu jiného objektu na vzdálené JVM. Při volání vzdálené metody získává klient referenci na vzdálený objekt prostřednictvím jmenné služby poskytované RMI. RMI používá objektovou serializaci pro posílání parametrů metod a návratových hodnot, tj. posílají se objekty u kterých je možno využít všech jejich vlastností včetně polymorfismu. Vzdálené volání metod má tu samou syntaxi jako volání metod lokálních objektů. RMI poskytuje podporu pro dynamické stahování kódu. Součásti RMI Funkční RMI systém má několik částí 1. Rozhraní definující vzdálené služby 2. Implementaci vzdálené služby a server poskytující tuto implementaci 3. Soubor se stubem, který umožňuje vzdálenou komunikaci. 4. RMI jmennou službu, která umožňuje klientovi službu najít 5. Klientský program, které požaduje vzdálené služby 6. Poskytovatele, který umožní dynamické stahování kódu(http nebo FTP server) Veškeré třídy, rozhraní a nástroje pro vytvoření a spuštění RMI aplikace jsou součástí J2SE. Třídy a rozhraní pro RMI jsou obsaženy ve více balíčcích. Nejpoužívanější jsou balíčky java.rmi a java.rmi.server. Rozhraní definující vzdálené služby vzdálené rozhraní. Vzdáleně mohou být volány pouze metody deklarované v tzv. vzdáleném rozhraní. Vzdálené rozhraní je potomkem rozhraní java.rmi.remote. V tomto rozhraní deklarujeme vzdáleně volané metody. Každá metoda musí vyhazovat výjimku java.rmi.remoteexception. Parametry a návratové hodnoty mohou být jakéhokoli typu, který je možno serializovat. Primitivní datové typy je možno používat bez problémů. Implementace vzdálené služby vzdálený objekt Je třeba vytvořit implementaci vzdáleného rozhraní, tj.třídu která bude součástí serveru. Tato třída bude implementovat rozhraní definující vzdálené služby a musí mít konstruktor vyhazující výjimku java.rmi.remoteexception. Třída může obsahovat jakékoli další metody, ty však nebude možno volat přímo přes RMI. Pokud nepotřebujeme tuto třídu napsat jako potomka jiné třídy, použijeme dědičnost od třídy java.rmi.server.unicastremoteobject. V případě, že chceme aby třída dědila od jiného předka než je UnicastRemoteObject, musí konstruktor vaší třídy obsahovat tento kód: UnicastRemoteObject.exportObject(this); Volání této metody (či volání konstruktoru předka, v případě dědění od třídy UnicasteRemoteObject,) spustí čekání tohoto objektu na volání metody klientem. V okamžiku, kdy klient požádá server o službu,je pro obsluhu vytvořeno samostatné vlákno. Službu je tedy možno poskytovat více klientům najednou. V metodě main třídy serveru (může to být třída implementující vzdálené rozhraní nebo samostatná třída) je nutné: 1. Vytvořit instanci rozhraní, které definuje vzdálené služby. A to tak. že vytvoříme instanci třídy implementující toto rozhraní a přetypujeme ho na typ tohoto rozhraní. 2. Zaregistrovat se u jmenné služby RMI rmiregistry

Registrace proběhne pomocí třídy java.rmi.naming. Tato třída má několik metod třídy, které si nyní objasníme. static void bind(string name, Remote obj) zaregistruje službu se zadaným jménem a převezme odkaz na objekt, který ji reprezentuje.parametr obj je tedy instance vzdáleného rozhraní. Pokud již služba tohoto jména existuje vyhodí výjimku java.rmi.alreadyboundexception. static void rebind(string name, Remote obj) od metody bind se liší tím, že pokud již služby tohoto jména existuje, je její registrace přepsána touto novou. static String[] list(string name) vrací pole se jmény zaregistrovaných služeb static Remote lookup(string name) vrací referenci na stub objektu, který je asociován s daným jménem služby. I třída stubu implementuje vzdálené rozhraní, je ji tedy možno přetypovat na java.rmi.remote. V případě, že služba tohoto jména není na daném počítači registrována je vyhozena výjimka java.rmi.notboundexception static void unbind(string name) zruší registraci služby daného jména. Jméno služby je stringová hodnota s následující strukturou: //host:port/jmeno host:port udávají počítač a port, na kterém je spuštěno RMIregistry pokud není uveden host, bere se localhost pokud není určen jiný port bere se defaultní tj.1099 jmeno je jednoznačné jméno služby Stuby Při vzdáleném volání metod používá RMI pro komunikaci instance stubů 1. Instance stubu odpovídající volanému vzdálenému objektu je poslána na klienta, klient volá metodu na stubu. Na straně serveru je vytvořena instance stubu a tyto dvě instance mezi sebou komunikují pomocí socketů. Stub na straně klienta převezme požadavek na volání metody a. převede jej do streamů, pro převod všech parametrů je použita serializace.tato činnost se v distribuovaných systémech nazývá marshalování. Požadavek je přes TCP/IP komunikaci přenesen na server, kde je instance stubu (případně skeletonu) převede za pomoci serializace zpět do podoby volání metody. Metoda je pak spuštěna a vrátí návratovou hodnotu stubu, který ji marshaluje na klienta. Stub na klientovi provede demarshalování a předá výsledek metody klientskému objektu. Kód stubu je generován pomocí programu rmic. Tento nástroj na základě implementace rozhraní vytvoří vlastní zdrojový kód stubu, přeloží jej a, pokud neuvedete jinak, tento zdrojový kód odstraní. Pokud používáte Javu verze 1.4 není třeba vytvářet skeletony. Nová verze protokolu 1.2 je již nevyžaduje. Použijte tedy při vytváření přepínač v1.2. Pokud si chcete prohlédnout zdrojový kód stubu použijte přepínač keep. Jmenná služba RMIregistry Pro registraci RMI má Java jednoduchou registrační službu RMIregistry. Tuto službu je možné spustit dvěma způsoby. 1. Z příkazového řádku pomocí příkazu rmiregistry. Tuto službu musíte mít spuštěnou před samotným spouštěním serveru a klienta. Pokud nechceme používat standardní číslo portu pro RMI tj. 1099, uvedeme číslo portu jako parametr při spuštění. Je třeba spouštět tuto službu v jiném adresáři než je adresář serveru. 2. Na serveru pomocí statické metody java.rmi.registry.locateregistry.createregistry(int port), která má jako parametr 1 V starších verzích Javy (do verze 1.3.1) byly pro komunikaci používány i instance skeletonů. Vytváří se pomocí rmic bez parametru v1.4. Distribuují se stejným způsobem jako stuby.

číslo portu. V této variantě je třeba uvádět i implicitní číslo portu 1099. Tuto metodu voláme v metodě main serveru před registrací vzdálené služby. Klient Při tvorbě klienta narozdíl od lokálního spouštění metody musíme nejdříve získat referenci na stub vzdáleného objektu. Tato činnost se provádí pomocí již zmíněné metody lookup() třídy Naming. Pokud používáme dynamické stahování kódu je také vyžadováno vytvoření instance třídy java.rmi.rmisecuritymanager a nastavení odpovídajících bezpečnostních politik pro přístup k jednotlivým souborům či portům. Poskytovatel pro dynamické stahování kódu Je možné vytvořit funkční RMI aplikaci bez dynamického stahování ködu. Pak ovšem při každé změně implementace vzdáleného rozhraní budeme muset na všechny klienty nakopírovat novou verzi stubu. Dynamicky si klient obvykle stahuje class soubor stubu. Je možné, aby si klient i server stahovali soubory.class tříd, instance kterých jsou návratovými hodnotami nebo parametry vzdáleně volaných metod. RMI umožňuje i dynamické stahování kódu v rámci jednoho počítače, kdy server a klient běží ve dvou nezávislých instancích JVM a příslušný kód si klient nebo i server stahují s určených adresářů. To umožňuje ladění RMI aplikací s dynamickým stahováním kódu na jednom stroji. Při praktickém běhu aplikace se pak používá stahování pomocí FTP nebo HTTP. Informace o umístění stubu a případně i dalších souborů class poskytuje server prostřednictvím své systémové proměnné java.rmi.server.codebase. Stejnou proměnnou používá i klient pro informování serveru o umístění pro něj potřebných souborů. RMI využívá pro zajištění bezpečnosti instanci třídy RMISecurityManager, je tedy nutné nastavovat bezpečnostní politiky pro některé porty a případně i adresáře (pokud se soubory class čtou z lokálního disku). Komunikace mezi jednotlivými částmi RMI aplikace s dynamickým stahováním kódu Na následujícím obrázku je uveden postup komunikace při spouštění RMI aplikace. Je zde uvedena varianta, kdy je dynamicky stahován kód stubu na klienta. Server má k dispozici všechny potřebné class soubory. Server java.rmi.server.codebase=url location 1 9 8 RMIregistry 2 3 URL location (ftp, http nebo file) 4 5 6 7 Klient

1. Server si vytvoří svoji instanci stubu a registruje službu u RMIregistry, tj. nastaví její jméno, pošle instanci vzdáleného rozhraní a obsah proměnné java.rmi.server.codebase. (V případě, kdy se kód nestahuje dynamicky je tato proměnná nastavena na aktuální adresář serveru.) 2. RMIregistry si na základě udané codebase požaduje soubory class stubu a vzdáleného rozhraní, aby mohl vytvořit instanci stubu. 3. RMIregistry získá požadované soubory. 4. Klient pomocí metody lookup() hledá službu daného jména u služby RMIregistry. 5. RMIregistry poskytuje klientovi instanci stubu vzdáleného objektu, informace o serveru a příslušnou codebase. 6. Klient potřebuje class soubor stubu, pokud ho nenajde na své classpath, požaduje tento soubor z URL uvedené v codebase serveru. 7. Klient získá odpovídající soubor class stubu. 8. Klient volá vzdálenou metodu na instanci stubu, ta provede odpovídající serializaci parametrů a pošle požadavek na server, kde je deserializován a spuštěna metoda. 9. Výsledek metody je opět serializován a pomocí streamů poslán na klienta, kde stub provede deserializaci a předá výsledek klientovi. Při dynamickém stahování kódu a pro komunikaci mezi klientem a serverem je možné použít i zabezpečenou komunikaci přes SSL. Pak je třeba napsat si vlastní implementaci rozhraní java.rmi.server.seversocketfactory a java.rmi.server.clientsocketfactory, které budou používat šifrování. Bližší informace naleznete na stránkách firmy Sun. Příklad jednoduché aplikace používající RMI Napíšeme velmi jednoduchou aplikaci, která bude umožňovat na serveru sčítat dvě celá čísla. V celém příkladě jsou záměrně všechny výjimky posílány až na JVM, aby ukázkový kód nebyl příliš rozsáhlý. V praxi je samozřejmě nutné výjimky ošetřit. Pro jednoduchost vytvoříme v prvním kroku RMI aplikaci, která bude celá v jednom adresáři. Po jejím zprovoznění si ukážeme jak postupovat při další distribuci Vytvoření rozhraní definujícího vzdálené služby. Vytvoříme tedy rozhraní, definující metodu pro sčítání dvou čísel. Rozhraní musí být potomkem java.rmi.remote a metoda musí vyhazovat výjimku java.rmi.remoteexception. import java.rmi.*; public interface ScitaniCisel extends Remote { int secti (int a, int b) throws RemoteException; Vytvoření implementace vzdálené služby. Vytvoříme třídu, která bude implementovat ScitaniCisel. import java.rmi.*; import java.rmi.server.*; import java.net.*; public class ScitaniNaServeru extends UnicastRemoteObject implements ScitaniCisel {

public int secti (int a, int b) throws RemoteException { return a+b; public ScitaniNaServeru() throws RemoteException { super(); Vytvoření serveru Server vytvoříme jako samostatnou třídu, která vytvoří instanci vzdáleného rozhraní a zaregistruje službu se jménem Scitani na lokalhostu na portu 1099. import java.rmi.*; import java.rmi.server.*; import java.net.*; public class Server { public static void main(string[] args) throws RemoteException, MalformedURLException { String name = "///Scitani"; ScitaniCisel scitani = new ScitaniNaServeru(); Naming.rebind(name, scitani); System.out.println("Probehla registrace"); Vytvoření třídy stubu Nyní vytvoříme stub pomocí rmic. Jako parametr tohoto příkazu uvedeme jméno třídy implementující vzdálené rozhraní tj. v našem příkladě VzdálenyObjekt. Příkazová řádek může vypadat takto: rmic v1.4 keep ScitaniNaServeru Po provedení tohoto příkazu budou v aktuálním adresáři vytvořeny dva soubory ScitaniNaServeru _Stub.java a ScitaniNaServeru _Stub.class. Vytvoření klienta. Nyní vytvoříme jednoduchého klienta, který bude využívat metodu secti() na serveru. V cyklu vygenerujeme 10x náhodná čísla, která budeme vzdáleně sčítat. Stejně jako v případě serveru i u klienta je vynecháno ošetření výjimek. V případě klienta musí být ošetřeny tyto výjimky: RemoteException, NotBoundException, java.net.malformedurlexception. Jméno služby je Scitani a hledáme ji na lokalhostu na portu 1099. Kód klienta je uveden v následujícím výpise. import java.rmi.*; public class Klient {

public static void main (String [] args) throws Exception { String name = "///Scitani"; ScitaniCisel scitani = (ScitaniCisel) Naming.lookup(name); for( int i = 0; i<10; i++) { int a = (int)(math.random()*10); int b = (int)(math.random()*10); System.out.println("Vysledek je :" + scitani.secti(a,b)); Spuštění registrační služby; Před spuštěním jmenné služby se nastavíme do adresáře, který není přístupný přes classpath serveru! RMIregistry spustíme z příkazového řádku příkazem rmiregistry. Budeme používat port 1099, neuvedeme tedy žádný parametr. Spuštění celého příkladu bez dynamického stahování kódu. Pokud tedy máme spuštěnou jmennou službu RMIregistry a vytvořen stub třídy serveru, můžeme spustit server a poté klienta v samostatných instancích JVM. Pokud nyní zkusíte rozdělit aplikaci do dvou adresářů nebo na dva různé stroje a nebudete požadovat dynamické stahování kódu, bude aplikace fungovat. Znamená to pouze,že na počítači (případně v adresáři) klienta musíte mít tyto soubory class (pro verzi Javy 1.4 a vyšší): ScitaniCisel.class Klient.class ScitaniNaServeru_Stub.class Při síťovém spouštění musíte upravit jméno služby v metodě lookup(), aby se služba hledala na počítači se spuštěným RMIregistry a serverem. Pro server platí, že musí mít spuštěné rmiregistry a dostupné soubory class: Server.class ScitaniCisel.class ScitaniNaServeru.class ScitaniNaServeru_Stub.class Spuštění celého příkladu s dynamickým stahováním kódu. Dalším logickým krokem je vyzkoušet fungování RMI, pokud je požadováno dynamické natažení kódu stubu na klienta. Tuto funkčnost je možno vyzkoušet i na jednom počítači, pokud rozdělíme kód klienta a kód serveru do dvou adresářů tak, že v adresáři klienta nebude soubor se stubem a při spouštění nebude dostupný ani nikde na CLASSPATH.Tento kód bude pro potřeby klienta umístěn v dalším adresáři spolu s kódem vzdáleného rozhraní. Důvodem k tomu je fakt, že RMIregistry hledá potřebný kód podle codebase a potřebuje stáhnout i kód vzdáleného rozhraní. Adresářová struktura našeho příkladu bude následující: H:\server\ Server.class ScitaniCisel.class ScitaniNaServeru.class ScitaniNaServeru_Stub.class H:\klient\ ScitaniCisel.class.class Klient.class H:\zdroj\ ScitaniCisel.class.class

ScitaniNaServeru_Stub.class Při spouštění serveru se v této variantě nic nemění. Při spouštění klienta je však vyhozena výjimka java.rmi.unmarshalexception, která je důsledkem toho, že nebyl nalezen stub. Naší snahou tedy bude sdělit klientovi, odkud si má stáhnout class soubor stubu. K tomu se používá systémová proměnná java.rmi.server.codebase. Spustíme tedy znovu server, tentokrát však s nastavením parametru java.rmi.server.codebase java Djava.rmi.server.codebase= file:/h:\zdroj/ Server Ani to však nevede ke správnému fungování aplikace, chybové hlášení je velmi podobné. Při podrobnějším prostudování výpisu chyby zjistíte, že na straně klienta chybí spuštění security managera. Do kódu klienta tedy doplníme jeho spuštění, použijeme instanci třídy RMISecurityManager. if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); Když třídu klienta upravíme, přeložíme a spustíme, dojde znovu k chybě, tentokrát je to java.security.accesscontrolexception. Je třeba povolit čtení z adresáře, kde je uložen stub a socketovou komunikaci se serverem (bližší podrobnosti viz kapitola o bezpečnosti v Javě). Soubor s bezpečnostní politikou javarmi.policy by mohl vypadat následovně: grant { permission java.net.socketpermission "*:1025-65535", "connect,accept"; permission java.io.filepermission "H:\\zdroj\\-","read"; ; Klienta pak spustíme takto: java Djava.security.policy=javaRMI.policy Klient Pak již celá aplikace funguje bez problémů. Při umístění souborů pro dynamické stahování kódu na webserveru je třeba v bezpečnostní politice povolit přístup přes port 80.