一波三折的rmi调用

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/iteye_13353/article/details/81919824

        很久以前写了基于rmi的分布式java程序,现在基本都忘记了,只有一个大概印象。今天写了个小例子复习了下,比较简单,主要在于使自己熟悉下api和部署过程。一共有4个java文件。

   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


我因为粗心犯的错误

1:本来是TestRemote s = (TestRemote) Naming.lookup("rmi://localhost:1099/server");我写成了TestRemote s = (TestRemoteImpl) Naming.lookup("rmi://localhost:1099/server");
造成程序报ClassCaseException,因为lookup出来的是rmi框架自己实现了TestRemote接口的代理类,转成TestRemoteImpl当然不行。

2:在命令行下执行rmi服务器程序时,老是报ClassNotFoundException,检查了好半天,最后发现,是CLASSPATH被公司的一个工具给改写了,CLASSPATH环境变量里没有当前路径“.”,于是我在命令行里执行export $CLASSPATH=./$CLASSPATH,结果当然悲剧啊,唉,粗心阿,应该是执行export CLASSPATH=./$CLASSPATH。
  
3:接着是rmiregistery,linux下是rmiregistery,而windows下是start rmiregistery,而我在linux下,一开始就输入命令start rmiregistery

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

 

 

5:总结

       (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命令。

 

展开阅读全文

ejb3.0 rmi调用失败??

01-25

最近很郁闷,碰到了个稀奇古怪的问题,花了我好几天的宝贵的时间,现在还是没有头绪。想请各位哥们都发表发表意见!rn我有两台liunx系统,两台windows xp系统,jdk都是1.6 ,jboss服务是5.0。rn1、在两台windows系统上分别部署了rmi客户端与服务端,并且都是使用-b 0.0.0.0来启动服务的。 测试时使用客户端访问服务端是没有问题的。rn2、在linux系统上分别部署rmi客户端与服务端,并且分别使用-b 192.168.1.13(这个ip是物理机器的真实的ip) 、 -b 192.168.1.14(这个ip是物理机器的真实的ip)来启动客户端与服务端的服务,然后使用客户端去访问服务端是没有问题的,但是当我这样-b 0.0.0.0 、-b 0.0.0.0来启动服务的时候,客户端调用服务端是调用不成功的。rn3、当我在liunx系统上部署了客户端,并以-b 192.168.1.13来启动服务。在window系统上部署了服务端,并以-b 0.0.0.0来启动服务,在客户端调用服务端是调用不成功的,如果在windowx系统上以-b 192.168.1.15来启动服务的话,客户端访问访问服务端时没有问题的。rn4、当我在window系统上部署了客户端,并以-b 192.168.1.15来启动服务,在linux系统上部署了服务端,并以-b 0.0.0.0来启动服务,在客户端调用服务端是调用不成功的,如果在linux系统上以-b 192.168.1.14来启动服务的话,客户端访问访问服务端时没有问题的。rnrn个人总结的测试结果:rn 1、在linux系统上部署了服务端,并以-b 0.0.0.0启动服务的话,不管是linux客户端还是windows客户端都是访问不成功的。rn 2、在window系统上部署了服务端,并以-b 0.0.0.0启动服务的话,windows客户端是可以访问的,linux客户端是不可以访问的。rnrnrnrn我想知道为什么不能访问,肯定是有地方出了乱子,希望各位哥们都发表发表看法。 论坛

RMI调用端口问题,请教各位

12-16

为什么我运行RMI的server时,程序总是报错,说access denied,我的server 如下:rnrnpackage gxlu.dmt.service;rnrnimport java.rmi.RMISecurityManager;rnimport java.rmi.Naming;rnrnpublic class FindIndexServer rn public FindIndexServer()rn rn rnrn public static void main(String[] args)rn rn // Create and install a security managerrn if (System.getSecurityManager() == null) rn System.setSecurityManager(new RMISecurityManager());rn rnrn try rn FindIndexImpl obj = new FindIndexImpl();rnrn // Bind this object instance to the name "HelloServer"rn Naming.rebind("//localhost:2001/findIndex", obj);rnrn System.out.println("FindIndexServer bound in registry");rn rn catch (Exception e) rn System.out.println("FindIndexImpl err: " + e.getMessage());rn e.printStackTrace();rn rn rnrnrnrn错误信息如下:rnFindIndexImpl err: access denied (java.net.SocketPermission 127.0.0.1:2001 connernct,resolve)rnjava.security.AccessControlException: access denied (java.net.SocketPermission 1rn27.0.0.1:2001 connect,resolve)rn at java.security.AccessControlContext.checkPermission(AccessControlConternxt.java:272)rn at java.security.AccessController.checkPermission(AccessController.java:rn399)rn at java.lang.SecurityManager.checkPermission(SecurityManager.java:545)rn at java.lang.SecurityManager.checkConnect(SecurityManager.java:1044)rn at java.net.Socket.(Socket.java:262)rn at java.net.Socket.(Socket.java:100)rn at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectrnSocketFactory.java:25)rn at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterrnSocketFactory.java:120)rn at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:499)rn at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:190rn)rn at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:174)rn at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:318)rn at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)rn at java.rmi.Naming.rebind(Naming.java:160)rn at gxlu.dmt.service.FindIndexServer.main(FindIndexServer.java:22) 论坛

Linux下RMI调用出现的奇怪问题!!

08-21

FileServer是一个文件下载服务程序,供FileClient远程调用其Download(filename)方法。该程序在Windows下做服务器和客户机都完全没有问题。但是在Linux下一运行FileServer就返回如下出错信息.我郁闷的是为什么FileServer 程序在Windows下运行没有任何问题,到了Linux下就报错呢?rnrn请各位高手相助,分数方面好说:)rnrn端口采用默认的1099,如:rmiregistry 1099rnrn其中policy.txt内容如下:rnrngrant rn permission java.security.AllPermission "", "";rn;rnrnFileServer 返回的错误信息为:rnrn[CHN@SAIBOG rmi]$ java -Djava.security.policy=policy.txt FileServerrnFileServer: Error unmarshaling return header; nested exception is:rn java.net.SocketException: Connection resetrnjava.rmi.UnmarshalException: Error unmarshaling return header; nested exceptionrnis:rn java.net.SocketException: Connection resetrn at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:rn203)rn at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:350)rn at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)rn at java.rmi.Naming.rebind(Naming.java:160)rn at FileServer.main(FileServer.java:27)rnCaused by: java.net.SocketException: Connection resetrn at java.net.SocketInputStream.read(SocketInputStream.java:168)rn at java.io.BufferedInputStream.fill(BufferedInputStream.java:183)rn at java.io.BufferedInputStream.read1(BufferedInputStream.java:222)rn at java.io.BufferedInputStream.read(BufferedInputStream.java:277)rn at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.javarn:2150)rn at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStreamrn.java:2163)rn at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputSrntream.java:2634)rn at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:734rn)rn at java.io.ObjectInputStream.(ObjectInputStream.java:253)rn at sun.rmi.server.MarshalInputStream.(MarshalInputStream.java:110)rn at sun.rmi.transport.ConnectionInputStream.(ConnectionInputStream.rnjava:38)rn at sun.rmi.transport.StreamRemoteCall.getInputStream(StreamRemoteCall.jarnva:111)rn at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:rn197)rn ... 4 morern[CHN@SAIBOG rmi]$rnrn--------------rnFileServer 源代码rnrnimport java.io.*;rnimport java.rmi.*;rn rnpublic class FileServer rn public static void main(String argv[]) rn if(System.getSecurityManager() == null) rn System.setSecurityManager(new RMISecurityManager());rn rn try rn FileInterface fi = new FileImpl("FileServer");rn Naming.rebind("//127.0.0.1/FileServer", fi);//总是绑定rn catch(Exception e) rn System.out.println("FileServer: "+e.getMessage());rn e.printStackTrace();rn rn rn 论坛

关于Spring中的rmi调用失败的问题(spring版本2.5)

11-29

各位朋友好:rn在学习Spring 中的RMI 调用时遇到一个问题rn新建了两个Spring工程,一个client端,一个服务端。当两个应用都在本机电脑时,可以调用成功。(rmi://localhost/UserService) 但是当我把服务端部署到另一台机器上是,调用失败。从网上找了很多资料,比如说客户端调用服务端时需要指定System.setProperty("java.rmi.server.hostname","10.10.81.24"),防火墙也关闭了 但是不好用rn报错信息如下:rn[code=java]Exception in thread "main" org.springframework.remoting.RemoteConnectFailureException: Could not connect to remote service [rmi://10.10.81.24:1099/UserService]; nested exception is java.rmi.ConnectIOException: Exception creating connection to: 2001:0:5ef5:79fb:883:1b16:f5f5:aee7; nested exception is: rn java.net.SocketException: Network is unreachable: connectrn at org.springframework.remoting.rmi.RmiClientInterceptorUtils.convertRmiAccessException(RmiClientInterceptorUtils.java:187)rn at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:346)rn at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:258)rn at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)rn at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)rn at $Proxy0.addUser(Unknown Source)rn at com.springinaction.client.rmi.UserServiceClient.addUser(UserServiceClient.java:22)rn at com.springinaction.client.rmi.UserServiceClient.main(UserServiceClient.java:35)rnCaused by: java.rmi.ConnectIOException: Exception creating connection to: 2001:0:5ef5:79fb:883:1b16:f5f5:aee7; nested exception is: rn java.net.SocketException: Network is unreachable: connectrn at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:587)rn at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)rn at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)rn at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:94)rn at org.springframework.remoting.rmi.RmiInvocationWrapper_Stub.invoke(Unknown Source)rn at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:397)rn at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:343)rn ... 6 morernCaused by: java.net.SocketException: Network is unreachable: connectrn at java.net.PlainSocketImpl.socketConnect(Native Method)rn at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)rn at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)rn at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)rn at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:364)rn at java.net.Socket.connect(Socket.java:507)rn at java.net.Socket.connect(Socket.java:457)rn at java.net.Socket.(Socket.java:365)[/code]rnrnrn下面我贴一下代码,希望指定的朋友帮助解答一下 谢谢!rnrnServer端:rn[code=java]rnpackage com.springinaction.server;rnrnpublic interface UserService rn public String addUser(String name);rnrnrnpackage com.springinaction.server.impl;rnrnimport com.springinaction.server.UserService;rnrnpublic class UserServiceImpl implements UserService rnrn public String addUser(String name) rn if(name == null || name.equals("")) rn return "";rn else rn return "添加姓名为[" + name + "]的用户成功"; rn rn rnrnrn[/code]rn[code=html]rnrn rn rn rn rn rn rn rn rn rn rn rn rn[/code]rnrnrnClient端:rn[code=html]rnrn rn rn rn rn rn rn rn rn rn rn rn rn rn[/code] 论坛

没有更多推荐了,返回首页