我在分布式处理工具的范围内遇到了一个涉及 RMI 注册表创建和获取的问题。首先,我将简要描述一下我的环境:
环境
我需要一个后台 Java 进程来永久执行。我的软件实例(在同一台物理机器中)需要与该进程通信才能执行某些操作。几个月前我发现在同一台物理机器上通信不同 JVM 的解决方案是 Java RMI。因此,我启动后台进程并从中创建一个注册表:
CAEATServiceManagerInterface smi = (CAEATServiceManagerInterface)UnicastRemoteObject.exportObject(csm, 0);
Registry registry = LocateRegistry.createRegistry(8090);
registry.rebind("ServiceManager", smi);
注意:csm是要导出的远程对象。安全策略已正确安装(所有人的 AllPermission),RMISecurityManager 也已正确安装。
现在,我的主程序的实例能够在任何给定时刻查找注册表并获取远程对象:
Registry registry = LocateRegistry.getRegistry(8090);
smi = (CAEATServiceManagerInterface)registry.lookup("ServiceManager");
问题
当我的程序(获取注册表的主程序和创建它的后台程序)从 jar 文件中执行时,就会出现问题。如果它们是从 Eclipse 执行的,则一切正常。如果它们直接从命令行执行,也可以。但是当它们被打包成一个自动执行的 jar 文件进行分发时,后台进程似乎可以很好地创建注册表,但是当主程序尝试查找它时,会发生这种情况:
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.io.EOFException
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at sener.caeat.autoejecutable.PublicadorStandalone.getServiceManagerInterface(PublicadorStandalone.java:170)
at sener.caeat.autoejecutable.PublicadorStandalone.publicarEsquema(PublicadorStandalone.java:319)
at sener.caeat.autoejecutable.CargadorStandalone.mostrarDialogoOpcionesPublicacion(CargadorStandalone.java:415)
at sener.caeat.autoejecutable.ExtractorJars.main(ExtractorJars.java:32)
Caused by: java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2553)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1296)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at sun.rmi.server.MarshalInputStream.readLocation(MarshalInputStream.java:285)
at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:228)
at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1530)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1492)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
... 5 more
忘记我的课程,我不明白的是 EOFException ...为什么它只在程序从 jar 中执行时才启动?
附加数据:如果后台程序是从jar文件中启动的,但是查找注册表的主程序是从Eclipse启动的,问题仍然存在。
提前致谢。