运行示例程序
原文: https://docs.oracle.com/javase/tutorial/rmi/running.html
关于安全的说明
服务器和客户端程序在安装了安全管理器的情况下运行运行任一程序时,需要指定安全策略文件,以便为代码授予其运行所需的安全权限。以下是与服务器程序一起使用的示例策略文件:
grant codeBase "file:/home/ann/src/" {permission java.security.AllPermission;};
以下是与客户端程序一起使用的示例策略文件:
grant codeBase "file:/home/jones/src/" {permission java.security.AllPermission;};
对于两个示例策略文件,所有权限都授予程序的本地类路径中的类,因为本地应用程序代码是受信任的,但是没有权限授予从其他位置下载的代码。因此,计算引擎服务器限制它执行的任务(其代码不可信并且可能是恶意的)执行任何需要安全权限的操作。示例客户端的Pi任务不需要任何权限来执行。
在此示例中,服务器程序的策略文件名为server.policy,客户端程序的策略文件名为client.policy。
启动服务器
在启动计算引擎之前,您需要启动 RMI 注册表。 RMI 注册表是一个简单的服务器端引导程序命名工具,它使远程客户端能够获取对初始远程对象的引用。它可以使用rmiregistry命令启动。在执行rmiregistry之前,必须确保将运行rmiregistry的 shell 或窗口没有设置CLASSPATH环境变量或者具有不包含任何类路径的CLASSPATH环境变量您希望下载到远程对象的客户端。
要在服务器上启动注册表,请执行rmiregistry命令。此命令不产生输出,通常在后台运行。对于此示例,注册表在主机mycomputer上启动。
Microsoft Windows (如果start不可用,则使用javaw):
start rmiregistry
Solaris OS 或 Linux :
rmiregistry &
默认情况下,注册表在端口 1099 上运行。要在其他端口上启动注册表,请在命令行上指定端口号。不要忘记取消设置CLASSPATH环境变量。
Microsoft Windows :
start rmiregistry 2001
Solaris OS 或 Linux :
rmiregistry 2001 &
注册表启动后,您可以启动服务器。您需要确保compute.jar文件和远程对象实现类都在类路径中。启动计算引擎时,需要使用java.rmi.server.codebase属性指定服务器类可通过网络访问的位置。在此示例中,可供下载的服务器端类是Compute和Task接口,可在用户ann的public_html\classes目录的compute.jar文件中找到。计算引擎服务器在主机mycomputer上启动,该主机是启动注册表的主机。
Microsoft Windows :
java -cp c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar-Djava.rmi.server.codebase=file:/c:/home/ann/public_html/classes/compute.jar-Djava.rmi.server.hostname=mycomputer.example.com-Djava.security.policy=server.policyengine.ComputeEngine
Solaris OS 或 Linux :
java -cp /home/ann/src:/home/ann/public_html/classes/compute.jar-Djava.rmi.server.codebase=http://mycomputer/~ann/classes/compute.jar-Djava.rmi.server.hostname=mycomputer.example.com-Djava.security.policy=server.policyengine.ComputeEngine
上面的java命令定义了以下系统属性:
java.rmi.server.codebase属性指定位置,即代码库 URL,从中可以下载来自此服务器的类的定义。如果代码库指定了目录层次结构(而不是 JAR 文件),则必须在代码库 URL 的末尾包含一个尾部斜杠。java.rmi.server.hostname属性指定要放入此 Java 虚拟机中导出的远程对象的存根中的主机名或地址。此值是客户端在尝试传递远程方法调用时使用的主机名或地址。默认情况下,RMI 实现使用java.net.InetAddress.getLocalHostAPI 指示的服务器 IP 地址。但是,有时,此地址不适用于所有客户端,并且完全限定的主机名将更有效。要确保 RMI 使用可从所有潜在客户端路由的服务器的主机名(或 IP 地址),请设置java.rmi.server.hostname属性。java.security.policy属性用于指定包含您要授予的权限的策略文件。
启动客户端
注册表和计算引擎运行后,您可以启动客户端,指定以下内容:
- 客户端使用
java.rmi.server.codebase属性为其类(Pi类)提供服务的位置 java.security.policy属性,用于指定包含您要授予各种代码的权限的安全策略文件- 作为命令行参数,服务器的主机名(以便客户端知道
Compute远程对象的位置)以及
计算中使用的小数位数
在另一台主机(例如,名为mysecondcomputer的主机)上启动客户端,如下所示:
Microsoft Windows :
java -cp c:\home\jones\src;c:\home\jones\public_html\classes\compute.jar-Djava.rmi.server.codebase=file:/c:/home/jones/public_html/classes/-Djava.security.policy=client.policyclient.ComputePi mycomputer.example.com 45
Solaris OS 或 Linux :
java -cp /home/jones/src:/home/jones/public_html/classes/compute.jar-Djava.rmi.server.codebase=http://mysecondcomputer/~jones/classes/-Djava.security.policy=client.policyclient.ComputePi mycomputer.example.com 45
请注意,类路径是在命令行上设置的,以便解释器可以找到客户端类和包含接口的 JAR 文件。另请注意,指定目录层次结构的java.rmi.server.codebase属性的值以尾部斜杠结尾。
启动客户端后,将显示以下输出:
3.141592653589793238462643383279502884197169399
下图说明了rmiregistry,ComputeEngine服务器和ComputePi客户端在程序执行期间获取类的位置。

当ComputeEngine服务器在注册表中绑定其远程对象引用时,注册表会下载存根类所依赖的Compute和Task接口。这些类是从ComputeEngine服务器的 Web 服务器或文件系统下载的,具体取决于启动服务器时使用的代码库 URL 的类型。
因为ComputePi客户端在其类路径中同时具有Compute和Task接口,所以它从类路径加载它们的定义,而不是从服务器的代码库加载它们的定义。
最后,当Pi对象在executeTask对象的executeTask远程调用中传递时,Pi类被加载到ComputeEngine服务器的 Java 虚拟机中。 Pi类由服务器从客户端的 Web 服务器或文件系统加载,具体取决于启动客户端时使用的代码库 URL 的类型。
