rmi remote exception. RMI doesnt work - java

I get a remote exception when I try to run my RMI example. I cannot understand why.
I run the program without any arguments to the program itself or to the JVM.
Please help me to get rid of the exception.
Thanks very much
This is the exception I get:
Server exception: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: hello.Hello
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: hello.Hello
These are the classes I have:
The client class:
package hello;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
private Client() {}
public static void main(String[] args) {
String host = (args.length < 1) ? null : args[0];
try {
Registry registry = LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("Hello");
String response = stub.sayHello();
System.out.println("response: " + response);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
The remote interace:
package hello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
String sayHello() throws RemoteException;
}
And finally the server:
package hello;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server implements Hello {
public Server() {}
public String sayHello() {
return "Hello, world!";
}
public static void main(String args[]) {
try {
Server obj = new Server();
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
// Bind the remote object's stub in the registry
Registry registry = LocateRegistry.getRegistry("localhost");
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}

Either the Registry or the client or both cannot find the class named in the exception. There are several possible solutions:
include that class in the classpath when executing the Registry and the client. And all the classes it depends on, recursively until closure.
Start the Registry from inside the server JVM, with LocateRegistry.createRegistry(), which solves that classpath problem, and provide the necessary classes on the client's classpath only.
Use the codebase feature to ensure all the system components can access the required server-side classes.

As outlined in the RMI trail
You may need to supply the java.rmi.server.codebase parameter that list all the jars that the RMI server needs to export the objects...
See Running the examples and look at the "Starting the server" section. Also be sure to check out the section on running the client program for additional suggested parameters

Related

RMI dynamic class loading

I'm trying to learn RMI. Managed to launch a simple example but I can't achieve dynamic loading of classes.
Hello.java
package com.example;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
String greet(String name) throws RemoteException;
}
HelloImpl.java
package com.example;
public class HelloImpl implements Hello {
public String greet(String name) {
System.out.println("Call from " + name);
return "Hello " + name + "!";
}
}
Server.java
package com.example;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server extends HelloImpl {
public Server() {}
public static void main(String args[]) {
System.setSecurityManager(new SecurityManager());
try {
HelloImpl greeter = new HelloImpl();
Hello stub = (Hello) UnicastRemoteObject.exportObject(greeter, 0);
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
Client.java
package com.example;
import java.rmi.Naming;
public class Client {
private Client() {}
public static void main(String[] args) {
System.setSecurityManager(new SecurityManager());
try {
Hello stub = (Hello) Naming.lookup("//localhost/Hello");
System.out.println(stub.greet(args[0]));
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
rmi.policy
grant {
permission java.security.AllPermission;
};
I started rmiregistry, web-server and executed java -Djava.security.policy=rmi.policy com.example.Server. When I try to start the client application with command
java -Djava.rmi.server.codebase=http://localhost:8000/ -Djava.security.policy=rmi.policy com.example.Client Hivemaster
web-server get request
127.0.0.1 - - [13/Dec/2017 14:06:45] "GET /com/example/Hello.class HTTP/1.1" 200
but program get exception
Exception in thread "main" java.lang.NoClassDefFoundError: com/example/Hello
at com.example.Client.main(Client.java:17)
Caused by: java.lang.ClassNotFoundException: com.example.Hello
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more
Why?
If the client is using the Hello interface by name, it must be present on its classpath. Same as it does when compiling it.
The codebase feature is for classes derived from those mentioned in remote interfaces. In this case there is no apparent need to use the codebase feature at all: but if you do, the codebase property needs to be set at the JVM which is sending instances of those classes.

can't run rmi registry on my system

I am learning RMI concepts and had built a simple program taking reference from head first java. All Went fine the first time i ran the code through command prompt.
the next time I ran code the command:
rmiregistry
took too long to load and nothing happened.
I even tried the solution in this thread but nothing happend.
need help to run RMI Registry
also when i run my server and client file i get this error:
Exception: java.rmi.ConnectException: Connection refused to host: 192.168.1.105; nested exception is:
java.net.ConnectException: Connection refused: connect
My Source Code:
myremote.java
import java.rmi.*;
public interface myremote extends Remote
{
public String sayhello() throws RemoteException;
}
Server.java
import java.rmi.*;
import java.rmi.server.*;
public class Server extends UnicastRemoteObject implements myremote
{
public Server() throws RemoteException{}
public String sayhello()
{
return("Server says hi");
}
public static void main(String args[])
{
try
{
myremote S = new Server();
Naming.rebind("remotehello",S);
}
catch(Exception E)
{
System.out.println("Exception: "+E);
}
}
}
client.java
import java.rmi.*;
public class client
{
public static void main(String[] args)
{
client c = new client();
c.go();
}
public void go()
{
try
{
myremote S=(myremote) Naming.lookup("rmi://127.0.0.1/remotehello");
System.out.println("Output:"+S.sayhello());
}
catch(Exception E)
{
System.out.println("Exception: "+ E);
}
}
}
Can't run RMI registry on my system
You've provided no evidence of that.
took too long to load
I don't know what this means. Evidence?
nothing happened.
Nothing is supposed to happen. The RMI registry doesn't print anything. It just sits there.
Run it and try again. You'll be surprised.

RMI programme: Client side giving Error

I am creating RMI program for my class assignment in Netbeans. It is a simple RMI program and The server side is working properly. But as I run my client side file. It ends up giving me error
Exception in thread "main" java.security.AccessControlException: access denied ("java.net.SocketPermission" "127.0.0.1:1099" "connect,resolve")
plus it is saying some error at line 26 at client code.
For clear understanding I am giving full code of all three files.
Interface.java :
package RMI;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface DemoInterface extends Remote {
public String SayDemo() throws RemoteException;
}
Server.java
package RMI;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class Server implements Interface{
public Server()
{
super();
}
private String message;
public Server(String msg) throws RemoteException
{
message = msg;
}
public static void main(String[] args) {
try {
DemoInterface h = new Server("Hello");
DemoInterface stub = (DemoInterface) UnicastRemoteObject.exportObject(h,0);
LocateRegistry.createRegistry(4096);
Registry registry = LocateRegistry.getRegistry("127.0.0.1",4096);
registry.rebind("Hello", stub);
System.out.println("Server is connected and ready to use");
}
catch(Exception e)
{
System.out.println("server not connected\n"+e);
}
}
#Override
public String SayDemo() throws RemoteException {
System.out.println("Server.saydemo override");
return message;
}
}
Client.java
package RMI;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
public static void main(String[] args) {
if(System.getSecurityManager() == null)
{
System.setSecurityManager(new SecurityManager());
}
try {
Registry reg = LocateRegistry.getRegistry("127.0.0.1", 4096);
System.out.println("in try after reg locate");
DemoInterface h = (DemoInterface) reg.lookup("Hello");//Error Showed on this line by netbeans
System.out.println(h.SayDemo());
}
catch(RemoteException | NotBoundException e)
{
System.out.println(""+e );
}
}
}
please guide me where I am wrong. Thank You in advance.
You set a SecurityManager in your client main method. Did you also provide a security policy file? The default policy is not very permissive, and denies, among other things, Socket operations.
You can specify a policy that allows all permissions to all code bases like so.
grant {
permission java.security.AllPermission;
};
add it to your command line for invoking java. Substitute mypolicy for your policy file and SomeApp for your main class. Note the two = characters in the second argument
java -Djava.security.manager -Djava.security.policy==mypolicy SomeApp
Note that this is not a safe policy to run for RMI in a production environment (RMI can load remote code bases).
Proper use of the SecurityManager class and policy configuration is a complex topic, for further reading I suggest Java SE 7 Security Documentation and in particular Default Policy Implementation and Policy File Syntax

java.lang.NoClassDefFoundError

I have no idea of why this is having a runtime error, I have googled the problem and it says that a class that was available during compile time is no longer available at run time.
This is the code:
package examples.RMIShape;
import java.rmi.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
//import java.rmi.server.UnicastRemoteObject;
public class ShapeListServer {
public static void main(String args[]){
// System.setSecurityManager(new RMISecurityManager());
System.out.println("Main OK");
try{
ShapeList aShapelist = new ShapeListServant();
System.out.println("After create");
String registryURL = "rmi://localhost:" + "/ShapeList";
startRegistry();
Naming.rebind(registryURL, aShapelist);
System.out.println("ShapeList server ready");
}catch(Exception e) {
System.out.println("ShapeList server main " + e.getMessage());
}
}
// This method starts a RMI registry on the local host, if it
// does not already exists at the specified port number.
private static void startRegistry()throws RemoteException{
Registry registry;
try {
registry = LocateRegistry.getRegistry();
registry.list( ); // This call will throw an exception
// if the registry does not already exist
}
catch (RemoteException e) {
// No valid registry at that port.
System.out.println ("RMI registry cannot be located at port " + Registry.REGISTRY_PORT );
registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
System.out.println("RMI registry created at port " + Registry.REGISTRY_PORT);
}
} // end startRegistry
}
I have googled the problem and it says that a class that was available during compile time is no longer available at run time.
That's not correct. That would cause ClassNotFoundException. This one has several causes, but the most common one is that the class in the file isn the class implied by the filename and directory hierarchy.
Basicall java.lang.NoClassDefFoundError thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.
following links will be helpful. This links will guide you slove issue.
http://javarevisited.blogspot.in/2011/06/noclassdeffounderror-exception-in.html
http://javaeesupportpatterns.blogspot.in/2012/06/javalangnoclassdeffounderror-how-to.html
Hope this will be helpful

how to solve java.rmi.ConnectException in java program?

i have created one simple java RMI program for understanding how it works.But when i trying to run my server side it raising the following exception.
EDIT: We are using proxy connection...
Remote exception: java.rmi.ConnectException: Connection refused to host: 10.7.150.18; nested exception is:
java.net.ConnectException: Connection refused: connect
This is my Server side code for your reference...
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
public class SampleServerImpl extends UnicastRemoteObject implements SampleServer
{
SampleServerImpl() throws RemoteException
{
super();
}
#Override
public int sum(int a,int b) throws RemoteException
{
return a + b;
}
public static void main(String[] args)
{
try
{
//set the security manager
//System.setSecurityManager(new RMISecurityManager());
//create a local instance of the object
SampleServerImpl Server = new SampleServerImpl();
//put the local instance in the registry
Naming.rebind("//10.7.150.18:9999" , Server);
System.out.println("Server waiting.....");
}
catch (java.net.MalformedURLException me)
{
System.out.println("Malformed URL: " + me.toString());
}
catch (RemoteException re)
{
System.out.println("Remote exception: " + re.toString());
}
}
}
Please guide me to get out of this issue...
The Naming class provides methods for storing and obtaining references to remote objects in a remote object registry. Each method of the Naming class takes as one of its arguments a name that is a java.lang.String in URL format (without the scheme component) of the form:
//host:port/name
add a name with in the URL format
//10.7.150.18:9999/Server

Categories

Resources