Прохожу курс "Построение распределенных систем на Java" в третьей лекции где описывается TCPServer вылетает эта ошибка
"Connection cannot be resolved to a type" Java version 1.7.0_05 |
Использование Java RMI
Второй пример
В предыдущем примере мы создали серверный объект, который принимает от клиента (методы изменения баланса) и возвращает клиенту (метод запроса значения баланса) переменные простых типов. Однако с помощью RMI могут создаваться приложения, обмен в которых осуществляется посредством передачи сложных типов - классов, определенных пользователем. Для того чтобы проиллюстрировать эту технику, изменим наш пример. Предположим, что операции начисления и списания наличных с карт передаются на сервер не по одной, а пакетом, т.е. массивом. Предположим также, что у сервера вместо метода запроса баланса должен быть реализован метод запроса карты по ее идентификатору. Карта - класс, который кроме номера содержит также имя владельца, баланс и дату заведения.
Определение удаленного интерфейса
В отличие от предыдущего варианта интерфейс BillingService (пример 5.7) имеет не четыре, а три метода. Метод addNewCard (строка 11) заводит новую карту с указанными параметрами. Метод processOperations (строка 13) производит изменение баланса карт с указанными параметрами. В предыдущей реализации изменение баланса карты производилось двумя методами, один из которых увеличивал текущий баланс карты, другой - уменьшал, а величина изменения в любом случае была положительной. В данном случае величина изменения баланса может быть любой - как положительной, так и отрицательной; в первом случае это означает поступление денежных средств на баланс карты, во втором - списание денежных средств. Метод getCard (строка 15) по номеру карты возвращает экземпляр класса Card.
1 // BillingService.java 2 // Интерфейс BillingService объявляет методы для работы 3 // с пластиковыми картами 4 package com.asw.rmi.ex2; 5 6 // Набор базовых пакетов Java 7 import java.rmi.*; 8 9 public interface BillingService extends Remote { 10 // определение новой карты 11 public void addNewCard(Card card) throws RemoteException; 12 // изменение баланса карты 13 public void processOperations(CardOperation[] operations) throws RemoteException; 14 // получение баланса карты 15 public Card getCard(String card) throws RemoteException; 16 }Листинг 5.7. Интерфейс BillingService
Как уже говорилось ранее, RMI использует механизм сериализации по умолчанию Java для передачи параметров методу и возврата значений через сеть. Поэтому все классы, используемые в качестве параметров метода и возвращаемых значений, должны иметь описатель Serializable.
Тип Card (пример 5.8) несет информацию об имени посетителя ( person ), дате получения карты (createDate),номере карты (cardNumber) и балансе (balance).
1 // Card.java 2 // описание типа переменных Card 3 package com.asw.rmi.ex2; 4 5 // Набор базовых пакетов Java 6 import java.io.Serializable; 7 import java.util.*; 8 9 public class Card implements Serializable{ 10 public Card(String person, Date createDate, String cardNumber, double balance)] 11 this.person = person; 12 this.createDate = createDate; 13 this.cardNumber = cardNumber; 14 this.balance = balance; 15 } 16 public String person; 17 public Date createDate; 18 public String cardNumber; 19 double balance; 20 public String toString(){ 21 return "Card: cardNumber="+cardNumber+"\tBalance="+balance+ 22 +"\tPerson="+person+"\tCreateDate="+createDate+""; 23 } 24 }Листинг 5.8. Описание типа Card
Тип CardOperation (пример 5.9) представляет собой одну операцию изменения баланса карты и несет информацию о номере карты (card),величине изменения баланса карты ( amount ) и дате операции (operationDate).
1 // CardOperation.java 2 // описание типа переменных CardOperation 3 package com.asw.rmi.ex2; 4 5 // Набор базовых пакетов Java 6 import java.util.*; 7 import java.io.*; 8 9 public class CardOperation implements Serializable { 10 public CardOperation(String card,double amount,Date operationDate){ 11 this.card = card; 12 this.amount = amount; 13 this.operationDate = operationDate; 14 } 15 public String card; 16 public double amount; 17 public Date operationDate; 18 }Листинг 5.9. Описание типа CardOperation
Реализация удаленного интерфейса
Класс BillingServiceImpl (пример 5.10) является удаленным объектом, который реализует удаленный интерфейс BillingService.Класс BillingServiceImpl реализует методы addNewCard (строки 22-25), processOperations (строки 28-36), getCard (строки 39-42) интерфейса BillingService,чтобы отвечать на удаленные запросы. Класс BillingServiceImpl хранит сведения о картах в хэш-таблице (Hashtable),содержащей карты (Card),где номер карты (cardNumber) является ключом таблицы.
1 // BillingServicelmpl.java 2 // BillingServiceImpl реализует удаленный интерфейс BillingService 3 // для предоставления удаленного объекта BillingService 4 package com.asw.rmi.ex2; 5 6 // Набор базовых пакетов Java 7 import java.rmi.*; 8 import java.util.*; 9 import java.rmi.server.*; 10 11 public class BillingServiceImpl extends UnicastRemoteObject 12 implements BillingService { 13 14 private Hashtable hash; // хэш-таблица для хранения карт 15 // инициализация сервера 16 public BillingServiceImpl() throws RemoteException] 17 super(); 18 hash = new Hashtable(); 19 } 20 21 // реализация метода addNewCard интерфейса BillingService 22 public void addNewCard(Card card) throws RemoteException { 23 24 hash.put(card.cardNumber, card); 25 } 26 27 // реализация метода processOperations интерфейса BillingService 28 public void processOperations(CardOperation[] operations) 29 throws RemoteException { 30 for (int i=0;i<operations.length;i++){ 31 Card c = (Card)hash.get(operations[i].card); 32 if (c==null) throw new NotExistsCardOperation(); 33 c.balance+=operations[i].amount; 34 hash.put(operations[i].card,c); 35 } 36 } 37 38 // реализация метода getCard интерфейса BillingService 39 public Card getCard(String card) throws RemoteException{ 40 Card c = (Card)hash.get(card); 41 return c; 42 }; 43 44 // запуск удаленного объекта BillingService 45 public static void main (String[] args) throws Exception { 46 System.out.println("Initializing BillingService..."); 47 48 // создание удаленного объекта 49 BillingService service = new BillingServiceImpl(); 50 51 //задание имени удаленного объекта 52 String serviceName = "rmi://localhost/BillingService"; 53 // регистрация удаленного объекта BillingService в реестре rmiregistry 54 Naming.rebind(serviceName, service); 55 } 56 57 }Листинг 5.10. Класс BillingServiceImpl реализует удаленный интерфейс BillingService
Метод main (строки 45-55) создает удаленный объект BillingServiceImpl.В строке 52 определяется URL, который клиент может применить для получения удаленной ссылки на объект для вызова методов удаленного объекта.
В этой программе URL удаленного объекта имеет вид rmi://localhost/BillingService, т.е. реестр RMI выполняется на машине localhost (т.е. на локальном компьютере), а для обнаружения клиентом сервиса должно использоваться имя BillingService.Имя localhost является синонимом IP -адреса 127.0.0.1.
В строке 54 вызывается статический метод rebind класса Naming (пакет java.rmi) для связывания удаленного объекта service класса BillingServiceImpl в реестре RMI с URL rmi://localhost/BillingService.
Класс NotExistsCardOperation (пример 5.11) расширяет класс RemoteException.
1 // NotExistsCardOperation.java 2 package com.asw.rmi.ex2; 3 4 // Набор базовых пакетов Java 5 import java.rmi.RemoteException; 6 7 public class NotExistsCardOperation extends RemoteException { 8 9 }Листинг 5.11. Класс NotExistsCardOperation реализует обработку исключений