JAVA RMI ClassNotFound
from docs
The URL of a directory in which the classes are organized in
package-named sub-directories
so URL should point to classes root directory, more or less something like this:
-Djava.rmi.server.codebase=file://E:/Rmi/src
Try it out.
RMI UnmarshalException ClassNotFoundException server only
java.lang.ClassNotFoundException: nl.marktielemans.rmisorter.server.factory.ISortFactory
...
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
The Registry doesn't have that class available in its CLASSPATH.
If you're using the java.rmi.server.codebase
property you need to set it before exporting any remote objects, and the codebase needs to be something the Registry and the clients can use.
public static void addCodeBaseFor(Class<?> clazz) {
System.setProperty("java.rmi.server.codebase", clazz.getProtectionDomain().getCodeSource().getLocation().toString());
}
This isn't going to work. The location on the server of the containing JAR file can't be seen from the client. Generally it is an http: or ftp: URL.
Java RMI and ClassNotFoundException
You are trying to send a serialized object of a class that is unknown to the server.
When you execute:
Pi task = new Pi(Integer.parseInt(args[1]));
BigDecimal pi = comp.executeTask(task);
The server doesn't really know what is Pi
. And since the Pi
class is a part of your API, it should be loaded on server, too.
When I have an application that needs to execute something remotely, using for example RMI
, Spring Remoting or similar, I divide my project in 3 projects: API
, Server and Client. The API project will have all interfaces and model classes relevant to the functionality (this project will result in a jar, and is more or less like your computer JAR). The server will import the API JAR, will implement the interfaces and make the service available through an Remote layer (like you did with your server), and the client as you did with your client.
When you work with serialization, the class itself must be known by both sides. What is then transferred is the state of the objects in order to rebuild it on the other side.
Serialization is the mechanism used by RMI to pass objects between
JVMs, either as arguments in a method invocation from a client to a
server or as return values from a method invocation.
A bit of Serialization on RMI By William Grosso (October 2001). And here a bit more info.
Running RMI Server, got errors with marshalling arguments and class not found
Summarizing the comment chain.
What is essential is that the registry should be aware of the Server stub. In order for this to happen, there are two options. Option one is the Registry and the Server to share the same VM. This can be achieved through
adding LocateRegistry.createRegistry()
In the beginning of the server main class.
Option two is
two configure the server to use automatic download of the stub files this can be achieved through java.rmi.server.codebase
example command
java -cp c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar
-Djava.rmi.server.codebase=file:/c:/home/ann/public_html/classes/compute.jar
-Djava.rmi.server.hostname=mycomputer.example.com
-Djava.security.policy=server.policy
engine.ComputeEngine
this is taken from https://docs.oracle.com/javase/tutorial/rmi/running.html
Related Topics
How to Use .Jar Files in Netbeans
Why Does This Go into an Infinite Loop
Naming Threads and Thread-Pools of Executorservice
Coding Conventions - Naming Enums
Open a Link in Browser with Java Button
Java Conditional Compilation: How to Prevent Code Chunks from Being Compiled
Docker: Combine Multiple Images
Intellij Idea Java Classes Not Auto Compiling on Save
Use of Class Definitions Inside a Method in Java
Using Internal Sun Classes with Javac
Get All of the Classes in the Classpath