I'm implementing a simple RMI Server Client program in JAVA. I'm new to this actually. i have four java files.
Stack.java
import java.rmi.*;
public interface Stack extends Remote{
public void push(int p) throws RemoteException;
public int pop() throws RemoteException;
}
StackImp.java
import java.rmi.*;
import java.rmi.server.*;
public class StackImp extends UnicastRemoteObject implements Stack{
private int tos, data[], size;
public StackImp()throws RemoteException{
super();
}
public StackImp(int s)throws RemoteException{
super();
size = s;
data = new int[size];
tos=-1;
}
public void push(int p)throws RemoteException{
tos++;
data[tos]=p;
}
public int pop()throws RemoteException{
int temp = data[tos];
tos--;
return temp;
}
}
RMIServer.java
import java.rmi.*;
import java.io.*;
public class RMIServer{
public static void main(String[] argv) throws Exception{
StackImp s = new StackImp(10);
Naming.rebind("rmi://localhost:2000/xyz", s);
System.out.println("RMI Server ready....");
System.out.println("Waiting for Request...");
}
}
RMIClient.java
import java.rmi.*;
public class RMIClient{
public static void main(String[] argv)throws Exception{
Stack s = (Stack)Naming.lookup("rmi://localhost:2000/xyz");
s.push(25);
System.out.println("Push: "+s.push());
}
}
I'm using JDK1.5. The sequence in which i compiled the files is, first i compiled Stack.java then i compiled StackImp.java then i used this command rmic StackImp this all was successful. But when i tried to run the registry this way rmiregistery 2000, command prompt took too long. Nothing happened. I'm doing this all at my home PC. And this PC is not on the network. Please suggest me what to do to successfully work with this program.
command prompt took too long. Nothing happened.
Nothing is supposed to happen - the registry is running, and you can now start your server from another command prompt.
Alternatively, if you're only running the one RMI server process on this machine you can run the registry in the same process as the RMI server:
import java.rmi.*;
import java.rmi.registry.*;
import java.io.*;
public class RMIServer{
public static void main(String[] argv) throws Exception{
StackImp s = new StackImp(10);
Registry reg = LocateRegistry.createRegistry(2000);
reg.rebind("xyz", s);
System.out.println("RMI Server ready....");
System.out.println("Waiting for Request...");
}
}
This way you don't need a separate rmiregistry command, just run the server (which includes the registry) and then the client (which talks to the registry that is running in the server process).
Related
package RMI_Package;
import java.rmi.server.*;
import java.rmi.*;
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
public String sayHello(){
return "Server says,'Hey'";
}
public MyRemoteImpl() throws RemoteException{}
public static void main(String [] args){
try{
MyRemote service = new MyRemoteImpl();
Naming.rebind("Remote Hello",service);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
This code is from Head First Java Book when i run it, it throws the java.net.MalformedURLException.
As specified by the Naming documentation, the first parameter of bind should be a valid URL.
As an example (taken from here):
Naming.bind("rmi://localhost:8800/YourObject", service);
In the below code, I'm using vert.x to create a route
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.ext.web.Router;
import java.util.function.Consumer;
public class VerticleMain extends AbstractVerticle {
#Override
public void start() throws Exception {
Router router = Router.router(vertx);
router.route().handler(routingContext -> {
routingContext.response()
.putHeader("content-type","text/html;charset=UTF-8")
.end("people");
});
vertx.createHttpServer().requestHandler(router::accept).listen(8181);
}
public static void deployVertx() {
String verticleId = VerticleMain.class.getName();
VertxOptions options = new VertxOptions();
Consumer<Vertx> runner = vertxStart -> {
vertxStart.deployVerticle(verticleId);
};
Vertx vertx = Vertx.vertx(options);
runner.accept(vertx);
}
public static void main(String[] args) {
VerticleMain.deployVertx();
}
}
However, when i tried executing the code again, the log is
java.net.BindException: Address already in use
If this port is used, I want to stop the process which occupied the port, and then execute the code. Is there any way to accomplish this goal?
I hope you can provide a simply example
Your code is absolutely fine. please kill all the java process or restart your machine and try again. it should work fine. only one import was missing and i added that.
package com.americanexpress.digitalpayments.pipe;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.ext.web.Router;
import java.util.function.Consumer;
public class VerticleMain extends AbstractVerticle {
public static void deployVertx() {
String verticleId = VerticleMain.class.getName();
VertxOptions options = new VertxOptions();
Consumer<Vertx> runner = vertxStart -> {
vertxStart.deployVerticle(verticleId);
};
Vertx vertx = Vertx.vertx(options);
runner.accept(vertx);
}
public static void main(String[] args) {
VerticleMain.deployVertx();
}
#Override
public void start() throws Exception {
Router router = Router.router(vertx);
router.route().handler(routingContext -> {
routingContext.response()
.putHeader("content-type", "text/html;charset=UTF-8")
.end("people");
});
vertx.createHttpServer().requestHandler(router::accept).listen(8181);
}
}
you need to kill the port:
for ubuntu:
sudo kill $(sudo lsof -t -i:8081)
I have the following RMI Connection code which returns a com.sun.proxy.$Proxy0 cannot be cast to Client.AdditionInterface error. I created two separate packages Client & Server and putted the Interface in both of them. Here is my complete code:
package Serveur;
import java.rmi.*;
import java.rmi.registry.LocateRegistry;
public class AdditionServer {
public static void main (String[] argv) {
try {
LocateRegistry.createRegistry(1099);
Addition Hello = new Addition();
Naming.rebind("rmi://"+java.net.InetAddress.getLocalHost().getHostName()+"/ABC", Hello);
System.out.println("Addition Server is ready.");
}
catch (Exception e) {
System.out.println("Addition Server failed: " + e);
}
}
}
//////////////////////////////////////
package Serveur;
import java.rmi.*;
import java.rmi.server.*;
public class Addition extends UnicastRemoteObject implements AdditionInterface {
public Addition () throws RemoteException {
super();
}
#Override
public int add(int a, int b) throws RemoteException {
int result=a+b;
return result;
}
#Override
public String aff(int a, int b) throws RemoteException {
return String.valueOf(add(a, b));
}
}
////////////////////////////
package Client;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface AdditionInterface extends Remote {
public int add(int a,int b) throws RemoteException;
public String aff(int a, int b) throws RemoteException;
}
////////////////////////////
package Client;
import java.rmi.*;
public class AdditionClient {
public static void main (String[] args) throws Exception {
AdditionInterface add = (AdditionInterface) Naming.lookup("rmi://"+java.net.InetAddress.getLocalHost().getHostName()+"/ABC");
System.out.println("Result is :"+add.add(9, 10));
System.out.println(add.aff(26, 45));
}
}
Any help please? Thank you.
As in both a Client.AdditionInterface for the client and a Server.AdditionInterface for the server? Effectively the error is saying Server.AdditionInterface cannot be cast to Client.AdditionInterface.
With RMI you must have the same interface class on both client and server, but then clearly the server implementation class (AdditionServer) just on the server. The interface could be in a shared package (e.g. common.AdditionInterface ).
This question already has an answer here:
RMI connection refused on localhost
(1 answer)
Closed 5 years ago.
I am developing a simple server based calculation program in java and rmi. However, The Server is not initializing with the following exception.
Initializing Server
Remote Server Error:Connection refused to host: 192.168.1.3; nested exception is:
java.net.ConnectException: Connection refused: connect
I have turned off my microsoft firewall. After that also, the problem persists. Here is the code I am running :
import java.rmi.*;
import java.rmi.Naming.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.net.*;
import java.util.*;
interface mathInterface extends Remote
{
public int add(int a,int b) throws RemoteException;
public int subt(int a,int b) throws RemoteException;
public int mult(int a,int b) throws RemoteException;
public int div(int a,int b) throws RemoteException;
}
public class mathServer extends UnicastRemoteObject implements mathInterface
{
public mathServer() throws RemoteException
{
System.out.println("Initializing Server");
}
public int add(int a,int b)
{
return(a+b);
}
public int subt(int a,int b)
{
return(a-b);
}
public int mult(int a,int b)
{
return(a*b);
}
public int div(int a,int b)
{
return(a/b);
}
public static void main(String args[])
{
try
{
mathServer ms=new mathServer();
java.rmi.Naming.rebind("MathServ",ms);
System.out.println("Server Ready");
}
catch(RemoteException RE)
{
System.out.println("Remote Server Error:"+ RE.getMessage());
System.exit(0);
}
catch(MalformedURLException ME)
{
System.out.println("Invalid URL!!");
}
}
}
Kindly help me sort out this issue.
You haven't started the RMI Registry.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
i have problem that when i run my rmi server i got an exception notbound exception
even i export the remote object and bind it to registry
here is my remote interface code
import java.rmi.Remote;
public interface fact extends Remote {
public int factory(int a);
}
and here the interface implementation
public class factimport implements fact {
#Override
public int factory(int a) {
int mult=1;
for (int i=1;i<=a;i++)
mult=mult*i;
return mult;
}
}
and server code
import java.net.MalformedURLException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class Server extends UnicastRemoteObject {
/**
*
*/
private static final long serialVersionUID = 1L;
protected Server() throws RemoteException {
super();
}
public static void main() throws RemoteException, MalformedURLException{
factimport fi=new factimport();
Registry reg=LocateRegistry.createRegistry(1099);
reg.rebind("factobject", exportObject(fi));
System.out.println("server started");
}
}
and client
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
/**
* #param args
* #throws NotBoundException
* #throws RemoteException
* #throws MalformedURLException
*/
public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException {
// TODO Auto-generated method stub
Registry reg=LocateRegistry.getRegistry("127.0.0.1",1099);
factimport x=(factimport)reg.lookup("factobject");
System.out.println(x.factory(5));
}
}
Unless you're running the server and client on the same host, which makes RMI pretty pointless, your getRegistry() call in the client needs to be modified to point to the server host, not the client host (itself).
Your remote method must be declared to throw RemoteException in the remote interface.
Unless you have run rmic on the remote interface, which you can't have done or you would have detected (2), you need to change the exportObject() call to exportObject(fi, 0), for reasons explained in the preamble to the Javadoc for UnicastRemoteObject.
Your Server.main() method doesn't have a correct signature so it won't execute. It should be public static void main(String[] args) ...
You should make the Registry reg variable in the server static to prevent it from being garbage-collected.
In your client, your variable of type factimport should be of type fact, and you should cast the lookup result to fact.
If the BindException was really the result of running this code in this state on a single machine, it can only mean that you ignored runtime exceptions when starting the server.
Your code is a little unorthodox. I don't know if this will help, but it might.
Normally, the remote object implementation would extend UnicastRemoteObject. So, you have this factimport class:
public class factimport implements fact extends UnicastRemoteObject {
#Override
public int factory(int a) {
int mult=1;
for (int i=1;i<=a;i++)
mult=mult*i;
return mult;
}
}
And the server class:
public class Server {
/**
*
*/
private static final long serialVersionUID = 1L;
protected Server() throws RemoteException {
super();
}
public static void main() throws RemoteException, MalformedURLException{
factimport fi=new factimport();
Registry reg=LocateRegistry.createRegistry(1099);
reg.rebind("factobject", fi);
System.out.println("server started");
}
}
I hope this will work.