У меня очень простое клиент-серверное приложение 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
Любая помощь будет очень приветствоваться.