当前位置: 技术问答>java相关
关于rmi的问题???怪怪的.
来源: 互联网 发布时间:2015-08-30
本文导语: 如果我在我的包含*.class的目录中启动rmiregistry,然后再启动的我的ProductServer不会出错。但是在其他目录启动rmiregistry后,在再包含*.class的目录中启动ProductServer出错。 Constructing server implements... Binding server implements...
如果我在我的包含*.class的目录中启动rmiregistry,然后再启动的我的ProductServer不会出错。但是在其他目录启动rmiregistry后,在再包含*.class的目录中启动ProductServer出错。
Constructing server implements...
Binding server implements to registry...
Error:java.rmi.ServerException: RemoteException occurred in server thread; neste
d exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested excep
tion is:
java.lang.ClassNotFoundException: ProductImpl_Stub
我的程序如下:
import java.rmi.*;
public interface Product extends Remote
{
public String getDescription() throws RemoteException;
}
import java.rmi.*;
import java.rmi.server.*;
public class ProductClient
{
public static void main(String args[])
{
System.setSecurityManager(new RMISecurityManager());
String url="rmi://localhost/";
try
{
Product c1=(Product)Naming.lookup(url+"toaster");
Product c2=(Product)Naming.lookup(url+"microwave");
System.out.println(c1.getDescription());
System.out.println(c2.getDescription());
}
catch(Exception e){System.out.println("Error:"+e);}
System.exit(0);
}
}
import java.rmi.*;
import java.rmi.server.*;
public class ProductImpl extends UnicastRemoteObject implements Product
{
public ProductImpl(String n) throws RemoteException
{
name=n;
}
public String getDescription() throws RemoteException
{
return "I am a "+name+". Buy me!";
}
private String name;
}
import java.rmi.*;
import java.rmi.server.*;
import sun.applet.*;
public class ProductServer
{
public static void main(String args[])
{
try
{
System.out.println("Constructing server implements...");
ProductImpl p1=new ProductImpl("Blackwell Toaster");
ProductImpl p2=new ProductImpl("ZapXpress Microwave Oven");
System.out.println("Binding server implements to registry...");
Naming.rebind("toaster",p1);
Naming.rebind("microwave",p2);
System.out.println("Waiting for invocations from clients...");
}catch(Exception e){System.out.println("Error:"+e);}
}
}
Constructing server implements...
Binding server implements to registry...
Error:java.rmi.ServerException: RemoteException occurred in server thread; neste
d exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested excep
tion is:
java.lang.ClassNotFoundException: ProductImpl_Stub
我的程序如下:
import java.rmi.*;
public interface Product extends Remote
{
public String getDescription() throws RemoteException;
}
import java.rmi.*;
import java.rmi.server.*;
public class ProductClient
{
public static void main(String args[])
{
System.setSecurityManager(new RMISecurityManager());
String url="rmi://localhost/";
try
{
Product c1=(Product)Naming.lookup(url+"toaster");
Product c2=(Product)Naming.lookup(url+"microwave");
System.out.println(c1.getDescription());
System.out.println(c2.getDescription());
}
catch(Exception e){System.out.println("Error:"+e);}
System.exit(0);
}
}
import java.rmi.*;
import java.rmi.server.*;
public class ProductImpl extends UnicastRemoteObject implements Product
{
public ProductImpl(String n) throws RemoteException
{
name=n;
}
public String getDescription() throws RemoteException
{
return "I am a "+name+". Buy me!";
}
private String name;
}
import java.rmi.*;
import java.rmi.server.*;
import sun.applet.*;
public class ProductServer
{
public static void main(String args[])
{
try
{
System.out.println("Constructing server implements...");
ProductImpl p1=new ProductImpl("Blackwell Toaster");
ProductImpl p2=new ProductImpl("ZapXpress Microwave Oven");
System.out.println("Binding server implements to registry...");
Naming.rebind("toaster",p1);
Naming.rebind("microwave",p2);
System.out.println("Waiting for invocations from clients...");
}catch(Exception e){System.out.println("Error:"+e);}
}
}
|
在rebind()的时候,rmiregistry 要寻找stub 和 skeleton类来序列化和反序列化客户端的请求。
你的问题比较明白,stub类所在的路径没有被包含进 CLASSPATH 中,但是当前路径 “.”在CLASSPATH中。所以rmiregistry在你的.class路径中启动就没错,但是在其他地方不行。
另外,rmiregistry 不能在包括 stub 的目录下运行,否则客户端不能得到 stub. stub 是要传递给客户的,否则客户没有帮法序列化对server的请求。但是rmiregistry发现当前路径下有stub,就会认为客户已经得到了stub,于是就不传递了。
rmi的深入理解有些复杂的地方,多看看书,在做实验吧!
你的问题比较明白,stub类所在的路径没有被包含进 CLASSPATH 中,但是当前路径 “.”在CLASSPATH中。所以rmiregistry在你的.class路径中启动就没错,但是在其他地方不行。
另外,rmiregistry 不能在包括 stub 的目录下运行,否则客户端不能得到 stub. stub 是要传递给客户的,否则客户没有帮法序列化对server的请求。但是rmiregistry发现当前路径下有stub,就会认为客户已经得到了stub,于是就不传递了。
rmi的深入理解有些复杂的地方,多看看书,在做实验吧!
|
如果我在我的包含*.class的目录中启动rmiregistry,然后再启动的我的ProductServer不会出错。但是在其他目录启动rmiregistry后,在再包含*.class的目录中启动ProductServer出错。
rmiregistry所在的jvm(实例)和你的服务器所用的jvm不是一个,所以:
"如果我在我的包含*.class的目录中启动rmiregistry,然后再启动的我的ProductServer不会出错。" 因为,rmiregistry所用的jvm能找到需要的类。
"但是在其他目录启动rmiregistry后,在再包含*.class的目录中启动ProductServer出错。" 因为,虽然你的ProductServer所用的jvm能找到需要的类,但是rmiregistry所用的jvm却找不到需要的类。
rmiregistry所在的jvm(实例)和你的服务器所用的jvm不是一个,所以:
"如果我在我的包含*.class的目录中启动rmiregistry,然后再启动的我的ProductServer不会出错。" 因为,rmiregistry所用的jvm能找到需要的类。
"但是在其他目录启动rmiregistry后,在再包含*.class的目录中启动ProductServer出错。" 因为,虽然你的ProductServer所用的jvm能找到需要的类,但是rmiregistry所用的jvm却找不到需要的类。
|
这很显然嘛,否则它怎么找到stub呀。