Java Remote Method Invocation (RMI) est un mécanisme qui permet à un objet Java dans une machine virtuelle Java (JVM) d’appeler des méthodes sur un objet distant dans une autre JVM, comme si cet objet distant était local. Cela facilite la communication et la collaboration entre les applications distribuées écrites en Java. Pour bien comprendre son fonctionnement, voici quelques exercices corrigés sur Java RMI.
Dans cet exercice, nous allons créer un service d’addition distante. Le client enverra deux nombres au serveur, qui les additionnera et renverra le résultat au client.
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class AdditionServiceImpl extends UnicastRemoteObject implements AdditionService {
protected AdditionServiceImpl() throws RemoteException {
super();
}
@Override
public int add(int a, int b) throws RemoteException {
return a + b;
}
public static void main(String[] args) {
try {
AdditionService service = new AdditionServiceImpl();
Naming.rebind("//localhost/AdditionService", service);
System.out.println("Service d'addition prêt.");
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface AdditionService extends Remote {
int add(int a, int b) throws RemoteException;
}
import java.rmi.Naming;
public class AdditionClient {
public static void main(String[] args) {
try {
AdditionService service = (AdditionService) Naming.lookup("//localhost/AdditionService");
int a = 5;
int b = 3;
int result = service.add(a, b);
System.out.println("Résultat de l'addition : " + result);
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
Dans cet exercice, nous allons créer un service de conversion de température qui convertit les degrés Celsius en degrés Fahrenheit.
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class TemperatureServiceImpl extends UnicastRemoteObject implements TemperatureService {
protected TemperatureServiceImpl() throws RemoteException {
super();
}
@Override
public double celsiusToFahrenheit(double celsius) throws RemoteException {
return celsius * 9 / 5 + 32;
}
public static void main(String[] args) {
try {
TemperatureService service = new TemperatureServiceImpl();
Naming.rebind("//localhost/TemperatureService", service);
System.out.println("Service de conversion de température prêt.");
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface TemperatureService extends Remote {
double celsiusToFahrenheit(double celsius) throws RemoteException;
}
import java.rmi.Naming;
public class TemperatureClient {
public static void main(String[] args) {
try {
TemperatureService service = (TemperatureService) Naming.lookup("//localhost/TemperatureService");
double celsius = 20;
double fahrenheit = service.celsiusToFahrenheit(celsius);
System.out.println("Conversion de " + celsius + " degrés Celsius en Fahrenheit : " + fahrenheit);
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
Ces exercices vous donnent un aperçu de la façon dont Java RMI peut être utilisé pour créer des services distribués. Vous pouvez étendre ces exercices en ajoutant plus de fonctionnalités aux services ou en créant de nouveaux services pour répondre à d’autres besoins.
Voici quelques exercices avancés sur Java RMI qui vont au-delà des exemples basiques précédents :
Créez un service de gestion de fichiers distant qui permet aux clients d’accéder et de manipuler des fichiers sur le serveur. Les fonctionnalités peuvent inclure la lecture, l’écriture, la suppression et la liste des fichiers présents sur le serveur.
Développez un service de chat qui permet à plusieurs utilisateurs de communiquer entre eux via un serveur central. Les utilisateurs peuvent envoyer des messages aux autres utilisateurs connectés au service.
Implémentez un service de gestion de transactions bancaires qui permet aux clients d’effectuer des opérations telles que le dépôt, le retrait et le transfert d’argent entre comptes bancaires. Assurez-vous que les opérations sont sûres et cohérentes, même en cas de transactions concurrentes.
Créez un service de partage de fichiers pair-à-pair qui permet aux utilisateurs de partager des fichiers directement entre eux sans passer par un serveur central. Les utilisateurs peuvent rechercher, télécharger et partager des fichiers avec d’autres utilisateurs connectés au réseau.
Développez un service de calcul distribué qui permet de répartir des tâches de calcul sur plusieurs machines distantes. Les clients peuvent soumettre des tâches de calcul au serveur, qui les distribue aux nœuds disponibles pour l’exécution. Une fois les calculs terminés, les résultats sont renvoyés au client.
Ces exercices avancés mettront à l’épreuve votre compréhension de Java RMI et vous permettront de vous familiariser avec des concepts plus complexes tels que la concurrence, la sécurité et la gestion des transactions dans un environnement distribué.
Voici des solutions simplifiées pour chaque exercice avancé sur Java RMI :
Ces solutions sont des guides généraux pour la mise en œuvre des exercices avancés sur Java RMI. Selon les besoins spécifiques et les contraintes du projet, vous devrez peut-être les adapter ou les étendre.
Voici des solutions réécrites avec des exemples de code pour chaque exercice avancé sur Java RMI :
FileService.java
):import java.rmi.Remote;
import java.rmi.RemoteException;
public interface FileService extends Remote {
byte[] readFile(String fileName) throws RemoteException;
void writeFile(String fileName, byte[] data) throws RemoteException;
void deleteFile(String fileName) throws RemoteException;
String[] listFiles() throws RemoteException;
}
FileServer.java
):import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class FileServer extends UnicastRemoteObject implements FileService {
protected FileServer() throws RemoteException {
super();
}
@Override
public byte[] readFile(String fileName) throws RemoteException {
try {
return Files.readAllBytes(Paths.get(fileName));
} catch (IOException e) {
throw new RemoteException("Erreur lors de la lecture du fichier", e);
}
}
@Override
public void writeFile(String fileName, byte[] data) throws RemoteException {
try {
Files.write(Paths.get(fileName), data);
} catch (IOException e) {
throw new RemoteException("Erreur lors de l'écriture du fichier", e);
}
}
@Override
public void deleteFile(String fileName) throws RemoteException {
try {
Files.deleteIfExists(Paths.get(fileName));
} catch (IOException e) {
throw new RemoteException("Erreur lors de la suppression du fichier", e);
}
}
@Override
public String[] listFiles() throws RemoteException {
try {
return Files.list(Paths.get("")).map(p -> p.getFileName().toString()).toArray(String[]::new);
} catch (IOException e) {
throw new RemoteException("Erreur lors de la récupération de la liste des fichiers", e);
}
}
public static void main(String[] args) {
try {
FileService service = new FileServer();
Naming.rebind("//localhost/FileService", service);
System.out.println("Service de gestion de fichiers prêt.");
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
FileClient.java
):import java.rmi.Naming;
import java.util.Scanner;
public class FileClient {
public static void main(String[] args) {
try {
FileService service = (FileService) Naming.lookup("//localhost/FileService");
Scanner scanner = new Scanner(System.in);
String fileName = "test.txt";
byte[] data = "Hello, world!".getBytes();
// Écriture d'un fichier
service.writeFile(fileName, data);
System.out.println("Fichier écrit avec succès.");
// Lecture d'un fichier
byte[] fileData = service.readFile(fileName);
System.out.println("Contenu du fichier : " + new String(fileData));
// Liste des fichiers
String[] files = service.listFiles();
System.out.println("Liste des fichiers sur le serveur :");
for (String file : files) {
System.out.println(file);
}
// Suppression d'un fichier
service.deleteFile(fileName);
System.out.println("Fichier supprimé avec succès.");
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
Dans cette solution, le serveur fournit des fonctionnalités pour lire, écrire, supprimer et lister des fichiers, tandis que le client se connecte au serveur et utilise ces fonctionnalités via RMI.
Les autres exercices peuvent être implémentés de manière similaire en utilisant des interfaces RMI et des classes serveur et client appropriées pour chaque fonctionnalité spécifique.
ChatService.java
):import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ChatService extends Remote {
void sendMessage(String message) throws RemoteException;
String receiveMessage() throws RemoteException;
}
ChatServer.java
):import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;
public class ChatServer extends UnicastRemoteObject implements ChatService {
private List<String> messages;
protected ChatServer() throws RemoteException {
super();
messages = new ArrayList<>();
}
@Override
public synchronized void sendMessage(String message) throws RemoteException {
messages.add(message);
}
@Override
public synchronized String receiveMessage() throws RemoteException {
if (messages.isEmpty()) {
return "Pas de nouveaux messages";
} else {
String message = messages.get(0);
messages.remove(0);
return message;
}
}
public static void main(String[] args) {
try {
ChatService service = new ChatServer();
Naming.rebind("//localhost/ChatService", service);
System.out.println("Service de chat prêt.");
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
ChatClient.java
):import java.rmi.Naming;
import java.util.Scanner;
public class ChatClient {
public static void main(String[] args) {
try {
ChatService service = (ChatService) Naming.lookup("//localhost/ChatService");
Scanner scanner = new Scanner(System.in);
// Envoi d'un message
System.out.print("Votre message : ");
String message = scanner.nextLine();
service.sendMessage(message);
// Réception des messages
String receivedMessage = service.receiveMessage();
System.out.println("Message reçu : " + receivedMessage);
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
La solution pour l’exercice 3 nécessiterait une conception plus complexe avec la gestion des comptes bancaires, des opérations de dépôt, de retrait et de transfert, ainsi que la prise en charge des transactions sécurisées. Je vais fournir une esquisse simplifiée pour chaque composant :
BankService.java
):import java.rmi.Remote;
import java.rmi.RemoteException;
public interface BankService extends Remote {
void deposit(String accountNumber, double amount) throws RemoteException;
void withdraw(String accountNumber, double amount) throws RemoteException;
void transfer(String fromAccount, String toAccount, double amount) throws RemoteException;
double getBalance(String accountNumber) throws RemoteException;
}
BankServer.java
):import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
public class BankServer extends UnicastRemoteObject implements BankService {
private Map<String, Double> accounts;
protected BankServer() throws RemoteException {
super();
accounts = new HashMap<>();
// Initialisation des comptes avec des soldes fictifs
accounts.put("12345", 1000.0);
accounts.put("67890", 2000.0);
}
@Override
public synchronized void deposit(String accountNumber, double amount) throws RemoteException {
double balance = accounts.getOrDefault(accountNumber, 0.0);
accounts.put(accountNumber, balance + amount);
}
@Override
public synchronized void withdraw(String accountNumber, double amount) throws RemoteException {
double balance = accounts.getOrDefault(accountNumber, 0.0);
if (balance >= amount) {
accounts.put(accountNumber, balance - amount);
} else {
throw new RemoteException("Solde insuffisant");
}
}
@Override
public synchronized void transfer(String fromAccount, String toAccount, double amount) throws RemoteException {
withdraw(fromAccount, amount);
deposit(toAccount, amount);
}
@Override
public synchronized double getBalance(String accountNumber) throws RemoteException {
return accounts.getOrDefault(accountNumber, 0.0);
}
public static void main(String[] args) {
try {
BankService service = new BankServer();
Naming.rebind("//localhost/BankService", service);
System.out.println("Service de gestion bancaire prêt.");
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
Dans ces solutions, le serveur fournit des fonctionnalités de chat et de gestion bancaire, tandis que le client se connecte au serveur et utilise ces fonctionnalités via RMI. Vous pouvez étendre ces solutions pour gérer des fonctionnalités plus avancées et répondre à des besoins spécifiques.
Voici les solutions pour les deux autres exercices avancés sur Java RMI :
ChatService.java
):import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ChatService extends Remote {
void sendMessage(String message) throws RemoteException;
String receiveMessage() throws RemoteException;
}
ChatServer.java
):import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;
public class ChatServer extends UnicastRemoteObject implements ChatService {
private List<String> messages;
protected ChatServer() throws RemoteException {
super();
messages = new ArrayList<>();
}
@Override
public synchronized void sendMessage(String message) throws RemoteException {
messages.add(message);
}
@Override
public synchronized String receiveMessage() throws RemoteException {
if (messages.isEmpty()) {
return "Pas de nouveaux messages";
} else {
String message = messages.get(0);
messages.remove(0);
return message;
}
}
public static void main(String[] args) {
try {
ChatService service = new ChatServer();
Naming.rebind("//localhost/ChatService", service);
System.out.println("Service de chat prêt.");
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
ChatClient.java
):import java.rmi.Naming;
import java.util.Scanner;
public class ChatClient {
public static void main(String[] args) {
try {
ChatService service = (ChatService) Naming.lookup("//localhost/ChatService");
Scanner scanner = new Scanner(System.in);
// Envoi d'un message
System.out.print("Votre message : ");
String message = scanner.nextLine();
service.sendMessage(message);
// Réception des messages
String receivedMessage = service.receiveMessage();
System.out.println("Message reçu : " + receivedMessage);
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
La solution pour l’exercice 3 nécessiterait une conception plus complexe avec la gestion des comptes bancaires, des opérations de dépôt, de retrait et de transfert, ainsi que la prise en charge des transactions sécurisées. Je vais fournir une esquisse simplifiée pour chaque composant :
BankService.java
):import java.rmi.Remote;
import java.rmi.RemoteException;
public interface BankService extends Remote {
void deposit(String accountNumber, double amount) throws RemoteException;
void withdraw(String accountNumber, double amount) throws RemoteException;
void transfer(String fromAccount, String toAccount, double amount) throws RemoteException;
double getBalance(String accountNumber) throws RemoteException;
}
BankServer.java
):import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
public class BankServer extends UnicastRemoteObject implements BankService {
private Map<String, Double> accounts;
protected BankServer() throws RemoteException {
super();
accounts = new HashMap<>();
// Initialisation des comptes avec des soldes fictifs
accounts.put("12345", 1000.0);
accounts.put("67890", 2000.0);
}
@Override
public synchronized void deposit(String accountNumber, double amount) throws RemoteException {
double balance = accounts.getOrDefault(accountNumber, 0.0);
accounts.put(accountNumber, balance + amount);
}
@Override
public synchronized void withdraw(String accountNumber, double amount) throws RemoteException {
double balance = accounts.getOrDefault(accountNumber, 0.0);
if (balance >= amount) {
accounts.put(accountNumber, balance - amount);
} else {
throw new RemoteException("Solde insuffisant");
}
}
@Override
public synchronized void transfer(String fromAccount, String toAccount, double amount) throws RemoteException {
withdraw(fromAccount, amount);
deposit(toAccount, amount);
}
@Override
public synchronized double getBalance(String accountNumber) throws RemoteException {
return accounts.getOrDefault(accountNumber, 0.0);
}
public static void main(String[] args) {
try {
BankService service = new BankServer();
Naming.rebind("//localhost/BankService", service);
System.out.println("Service de gestion bancaire prêt.");
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
Dans ces solutions, le serveur fournit des fonctionnalités de chat et de gestion bancaire, tandis que le client se connecte au serveur et utilise ces fonctionnalités via RMI. Vous pouvez étendre ces solutions pour gérer des fonctionnalités plus avancées et répondre à des besoins spécifiques.
D’accord ! Voici les solutions pour les deux derniers exercices avancés sur Java RMI :
FileSharingService.java
):import java.rmi.Remote;
import java.rmi.RemoteException;
public interface FileSharingService extends Remote {
byte[] downloadFile(String fileName) throws RemoteException;
void uploadFile(String fileName, byte[] data) throws RemoteException;
String[] searchFiles(String keyword) throws RemoteException;
}
FileSharingServer.java
):import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
public class FileSharingServer extends UnicastRemoteObject implements FileSharingService {
private Map<String, byte[]> sharedFiles;
protected FileSharingServer() throws RemoteException {
super();
sharedFiles = new HashMap<>();
}
@Override
public synchronized byte[] downloadFile(String fileName) throws RemoteException {
return sharedFiles.get(fileName);
}
@Override
public synchronized void uploadFile(String fileName, byte[] data) throws RemoteException {
sharedFiles.put(fileName, data);
}
@Override
public synchronized String[] searchFiles(String keyword) throws RemoteException {
return sharedFiles.keySet().stream()
.filter(fileName -> fileName.contains(keyword))
.toArray(String[]::new);
}
public static void main(String[] args) {
try {
FileSharingService service = new FileSharingServer();
Naming.rebind("//localhost/FileSharingService", service);
System.out.println("Service de partage de fichiers prêt.");
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
FileSharingClient.java
):import java.rmi.Naming;
import java.util.Scanner;
public class FileSharingClient {
public static void main(String[] args) {
try {
FileSharingService service = (FileSharingService) Naming.lookup("//localhost/FileSharingService");
Scanner scanner = new Scanner(System.in);
// Uploader un fichier
String fileName = "test.txt";
byte[] data = "Contenu du fichier".getBytes();
service.uploadFile(fileName, data);
System.out.println("Fichier téléchargé avec succès.");
// Rechercher des fichiers
System.out.print("Mot-clé de recherche : ");
String keyword = scanner.nextLine();
String[] files = service.searchFiles(keyword);
System.out.println("Fichiers trouvés : ");
for (String file : files) {
System.out.println(file);
}
// Télécharger un fichier
System.out.print("Sélectionnez un fichier à télécharger : ");
String selectedFile = scanner.nextLine();
byte[] downloadedData = service.downloadFile(selectedFile);
System.out.println("Contenu du fichier téléchargé : " + new String(downloadedData));
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
CalculationService.java
):import java.rmi.Remote;
import java.rmi.RemoteException;
public interface CalculationService extends Remote {
double calculate(double operand1, double operand2, String operator) throws RemoteException;
}
CalculationServer.java
):import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class CalculationServer extends UnicastRemoteObject implements CalculationService {
protected CalculationServer() throws RemoteException {
super();
}
@Override
public double calculate(double operand1, double operand2, String operator) throws RemoteException {
switch (operator) {
case "+":
return operand1 + operand2;
case "-":
return operand1 - operand2;
case "*":
return operand1 * operand2;
case "/":
if (operand2 != 0) {
return operand1 / operand2;
} else {
throw new RemoteException("Division par zéro");
}
default:
throw new RemoteException("Opérateur non valide");
}
}
public static void main(String[] args) {
try {
CalculationService service = new CalculationServer();
Naming.rebind("//localhost/CalculationService", service);
System.out.println("Service de calcul distribué prêt.");
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
CalculationClient.java
):import java.rmi.Naming;
public class CalculationClient {
public static void main(String[] args) {
try {
CalculationService service = (CalculationService) Naming.lookup("//localhost/CalculationService");
double operand1 = 10;
double operand2 = 5;
// Addition
double additionResult = service.calculate(operand1, operand2, "+");
System.out.println("Addition : " + additionResult);
// Soustraction
double subtractionResult = service.calculate(operand1, operand2, "-");
System.out.println("Soustraction : " + subtractionResult);
// Multiplication
double multiplicationResult = service.calculate(operand1, operand2, "*");
System.out.println("Multiplication : " + multiplicationResult);
// Division
double divisionResult = service.calculate(operand1, operand2, "/");
System.out.println("Division : " + divisionResult);
} catch (Exception e) {
System.err.println("Erreur : " + e);
}
}
}
Dans ces solutions, le serveur fournit des fonctionnalités de partage de fichiers et de calcul, tandis que le client se connecte au serveur et utilise ces fonctionnalités via RMI. Ces solutions peuvent être étendues pour inclure des fonctionnalités supplémentaires selon les besoins spécifiques.
Voici une série de questions à choix multiples (QCM) sur Java RMI, couvrant différents aspects de cette technologie :
a) Un mécanisme pour exécuter du code JavaScript dans une application Java.
b) Un langage de modélisation pour créer des modèles en trois dimensions.
c) Un mécanisme de communication entre processus distants en Java.
d) Un framework pour le développement d’applications mobiles en Java.
Réponse correcte : c) Un mécanisme de communication entre processus distants en Java.
a) Créer des animations graphiques en Java.
b) Faciliter la communication entre différentes machines virtuelles Java.
c) Gérer les entrées/sorties de données dans une application Java.
d) Fournir des outils de développement pour créer des jeux en Java.
Réponse correcte : b) Faciliter la communication entre différentes machines virtuelles Java.
a) Java RMI permet d’appeler des méthodes sur des objets distants, tandis que les appels de méthode locaux s’exécutent sur le même ordinateur.
b) Java RMI est utilisé pour la manipulation de bases de données, tandis que les appels de méthode locaux sont utilisés pour les calculs mathématiques.
c) Java RMI ne peut être utilisé que pour les applications web, tandis que les appels de méthode locaux peuvent être utilisés dans n’importe quelle application Java.
d) Il n’y a pas de différence, Java RMI est simplement un autre nom pour les appels de méthode locaux en Java.
Réponse correcte : a) Java RMI permet d’appeler des méthodes sur des objets distants, tandis que les appels de méthode locaux s’exécutent sur le même ordinateur.
a) En utilisant des appels de méthode locaux.
b) En envoyant des requêtes HTTP.
c) En utilisant des appels de méthode distants via l’interface RMI.
d) En utilisant des sockets pour la communication directe.
Réponse correcte : c) En utilisant des appels de méthode distants via l’interface RMI.
a) Définir la structure de base de l’application.
b) Permettre la communication entre le client et le serveur.
c) Contrôler l’accès aux données de l’application.
d) Gérer l’interface utilisateur graphique de l’application.
Réponse correcte : b) Permettre la communication entre le client et le serveur.
a) Authentification basée sur des certificats.
b) Chiffrement des données échangées.
c) Autorisations basées sur des rôles.
d) Toutes les réponses ci-dessus.
Réponse correcte : d) Toutes les réponses ci-dessus.
Ces questions offrent une vue d’ensemble des concepts fondamentaux de Java RMI et peuvent être utilisées pour évaluer la compréhension des étudiants ou des professionnels sur ce sujet.
Voici des exercices corrigés en gestion de stock sur le thème du stock de sécurité,…
L’observation et l’analyse des situations de travail dangereuses sont des étapes clés dans la prévention…
Une fiche méthodologique est un outil structuré et synthétique qui facilite l’organisation et la communication…
Voici une série d’exercices conçus pour perfectionner vos compétences Excel. Les corrigés sont inclus pour…
Excel offre plusieurs méthodes pour calculer une moyenne tout en tenant compte des filtres ou…
Excel propose plusieurs fonctions pour insérer ou manipuler la date actuelle. Voici les principales méthodes…
This website uses cookies.