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?
Related
Im losing my mind, is there any clear documentation how to run java RMI between host and client remotly? i find in different forums, various puzzle pieces, but never, a from a to z guide, which scurity guidelines have to be followed etc, so that a RMI works. Well, if I run the server and client locally, it works.
Now, my low-level problem is that even if I set the external server address everywhere (?), in the error message it says that "localhost" has refused the connection.... Do you have any ideas?
Client:
try {
System.setProperty("java.rmi.server.hostname","42.155.241.914");
String name = "RemoteBookService";
String serverIP = "42.155.241.914"; // or localhost if client and server on same machine.
int serverPort = 1099;
Registry registry = LocateRegistry.getRegistry(serverIP, serverPort);
IRemoteService rs = (IRemoteService) registry.lookup(name);
Error:
java.rmi.ConnectException: Connection refused to host: localhost;
nested exception is:
java.net.ConnectException: Connection refused: connect
Server:
public static void main(String[] args) throws MalformedURLException, AlreadyBoundException {
try {
System.setProperty("java.rmi.server.hostname","42.155.241.914");
LocateRegistry.createRegistry(1099);
String name="//42.155.241.914/RemoteBookService";
RemoteService rs = new RemoteService();
Naming.bind(name, rs);
System.out.println("Service started");
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("could not start registry");
}
}
At first glance it looks like your server uses LocateRegistry.createRegistry(port); which implies own registry (same process) which you don't store to local variable, and then you call Naming.rebind(bind, rs) which implies use of a local registry (same host, other process) on the default port.
Try changing the lines on server to:
Registry registry = LocateRegistry.createRegistry(port);
...
// NOTE registry.rebind not called with name="//42.155.241.914/RemoteBookService"
registry.rebind("RemoteBookService", stub);
Hopefully this may get you to the next step, but there are plenty of ways this could have gone wrong so you might need to edit the question with more details.
I creating a gRPC server but everything seems to run okay but the server never starts up on the specifies port and application is throwing no errors. But when I test with telnet on that specific port, I get this from terminal
isaack$ telnet localhost 9000
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host
Below is my code to create the server (NB: All the services are generated okay with proto and the generated code has no errors)
import java.io.File;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.ServerInterceptors;
import io.grpc.ServerServiceDefinition;
public class EmployeeServiceServer {
private Server server;
public static void main(String[] args) {
try {
EmployeeServiceServer service = new EmployeeServiceServer();
service.start();
} catch (Exception e) {
System.err.println(e);
}
}
private void start() throws InterruptedException {
File certificate = new File("/Users/i/certificates/cert.pem");
File key = new File("/Users/i/certificates/key.pem");
final int port = 9000;
EmployeeService employeeService = new EmployeeService();
ServerServiceDefinition serverServiceDefinition = ServerInterceptors.interceptForward(employeeService,
new HeaderServerInterceptor());
server = ServerBuilder.forPort(port).useTransportSecurity(certificate, key).addService(serverServiceDefinition)
.build();
System.out.println("Listening on Port " + port);
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
System.out.println("Shuttin Down Server");
EmployeeServiceServer.this.stop();
}
});
server.awaitTermination();
}
private void stop() {
if (server != null) {
server.isShutdown();
}
}
}
Below is the log from but when I ping it, I get nothing.
Listening on Port 9000
My client is throwing this error as well:
Exception in thread "main" io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:233)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:214)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:139)
at com.base.services.EmployeeServiceGrpc$EmployeeServiceBlockingStub.getBadgebyNumber(EmployeeServiceGrpc.java:373)
at com.base.client.Client.sendMetaData(Client.java:66)
at com.base.client.Client.main(Client.java:37)
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/0:0:0:0:0:0:0:1:9000
You may want to start() your server, as build suggests:
Builds a server using the given parameters.
The returned service will not been started or be bound a port. You will need to start it with Server.start().
Perhaps that server.awaitTermination(); line could become
server.start().awaitTermination();
though I am not entirely sure.
I have faced the same error. The reason being grpc server didn't start.
Server server = ServerBuilder.forPort(port).useTransportSecurity(certificate, key).addService(serverServiceDefinition)
.build().start();
I had written start method as chain to build.
To make it work i had to call start() method separately.
server.start();
This solved the error for me.
PS: I'm writing this answer as the above solution didn't clarify much and had to research alot before finding the solution. Hope this will be helpful for other developers.
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.
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.
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.