Q&A for Work

Setup a private space for you and your coworkers to ask questions and share information. Learn more about Teams

I have a very simple RMI client/server application that has been working perfectly well on different versions of JDK, up to JDK8. All of a sudden, it does not work anymore after updating to JDK9 or JDK10. There must be some change in JKD9 and JDK10, probably related to the codebase property, that I have been unable to find. No changes neither in the code, nor in the classpath, codebase, java.policy. Nothing. Only upgrading to JDK10 and the server crashes.

The error is the typical one when the codebase is not correct.

java.rmi.UnmarshallException:error unmarshalling arguments java.lang.ClassNotFoundException.

This is the code, which is very very silly. We have a remote interface, IServer.java

package sd.rmi.server;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IServer extends Remote {
 String sayHello() throws RemoteException;

Then we have the class that implements the remote interface.

package sd.rmi.server;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class Server implements IServer {
private static final long serialVersionUID = 1L;
protected Server() throws RemoteException {
    super();
public String sayHello() {
    return "Hello World!";
public static void main(String[] args) {
    if (System.getSecurityManager() == null) {
        System.setSecurityManager(new SecurityManager());
    String name = "//" + args[0] + ":" + args[1] + "/" + args[2];
    try {       
        IServer objServer = new Server();
        IServer stubServer = (IServer) UnicastRemoteObject.exportObject(objServer,0);
        Registry registry = LocateRegistry.getRegistry();
        registry.rebind(name, stubServer);
        System.out.println("* Server '" + name + "' active and waiting...");
    } catch (Exception e) {
        System.err.println("- Exception running the server: " + e.getMessage());
        e.printStackTrace();

The project structure is simple. There is basedir, named exampleRMI. Then we have exampleRMI\src for the java classes. Then exampleRMI\bin for the bytecodes, and exampleRMI\security for the java.policy and the policy is

grant {
    permission java.security.AllPermission;

Then we have an ANT build.xml file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." name="2.2_exampleRMI_Server">    
<property name="source.dir" location="src"/>
<property name="build.dir" location="bin"/>
<property name="classpath" location="bin"/>
<property name="server.port" value="1099"/> 
<property name="server.IP" value="127.0.0.1"/>
<property name="server.Name" value="HelloServer"/>
<property name="policy.file" location="security/java.policy"/>  
<target name="build" description="Builds the project">
    <delete dir="${build.dir}"/>
    <mkdir dir="${build.dir}"/>
    <javac srcdir="${source.dir}" destdir="${build.dir}" classpath="${classpath}" deprecation="true" fork="true" includeAntRuntime="no"/>
</target>
<target name="server" description="Runs the Server">
    <java classname="sd.rmi.server.Server" classpath="${classpath}" fork="true">
        <jvmarg value="-Djava.rmi.server.codebase=file:${build.dir}/"/>
        <jvmarg value="-Djava.security.policy=${policy.file}"/> 
        <jvmarg value="-Djava.rmi.server.useCodebaseOnly=false"/>           
        <arg value="${server.IP}"/> 
        <arg value="${server.port}"/> 
        <arg value="${server.Name}"/> 
    </java>
</target>
                Java 9 introduced a new module system. Be sure to check if you have the correct modules loaded. According to the Java API documentation you need to include the java.rmi module
                    – Lukas
                Sep 20 '18 at 12:07
                It would be interesting to know if you were using a recent or really old JDK 8 update. This is interesting because remote class loading was disabled by default a long time ago and maybe this is what you are running into.
                    – Alan Bateman
                Sep 20 '18 at 15:49
                As far as I know, we can still use the non-modular code in JDK9, and in any case, the java.rmi module belongs to java.base module.
                    – ardot
                Sep 21 '18 at 14:51
                Off hand, I can't think of anything in JDK 9 to explain what you are seeing. It may be useful to share a standalone project that shows the rmiregistry and other commands that you are using. It's probably something simple not right, just not enough information in the post or discussion here to guess.
                    – Alan Bateman
                Sep 22 '18 at 7:05
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

site design / logo © 2019 Stack Exchange Inc; user contributions licensed under cc by-sa 3.0 with attribution required. rev 2019.7.26.34458