Java RPC通信机制之RMI

大卫注1:

写完CORBA系列后,本想接着写写其它几种典型的远程通信协议:RMI、XML-RPC、SOAP,但由于工作的原因,加之房子装修等麻烦事,一直没有心情动笔。今天接到装修公司老板电话说开工证要晚几天办下来,要停工4-5天,狂怒后突然有了静下心来完成原本想写的东西的想法,既来之,则安之(i.e.郁闷啊,郁闷啊,就习惯了...)

大卫注2:

这个系列基本上是一份笔记,没有加入太多我自己的东西,仅仅记录了自己在使用过程中遇到的问题,及其解决办法。

 

在传统的RPC编程接口逐渐淡出人们视线的同时,新的、更便于使用且附加了更多特性的RPC编程接口也不断涌现,CORBA作为分布式对象计算技术的典范,在很长一段时间内极大地吸引了大家的注意,但是由于CORBA规范试图覆盖过多的内容,使得CORBA显得过于复杂,也极大地限制了CORBA的应用范围,本系列将向大家介绍几种轻量级的,更适于在Java开发中使用的RPC编程接口:RMI、XML-RPC、SOAP。

RMI(Remote Method Invocation)

与本系列将介绍的其它两种RPC编程接口不同,RMI(Remote Method Invocation)显得有些老旧,它是在Java-IDL加入J2SE之前被引入的。RMI开发流程与CORBA如出一辙(从出现的时间上无法确定RMI是否是按照CORBA规范定制的),因此,其开发过程相对比较烦琐,但是由于RMI是EJB的基础,因此,它在Java开发中具有十分重要的地位。

以下是创建远程方法调用的5个步骤:

1.   定义一个扩展了Remote接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常;

2.   定义一个实现该接口的类;

3.   使用rmic程序生成远程实现所需的存根和框架;

4.   创建一个客户程序和服务器进行RMI调用;

5.   启动rmiregistry并运行自己的服务程序和客户程序。

下面举一个简单、而且被无数次引用的例子:Echo。

1、定义Echo接口

//Echo.java

//The Echo remote interface

package demo.rmi;

 

import java.rmi.*;

 

public interface Echo extends Remote {

      String echo(String msg) throws RemoteException;

}

2、实现Echo接口

//EchoServer.java

//The implementation of the Echo remote object

package demo.rmi;

 

import java.net.*;

import java.rmi.*;

import java.rmi.registry.*;

import java.rmi.server.*;

 

public class EchoServer

      extends UnicastRemoteObject

      implements Echo {

       //默认构件器,也要“掷”出RemoteException违例

      public EchoServer() throws RemoteException {

            super();

      }

 

      public String echo(String msg) throws RemoteException {

            return "Echo: " + msg;

      }

 

      public static void main(String [] args) {

            /*创建和安装一个安全管理器,令其支持RMI。作为Java开发包的一部分,适用于RMI唯一一个是RMISecurityManager.*/

            System.setSecurityManager(new RMISecurityManager());

 

            try {

                     /*创建远程对象的一个或多个实例,下面是EchoServer对象*/

                  EchoServer es = new EchoServer();

                  /*向RMI远程对象注册表注册至少一个远程对象。一个远程对象拥有的方法即可生成指向其他远程对象的句柄,这样,客户到注册表里访问一次,得到第一个远程对象即可.*/

                  Naming.rebind("EchoServer", es);

                  System.out.println("Ready to provide echo service...");

            } catch (Exception e) {

                  e.printStackTrace();

            }

      }

}

这个实现类使用了UnicastRemoteObject去连接RMI系统。在我们的例子中,我们是直接的从UnicastRemoteObject这个类上继承的,事实上并不一定要这样做,如果一个类不是从UnicastRmeoteObject上继承,那必须使用它的exportObject()方法去连接到RMI。(否则,运行时将被告知无法序列化。)

如果一个类继承自UnicastRemoteObject,那么它必须提供一个构造函数并且声明抛出一个RemoteException对象(否则,会遇到编译错误)。当这个构造函数调用了super(),它就激活UnicastRemoteObject中的代码完成RMI的连接和远程对象的初始化。

3、运行rmic编译实现类,产生_Stub类

在demo.rmi.EchoServer.java上级目录下运行如下命令:

rmic demo.rmi.EchoServer

4、编写客户程序

//EchoClient.java

//Uses remote object EchoServer

package demo.rmi;

 

import java.rmi.*;

import java.rmi.registry.*;

 

public class EchoClient {

      public static void main(String [] args) {

            System.setSecurityManager(new RMISecurityManager());

 

            try {

                  Echo t = (Echo)Naming.lookup("EchoServer");

 

                  for (int i = 0; i < 10; i++) {

                        System.out.println(t.echo(String.valueOf(i)));

                  }

            } catch (Exception e) {

                  e.printStackTrace();

            }

      }

}

5、运行

编码的工作就只有这些,现在可以依次启动rmiregistry(启动rmiregistry时可以附加一个端口,一般使用默认的端口1099即可,这是默认的Naming Service运行端口)、EchoServer、EchoClient了。但是,虽然有些RMI的资料没有提到,但你运行时不可避免会遇到如下两个错误:

1)java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099 connect,resolve)

原因很简单,RMI Server/Client程序试图通过Socket连接访问本机的rmiregistry服务(即RMI的Naming Service,其运行的默认端口是1099)。要解决这个问题,可以在运行Server/Client时指定一个Policy文件(关于Policy的更多信息,见参考2),如下:

java -Djava.security.policy=demo/rmi/policyfile.txt demo.rmi.EchoServer

Policy文件的内容为:

grant{

      permission java.net.SocketPermission "localhost:1099", "connect, resolve";

};

即允许访问本机的1099端口。

或者干脆来个彻底开放:

grant {

      permission java.security.AllPermission "", "";

};

2)java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:

        java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:

        java.lang.ClassNotFoundException: demo.rmi.EchoServer_Stub

        ...

如果你凑巧用启动rmiregistry的终端窗口启动了EchoServer,那么你很走运,你看不到上面的错误,但如果你不是在看完这篇文章后就再也用不到RMI,那么,这个错误在那里等着你,:)。

错误很明显,

32、社交媒体大数据中的情感分析与网络欺凌检测 本文探讨了社交媒体大数据在情感分析和网络欺凌检测中的应用。情感分析有助于应对自动化带来的社会变化、促进社会包容和推动环境保护。网络欺凌作为一种严重的在线危害,其检测依赖于数据预处理、特征提取与深度学习模型(如CNN、LSTM)进行分类。文章还总结了大数据在欺诈检测、医疗、制造、交通等领域的广泛应用,并分析了数据存储、处理速度、质量和技术工具等方面的挑战,提出了相应的应对策略。未来,随着技术进步,社交媒体大数据将在更多领域发挥关键作用。 阅读详情

相关推荐

STM32 HAL库定时器中断里读编码器速度准吗?聊聊MG310电机的测速与防溢出处理

本文探讨了STM32 HAL库在定时器中断中读取编码器速度的精度问题,特别针对MG310电机的测速与防溢出处理提供了解决方案。通过对比定时中断法和编码器模式的性能,揭示了硬件编码器接口在降低误差和CPU占用率方面的优势,并详细介绍了CubeMX配置技巧和防溢出处理的工程实践。

weixin_28720767的博客 401

java.rmi.server_java.rmi.ServerException:服务器线程中发生Remo...

我在运行Server类(使用java服务器命令)时遇到异常,如下所示(我已经使用start rmiregistry命令启动了rmiregistry).可能是什么问题呢?C:\Users\william\Desktop\HelloWorld\Server>java Serverjava.rmi.ServerException: RemoteException occurred in serve...

weixin_35998457的博客 2051

HyperMesh 2025新功能尝鲜:用Volume Tetramesh一键生成工业级四面体网格

HyperMesh 2025推出的Volume Tetramesh功能,通过“体到体”的全新范式,实现了工业级四面体网格的一键生成。该功能利用Proximity与Curvature参数智能识别并加密几何特征,将工程师从繁琐的几何清理和表面网格划分中解放出来,在保证网格质量的同时,显著提升了前处理效率,尤其适用于发动机缸体等复杂模型的仿真分析。

weixin_29229055的博客 477

RmiServiceException(RMI服务异常)可能的原因和解决方法

异常时,首先查看异常的详细信息以获取更多的上下文。仔细检查涉及到的 RMI 注册、服务实现、客户端调用等,确保它们在当前的网络环境和使用场景下是有效的。根据异常信息,逐步排查可能的原因,以便更好地理解和解决问题。异常时,查看异常的详细信息以获取更多的上下文。仔细检查涉及到的 RMI 注册、服务实现、客户端调用等,确保它们在当前的网络环境和使用场景下是有效的。根据异常信息,逐步排查可能的原因,以便更好地理解和解决问题。

Java开源程序猿 2463

08-SD卡-TF卡硬件电路设计

SD卡-TF卡硬件电路设计

weixin_66510961的博客 8258

Android13 CarPowerManagementService启动流程分析

在CarPowerManagementService中init调用PowerHalService的setListener设置事件侦听器以接收车辆的电源事件。

liuning1985622的博客 956

聊聊分布式架构04——RPC通信原理

RPC(Remote Procedure Call)是一种远程过程调用协议,用于在分布式系统中进行远程通信,允许一个计算机程序调用另一个地址空间(通常是在不同的机器上)的函数或过程,就像调用本地函数一样。在RPC(Remote Procedure Call,远程过程调用)中使用反射的主要目的是实现透明的远程调用,即使在客户端和服务器之间存在远程分离,也可以像调用本地方法一样调用远程服务。

Elaine2391的博客 3036

电子结构设计(EMD)十年知识总结

客官,你的面相是做结构设计的奇才~1. 材料选择【一出手的0.1s就败了】2. 钣金件设计【折来折去有啥难】3. 塑胶件设计【看着好复杂】4. 型材件设计【凭啥不让我设计】5. 电子结构(PCBA)设计【静电肿么要我背锅】6. 包装设计【要的就是金玉其外,败絮其中】7. 外观(工业)设计【好不好看,谁说了算】8. 标签设计【】9. 标准件选择【一个螺丝难倒英雄汉/提起螺丝,英雄气短】10. 计算仿...

wfeng86的博客 1569

【RPC】RPC和RMI的区别-----未完全研透

一:RPC 远程过程调用(注:可以这么理解,RPC是所有语言的通用协议,有点像SOAP,而RMI是RPC的一种Java实现『或说RMI是RPC的java版的细化要求』;这是自己目前的理解如果有不正确的地方还望能指出) RPC(Remote Procedure Call Protocol)远程过程调用协议,通过网络从远程计算机上请求调用某种服务。(注:可以这么理解,只要是通过网络从而调有远端的某种服务,那么这就是RPC,而不一定就是要http请求,tcp请求,udp请求,soap报文请求都可以,何况这几种.

我的笔记本 2415

Cesium中级开发教程之五十二:气泡弹窗

支持多种交互方式触发气泡弹窗显示,如鼠标悬停、点击地图上的特定元素(像实体、标注、模型等)。例如,当用户鼠标悬停在一个表示城市的点上时,弹出显示该城市名称、人口等信息的气泡。:依据特定的数据条件或业务逻辑触发。比如,当某个区域的气象数据达到一定阈值时,自动弹出显示相关气象预警信息的气泡。

664

分享Charles抓包 显示<unknown> 解决方案 !

首先电脑上需要安装charles,然后需要设置手机上的WiFi设置,修改配置中的代理设置,把服务器的主机名设置成你电脑当前的ip地址(需要注意的是,你的代理服务器主机名的ip地址要和你当前连的ip地址的网段需要一致)。像 Charles 这样的工具,虽然功能强大,但仍然需要用户具备一定的配置和排障能力,以应对各种复杂的网络环境。通过将 Charles 的 SSL 证书正确安装到移动设备中,并在设置中启用“允许不安全的内容”选项,最终成功解决了这一问题,并准确抓取到所有请求数据。Charles 显示。

朱雀随云记的博客 8105

学习Java并发编程中的消息通信和RPC

1.背景介绍 在Java并发编程中,消息通信和远程过程调用(RPC)是两个非常重要的概念。这篇文章将涵盖这两个概念的背景、核心概念、算法原理、最佳实践、实际应用场景、工具和资源推荐以及未来发展趋势与挑战。 1. 背景介绍 Java并发编程是一种编程范式,它允许多个线程同时执行多个任务。这种编程方式在现代计算机系统中非常常见,因为它可以充分利用多核心和多处理器的资源,提高程序的执行效率。 消...

AI天才研究院 864

UG\NX二次开发 一种获取点的面的方法

有时,我们需要用户选择“面上的点”时,同时获取点所在的面。例如:调标准件、刻字等。通过点击点,ug会创建一个智能对象,可通过函数获得对象的父项,即为点所在的面。下面是封装的函数以及测试例子点在曲线上,获取点所在的曲线同理。UF_UI_point_constructd点对话框 和 block UI对话框都可以使用。

王牌飞行员_里海的博客 1779

深入HDFS——从RPC到Hadoop IPC

深入介绍了从RPC到Java RMI,再到Hadoop IPC的设计与实现思路。

从知识输入到知识输出 1428

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

深究Java中的RMI

前言:随着一个系统被用户认可,业务量、请求量不断上升,那么单机系统必然就无法满足了,于是系统就慢慢走向分布式了,随之而来的是系统之间“沟通”的障碍。一般来说,解决系统之间的通信可以有两种方式:即远程调用和消息。RMI(Remote Method Invocation)就是远程调用的一种方式,也是这篇文章主要介绍的。 一、RPC和RMI的关系 从目标上来看,它们都是为了实现远程调用的。不

qq_35149957的博客 2051

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【Java-分布式】RMI 和 RPC 有什么区别?

摘要: RPC(远程过程调用)是一种跨语言通信协议,支持不同语言服务调用(如Python调用Go),典型框架如gRPC;RMI(远程方法调用)是Java专属机制,仅支持Java对象间通信,依赖序列化传递对象。核心区别在于RPC通用性强(跨语言/函数级通信),而RMI深度集成Java生态(对象级调用)。应用场景上,RPC适合多语言微服务,RMI适用于纯Java系统(如EJB)。简言之,RPC是“通用翻译官”,RMI是“Java专属快递员”。

ZGW0513的博客 484

Java通信方式总结

Java通信方式总结 1 Java对象、方法间通信方式 1.1 值传递、引用传递 (1)值传递:将副本传递给方法,调用方法改变副本的值,但是并不改变原值 (2)引用传递:传递的是对象(或者变量)的引用,对其修改,会改变原值 从内存分配的角度讲解Java中只存在值传递,不存在引用传递 1.2 浅拷贝、深拷贝 (1)浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。 (2)深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容

Mr.X 6259

RPC零基础学习指南

分布式基础 为什么要使用RPC 分布式的定义及解决问题的方式非常简单,即业务服务器接收到用户的计算请求后根据特定的算法,将计算的不同部分交由后台的不同主机处理,待结果汇总后,由业务服务器反馈给客户端。 在这个过程中,开发人员最为关注的就是计算的分发调度方式,因为这涉及到对网络通讯和并发的控制。 如果有一种方式能够将网络通讯和并发控制对程序开发人员透明化,那么将极度简化此类应用的开发成本...

知而获智,智达高远 478

Java面试题总结15之简述你对RPC,RMI的理解

远程对象必须实现Java.rmi.server.uniCastRemoteObject类,这样草能保证客户端访问获得远程对象时,该远程对象将会把自身的一个拷贝以Socket的形式传输给客户端,此时客户端所获得的这个拷贝称为存根,而服务器端本身已存在的远程对象则称之为骨架,其实此时的存根时客户端的一个代理,用于与服务器端的通信,而骨架也可认为是服务器端的一个代理,用于接受客户端的请求之后调用远程方法来响应客户端的请求。RPC:在本地调用远程的函数,远程过程调用,可以跨语言实现,httpClient。

weixin_51627264的博客 602
上一篇: Java操作SQL数据库[查询,更新,存储过程,类型对照]
下一篇: java中文件操作大全
jdlsfl
博客等级 码龄20年 235粉丝 36原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值