سؤال

ولدي مشكلة في استخدام جافا RMI:

عند أحاول تشغيل خدمة بلدي، وأحصل على connectException (انظر أدناه).

واستثناء يحدث عند تنفيذ الأسلوب rebind:

Runtime.getRuntime().exec("rmiregistry 2020");
MyServer server = new MyServer();
Naming.rebind("//localhost:2020/RemoteDataPointHandler", server);

وعند استخدام RMI: // المضيف المحلي: 2020 / RemoteDataPointHandler بدلا من ذلك، فإنه لا يعمل سواء. أيضا باستخدام المنفذ الافتراضي لا يعمل. كما أنني حاولت استخدام 127.0.0.1 عنوان بروتوكول الإنترنت، ولكن مع نفس التأثير.

وبلدي وسائط وقت التشغيل:

-Djava.security.policy=java.security.AllPermission
Exception in thread "main" java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: 
    java.net.ConnectException: Connection refused
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
    at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
    at java.rmi.Naming.rebind(Naming.java:160)
    at be.fortega.knx.server.Main.(Main.java:25)
    at be.fortega.knx.server.Main.main(Main.java:16)
Caused by: java.net.ConnectException: Connection refused
    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:433)
    at java.net.Socket.connect(Socket.java:524)
    at java.net.Socket.connect(Socket.java:474)
    at java.net.Socket.(Socket.java:371)
    at java.net.Socket.(Socket.java:184)
    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:569)
    ... 7 more

هل كانت مفيدة؟

المحلول 2

ويبدو أن العمل عندما كنت محل

Runtime.getRuntime().exec("rmiregistry 2020");

وقبل

LocateRegistry.createRegistry(2020);

وأي شخص فكرة لماذا؟ ما هو الفرق؟

نصائح أخرى

كان

ومشكلة مشابهه مع هذا الاستثناء الاتصال. يتم طرح ذلك إما عند عدم بدء التسجيل بعد (كما هو الحال في قضيتك) أو عند التسجيل هو unexported بالفعل (كما في حالتي).

ولكن تعليق قصير الفرق بين الطرق 2 لبدء التسجيل:

Runtime.getRuntime().exec("rmiregistry 2020");

ويدير rmiregistry.exe في javas بن لدليل في عملية جديدة ويستمر بالتوازي مع كود جافا الخاص بك.

LocateRegistry.createRegistry(2020);

واستدعاء الأسلوب جمهورية جزر مارشال يبدأ التسجيل، ترجع الإشارة إلى أن التسجيل كائن بعيد ثم تواصل مع العبارة التالية.

وفي قضيتك لم يتم بدء التسجيل في الوقت المناسب عند محاولة ربط الكائن

وتحتاج إلى أن يكون rmiregistry على التوالي قبل محاولة الاتصال (تسجيل) خدمة RMI معها.

واستدعاء الأسلوب LocateRegistry.createRegistry(2020) يخلق والصادرات والتسجيل على رقم المنفذ المعين.

وراجع وثائق LocateRegistry

واحد الفرق يمكننا أن نلاحظ في نظام التشغيل Windows هو:

إذا كنت تستخدم Runtime.getRuntime().exec("rmiregistry 1024");

ويمكنك ان ترى عملية rmiregistry.exe سيتم تشغيل في إدارة المهام الخاصة بك

وأما إذا كنت تستخدم Registry registry = LocateRegistry.createRegistry(1024);

وكنت لا تستطيع رؤية عملية تشغيل في إدارة المهام،

وأعتقد جافا يعالج بطريقة مختلفة.

وهذا هو ملف server.policy بلدي

وقبل تشغيل التطبيق، تأكد من أن قتل كل ما تبذلونه من القائمة javaw.exe وrmiregistry.exe يتوافق مع برامج RMI الخاصة بك والتي هي التشغيل مسبقا.

والتعليمة البرمجية التالية يعمل بالنسبة لي باستخدام Registry.LocateRegistry() أو

Runtime.getRuntime.exec("");


// Standard extensions get all permissions by default

grant {
    permission java.security.AllPermission;
};

وVM حجة

-Djava.rmi.server.codebase=file:\C:\Users\Durai\workspace\RMI2\src\

والرمز:

package server;    

import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class HelloServer 
{
  public static void main (String[] argv) 
  {
    try {

        if(System.getSecurityManager()==null){
            System.setProperty("java.security.policy","C:\\Users\\Durai\\workspace\\RMI\\src\\server\\server.policy");
            System.setSecurityManager(new RMISecurityManager());
        }

 Runtime.getRuntime().exec("rmiregistry 1024");

 //     Registry registry = LocateRegistry.createRegistry(1024);
   //   registry.rebind ("Hello", new Hello ("Hello,From Roseindia.net pvt ltd!"));
   //Process process = Runtime.getRuntime().exec("C:\\Users\\Durai\\workspace\\RMI\\src\\server\\rmi_registry_start.bat");

        Naming.rebind ("//localhost:1024/Hello",new Hello ("Hello,From Roseindia.net pvt ltd!")); 
      System.out.println ("Server is connected and ready for operation.");
    } 
    catch (Exception e) {
      System.out.println ("Server not connected: " + e);
      e.printStackTrace();
    }
  }
}

ويبدو أن يجب تعيين الأمر الخاص باعتباره String[]، على سبيل المثال:

String[] command = new String[]{"rmiregistry","2020"};
Runtime.getRuntime().exec(command);

وتماما مثل أسلوب main(String[] args).

scroll top