Java RMI之HelloWorld程序以及相关的安全管理器的知识

Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。Java RMI不是什么新技术(在Java1.1的时代都有了),但却是是非常重要的底层技术。大名鼎鼎的EJB都是建立在RMI基础之上的,现在还有一些开源的远程调用组件,其底层技术也是RMI。在大力鼓吹Web Service、SOA的时代,是不是每个应用都应该选用笨拙的Web Service组件来实现,通过对比测试后,RMI是最简单的,在一些小的应用中是最合适的。下面通过一个简单的例子来说明RMI的原理和应用,下面这个例子是一个简单HelloWorld,但已涵盖RMI的核心应用与开发模式。

服务器上的JAVA类如下:

远程接口:HelloService.java

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

远程接口实现类:HelloServiceImpl .java

import java.rmi.RemoteException;import java.rmi.server.UnicastRemoteObject;/** * 远程接口实现类 * @author * */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;}}

远程服务器端启动类:SimpleServer .java

import java.rmi.Remote;import java.rmi.RemoteException;/** * 远程接口 * @author  * */public interface HelloService extends Remote {<span style="white-space:pre"></span>public String showMessage(String s) throws RemoteException;}

以下是客户端运行的Java类:

远程接口:HelloService.java

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

客户端启动类:SimpleClient .java

import java.rmi.RemoteException;import javax.naming.Context;import javax.naming.InitialContext;import javax.naming.NamingException;/** * 客户端启动类 * @author * */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个代理对象即客户端的2个存根地址不一样//System.out.println(helloService1.equals(helloService2));//一个远程对象的2个代理对象即客户端的2个存根内容一样,,都是指的一样的远程对象} catch (RemoteException e) {e.printStackTrace();}} catch (NamingException e) {e.printStackTrace();}}}测试时,先启动SimpleServer,然后启动SimpleClient服务器端输出:There is a customer call this method!客户端输出: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是为客户端和服务器端生成相关的存根和骨架(实际上就是一种代理类),但是我们直接在javac java的过程就可以直接调用远程方法,好像没有rmic的调用。原因:在jdk5.0以前的版本中,需要用rmic命令来为远程对象生成静态的代理类(包括存根和骨架类),而在jdk5.0中rmi框架会在运行的过程中自动为远程 对象生成动态代理类(包括存根和骨架类),从而更彻底的封装了rmi框架的实现细节。简化了rmi框架的使用方式。3.registry本地注册表为何不启动rmiregistry.exe就能完成本地。注册捏?实际上LocateRegistry.createRegistry(rmiPort)就是创建对远程或者本地注册表的本地引用,创建并导出Registry实例。

版权声明:本文为博主原创文章,未经博主允许不得转载。

我希望你能知道,我的心永远只为你跳动。

Java RMI之HelloWorld程序以及相关的安全管理器的知识

相关文章:

你感兴趣的文章:

标签云: