JDK8 RMI服务器无法在JDK9或JDK10中运行-ClassNotFoundException

时间:2018-09-20 11:45:12

标签: java java-8 rmi java-9 java-10

我有一个非常简单的RMI客户端/服务器应用程序,它在不同版本的JDK(直到JDK8)上都可以正常运行。突然之间,在更新为JDK9或JDK10之后,它不再起作用。 JKD9和JDK10中必须有一些更改,可能与我无法找到的codebase属性有关。 代码和类路径,代码库,java.policy均无变化。没有。仅升级到JDK10会导致服务器崩溃。

该错误是代码库不正确时的典型错误。

java.rmi.UnmarshallException:错误解组参数 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();
    }
}
}

项目结构很简单。有一个基于exampleirRMI的目录。然后,对于java类,我们有exampleRMI \ src。然后为字节码提供exampleRMI \ bin,为java.policy提供exampleRMI \ security,策略为

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

非常欢迎任何帮助。

0 个答案:

没有答案