博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java RMI之HelloWorld程序以及相关的安全管理器的知识
阅读量:5970 次
发布时间:2019-06-19

本文共 4093 字,大约阅读时间需要 13 分钟。

Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,可以让在某个 Java 虚拟机上的对象调用还有一个 Java 虚拟机中的对象上的方法。可以用此方法调用的不论什么对象必须实现该远程接口。

Java RMI不是什么新技术(在Java1.1的时代都有了),但却是是很重要的底层技术。

大名鼎鼎的EJB都是建立在RMI基础之上的,如今另一些开源的远程调用组件,其底层技术也是RMI。
在大力鼓吹Web Service、SOA的时代,是不是每一个应用都应该选用笨拙的Web Service组件来实现,通过对照測试后,RMI是最简单的,在一些小的应用中是最合适的。
以下通过一个简单的样例来说明RMI的原理和应用,以下这个样例是一个简单HelloWorld。但已涵盖RMI的核心应用与开发模式。

server上的JAVA类例如以下:

远程接口:HelloService.java

import java.rmi.Remote;import java.rmi.RemoteException;/** * 远程接口 * @author www.wjrong.com * */public interface HelloService extends Remote {	public String showMessage(String s) throws RemoteException;}

远程接口实现类:HelloServiceImpl .java

import java.rmi.RemoteException;import java.rmi.server.UnicastRemoteObject;/** * 远程接口实现类 * @author www.wjrong.com * */public class HelloServiceImpl extends UnicastRemoteObject implements HelloService { private static final long serialVersionUID = 1L; public HelloServiceImpl() throws RemoteException    {     super();    } public String showMessage(String s) throws RemoteException {	 System.out.println("There is a customer call this method!");	 	 return "Hello "+s;	}}

远程server端启动类:SimpleServer .java

import java.rmi.Remote;import java.rmi.RemoteException;/** * 远程接口 * @author www.wjrong.com * */public interface HelloService extends Remote {	public String showMessage(String s) throws RemoteException;}

下面是client执行的Java类:

远程接口:HelloService.java

import java.rmi.Remote;import java.rmi.RemoteException;/** * 远程接口 * @author www.wjrong.com * */public interface HelloService extends Remote {	public String showMessage(String s) throws RemoteException;}

client启动类:SimpleClient .java

import java.rmi.RemoteException;import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;/** * client启动类 * @author www.wjrong.com * */public class SimpleClient {	public static final int rmiPort=8080;	public static void main(String[] args) {		try {			Context context=new InitialContext();			HelloService helloService1=(HelloService)context.lookup("rmi://192.168.1.180:"+rmiPort+"/HelloService");			HelloService helloService2=(HelloService)context.lookup("rmi://localhost:"+rmiPort+"/HelloService");			   try {				    System.out.println(helloService1.showMessage("World!"));				    //System.out.println(helloService1==helloService2);//一个远程对象的2个代理对象即client的2个存根地址不一样				    //System.out.println(helloService1.equals(helloService2));//一个远程对象的2个代理对象即client的2个存根内容一样。都是指的一样的远程对象				} catch (RemoteException e) {					e.printStackTrace();				}			} catch (NamingException e) {				e.printStackTrace();			}	}}
測试时,先启动SimpleServer,然后启动SimpleClient
server端输出:
There is a customer call this method!
client输出:
Hello World!
简单RMI測试成功!
 
细节须要注意的地方:
1.安全管理器

当没有写策略文件覆盖C:\Program Files\Java\jre1.6.0_05\lib\security里的java.policy时,调用

if(System.getSecurityManager()==null)

System.setSecurityManager(new RMISecurityManager());

系统会抛出异常 java.security.AccessControlException。

原因:每一个Java应用都能够有自己的安全管理器,它是防范恶意攻击的主要安全卫士。

安全管理器通过执行执行阶段检查和訪问授权。以实施应用所需的安全策略。从而保护资源免受恶意操作的攻击。实际上,安全管理器依据Java安全策略文件决定将哪组权限授予类。

然而。当不可信的类和第三方应用使用JVM 时,Java安全管理器将使用与JVM相关的安全策略来识别恶意操作。在非常多情况下,威胁模型不包括执行于JVM中的恶意代码。此时Java安全管理器便没必要的。

当安全管理器检測到违反安全策略的操作时,JVM将引发 AccessControlException或SecurityException。

  在Java应用中,安全管理器是由System类中的方法setSecurityManager设置的。

要获得当前的安全管理器。能够用法 getSecurityManager。 java.lang.SecurityManager类包括了非常多checkXXXX方法。如用于推断对文件訪问权限的checkRead(String file)方法。

这些检查方法调用SecurityManager.checkPermission方法。后者依据安全策略文件推断调用应用是否有运行所请求的操作权限。假设没有,将引发SecurityException。  假设想让应用使用安全管理器和安全策略,可在启动JVM时设定-Djava.security.manager选项。还能够同一时候指定安全策略文件。假设在应用中启用了Java安全管理器。却没有指定安全策略文件,那么Java安全管理器将使用默认的安全策略,它们是由位于文件夹$JAVA_HOME/jre /lib/security中的java.policy定义的。

类装载器用Policy对象帮助它们决定。把一段代码导入虚拟机时应该给它们什么样的权限. 不论什么时候,每个应用程序都仅仅有一个Policy对象.

2.有关rmic的疑惑rmic是为client和server端生成相关的存根和骨架(实际上就是一种代理类)。可是我们直接在javac java的过程就能够直接调用远程方法。好像没有rmic的调用。

原因:在jdk5.0曾经的版本号中。须要用rmic命令来为远程对象生成静态的代理类(包含存根和骨架类),而在jdk5.0中rmi框架会在执行的过程中自己主动为远程 对象生成动态代理类(包含存根和骨架类)。从而更彻底的封装了rmi框架的实现细节。简化了rmi框架的使用方式。
3.registry本地注冊表
为何不启动rmiregistry.exe就能完毕本地。注冊捏?实际上LocateRegistry.createRegistry(rmiPort)就是创建对远程或者本地注冊表的本地引用。创建并导出Registry实例。

转载地址:http://lkzox.baihongyu.com/

你可能感兴趣的文章
Web应用工作原理、动态网页技术
查看>>
EXCEL工作表保护密码破解 宏撤销保护图文教程
查看>>
Catalan数(卡特兰数)
查看>>
.Net Core下使用 RSA
查看>>
python 数据库中文乱码 Excel
查看>>
利用console控制台调试php代码
查看>>
递归算法,如何把list中父子类对象递归成树
查看>>
jsf初学解决GlassFish Server 无法启动
查看>>
hdu 1050 (preinitilization or postcleansing, std::fill) ...
查看>>
Form各键盘触发子所对应的“按键”
查看>>
【java IO】使用Java输入输出流 读取txt文件内数据,进行拼接后写入到另一个文件中...
查看>>
第一次模拟面试
查看>>
window.showModalDialog
查看>>
Pycharm选择pyenv安装的Python版本
查看>>
?Sized 和 Sized
查看>>
Java中如何防止内存泄漏的发生
查看>>
Java中Int转byte分析
查看>>
滑动窗口最大值的golang实现
查看>>
会计的思考(17):还原会计报表的企业个性之一
查看>>
java对象初始化顺序的简单验证
查看>>