【问题标题】:Exception when send an object through rmi arguments通过 rmi 参数发送对象时出现异常
【发布时间】:2017-10-28 08:24:44
【问题描述】:

当我尝试将对象作为参数发送给 rmi 时,我收到了这样的异常:

HelloClient exception: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: IntegralClient$1 (no security manager: RMI class loader disabled)

您能帮我弄清楚我的代码和 rmi 服务器-客户端关系实现有什么问题吗?

这是我的代码:

服务器端:

import java.rmi.*;
import java.rmi.server.*; 

public class IntegralServer
{
    public static void main (String[] argv) 
    {
         try 
         {
             IntegralComputeEngine integralCounter = new IntegralComputeEngine();
             Naming.rebind("rmi://localhost/integral", integralCounter);
             System.out.println("Integral Server is ready.");
         }
         catch (Exception e)
         {
             System.out.println("Addition Server failed: " + e);
         }
    }
}

客户端:

import java.rmi.*;

public class IntegralClient
{
    public static void main(String[] args) 
    {
        try 
        {
            IntegralComputeEngineInterface integralCounter = (IntegralComputeEngineInterface) Naming.lookup("rmi://localhost/integral");
            double result = integralCounter.computeIntegral(createFunction(), -1, 1);
            System.out.println("Result is: " + result);
        } 
        catch (Exception e) 
        {
            System.out.println("HelloClient exception: " + e);
        }
    }

    private static Function createFunction() 
    {
        return new Function()
        {
            @Override
            public double valueIn(double x) 
            {
                return 1-x;
            }
        };
    }
}

函数接口(位于客户端和服务器项目中):

import java.io.Serializable;

public interface Function extends Serializable
{
    public double valueIn(double x);
}

IntegralComputeEngineInterface(位于客户端和服务器项目中):

import java.rmi.*;

public interface IntegralComputeEngineInterface extends Remote 
{
    public double computeIntegral(Function function, double from, double to) throws RemoteException;
}

IntegralComputeEngineInterface(仅驻留在服务器上):

import java.rmi.*;
import java.rmi.server.*;

public class IntegralComputeEngine  extends UnicastRemoteObject implements IntegralComputeEngineInterface 
{
    private final double ACCURACY = 100;

    protected IntegralComputeEngine() throws RemoteException 
    {super();}

    @Override
    public double computeIntegral(Function function, double from, double to) throws RemoteException 
    {
        double stepValue = (to - from) / ACCURACY;  
        double stepLength = Math.abs(stepValue);
        double result = 0.0; 

        for(int i = 0; i < ACCURACY; i++)
        {result += stepLength * function.valueIn(from + stepValue*(i + 0.5));}

        return result;
    }
}

这是我的项目组织截图:

将感谢任何有关我的问题的帮助!

我发现了这个: 远程对象的参数或返回值可以是任何可序列化的对象。这包括实现 java.io.Serializable 接口的原始类型、远程对象和非远程对象。有关如何使类可序列化的更多详细信息,请参阅“Java 对象序列化规范”。本地不可用的参数或返回值的类由 RMI 系统动态下载。有关 RMI 在读取参数、返回值和异常时如何下载参数和返回值类的更多信息,请参阅“动态类加载”部分。 Here.

据此,我的论点传递一定没有问题,但它们仍然存在。

【问题讨论】:

标签: java serialization deserialization rmi


【解决方案1】:

您应该创建一个新类,扩展 UnicastRemoteObject 并同时实现您的 Function,它将能够通过 rmi 参数发送此类对象而不会出现任何问题。

所以,我将你的 Function 更改为 FunctionInterface,创建了新类 Function:

import java.rmi.RemoteException;
import java.rmi.server.*;

public class Function extends UnicastRemoteObject implements FunctionInterface
{
    protected Function() throws RemoteException
    {super();}

    @Override
    public double valueIn(double x) 
    {
        return 1-x;
    }
}

所以我的 IntegralClient 现在看起来是这样的:

import java.rmi.*;

public class IntegralClient
{
    public static void main(String[] args) 
    {
        try 
        {
            IntegralComputeEngineInterface integralCounter = (IntegralComputeEngineInterface) Naming.lookup("rmi://localhost/integral");
            double result = integralCounter.computeIntegral(createFunction(), -1, 1);
            System.out.println("Result is: " + result);
        } 
        catch (Exception e) 
        {
            System.out.println("HelloClient exception: " + e);
        }
    }

    private static Function createFunction() throws RemoteException 
    {
//      return new FunctionInterface()
//      {
//          @Override
//          public double valueIn(double x) 
//          {
//              return 1-x;
//          }
//      };

        return new Function();
    }
}

它有效!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 1970-01-01
    相关资源
    最近更新 更多