Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Работа с сетью > Помогите разобраться с RMI


Автор: korotin 4.5.2009, 15:22
Здравствуйте! 
Помогите запустить простейшее приложение. Допустим оно будет складывать два числа.

У меня JDK 1.6


Вот что я делаю:

Запускал клиентскую часть и серверную на одной машине, все работало, но на разных никак.
В чем причина?

Проконтролируйте, пожалуйста, мои действия

1)Создаю интерфейс

Код

package server;
//а для клиентской стороны
//package client;

import java.rmi.Remote;
import java.rmi.RemoteException;


public interface Adder extends Remote {
    public int add() throws RemoteException;
}


далее выполняю команду:
javac  client/Adder.java

2)Так как для данной версии JDK скелеты и стабы не нужны, 
то реализую класс для удаленных объектов:

Код

package server;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class AdderImpl extends UnicastRemoteObject implements Adder {

    private int a;
    private int b;

    public ProductImpl(int a, int b) throws RemoteException {
        this.a = a;
        this.b = b;
    }

    public int add() throws RemoteException {
        return (a+b);
    }
}


далее выполняю команду:
javac  client/AdderImpl.java

3)Программа сервер:

Код

package server;

import javax.naming.*;

public class AdderServer {
    public static void main(String[] args) {
        try{
            AdderImpl adder = new AdderImpl(7, 3);

            System.out.println("[begin]");

            Context cont = new InitialContext();
            cont.bind("rmi:michael", adder);

            
            System.out.println("[end]");
            
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}


далее выполняю команду:
javac  server/AdderServer.java

4)Запуск сервера. 
Я запускаю сервер на одной машине, 
клиентскую часть на другой. 

-Активизирую службу регистрации:
start rmiregistry

-Запуск AdderServer:
start java server.AdderServer


5)Клиентская часть:

Код

package client;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.swing.JDialog;
import javax.swing.JOptionPane;

public class AdderClient extends JOptionPane{

    public static void main(String[] args) {
        String url = "rmi://100.100.0.1/";//IP я заменял на имя host компьютера, но ничего не изменилось
        try {
            Context cont = new InitialContext();
            Adder adder = (Adder) cont.lookup(url + "michael");

            System.out.println(adder.add());

        } catch (Exception e) {
            JOptionPane jop = new JOptionPane(e.getMessage(), JOptionPane.ERROR_MESSAGE);
            JDialog d = jop.createDialog(jop, "Ошибка.");
            d.setVisible(true);
        }


    }
}



далее выполняю команду:
javac  client/AdderClient.java
java  client.AdderClient

Автор: korotin 5.5.2009, 23:48
Люди пожалуйста подскажите, где косяки. 
В последовательности моих действий вы не найдете использование файлов policy, потому что прочитав статейку, в которой сказано о том, что policy не используются в jdk1.5, я и удалил этот файл. Возможно в этом косяк? 
При использовании файлов policy и включение в код подобных строчек:
Код

System.setProperty("java.security.policy", "client.policy");
System.setSecurityManager(new RMISecurityManager());

возникает исключение.(((

Автор: Kangaroo 6.5.2009, 10:28
Цитата(korotin @  5.5.2009,  23:48 Найти цитируемый пост)
возникает исключение.((( 

Какое?

И что происходит при запуске без этих строчек?

Автор: Fieral 6.5.2009, 17:05
работай по этой инструкции:
http://patriot.net/~tvalesky/easyrmi.html
там всё довольно подробно и работоспособно

Автор: korotin 6.5.2009, 22:21
Цитата(Kangaroo @  6.5.2009,  10:28 Найти цитируемый пост)
возникает исключение.((( 

Какое?


Вот какой выводится exception:
java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099 connect,resolve)

Файл policy, например, для класса-сервер добавил в тот же пакет, где расположен сам класс.
Может вместо:
Код

System.setProperty("java.security.policy", "server.policy");

нужно указать
Код

System.setProperty("java.security.policy", "D:/Mi}{ey/ProgJ/IN_S/NetBeans6.5/TestWORK/build/classes/RMI_test/server/server.policy");
, но и так выводит все тот же exception.

Цитата(Kangaroo @  6.5.2009,  10:28 Найти цитируемый пост)
И что происходит при запуске без этих строчек? 

При запуске на одной машине работает. Если запускаю на разных, то в классе-клиент возникает exception, объект которого, с помощью метода e.getMessage - ничего не выводит, а так e.toString выводит вот что:
javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: 100.100.0.1; nested exception is:    java.net.ConnectException: Connection refused: connect]

Автор: korotin 7.5.2009, 23:56
После удаления строк(в классах клиент и сервер):

Код

System.setProperty("java.security.policy", "client.policy");
System.setSecurityManager(new RMISecurityManager());


И после некоторых изменений:

1)Вместо номера Ip  rmi://{номер Ip}/ использую rmi://{имя компьютера}/
2)
Вместо класса Context использую кдасс Naming(в классе клиент):
до:
Код

Context cont = new InitialContext();
Adder adder = (Adder) cont.lookup(url + "michael");


после:
Код

Adder adder = (Adder) Naming.lookup(url + "michael");


3) Вместо Context использую Naming(в классе сервер)
до:
Код

Context cont = new InitialContext();
cont.bind("michael", p1);


после:
Код

Naming.rebind("michael", p1);


4) Сгенерировал _Stup, командой rmic и разместил его на сервере и клиенте

Вот что показывает exception на стороне клиента:
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:    java.lang.ClassNotFoundException: RMI_test.server.ProductImpl_Stub (no security manager: RMI class loader disabled)


Подскажите как правильно использовать файлы policy? Нужно ли их использовать, если да, то куда добавить(в пакет с классами?)?
Файлы policy нужны только для клиента или для сервера тоже нужны?
Сгенерированный _Stub нужно ли добавить в пакет с классом клиента или он нужен только в пакете сервера?

Автор: Fieral 8.5.2009, 13:12
создай файл .java.policy в папке юзера  (в висте это тут C:\Users\%username%\.java.policy)
с контентом:
Код

grant {
  permission java.security.AllPermission;
};

Автор: korotin 8.5.2009, 21:34
Хорошую инфу. Fieral подкидываете, процесс немного движется.

Цитата(Fieral @  8.5.2009,  13:12 Найти цитируемый пост)
создай файл .java.policy в папке юзера  (в висте это тут C:\Users\%username%\.java.policy)
с контентом:...


Так и сделал, поместил .java.policy в папку user. Сначало только на стороне сервера, клиент выводил вес те же exception'ы, но после таких же действий на стороне клиента exception изменился:


java.rmi.UnmarshalException: error unmarshalling return; nested exception is:    java.lang.ClassNotFoundException: RMI_test.server.ProductImpl_Stub


Теперь клиент не может найти _Stub на стороне сервера, но он же содержится в пакете RMI_test.server
Нужно ли добавить в CLASSPATH путь к _Stub ? Если да, то как лучше это сделать, прописать его в системных переменных руками или
воспользоваться командной строкой:
set CLASSPATH=... ?

Много статей по этой теме, но рассматривается чаще всего версия jdk1.2, есть и 1.5, но там используются апплеты или просто автор разобравшись закрыл тему. Вот и возникают трудности(( 




Автор: Fieral 11.5.2009, 17:16
Попробуй так:

Создай 3 проекта.
1) Server
2) Client
3) DataSets

В DataSets создай классы которые ты собрался передавать. (Например класс Message)
Откомпиль DataSets в jar-ку.

Server и Client размести на разных машинах.

Подключи полученную jar-ку в первые два проекта (внеси её в "зависимости").

полиси-файл помоему достаточно разместить на сервере, (но размести на всякий случай и на клиенте)

Ну, а дальше попробуй запустить сервер и скинуть ему Message. (например создай метод Message Drop(Message m) throws RemoteException )

Да кстати все методы удалённого интерфейса должны "кидать" RemoteException (ну или "тип-того-Exception" - точно не помню) 
ну и сам "удалённый интерфейс" расположи в проекте DataSets

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)