Java RMI客户端访问被拒绝

我正在编写一个小型Java RMI服务器和客户端程序。 我花了一些时间试图找出错误消息但没有成功。

客户端生成以下错误:

试图连接到:127.0.0.1:3232错误!!!:StockClient:main:无法连接到服务器:java.rmi.UnmarshalException:错误解组返回标头; 嵌套exception是:java.rmi.UnmarshalException:错误解组返回标头; 嵌套exception是:sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:209)的sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359)sun中的java.io.EOFException java.io.EOFException StockClient.StockClient.main(StockClient.java:44)中的.rmi.registry.RegistryImpl_Stub.lookup(未知来源)引起:java.io.DataInputStream.readByte(DataInputStream.java:250)的java.io.EOFException .rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:195)… 3个其他

仅在客户端尝试连接时,服务器才会出现以下错误。

此地址= localhost / 127.0.0.1,port = 3232线程“RMI TCP连接(空闲)”中的exceptionjava.security.AccessControlException:java.security中的访问被拒绝(java.net.SocketPermission 127.0.0.1:62586 accept,resolve) .AccessControlContext.checkPermission(AccessControlContext.java:374)在java.security.AccessController.checkPermission(AccessController.java:549)java.lang.SecurityManager.checkPermission(SecurityManager.java:532)java.lang.SecurityManager.checkAccept( SecurityManager.java:1157)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)位于sun.rmi.transport的sun.rmi.transport.Transport.serviceCall(Transport.java:155)的java.security.AccessController.doPrivileged(Native Method)。 tcp.TCPTransport.handleMessages(TCPTransport.java:535)at sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler。 run0(TCPTransport.java:790)在java.util.concurrent.ThreadPoolExecutor的sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run(TCPTransport.java:649)java的java.Man.runTask(ThreadPoolExecutor.java:886) java.lang.Thread.run中的.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:908)(Thread.java:680)

由于服务器错误,我很确定它是安全性或注册表错误,服务器的安全策略是:

grant {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 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(); } 

除非客户端依赖代码库function为服务器提供类,否则您不需要RMI服务器中的SecurityManager 。 删除它,或调试.policy文件。 很明显,你写的那个没有加载。

使用-Djava.security.debug=access,failure运行服务器,您将看到所有安全域从中获取配置的位置,以及在抛出exception时失败的域。