以下方法:
private void startServer() { // snippet that starts the server on the local machine
try {
RemoteMethodImpl impl = new RemoteMethodImpl();
Naming.rebind( "Illusive-Server" , impl );
}catch(Exception exc) {
JOptionPane.showMessageDialog(this, "Problem starting the server", "Error", JOptionPane.ERROR_MESSAGE);
System.out.println(exc);
}
}
引发此异常: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.lang.ClassNotFoundException: Interfaces.RemoteMethodIntf
当我启动我的项目时,joptionpane中的消息告诉我启动服务器时出现问题,然后出现上述异常。为什么会这样?
我不明白为什么在我导入了正确的包之后,最后一个异常语句会说class not found exc
5条答案
按热度按时间kpbpu0081#
要解决此错误非常简单,请执行以下步骤:
例如,您的java文件需要考虑d驱动器
启动rmiregistry d驱动器(示例d:\start rmiregistry),然后不要在其他驱动器上启动rmiregistry,这将产生上述错误
(无论你的文件在哪里,开始
rmiregistry
)epfja78i2#
有四种例外情况。
导出时:您没有运行“rmic”,也没有按照javadoc前言中描述的步骤进行导出
UnicastRemoteObject
使它不必要。绑定时:注册表没有存根、远程接口或依赖于其类路径的东西。
查找时:客户机的类路径上没有这些东西。
在调用远程方法时:您要么向类路径上不存在的类的服务器发送了一些内容,或者从不在类路径上的类的服务器(包括异常)接收到某些内容:在这两种情况下,都可能是远程接口的方法签名中提到的类或接口的派生类或接口实现。
这是第二种情况。注册表找不到命名类。
有几种解决方案:
用包含相关jar或目录的类路径启动注册表。
在服务器jvm中启动注册表,通过
LocateRegistry.createRegistry().
使用动态存根,如UnicastRemoteObject.
但是,您可能仍然会遇到与远程接口本身或它所依赖的类相同的问题,在这种情况下,上面的1-3仍然适用于该类。确保上述情况(4)不会发生。
使用代码库功能。这实际上是一个部署选项,在初始开发阶段需要避免。
xkftehaa3#
您可以从任何地方启动rmiregistry,但必须确保编译的类已经在类路径中。为了example:-
以上的方法应该很有效。
通常,如果您从编译类的根位置启动rmiregistry(上面的示例是e:\armsremoteupdater\webcontent\web inf\classes),这将起作用,因为(点-当前目录)已在类路径中设置。
但一旦你离开(点-当前目录),上述工作条件也将失败。
希望我已经详细解释过了。
u0njafvf4#
我将尽可能地更好地解释我所做的:1.我声明classpath变量如下:
set classpath=%classpath%
set classpath=C:\compilerset classpath=C:\compiler\libro\cap07\rmi\hello\Hello.java
set classpath=C:\compiler\libro\cap07\rmi\hello\Server.javaset classpath=C:\compiler\libro\cap07\rmi\hello\Client.java
(一体式线条集:set classpath=%classpath%;C:\compiler;C:\compiler\libro\cap07\rmi\hello\Hello.java;C:\compiler\libro\cap07\rmi\hello\Server.java;C:\compiler\libro\cap07\rmi\hello\Client.java)
(我不确定这些.java文件是否是安全的,但我也写了它们以示怀疑)。第二。我用这句台词编译
javac -d C:\compiler Hello.java Server.java Client.java
. 哪里C:\compiler
是根目录,类似于eclipseide上的src。3.我跑了
start rmiregistry
线路(唐呢´不管你把它放在哪里,都是一样的)。第四。我跑了:
start java -classpath C:\compiler -Djava.rmi.server.codebase=file:C:\compiler/ libro.cap07.rmi.hello.Server
你已经知道了C:\compiler
,但您需要在最后定义包地址,以便命令可以找到.class文件。打开任何.java文件并复制包地址而不复制包sentense。当您打开src目录(在我的例子中是c:\compiler)时,您将看到创建的所有目录序列。当这个命令行被正确地创建时,不管您在哪里运行它,c:,d:,src,它将在任何地方运行。第五。最后,我运行了客户端类:
java -classpath C:\compiler libro.cap07.rmi.hello.Client
总之,如果classpath变量没有创建,或者创建错误,或者第4点的语句没有得到很好的处理,jvm就会抛出相同或类似的错误。在那里搜索!(对不起我的英语)。
knsnq2tg5#
我遇到了同样的问题,一个不同的解决方案对我有效。我运行了两个不同的intellij项目,每个项目中都有一个接口的副本。其中一个在包中,另一个没有,这就是导致这个错误的原因。
解决:
确保接口副本不在包中。
确保接口副本具有完全相同的包名称。