• 一个rmi远程调用入门的例子


    TestRemote.java 
         import java.rmi.Remote;
        import java.rmi.RemoteException;
        public interface TestRemote extends Remote {
            public String add(String a, String b) throws RemoteException;
            public String add() throws RemoteException;
        } 

       TestRemoteImpl.java

     import java.rmi.RemoteException;
    import java.rmi.server.UnicastRemoteObject;
    public class TestRemoteImpl extends UnicastRemoteObject implements TestRemote {
        private static final long serialVersionUID = 1L;
        public TestRemoteImpl() throws RemoteException {
            super();
        }

        public String add(String a, String b) throws RemoteException {
            return a + b;
        }

        public String add() throws RemoteException {
            return "Hello Word";
        }



    Server.java 
    import java.rmi.Naming;
    public class Server {
        public static void main(String[] args) throws Exception {
            try {
                // 创建远程对象
                TestRemote testRemote = new TestRemoteImpl();
                // 奖名称绑定到对象
                Naming.rebind("rmi://localhost:1099/server", testRemote);
                System.out.println("RMI服务器正在运行。。。。。。");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    Client.java 
    import java.rmi.Naming;
    public class Client {
        public static void main(String args[]) {
                try {
                    TestRemote s = (TestRemote) Naming.lookup("rmi://localhost:1099/server");
                    System.out.println(s.add());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.exit(0);

         }



    第一步  生成stub文件 
            class都编译好后,要生成stub文件,我测试的时候,class编译到我的工程下的bin目录,我在bin目录下执行命令“rmic TestRemoteImpl”,rmic后面完整路径的Remote接口的实现类,如果TestRemoteImpl在包com.test里,那么命令就是“rmic com.test.TestRemoteImpl”,后面不要带上java后缀。执行完后,TestRemoteImpl.class所在的目录(就是bin目录)就会出现一个TestRemoteImpl_Stub.class文件。

    第二步  准备java安全策略文件 
             在bin目录下新建一个名为“mypolicy”的文件,写入内容如下
    grant {   
    permission java.security.AllPermission "", "";   
    };

    第三步  启动rmi注册程序 
    在命令行下,执行命令:rmiregistry。特别要主意的是,这个命令一定要在class所在的根目录执行,比如class文件全部编译到myproject/bin目录里,那么这个命令就一定在 myproject/bin目录下执行,否则在注册远程对象的时候,就会报以下异常:

    java.rmi.UnmarshalException:   error   unmarshalling   return;   nested   exception   is:   
    java.lang.ClassNotFoundException 。。。。。。

    网上有很多人碰到这个问题,这是一定要主意的。 

    第四步  启动rmi服务器 
    在bin目录下,执行"java -Djava.security.policy=mypolicy Server",主要mypolicy是上面建立的安全策略文件。如果运行正确,命令行会输出:RMI服务器正在运行。。。。。。

    第五步  启动客户端验证rmi 
    在bin目录下,执行“java Client”,如果运行正确,命令行会输出:Hello Word

    java安全问题
    默认情况下,rmi在服务器端是被java安全策略限制的,要解决这个问题,可以通过两种途径。一种解决方法是自己建立一个java安全策略文件,然后执行程序时带上这个参数;另一种解决方法是自己在jre的安全策略文件里加入内容:
    grant {   
    permission java.security.AllPermission "", "";   
    };

    总结

           (1)勿以事小而不为,再简单的东西,知道归知道,实践归实践,实践过程中,总会碰到一些实际的问题,从而使经验得以成长。

           (2)如果只是报ClassNofFoundException,那么要检查CLASSPATH环境变量是否正确。

           (3)如果报以下异常:

    java.rmi.UnmarshalException:   error   unmarshalling   return;   nested   exception   is:   
    java.lang.ClassNotFoundException

    那就要特别注意,这是因为在将远程对象注册到rmi注册管理器的时候,注册管理器找不到要绑定的对象的class信息。

    如在命令行下执行:rmiregistry   那么rmi注册管理器在默认端口1099监听,在执行“Naming.rebind("rmi://localhost:1099/server", testRemote); ”的时候,告诉rmi注册管理器,我要绑定这个对象,rmi注册管理器就会寻找这个对象的class信息,但是很奇怪的是,rmi注册管理器并不关心系统的CLASSPATH,它只是在当前目录中寻找class定义,所以这是为什么要在class所在的根目录执行rmiregistry命令。

  • 相关阅读:
    推荐!国外程序员整理的 PHP 资源大全
    PHPSTORM/IntelliJ IDEA 常用 设置配置优化
    PHPStorm下XDebug配置
    MySQL修改root密码的多种方法
    php 修改上传文件大小 (max_execution_time post_max_size)
    phpstorm8注册码
    Linux提示no crontab for root的解决办法
    网站的通用注册原型设计
    解决mysql出现“the table is full”的问题
    通过php下载文件并重命名
  • 原文地址:https://www.cnblogs.com/xinzhuangzi/p/4100465.html
Copyright © 2020-2023  润新知