问题描述
我正在编写一个小型 Java RMI 服务器和客户端程序.我花了一些时间试图找出错误消息,但没有成功.
I have a small Java RMI Server and Client program I'm writing. I have spent some time trying to figure out the error messages without success.
客户端生成以下错误:
尝试连接到:127.0.0.1:3232错误!!!:StockClient:main:无法连接到服务器:java.rmi.UnmarshalException:解组返回标头时出错;嵌套例外是:java.rmi.UnmarshalException: 解组返回标头时出错;嵌套异常是:java.io.EOF异常java.io.EOF异常在 sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:209)在 sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359)在 sun.rmi.registry.RegistryImpl_Stub.lookup(来源不明)在 StockClient.StockClient.main(StockClient.java:44)引起:java.io.EOFException在 java.io.DataInputStream.readByte(DataInputStream.java:250)在 sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:195)... 3个
只有当客户端尝试连接时,服务器才会出现以下错误.
With the server the following error only when the client attempts to connect.
这个地址=localhost/127.0.0.1,port=3232线程RMI TCP 连接(空闲)"中的异常 java.security.AccessControlException:访问被拒绝(java.net.SocketPermission 127.0.0.1:62586 接受,解决)在 java.security.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)在 sun.rmi.transport.tcp.TCPTransport.checkAcceptPermission(TCPTransport.java:275)在 sun.rmi.transport.Transport$1.run(Transport.java:158)在 java.security.AccessController.doPrivileged(Native Method)在 sun.rmi.transport.Transport.serviceCall(Transport.java:155)在 sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)在 sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)在 java.lang.Thread.run(Thread.java:680)
由于服务器错误,我相当确定是安全或注册表错误,服务器的安全策略是:
Because of the server error I'm fairly sure its a security or registry error, security policy for the server is:
授予{权限 java.security.AllPermission;};
并使用以下参数运行
-Djava.security.policy=client.policy
我已经尝试了我能找到的所有方法,但似乎一直在兜圈子.
I've tried everything I can find but seem to keep going around in circles.
相关方法:
服务器:
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();
}
推荐答案
除非客户端依赖代码库功能为服务器提供类,否则 RMI 服务器中不需要 SecurityManager
.删除它,或调试 .policy 文件.很明显你写的那个没有被加载.
You don't need a SecurityManager
in an RMI server unless the client is relying on the codebase feature to supply the server with classes. Either remove it, or debug the .policy file. Clearly the one you've written isn't being loaded.
使用 -Djava.security.debug=access,failure
运行您的服务器,您将看到所有安全域从何处获取其配置,以及出现故障的域抛出异常.
Run your server with -Djava.security.debug=access,failure
and you will see where all the security domains are getting their configurations from, and the domain that is failing at the point where the exception is thrown.
这篇关于Java RMI 客户端访问被拒绝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!