在Myeclipse里用的RMI的插件,可以正常使用的简单项目
现在为了方便测试,要把server和common里的接口打成一个jar(server.jar)
client和common的接口打成一个jar(client.jar),安全策略文件在这个jar的根目录下现在用cmd运行jar,server启动起来了~~~
但是使用另一个cmd启动client.jar,会报错:
Exception in thread "Thread-0" java.security.AccessControlException: access denied ("java.net.SocketPermission" "*.*.*.*:1234" "connect,resolve")
        at java.security.AccessControlContext.checkPermission(AccessControlContext.java:345)
        at java.security.AccessController.checkPermission(AccessController.java:555)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
        at java.lang.SecurityManager.checkConnect(SecurityManager.java:1051)
        at java.net.Socket.connect(Socket.java:568)
        at java.net.Socket.connect(Socket.java:524)
        at java.net.Socket.<init>(Socket.java:421)
        at java.net.Socket.<init>(Socket.java:204)
        at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
        at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:146)
        at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
        at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
        at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
        at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:340)
        at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
        at java.rmi.Naming.lookup(Naming.java:101)
        at inClient.CallBackRemoteMethod.getRemoteStatus(CallBackRemoteMethod.java:26)
        at inClient.RemoteCallBack.run(RemoteCallBack.java:19)
若是在client的main方法中,我用System.setProperty("java.rmi.server.codebase", "file:/E:/client.jar");
写入了codebase,也不行,报下面的错
Exception in thread "Thread-0" java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.rmi.server.codebase" "write")
        at java.security.AccessControlContext.checkPermission(AccessControlContext.java:345)
        at java.security.AccessController.checkPermission(AccessController.java:555)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
        at java.lang.System.setProperty(System.java:775)
        at inClient.RemoteCallBack.run(RemoteCallBack.java:15)我若是在cmd中调用
>java -Djava.security.policy="file:/e:/client.policy" -jar "e:/client.jar"
执行这个jar包~~~也会报错·~~最上面的那个错误信息~~~
很郁闷啊·~~求达人给解读下·~~RMI项目应该如何打成Jar包  且运行

解决方案 »

  1.   

    policy文件写得不对!
    你可以贴出来让大家帮忙看一下
      

  2.   

    java.security.AccessControlException: access denied,给你打包的jar做下数字签名试试
      

  3.   

    1 policy文件的内容是否正确
    2 指定policy路径的参数是否正确
    建议直接把policy文件放入client.jar包中
    然后修改为参数修改为 -Djava.security.policy=policy
      

  4.   

    policy文件~~~の~~我用myEclipse的RMI插件自动生成的~~貌似是菜市场吧~~grant {
    permission java.security.AllPermission;};to bsr1983做数字签名?好高深伐·~~要怎么搞·~~to lysnow_oss如果我的jar在e盘根目录~~~policy文件也在E盘根目录·~·
    我cmd中这么写对么?
    >java java -Djava.security.policy="e:/client.policy" -jar "e:/client.jar"我的client.jar包里有这个文件的·~这么启动
    >java java -jar "e:/client.jar"
    这么启动  >java java -Djava.security.policy=client.policy -jar "e:/client.jar"
    ~还是会报错~~·
    jar包中没有~~在外面有·~运行
    >java java -Djava.security.policy="e:/client.policy" -jar "e:/client.jar"
    一样报错~~找不到stub·
    Exception in thread "Thread-0" java.security.AccessControlException: access denied ("java.net.SocketPermission" "*.*.*.*:1234" "connect,resolve")
    各位大佬·~~救我于水深火热啊·~
      

  5.   

    貌似我也遇到rmi 发布问题了 服务器发布成功 就是客户端老是出现
    java.rmi.ConnectException: Connection refused to host: 203.86.233.157; nested exception is: 
            java.net.ConnectException: Connection timed out: connect
            at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:601)
            at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
            at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
            at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322)
            at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
            at java.rmi.Naming.lookup(Naming.java:84)
            at dingqiaowu.frames.login.LoginWork.initServerConnection(LoginWork.java:54)
            at dingqiaowu.frames.login.LoginWork.loginServer(LoginWork.java:74)
            at dingqiaowu.frames.login.LoginWork$1.run(LoginWork.java:31)
            at qdingqiaowu.qthread.QThreadPool$WorkThread.run(QThreadPool.java:134)
    Caused by: java.net.ConnectException: Connection timed out: connect
            at java.net.PlainSocketImpl.socketConnect(Native Method)
            at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
            at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
            at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
            at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
            at java.net.Socket.connect(Socket.java:529)
            at java.net.Socket.connect(Socket.java:478)
            at java.net.Socket.<init>(Socket.java:375)
            at java.net.Socket.<init>(Socket.java:189)
            at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
            at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
            at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)
            ... 9 more
    java.lang.NullPointerException
            at dingqiaowu.frames.login.LoginWork.loginServer(LoginWork.java:81)
            at dingqiaowu.frames.login.LoginWork$1.run(LoginWork.java:31)
            at qdingqiaowu.qthread.QThreadPool$WorkThread.run(QThreadPool.java:134)
    啥意思呢
      

  6.   

    1. 客户端代码有 System.setSecurityManager(...); 了吗?
    2. 你的 common 里面的接口那个 jar 里面有 Stub 类吗?如果没有的话需要 java.rmi.server.codebase.
      

  7.   

    to humanity
    客户端在实例化的时候,new的时候就实例化了 System.setSecurityManager(...); common只有接口~~然后接口的实现是在server端~~~所以stub也在server里~~~~
    关于这里我有点疑问,是不是应该把接口实现、stub也放在common中,一边一份?
    公用的那个包的包结构是不是一定得一样?
    还有就是,如果我想要实现的是一个项目作为A_Server,B_Client,另一个项目作为A_Client,B_Server,二者的接口、接口的Impl、编译的stub也都放到common中另外,codebase该如何指定啊~~~~MyEclipse中按照RMI APP方式运行的时候可以在JVM选项卡中指定,
    但是如果我要打成jar包·~~这个是不是应当写到代码中啊?
    我试过~~~如果在代码中加入:java.rmi.server.codebase,JVM是会报错的
    Exception in thread "Thread-0" java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.rmi.server.codebase" "write")
      at java.security.AccessControlContext.checkPermission(AccessControlContext.java:345)
      at java.security.AccessController.checkPermission(AccessController.java:555)
      at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
      at java.lang.System.setProperty(System.java:775)
      at inClient.RemoteCallBack.run(RemoteCallBack.java:15)
    即使我将我机子上的JRE里的security/java.policy里添加了这个写的权限,也不行·~~愁死我了~~~
      

  8.   

    我觉得 interface 和 stub 两边都放吧,共用的,都放 common 里面。打包成 jar 之后,也可以创建一个快捷方式或 .bat 文件把参数加上。主要是那个 -Djava.security.policy 文件要指定。如果你觉得写成 batch 或快捷方式不专业,可以用 WinRun4J 包装一下,它有一个 ini 文件,你把参数写在里面,注意 ini 文件名(去除扩展名)必须和 exe 文件名一样,比如你的 exe 叫 WinRun4J.exe,你就叫WinRun4j.ini,你如果把 WinRun4J.exe 改成 launcher.exe,你就也把 ini 改成 launcher.ini.
    然后再用一个 NSIS (NullSoft Installation, Winamp 提供的免费安装制作程序)制作一个安装程序来分发给客户,这样显得专业。当然收费的 InstallShield 或许更好。
      

  9.   

    to dingqiaowu   
    你可以试试以下方法:
    如果你用myEClipse+RMI插件(genady.net),可以看教学视频,特别是指定codebase,和security.policy那段
    最重要的:关掉你的防火墙~~~RMI不会穿墙术
    to humanity
    の  那个我还真没试过把全部的stub放到公共包里·~~~
    嘿嘿  另外·~~我想请教下~~一般把java程序写成bat?这个  应该怎么写呢?那些参数应该怎么添加呢?  
    我从没用过·~光是听说过~~嘿嘿,那个jar2exe的程序我有下过一个exej4,听说不错·~可是我试了半天,发布出来的exe也不好用·~~不知道我哪里搞错了~~诶~~暂时不是直接给客户exe~~~都是在上面在包一层前台的东东~~~
      

  10.   

    直接在Eclipse 上以 Debug 模式运行一次,在某个地方放个断点,让程序在那个位置停下来,然后打开一个进程浏览器(比如:Process Explorer,system-internals.com 出品,现在被 M$ 收购了,去 M$ 站点下载),去查看它的启动命令行参数。把这些参数记录在一个DOS 批处理中,把 JAVA_HOME 之前的用变量代替,方案一:用 .bat 文件:
    最后得到类似下面这样的 launch.bat 文件:@echo off
    setlocalcd %~dp0set JAVA_HOME=D:/JavaEnv/J2SE4
    set LIB=%~dp0lib
    set JAVA_OPTION=-java.security.policy=%~dp0java.policy 
    set JAVA_OPTION=%JAVA_OPTION% -Djava.rmi.server.codebase=file://%LIB%/common.jarset CP=%CLASSPATH%;%LIB%/server.jar
    set PROGRAM_ARG=myprogram arguments%JAVA_HOME%/bin/javaw.exe %JAVA_OPTION% -classpath=%CP% com.yourcompany.biz.Main %PROGRAM_ARGendlocal
    %echo on方案二:用 exe 外壳:
    比如,我用一个程序叫 lighting,把 WinRun4J 解压安装后叫 lighting.exe,然后我写个 lighting.ini,内容如下,注意名字相同,仅扩展名不同,放在同一个目录下,配置完成后双击 lighting.exe 就可以启动程序,下面这个配置,要求 JVM 至少 1.6,给它配置了一些 classpath,-D JVM 系统参数 和日志参数,以及启动图片 splash.jpg :
    main.class=net.vicp.atreides.lighting.ui.MainFrameclasspath.1=lighting.jar
    classpath.2=lib/eclipselink.jar
    classpath.3=lib/j2ee.jar
    classpath.4=lib/derby.jar
    classpath.5=lib/jai_codec.jar
    classpath.6=lib/jai_core.jarvmarg.1=-Xms64M
    vmarg.2=-Dfile.encoding=GB18030
    vmarg.3="-Xbootclasspath/p:.\lib\jai_codec.jar;.\lib\jai_core.jar"
    vmarg.4=-Dlighting.max.size=100
    vmarg.5=-Dshadingtheme=truevm.version.min=1.6
    vm.heapsize.preferred=512single.instance=processlog=log/error.log
    log.level=info
    log.roll.size=5
    splash.image=splash.jpg
      

  11.   

    to humanity   好的·~~谢谢你的讲解~~O(∩_∩)O哈哈~~~~
    该贴结贴咯~~~分不多~~~谢谢各位的帮助~