Стартиране на две машини
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 |


