Запуск приложения RMI из командной строки - PullRequest
0 голосов
/ 15 января 2010

Я разрабатывал (несколько сложное) приложение, использующее RMI для чтения файла и JSON его содержимого. Я кодировал это приложение на NetBeans 6.7, поэтому у меня есть структура папок следующим образом:

Под C: \ MyApp:

-Build

--- классы

------- MyApp <--- Это пакет. Мои файлы .class там. Кроме того, я управлял отсюда. </p>

-dist

--- Lib

--------- [некоторые библиотеки .jar]

-src

...

[Некоторые файлы]

Мое приложение использует библиотеку из папки dist \ libs и загружает один файл для чтения из текущего каталога в разделе [Некоторые файлы].

Однако всякий раз, когда я запускаю приложение, используя: (из папки build \ classes)

java -cp .;..\..\dist\lib\gson-1.4.jar;..\..\..\MyApp -Djava.security.policy=C:\java.policy MyApp.Main

Я продолжаю получать ошибки ClassNotFoundException и список ошибок, касающихся моего интерфейса RMI, не найден. Однажды он не смог найти файл, который мне нужно прочитать. (Получил исключение NullPointerException в моем приложении).

Не могли бы вы, люди, сказать мне, что я делаю неправильно? Я считаю, что это связано с classpath.

Кроме того, если бы был способ запустить приложение RMI из самого Netbeans, было бы замечательно, но я не смог найти никакого способа сделать это во время поиска.

Ох, магистр работает. И мой файл политики содержит простой грант All.

Пожалуйста, помогите! Спасибо!

Ответы [ 2 ]

1 голос
/ 15 января 2010

Спасибо, Гелиос. Ваш ответ информативен. Я сохранил его для дальнейшего использования, если оно мне понадобится.

Во всяком случае, мне удалось решить проблему до того, как был опубликован ответ. Я не хотел использовать сложные вещи, такие как кодовая база и веб-серверы и еще много чего.

Во-первых, я пошел в папку build \ classes и оттуда запустил rmiregistry. Я знаю, что если он обнаруживает классы в classpath, он игнорирует параметр codebase. Это то, что я хотел.

Затем я изменил этот параметр classpath на что-то более простое. Я пошел в корень своего проекта, а затем сослался на необходимые библиотеки оттуда как

-classpath .;dist\lib <the jar files I needed>;build\classes

Наконец, для клиента у меня был файл интерфейса RMI непосредственно в основном пакете проекта. Оказывается, он должен быть в том же пакете, что и на сервере. Поэтому я создал необходимый пакет на клиенте и разместил там интерфейс RMI. Я использовал CodeBase для запуска на клиенте, но постоянно получал ошибку «$ Proxy0 not cast cast», которая дала мне решение по поводу пакета.

Теперь, похоже, все работает. Клиент может общаться с сервером. Пока я тестировал только на localhost, я не могу сказать, будет ли он работать с компьютеров в сети. Я полагаю, что исключения ClassNotFound произошли из-за того, что реестр RMI не был запущен должным образом (он не находил классы.)

Надеюсь, мое решение действительно уместно. Я не понимаю эту вещь кодовой базы. Как это должно динамически загружать классы или что-то еще. Я все еще учусь на Java / RMI / noob.

1 голос
/ 15 января 2010

Я думаю, вы должны указать c:\MyApp\build\classes в classpath, а НЕ ..\..\..\MyApp вещь, которую я понимаю, это базовый каталог вашего проекта.

По крайней мере ... с этим ваш Java будет иметь доступ к классам вашего проекта.

РЕДАКТИРОВАТЬ: пример применения без RMIRegistry

Если вы обычно запускаете свое приложение (на стороне сервера), вы можете опубликовать свой RMI-объект без инструмента rmiregisty. Он просто создает собственный реестр, резервируя и прослушивая на выбранном вами порту.

Это рабочий пример из приложения, которое я сделал.

Клиентское приложение должно будет иметь только интерфейс объекта в своем пути к классам (и, конечно, все интерфейсы и классы, на которые ссылаются!).

BatchServer - это RMI-объект, реализующий интерфейс RMI (BatchService) и не расширяющий ничего, в частности.

public static void publishAndRun(int port, String name, BatchServer server) throws RemoteException, AlreadyBoundException, NotBoundException
{
    Registry registry = LocateRegistry.createRegistry(port);
    GPRSService stub = (BatchService) UnicastRemoteObject.exportObject(server, 0);
    try
    {
        registry.bind(name, stub);
        try
        {
            server.run();
        }
        finally
        {
            registry.unbind(name);
        }
    }
    finally
    {
        UnicastRemoteObject.unexportObject(server, true);
    }
}

Вашему клиентскому приложению придется искать ВАШ реестр на компьютере: порт и запрашивать объект name:

    Registry registry = LocateRegistry.getRegistry(server, port);
    BatchService gprs = (BatchService)  registry.lookup(name);
...