【问题标题】:Running an RMI application from Command Prompt从命令提示符运行 RMI 应用程序
【发布时间】:2010-01-15 01:06:54
【问题描述】:

我一直在开发一个(有些复杂的)应用程序,它使用 RMI 来读取文件并以 JSON 格式读取其内容。我一直在 Netbeans 6.7 上编写此应用程序,因此我的文件夹结构如下:

在 C:\MyApp: 下

-构建

--- 类

------- MyApp

-dist

---库

--------- [一些 .jar 库]

-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。

请帮忙!谢谢!

【问题讨论】:

    标签: java rmi distributed-computing


    【解决方案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);
    

    【讨论】:

      【解决方案2】:

      谢谢赫利俄斯。你的回答很翔实。如果需要,我已将其保存以备将来参考。

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

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

      然后,我将该类路径参数更改为更简单的参数。我去了我的项目根目录,然后从那里引用了必要的库,例如

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

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

      现在,一切似乎都正常了。客户端可以与服务器通信。我现在只在 localhost 上进行了测试,我不能说它是否可以在网络上的机器上运行。我相信 ClassNotFound 异常是由于 RMI 注册表没有正确启动(它没有找到类。)

      希望我的解决方案实际上是合适的。我不明白那个代码库的东西。它应该如何动态下载类或其他什么。我仍然是 Java/RMI 学生/菜鸟。

      【讨论】:

      • 我不记得你在客户端需要什么才能在没有错误的情况下使用服务器对象,但我认为你只需要接口和直接从它们引用的类(如参数对象)。跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-13
      • 2017-02-26
      • 2017-11-15
      • 1970-01-01
      相关资源
      最近更新 更多