我正在编写一个小型Java RMI服务器和客户端程序。我花了一些时间试图弄清楚错误信息但没有成功。
客户端生成以下错误:
尝试连接到:127.0.0.1:3232 错误!!!:StockClient:main:无法连接到服务器:java.rmi.UnmarshalException:错误解组返回标头;嵌套 例外是: java.rmi.UnmarshalException:错误解组返回标头;嵌套异常是: java.io.EOFException的 java.io.EOFException的 at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:209) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359) at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) 在StockClient.StockClient.main(StockClient.java:44) 引起:java.io.EOFException at java.io.DataInputStream.readByte(DataInputStream.java:250) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:195) ......还有3个
仅在客户端尝试连接时,服务器才会出现以下错误。
此地址= localhost / 127.0.0.1,port = 3232 线程“RMI TCP连接(空闲)”中的异常java.security.AccessControlException:访问被拒绝 (java.net.SocketPermission 127.0.0.1:62586接受,解决) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374) 在java.security.AccessController.checkPermission(AccessController.java:549) 在java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.SecurityManager.checkAccept(SecurityManager.java:1157) at sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.checkAcceptPermission(TCPTransport.java:636) at sun.rmi.transport.tcp.TCPTransport.checkAcceptPermission(TCPTransport.java:275) at sun.rmi.transport.Transport $ 1.run(Transport.java:158) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:155) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) at sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run0(TCPTransport.java:790) at sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run(TCPTransport.java:649) at java.util.concurrent.ThreadPoolExecutor $ Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:908) 在java.lang.Thread.run(Thread.java:680)
由于服务器错误,我很确定它是安全性或注册表错误,服务器的安全策略是:
授予{ permission java.security.AllPermission; };
并使用以下参数运行
-Djava.security.policy = client.policy
我已经尝试了我能找到的所有内容,但似乎仍然在圈子里。
相关方法:
服务器:
public static void main(String[] args)
{//main(...) starts
// set up the data structures and data
//add users
//Users hard coded as this is an example proof on concept program
//Names and passwords not hashed for simplicity
User alpha = new User("Alpha", "AlphaPass");
User omega = new User("Omega", "OmegaPass");
users.add(alpha);
users.add(omega);
//startup the RMI server
try
{
System.setSecurityManager(new RMISecurityManager());
StockServer server = new StockServer();
StockServerInterface inter = (StockServerInterface)
UnicastRemoteObject.exportObject (server,0);
// create the registry and bind the name and object.
registry = LocateRegistry.createRegistry(thisPort);
registry.rebind("StockServer", inter);
}
catch (Exception e)
{
System.out.println("Unable to create StockServer: " + e);
e.printStackTrace();
System.exit(1);
}
}//main(...) ends
/**
* Constructor for StockServer
*
* @throws RemoteException
*/
public StockServer() throws RemoteException
{
//try to get the host machine's IP address
try
{
// get the address of this host.
thisAddress = (InetAddress.getLocalHost()).toString();
} catch (Exception e)
{
throw new RemoteException("can't get inet address. " + e);
}
//Set the port
thisPort = 3232;
//Print out the server address and port
System.out.println("this address=" + thisAddress + ",port=" + thisPort);
}
客户端:
private static StockServerInterface stockServer;
static public void main(String args[])
{
Registry registry;
//get the server address from the args
String serverAddress = args[0];
//get the server port from the args
String serverPort = args[1];
//Let the user know we are about to try to connect
System.out.println("Trying to connect to: " + serverAddress + ":" + serverPort);
try
{
// get the registry
registry = LocateRegistry.getRegistry(
serverAddress,
(new Integer(serverPort)).intValue());
// look up the remote object
stockServer = (StockServerInterface) (registry.lookup("StockServer"));
//Authenticate the user
authenticate();
//setup the hashset
HashSet<Stock> hashStockSet = null;
//setup the hashset of desired stocks
try
{
hashStockSet = getHashSet();
} catch (IOException e)
{
e.printStackTrace();
System.exit(1);
} catch (ClassNotFoundException e)
{
e.printStackTrace();
System.exit(1);
}
//bit of a heavy handed infinte loop so we continue to get the loop
while(true)
{
//Run the ticker
ticker(hashStockSet);
}
// call the remote method
}
catch (RemoteException e)
{
System.out.println("ERROR!!!: StockClient: main: Could not connect to the server: "+e);
e.printStackTrace();
}
catch (NotBoundException e)
{
System.out.println("ERROR!!!: StockClient: main: Could not connect to the server: "+e);
e.printStackTrace();
}
答案 0 :(得分:6)
除非客户端依赖代码库功能为服务器提供类,否则在RMI服务器中不需要SecurityManager
。删除它,或调试.policy文件。很明显,你写的那个没有加载。
使用-Djava.security.debug=access,failure
运行您的服务器,您将看到所有安全域从中获取配置的位置,以及在抛出异常时失败的域。