RMI调用的简单实例
最近写了个RMI的Demo,虽然很简单,但是中间走了很多弯路,现在整理一下,以便大家参考
整个项目结构如下:
client.java
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//System.setSecurityManager(new RMISecurityManager());
String url = "/sayhello";
Hello RMIObject = (Hello)Naming.lookup(url); // 寻得对象
System.out.println( RMIObject.sayHello("lions") );
} catch (RemoteException exc) {
System.out.println("Lookup error: " + exc.toString());
} catch (java.net.MalformedURLException ex) {
System.out.println("Malformed URL: " + ex.toString());
} catch (java.rmi.NotBoundException e) {
System.out.println("Not Bound: " + e.toString());
}
}
}
Hello.java
import java.rmi.Remote;
import java.rmi.RemoteException;
//public interface Hello extends Serializable, Remote {
public interface Hello extends Remote {
public String sayHello(String name) throws RemoteException;
}
MyHello.java
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class MyHello extends UnicastRemoteObject implements Hello {
public MyHello() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
public String sayHello(String name) throws RemoteException {
// TODO Auto-generated method stub
return "Hello, " + name;
}
}
Server.java
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
public class Server {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
//if (System.getSecurityManager() == null) {
//System.setSecurityManager(new RMISecurityManager());
//}
// System.setSecurityManager(new RMISecurityManager());
//LocateRegistry.createRegistry(8808); // 注册端口
MyHello server = new MyHello();
// Binding
Naming.rebind("/sayhello", server); // 将实现类绑到一个名字上去
}catch(java.net.MalformedURLException me){
System.out.println("Malformed URL:" + me.toString());
}catch(RemoteException e){
System.out.println("Remote Exception:" + e.toString());
}
}
}
client.bat
java Client
@pause
command.bat
cmd
rmi.policy
grant {
// Allow everything for now
permission java.security.AllPermission;
};
rmireg.bat
rmiregistry
@pause
server.bat
java Server
@pause
build.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- ======================================================================
Aug 4, 2008 9:36:42 AM
RMIDemo
description
Lions
====================================================================== -->
<project name="project" default="default">
<description>
RMIDemo
</description>
<property name="src" value="./src"/>
<property name="bin" value="./bin"/>
<property name="build" value="./dist"/>
<property name="script" value="./script"/>
<property name="classpath" value=""/>
<property name="class" value="MyHello"/>
<property name="jarfile" value="${build}/hello.jar"/>
<!-- =================================
target: default
================================= -->
<target name="default" depends="clean" description="--> description">
<javac srcdir="${src}"
destdir="${bin}"
classpath="${classpath}"
source="1.4">
</javac>
<rmic classname="${class}" base="${bin}"/>
<jar destfile="${jarfile}" basedir="${bin}"></jar>
<copydir dest="${build}" src="${script}"></copydir>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: clean
- - - - - - - - - - - - - - - - - -->
<target name="clean">
<delete>
<fileset dir="${build}">
<include name="*"/>
</fileset>
</delete>
<delete>
<fileset dir="${bin}">
<include name="*"/>
</fileset>
</delete>
</target>
</project>
上面的比较简单,在运行中有一点要特别注意,一定要把stub类加到环境变量classpath中,或者将hello.jar加到classpath中,不然会出现找不到stub类的错误。
首先运行rmireg.bat,启动rmiregistry。
然后运行server.bat,启动服务端。
最后运行client.bat,启动客户端,可以看到输出:hello,lions
OK,测试成功!
关于security manager,这里没有使用,但给了个policy的示例,代码里也有参考的写在注释里,可以试验下。
运行时有个参数 -Djava.rmi.server.codebase,之前设置了反而不能运行,不用倒是没有问题,还不太明白这个有什么用。
如果是远程调用,client代码修改如下:
String url = "rmi://192.168.0.119/sayhello";
Hello RMIObject = (Hello)Naming.lookup(url); // 寻得对象
远程只需要拷贝client.bat和hello.jar包,clent如下修改:
java -cp hello.jar Client
运行就可以看到结果。
如果网络不可访问,或是有防火墙,都会导致不可访问,需要和程序错误相区别对待。