RMI-сервер JDK8 не работает в JDK9 или JDK10 - ClassNotFoundException - PullRequest
0 голосов
/ 20 сентября 2018

У меня очень простое клиент-серверное приложение RMI, которое отлично работает на разных версиях JDK, вплоть до JDK8.Внезапно он не работает после обновления до JDK9 или JDK10.Должно быть какое-то изменение в JKD9 и JDK10, возможно, связанное со свойством codebase, которое мне не удалось найти.Никаких изменений ни в коде, ни в classpath, codebase, java.policy.Ничего такого.Только обновление до JDK10 и сбой сервера.

Ошибка является типичной, если кодовая база неверна.

java.rmi.UnmarshallException: ошибка unmarshalling arguments java.lang.ClassNotFoundException.

Это код, который очень очень глупый.У нас есть удаленный интерфейс, IServer.java

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

Затем у нас есть класс, реализующий удаленный интерфейс.

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();
    }
}
}

Структура проекта проста.Есть basedir, названный exampleRMI.Тогда у нас есть пример RMI \ src для классов Java.Затем exampleRMI \ bin для байт-кодов и exampleRMI \ security для java.policy и политики:

grant {
    permission java.security.AllPermission;
};

Затем у нас есть файл ANT build.xml:

<?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>

Затем мы запускаем rmiregistry

rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false

И крошечное приложение, использующее

ant build server

Любая помощь будет очень приветствоваться.

...