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.
The Client generates the following error:
Trying to connect to: 127.0.0.1:3232
ERROR!!!: StockClient: main: Could not connect to the server: java.rmi.UnmarshalException: Error unmarshaling return header; nested
exception is:
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is:
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)
at StockClient.StockClient.main(StockClient.java:44)
Caused by: java.io.EOFException
at java.io.DataInputStream.readByte(DataInputStream.java:250)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:195)
... 3 more
With the server the following error only when the client attempts to connect.
this address=localhost/127.0.0.1,port=3232
Exception in thread "RMI TCP Connection(idle)" java.security.AccessControlException: access denied
(java.net.SocketPermission 127.0.0.1:62586 accept,resolve)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
at java.security.AccessController.checkPermission(AccessController.java:549)
at 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)
at 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:
grant {
permission java.security.AllPermission;
};
and being run with the following argument
-Djava.security.policy=client.policy
I've tried everything I can find but seem to keep going around in circles.
relevant methods:
Server:
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);
}
Client:
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();
}
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.
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.
Related
I have created a RMI project with server and client. I run the server on my ec2 instance. I had some problems finding out how to run the server property on ec2 in order to accept my windows client. I followed the following steps :
Transfer the files with Filezilla.
Compiled the project as administrator.
I opened the port I still use for my server to my IP address.
The problem I had is that I couldnt connect to my server with the public ip that amazon gives me. So I ran ifconfig and used the private ip.
So inside the code as you will see I used the public amazon ip but when I run it. I run it with the following command
java SkyCorpServer "172.31.31.94" 666 (private ip)(port)
I don't know how but that way the client with the public IP was able to connect.
I have read about the bind and the registry of RMI and how it works (creating a registry and forward it to port. Connect to port and then find the registry and use the Servers stub).
The problem now is that the client connects after 30 secs and when I try to use the remote object (look_op) client crashes with the following message:
java.rmi.ConnectException: Connection refused to host: 172.31.31.94; nested exception is:
java.net.ConnectException: Connection timed out: connect
I have used the default permissions (accept all) because when i tried to do this the Security Manager didn't let me create the registry so I guess that is not the problem (permissions).
Server Code:
private static int port =666;
private static String hostname = "35.167.2xx.xx";
public static void main(String[] args) throws RemoteException {
String bindLocation = "//" + hostname + ":" + port + "/Hello";
System.setProperty("java.rmi.server.hostname",hostname);
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try { // special exception handler for registry creation
LocateRegistry.createRegistry(port);
System.out.println("java RMI registry created.");
} catch (RemoteException e) {
// do nothing, error means registry already exists
System.out.println("java RMI registry already exists.");
}
SkyCorpServer server = new SkyCorpServer();
try {
Naming.bind(bindLocation, server);
System.out.println("Addition Server is ready at:" + bindLocation);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
System.out.println("Addition Serverfailed: " + e);
}
Server output (running without error)(command i used scroll up) :
java RMI registry created.
SYSTEM: Checking for back-up files. // other staff
SYSTEM: Users file exists. Updating values.
SYSTEM: Checking for back-up files.
SYSTEM: Users file exists. Updating values.
Addition Server is ready at://172.31.31.94:666/Hello
As you can see server listens at 172.31.31.94 port:666
Client Code :
private final static String remoteHostName = "35.167.2xx.xx";
private final static int remotePort = 666;
public SkyCorpClient() throws NotBoundException, MalformedURLException, RemoteException {
String connectLocation = "//" + remoteHostName + ":" + remotePort + "/Hello";
look_op = (ChatInterface) Naming.lookup(connectLocation);
System.out.println("Connecting to client at : " + connectLocation);
}
Client's output (when connected)
Connecting to client at : //35.167.203.111:666/Hello
Connected at : 35.167.203.111
When try to use the remote object look_op :
java.rmi.ConnectException: Connection refused to host: 172.31.31.94; nested exception is:
java.net.ConnectException: Connection timed out: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
at com.sun.proxy.$Proxy0.registerUser(Unknown Source)
at SkyCorpClient.actionPerformed(SkyCorpClient.java:206)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6533)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6298)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4711)
My guess is that it connects to public ip 35.xxx and because the server has created the registry to 172.* I can't use the object. Is there something I am missing?
I am trying to establish two-communication between one server and two clients. This works very well when all programs run on the same machine but it doesn't work when I try using LAN network.
I got the error :
java.rmi.ConnectException: Connection refused to host: 192.168.1.24; nested exception is:
java.net.ConnectException: Connection timed out: connect
Here is the server code :
public class Server{
private Game partie; // The class Game extends UnicastRemoteObject and implements ServerInterface
public Server() throws RemoteException {
System.setProperty("java.rmi.server.hostname", "192.168.1.24");
partie = new Game();
LocateRegistry.createRegistry(1099);
try{
Naming.rebind("Server", partie);
}
catch(Exception e){
e.printStackTrace();
}
}
public static void main(String argv[]) throws RemoteException{
new Server();
}
}
Here is the constructor of the client code :
public Client(String aName, String aServerAdress) throws RemoteException {
super();
name = aName;
ServerAdress = aServerAdress; // = "192.168.1.24"
theRegistry = LocateRegistry.getRegistry(ServerAdress);
try {
serverInterface = (ServerInterface) theRegistry.lookup("Server");
} catch (NotBoundException e1) {
e1.printStackTrace();
}
try {
theRegistry.bind(name, this); // For two-way communication
} catch (AlreadyBoundException e) {
e.printStackTrace();
}
serverInterface.registerClient(name);
}
Where registerClient(String name) code is approximately (in Game class) :
cd_client = (ClientInterface) Naming.lookup("rmi://127.0.0.1/" + name);
All firewalls are disabled.
I have been working on this problems for many hours and I have still not found what is wrong. I would really appreciate if you could help me a bit.
Thank you
Change all occurances of 127.0.0.1 (except registry binding) to your LAN IP address (192.168.1.24 in your case)
127.0.0.1 is a Loopback address:
"Loopback (loop-back) describes ways of routing electronic signals,
digital data streams, or flows of items from their originating
facility back to the receiving end of the source without intentional
processing or modification. This is primarily a means of testing the
transmission or transportation infrastructure."
-- from Wikipedia
I know that this question has been asked several times but I've yet to find an answer that works for me. Basically I've implemented a client/server solution with RMI. My only problem is that connection to the server is sometimes extremely slow.
When the server is started and a client connects, for the first time, it will take seconds before it gets connected (sometimes it does not even connect but get the ConnectException instead) and after that I will get the Connection refused when trying to communicate with the server.
What makes it even more mind boggling is that it works perfectly fine when I disconnect the first failing client and connect again. The client then connects in under a second and all the communication works flawlessy.
I've tried manually starting the rmiregistry, I've double checked my PATH. I wasn't able to connect to the port with telnet but it works when I play on that port with my Othello game (which is not using RMI). It might be worth to say that I'm doing this on the same network and computer so I'm using localhost.
TL;DR: When I first connect to the server it takes forever, but I'm able to connect. When I then try to communicate with methods it crashes and I receive "java.rmi.ConnectException: Connection refused to host: 192.xxx.xxx.x; nested exception is:
java.net.ConnectException: Connection timed out: connect". If I then close that client and try to connect with another client it takes around one second to connect and then everything works flawlessy. Why is that?
Code for the client:
public class NetworkClient {
private Registry registry;
private IArenaServer server;
public NetworkClient(String ipAddress, int port) throws RemoteException {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
registry = LocateRegistry.getRegistry(ipAddress, port);
server = (IArenaServer)(registry.lookup("arenaServer"));
System.out.println("Client successfully connected to server at " + ipAddress + ":" + "port");
} catch (NotBoundException ex) {
Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
} catch (AccessException ex) {
Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
Code for the server:
public class ArenaServer extends UnicastRemoteObject implements IArenaServer {
private int port = 9029;
private String ipAddress;
private Registry registry;
public ArenaServer() throws RemoteException {
if(System.getSecurityManager() == null){
System.setSecurityManager(new RMISecurityManager());
}
// try {
//ipAddress = (InetAddress.getLocalHost()).toString();
registry = LocateRegistry.createRegistry(port);
registry.rebind("arenaServer", this);
System.out.println("Server successfully started...");
//System.out.println("Server's IP address is: " + ipAddress);
// } catch (UnknownHostException ex) {
// ErrorHandler.getInstance().reportError("Cannot get IP address", "");
// }
}
Generic example of what I get when trying to communicate with the server after connecting the first time:
java.rmi.ConnectException: Connection refused to host: 192.xxx.xxx.x; nested exception is:
java.net.ConnectException: Connection timed out: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy0.getInstalledGames(Unknown Source)
....
This sounds like a case for java.rmi.server.hostname. See item A.1 in the RMI FAQ, reachable via the RMI Home Page.
UPDATE:
The problem is, that i'm using a kind of 2-way connection.
On client side, this works:
String a = this.lobby.getMsg();
and this not:
this.lobby.login((Player)UnicastRemoteObject.exportObject(player, 0));
and ideas?
I'm working on a java application which uses RMI for network communication.
On one computer everythings works good, but if i try to run it via the internet i ran into problems.
It seems, that the client is able to retreive the registry from the server and to lookup the lobby-object.
But if the client tries to call the login method of the lobby object via rmi, it takes very long time and i receive the following exception:
Strange thing is, that there is the wrong ip(the client ip) mentioned in this exception.
And if I run a client on the same machine as the server, it works perfectly.
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.ConnectException: Connection refused to host: <client ip(should be server ip?)>; nested exception is:
java.net.ConnectException: Die Wartezeit für die Verbindung ist abgelaufen (=time out)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:353)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:160)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at $Proxy0.einloggen(Unknown Source)
at Client.login(Client.java:64)
Here is the relevant code:
My server class:
public static final int RMI_PORT = 55555;
public static final String SERVER_IP = "xyz.com";
/**
* Startet Spielserver
*
* #param args
*/
public static void main(String[] args) {
System.out.println("Server starten..");
System.setProperty("java.rmi.server.hostname", SERVER_IP);
try {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
Registry registry = LocateRegistry.getRegistry(SERVER_IP, RMI_PORT);
Lobby lobby = new LobbyImpl();
UnicastRemoteObject.exportObject(lobby, 0);
registry.bind("Lobby", lobby);
} catch (RemoteException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
}
}
Client class:
public Client() {
try {
Registry registry = LocateRegistry.getRegistry("xyz.com", Server.RMI_PORT);
lobby = (Lobby) registry.lookup("Lobby");
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
this.gui = new GUI(this);
}
public void login(String name) throws RemoteException {
Player player = new Player(name);
this.lobby.login((Player)UnicastRemoteObject.exportObject(player, 0));
}
Client startscript:
#!/bin/bash
SCRIPTDIR=$(dirname $0)
java -classpath $SCRIPTDIR/bin Client
Server startscript:
#!/bin/bash
SCRIPTDIR=$(dirname $0)
cd ${SCRIPTDIR}/bin
rmiregistry 55555 &
cd -
java -classpath $SCRIPTDIR/bin -Djava.security.policy=$SCRIPTDIR/src/server.policy -Djava.rmi.server.codebase=file:$SCRIPTDIR/bin/ Server
killall rmiregistry
and last but not least my first (test) policy file:
grant {
permission java.security.AllPermission;
};
what could be the problem?
regards
You need to look at item A.1 of the RMI FAQ on the RMI home page. The problem here is that the wrong IP address is being embedded into the remote stub. So the lookup works, because you are specifying the target IP address yourself in the client, but when you execute the remote method you are relying on the IP address in the stub, which is wrong. The solution is either to correct your /etc/hosts file or to set the system property java.rmi.server.hostname at the server JVM.
The error message is
java.rmi.ConnectException: Connection refused to host: <wrong ip of the server>;
I would check you can ping that server and telnet to the service point.
This question already has answers here:
java.rmi.NoSuchObjectException: no such object in table
(7 answers)
Closed 3 years ago.
My goal is to create a Distributed computing program that launches a server and client at the same time. I need it to be able to install on a couple of machines and have all the machines communicating with each other, i.e. Master node and 5 slave nodes all from one application.
My problem is that I cannot properly use unicastRef, I'm thinking that it is a problem with launching everything on the same port, is there a better way I am overlooking?
this is part of my code (the part that matters)
try {
RMIServer obj = new RMIServer();
obj.start(5225);
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println("We are slave's ");
Registry rr = LocateRegistry.getRegistry("127.0.0.1", Store.PORT, new RClient());
Call ss = (Call) rr.lookup("FILLER");
System.out.println(ss.getHello());
} catch (Exception e) {
e.printStackTrace();
}
}
this is my main class (above)
this is the server class (below)
public RMIServer() {
}
public void start(int port) throws Exception {
try {
Registry registry = LocateRegistry.createRegistry(port, new RClient(), new RServer());
Call stuff = new Call();
registry.bind("FILLER", stuff);
System.out.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
I don't know what I am missing or what I am overlooking but the output looks like this.
Listen on 5225
Listen on 8776
Server ready
We are slave's
Listen on 8776
java.rmi.NoSuchObjectException: no such object in table
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at Main.main(Main.java:62)
line 62 is this ::: Call ss = (Call) rr.lookup("FILLER");
Maybe it's because your reference to the stub in your server class is local to the try block and the reference is immediately garbage collected after. Try making stuff a class variable instead.