从命令提示符运行RMI应用程序

时间:2010-01-15 01:06:55

标签: java rmi distributed-computing

我一直在开发一个(有点复杂的)应用程序,使用RMI读取文件和JSON的内容。我一直在Netbeans 6.7上编写这个应用程序,因此我有一个文件夹结构如下:

在C:\ MyApp:

-build

---班级

------- MyApp< ---这是一个包。我的.class文件在那里。另外,我从这里开始运行rmiregistry。

-dist

--- LIB

--------- [some .jar libraries]

-src

...

[部分文件]

我的应用程序使用dist \ libs文件夹中的库,并在[Some files]部分中加载单个文件以便从当前目录中读取。

但是,每当我使用:(来自build \ classes文件夹)运行应用程序时

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

我一直收到ClassNotFoundException错误,并且找不到有关我的RMI接口的错误列表。有一次它运行,它无法找到我需要阅读的文件。 (在我的应用程序中得到了NullPointerException。)

你能不能告诉我我做错了什么?我相信它与类路径有关。

此外,如果有一种方法可以从Netbeans本身运行RMI应用程序,那就太好了,但是我在搜索时无法找到任何方法。

哦,rmiregistry正在运行。我的策略文件包含一个简单的单行授权All。

请帮忙!谢谢!

2 个答案:

答案 0 :(得分:1)

我认为你应该在类路径中提供c:\MyApp\build\classes而不是我理解的..\..\..\MyApp是你的项目基目录。

至少......你的java可以访问你项目的类。

编辑:没有RMIRegistry的应用程序示例

如果您正常运行应用程序(服务器端),则可以在不使用rmiregisty工具的情况下发布RMI对象。它很简单,在你选择的某个端口创建自己的注册表保留和监听。

这是我做过的应用程序的一个工作示例。

客户端应用程序只需要在其类路径中包含对象的接口(当然还有所有引用的接口和类!)。

BatchServer是实现RMI接口(BatchService)的RMI对象,并没有特别扩展。

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);
    }
}

您的客户端应用程序必须在machine:port中查找您的注册表并询问name对象:

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

答案 1 :(得分:1)

谢谢Helios。你的答案是有用的。如果需要的话,我保存了以备将来参考。

无论如何,我在发布答案之前设法解决了问题。我不想使用复杂的东西,比如代码库和网络服务器等等。

首先,我转到build \ classes文件夹并从那里运行rmiregistry。我知道如果它检测到类路径中的类,它会忽略codebase参数。这就是我想要的。

然后,我将该classpath参数更改为更简单的参数。我转到我的项目根目录,然后从那里引用必要的库,如

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

最后,对于客户端,我直接在主项目包中使用了RMI接口文件。事实证明它应该与服务器上的包在同一个包中。所以我在客户端上创建了必要的包,并将RMI接口放在那里。我使用CodeBase作为客户端的开始,但不断得到“$ Proxy0无法投射”错误,这给了我关于包装的解决方案。

现在,一切似乎都在发挥作用。客户端可以与服务器通信。我现在只在localhost上测试过,我不知道它是否适用于网络上的机器。我相信ClassNotFound异常是由于RMI注册表未正确启动(它没有找到类。)

希望我的解决方案实际上是合适的。我不明白代码库的事情。如何动态下载类或其他什么。我还是一名Java / RMI学生/菜鸟。