Стартиране на две машини
1. Автоматично
прехвърляне на класовете
При използването на отдалечена изчислителна услуга, Java машината на
клиента има локално всички необходими и класове и интерфейси и не се
нуждае от класове прехвърляни по мрежата. За Java машината на
сървъра обаче е неизвестен класът задаващ изчислителната
задача. Трябва да се отбележи, че RMI не изпраща дефиницията на
класовете заедно със сериализираните обекти.
RMI поддържа отдалеченето зареждане на класовете чрез RMIClassLoader
.
Ако сървър или клиент използват RMI и констатират, че е
необходимо зареждането на класа от отдалечена Java машина, те
извикват за целта e RMIClassLoader.
Начинът, по който RMI зарежда класовете се контролира от параметри
(property) задавани с -D при
стартирането на Java машината
java [
-D<PropertyName>=<PropertyValue> ] <ClassFile>
Параметърът java.rmi.server.codebase
се използва за задаване на URL.
Той може да бъде file:
, ftp:
, или http:
- мястото където се
намират класовете които се изпращат
от локалната Java
машина. Естествено това място трябва да бъде достъпно по мрежата,
в слуаите ftp:
, или http: -
трябва да бъде
стратиран
съответния сървър.Ако
една JVM изпраща обект на друга JVM , то
приемащата JVM трябва да зареди класа за този обект. Когато RMI
изпраща сериализиран обект тя вгражда съответния URL откъдето може да получен класа.
В случая на отдалечена изчислителна услуга такъв URL е необходим при изпращане на
класът, който задава изчислението. Това в примера се извършва от web сървър
стартиран на машината на клиента.
2. Сървър
- Нека да приемем, че сървърът има ip адрес 192.168.0.101
- В избрана директория на сървъра (нека да бъде D:\RMI\rmi-serv) се
разполагат двата описани по-горе пакета compute и
engine,
както и файла ex.policy.
Директорията compute
съдържа интерфейсите Compute и Task (в class файлове),
а директорията engine
-класа ComputeEngine (компилирани).
- Стартират се регистрите:
- Преминава се в директорията D:\RMI\rmi-serv и
се стартира сървъра:
start
java -Djava.rmi.server.codebase=file:/D:/RMI/rmi-serv/
-Djava.rmi.server.hostname=192.168.0.101
-Djava.security.policy=ex.policy engine.ComputeEngine |
codebase е зададено като file: защото сървърът не изнася към
клиента никаква дефиниция на клас, поради което не е необходимо и
стартирането на web съсрвър.
3. Клиент
- Нека да приемем, че машината на клиента има ip адрес 192.168.0.141
- В избрана директория на сървъра (нека да бъде D:\RMI\rmi-client) се
разполагат двата описани по-горе пакета compute и
client
както и файла ex.policy.
Директорията compute
съдържа интерфейсите Compute и Task (в class файлове),
а директорията client -
класoвете ComputePi и Pi
(компилирани).
- Нека в директорията D:\RMI\rmi-client да
разположим още един пакет - client2,
който съдържа класовете ComputeFact
и Fact
и ги компилираме:
-
package client2;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.math.*;
import compute.Compute;
public class ComputeFact {
public static void main(String args[]) {
if
(System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Compute";
Registry registry = LocateRegistry.getRegistry(args[0]);
Compute comp = (Compute) registry.lookup(name);
Fact
task = new Fact(Integer.parseInt(args[1]));
BigInteger fact = comp.executeTask(task);
System.out.println(fact);
} catch (Exception e) {
System.err.println("ComputeFact exception:");
e.printStackTrace();
}
}
} |
package client2;
import compute.Task;
import java.io.Serializable;
import java.math.*;
public class Fact implements Task<BigInteger>,Serializable {
private static final long serialVersionUID = 1000L;
private int k;
public Fact(int k){
this.k=k;
}
public BigInteger execute(){
BigInteger fact = new BigInteger("1");
if(k<=1)return fact;
for(int help=2;help<=k;help++)
fact=fact.multiply(new
BigInteger(""+help));
return fact;
}
} |
- Стартире се web сървър
който предоставя в мрежата директорията D:\RMI\rmi-client например
с URL http://192.168.0.141/client/
- Преминава се в директорията D:\RMI\rmi-client и се
стартират последователно двата клиента:
-
java -Djava.rmi.server.codebase=http://192.168.0.141/client/
-Djava.security.policy=ex.policy client.ComputePi
192.168.0.101 45 |
java
-Djava.rmi.server.codebase=http://192.168.0.141/client/
-Djava.security.policy=ex.policy client2.ComputeFact
192.168.0.101 45 |