`
jameswxx
  • 浏览: 777493 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

一波三折的rmi调用

    博客分类:
  • java
阅读更多

        很久以前写了基于rmi的分布式java程序,现在基本都忘记了,只有一个大概印象。今天写了个小例子复习了下,比较简单,主要在于使自己熟悉下api和部署过程。一共有4个java文件。

   TestRemote.java

     import java.rmi.Remote;
    import java.rmi.RemoteException;
    public interface TestRemote extends Remote {
        public String add(String a, String b) throws RemoteException;
        public String add() throws RemoteException;
    }
 



   TestRemoteImpl.java

 import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class TestRemoteImpl extends UnicastRemoteObject implements TestRemote {
    private static final long serialVersionUID = 1L;
    public TestRemoteImpl() throws RemoteException {
        super();
    }

    public String add(String a, String b) throws RemoteException {
        return a + b;
    }

    public String add() throws RemoteException {
        return "Hello Word";
    }
}
 




Server.java

import java.rmi.Naming;
public class Server {
    public static void main(String[] args) throws Exception {
        try {
            // 创建远程对象
            TestRemote testRemote = new TestRemoteImpl();
            // 奖名称绑定到对象
            Naming.rebind("rmi://localhost:1099/server", testRemote);
            System.out.println("RMI服务器正在运行。。。。。。");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
 



Client.java

import java.rmi.Naming;
public class Client {
    public static void main(String args[]) {
            try {
                TestRemote s = (TestRemote) Naming.lookup("rmi://localhost:1099/server");
                System.out.println(s.add());
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.exit(0);

     }
}
 



第一步  生成stub文件

        class都编译好后,要生成stub文件,我测试的时候,class编译到我的工程下的bin目录,我在bin目录下执行命令“rmic TestRemoteImpl”,rmic后面完整路径的Remote接口的实现类,如果TestRemoteImpl在包com.test里,那么命令就是“rmic com.test.TestRemoteImpl”,后面不要带上java后缀。执行完后,TestRemoteImpl.class所在的目录(就是bin目录)就会出现一个TestRemoteImpl_Stub.class文件。

第二步  准备java安全策略文件

         在bin目录下新建一个名为“mypolicy”的文件,写入内容如下
grant {  
permission java.security.AllPermission "", "";  
};

第三步  启动rmi注册程序

在命令行下,执行命令:rmiregistry。特别要主意的是,这个命令一定要在class所在的根目录执行,比如class文件全部编译到myproject/bin目录里,那么这个命令就一定在
myproject/bin目录下执行,否则在注册远程对象的时候,就会报以下异常:

java.rmi.UnmarshalException:   error   unmarshalling   return;   nested   exception   is:  
java.lang.ClassNotFoundException
。。。。。。

网上有很多人碰到这个问题,这是一定要主意的。

第四步  启动rmi服务器

在bin目录下,执行"java -Djava.security.policy=mypolicy Server",主要mypolicy是上面建立的安全策略文件。如果运行正确,命令行会输出:RMI服务器正在运行。。。。。。

第五步  启动客户端验证rmi

在bin目录下,执行“java Client”,如果运行正确,命令行会输出:Hello Word


我因为粗心犯的错误

1:本来是TestRemote s = (TestRemote) Naming.lookup("rmi://localhost:1099/server");我写成了TestRemote s = (TestRemoteImpl) Naming.lookup("rmi://localhost:1099/server");
造成程序报ClassCaseException,因为lookup出来的是rmi框架自己实现了TestRemote接口的代理类,转成TestRemoteImpl当然不行。

2:在命令行下执行rmi服务器程序时,老是报ClassNotFoundException,检查了好半天,最后发现,是CLASSPATH被公司的一个工具给改写了,CLASSPATH环境变量里没有当前路径“.”,于是我在命令行里执行export $CLASSPATH=./$CLASSPATH,结果当然悲剧啊,唉,粗心阿,应该是执行export CLASSPATH=./$CLASSPATH。
  
3:接着是rmiregistery,linux下是rmiregistery,而windows下是start rmiregistery,而我在linux下,一开始就输入命令start rmiregistery

4:java安全问题
默认情况下,rmi在服务器端是被java安全策略限制的,要解决这个问题,可以通过两种途径。一种解决方法是自己建立一个java安全策略文件,然后执行程序时带上这个参数;另一种解决方法是自己在jre的安全策略文件里加入内容:
grant {  
permission java.security.AllPermission "", "";  
};

 

 

5:总结

       (1)勿以事小而不为,再简单的东西,知道归知道,实践归实践,实践过程中,总会碰到一些实际的问题,从而使经验得以成长。

       (2)如果只是报ClassNofFoundException,那么要检查CLASSPATH环境变量是否正确。

       (3)如果报以下异常:

java.rmi.UnmarshalException:   error   unmarshalling   return;   nested   exception   is:  
java.lang.ClassNotFoundException

那就要特别注意,这是因为在将远程对象注册到rmi注册管理器的时候,注册管理器找不到要绑定的对象的class信息。

如在命令行下执行:rmiregistry   那么rmi注册管理器在默认端口1099监听,在执行“ Naming.rebind("rmi://localhost:1099/server", testRemote); ”的时候,告诉rmi注册管理器,我要绑定这个对象,rmi注册管理器就会寻找这个对象的class信息,但是很奇怪的是,rmi注册管理器并不关心系统的CLASSPATH,它只是在当前目录中寻找class定义,所以这是为什么要在class所在的根目录执行rmiregistry命令。

 

分享到:
评论
3 楼 yongsky 2012-03-18  
start rmiregistery写错了 
2 楼 whao189 2011-06-08  
感觉看了楼主的文章有很多收获,这些天也正在了解RMI,学习代理模式,呵呵。。

期待楼主讲讲并发包下面的 东西啊!
1 楼 wokeke 2011-05-25  
最喜欢这种短而精的DEMO了,3Q楼主!!

相关推荐

    Spring-RMI (RMI调用, HTTP调用)

    Spring通过提供RMI集成,简化了RMI服务的创建和调用。以下是一些关键点: 1. **服务接口定义**:首先,你需要定义一个远程服务接口,这个接口将包含你希望在远程进程中执行的方法。 2. **服务实现**:接着,创建该...

    利用RMI异步调用

    在IT行业中,远程方法调用(Remote Method Invocation, RMI)是Java平台提供的一种机制,允许在不同的Java虚拟机之间进行分布式计算。RMI使得一个Java对象能够像调用本地方法一样调用远端对象的方法,极大地扩展了...

    RMI远程过程调用

    RMI采用JRMP(Java Remote Method Protocol)通讯协议,是构建在TCP/IP协议上的一种远程调用方法。它允许运行在一个Java虚拟机上的对象调用运行在另一个Java虚拟机上的对象方法,从而使编程人员可以方便地在网络环境...

    rmi调用架构设计

    rmi调用架构设计

    RMI远程调用

    **RMI远程调用详解** 远程方法调用(Remote Method Invocation,简称RMI)是Java平台提供的一种机制,它允许一个Java对象调用另一个在不同Java虚拟机(JVM)上的对象的方法。RMI是Java分布式计算的核心技术,主要...

    rmi远程调用读取文件

    RMI(Remote Method Invocation,远程方法调用)是Java平台上的一个核心特性,它允许Java对象在不同的JVM之间进行通信,实现分布式计算。在这个场景中,“rmi远程调用读取文件”指的是通过RMI机制,使得一个JVM中的...

    分布式 RMI远程调用

    分布式RMI(Remote Method Invocation)远程调用是一种在分布式系统中实现对象间通信的技术,它允许一个对象在某个进程中调用另一个位于不同进程或者不同计算机上的对象的方法,从而实现跨网络的对象交互。...

    RMI远程方法调用RMI远程方法调用

    RMI远程方法调用是Java平台上的一个关键特性,它允许Java对象在不同的JVM之间进行通信,从而实现分布式计算。RMI的核心理念是让开发者能够像调用本地方法一样调用远程对象的方法,简化了分布式系统的设计和实现。 *...

    RMI远程调用代码及使用方法

    ### RMI远程调用代码及使用方法 #### 一、RMI简介 远程方法调用(Remote Method Invocation,简称RMI)是Java平台提供的一种分布式计算技术,它允许开发人员在不同的Java虚拟机(JVM)之间进行对象的远程调用。通过...

    使用rmi进行远程调用

    在Java编程领域,RMI(Remote Method Invocation,远程方法调用)是一种强大的技术,它允许在不同的Java虚拟机(JVM)之间进行分布式计算。在这个“使用rmi进行远程调用”的示例中,我们看到的是一个基于RMI实现的...

    Java-远程方法调用RMI参数详解.docx

    Java 远程方法调用(Remote Method Invocation,RMI)是一种在分布式环境中调用对象方法的技术,它使得Java应用程序能够透明地调用运行在不同 JVM 上的远程对象的方法。RMI 包含了一系列的参数,这些参数对于优化...

    java rmi远程调用

    最近在学习代理模式,用到了java rmi远程调用,包含服务端和客户端,之前一直没有接触过,学习了java rmi远程调用,一方面可以了解代理模式,一方面熟悉java低层的远程

    RMI实现的远程调用

    Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种用于在不同Java虚拟机之间进行远程通信的技术。通过RMI,开发者可以透明地调用运行在其他网络节点上的对象的方法,就像它们是在本地一样。...

    RMI 跨平台调用的demo

    远程方法调用(Remote Method Invocation,RMI)是Java提供的一种强大的分布式计算技术,它允许在不同的Java虚拟机(JVM)之间进行方法调用,实现了对象的跨平台交互。这个"RMI跨平台调用的demo"展示了如何在Windows...

    java rmi远程方法调用 客户端

    Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间透明地调用对象的方法。在RMI架构中,客户端能够像调用本地对象一样调用远程服务器上的对象...

    java调用RMI小结

    RMI(Remote Method Invocation,远程方法调用)是Java平台中用于分布式计算的一种技术,它允许一个Java对象调用另一个在不同 JVM(Java虚拟机)上的对象的方法,从而实现跨网络的通信。Java RMI 提供了一种透明的...

    xmemcached1.3.5源码-附带自己写的RMI调用它的JMX服务

    xmemcached1.3.5源码-附带自己写的RMI调用它的JMX服务,使用RMI调用JMX服务的详细过程,完整的eclipse工程,直接导入即可用。还用一些运行截图,很有用。 自己写的例子,类名是BaseExample 和RMITest.

    Java RMI(远程方法调用)Demo

    6. **序列化(Serialization)**:RMI依赖于Java的序列化机制来传输对象和方法调用。所有需要在网络间传递的对象都必须实现Serializable接口。 在Java RMI的Demo中,通常会包含以下步骤: 1. **创建远程接口**:...

    Java RMI 远程方法调用

    Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间进行方法调用,仿佛这些方法是在本地对象上执行一样。这个技术极大地简化了构建分布式应用的...

Global site tag (gtag.js) - Google Analytics