Ошибка обнаружения Jini / JavaSpaces - PullRequest
0 голосов
/ 28 июля 2011

Об этой статье: http://java.sun.com/developer/technicalArticles/tools/JavaSpaces/ - это руководство по запуску клиента JavaSpaces.Я написал эти классы в Eclipse, запустил скрипт Launch-All и пример Run.Оно работает.После этого я экспортировал эти классы в исполняемый файл jar (JavaSpaceClient.jar) и попробовал этот файл с помощью следующей команды: java -jar JavaSpaceClient.jar Он работает нормально, дает мне результат: поиск JavaSpace ... Обнаружено JavaSpace.Запись сообщения в пространство ... Чтение сообщения из пространства ... Сообщение прочитано: Здраво JavaSpace света!

Моя проблема в том, что когда я перемещаю этот файл jar на другой компьютер локальной сети, он показываетошибка при вводе одной и той же команды.Вот ошибка:

cica@cica-System-Name:~/Desktop$ java -jar JavaSpaceClient.jar 
Searching for a JavaSpace...
Jul 27, 2011 11:20:54 PM net.jini.discovery.LookupDiscovery$UnicastDiscoveryTask run
INFO: exception occurred during unicast discovery to biske-Inspiron-1525:4160 with constraints InvocationConstraints[reqs: {}, prefs: {}]
java.net.UnknownHostException: biske-Inspiron-1525
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:175)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
at java.net.Socket.connect(Socket.java:546)
at java.net.Socket.connect(Socket.java:495)
at com.sun.jini.discovery.internal.MultiIPDiscovery.getSingleResponse(MultiIPDiscovery.java:134)
at com.sun.jini.discovery.internal.MultiIPDiscovery.getResponse(MultiIPDiscovery.java:75)
at net.jini.discovery.LookupDiscovery$UnicastDiscoveryTask.run(LookupDiscovery.java:1756)
at net.jini.discovery.LookupDiscovery$DecodeAnnouncementTask.run(LookupDiscovery.java:1599)
at com.sun.jini.thread.TaskManager$TaskThread.run(TaskManager.java:331)

Я просто пишу «Поиск JavaSpace ...» и через некоторое время печатает эти сообщения об ошибках.Может ли кто-нибудь помочь мне с этой ошибкой?

РЕДАКТИРОВАТЬ: Для обнаружения я использую класс LookupDiscovery, который я нашел в Интернете:

import java.io.IOException;

import java.rmi.RemoteException;

import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceTemplate;

import net.jini.discovery.LookupDiscovery;
import net.jini.discovery.DiscoveryListener;
import net.jini.discovery.DiscoveryEvent;

/**
   A class which supports a simple JINI multicast lookup.  It doesn't register
   with any ServiceRegistrars it simply interrogates each one that's
   discovered for a ServiceItem associated with the passed interface class.
   i.e. The service needs to already have registered because we won't notice
   new arrivals. [ServiceRegistrar is the interface implemented by JINI
   lookup services].

   @todo Be more dynamic in our lookups - see above

   @author  Dan Creswell (dan@dancres.org)
   @version 1.00, 7/9/2003
 */
public class Lookup implements DiscoveryListener {
    private ServiceTemplate theTemplate;
    private LookupDiscovery theDiscoverer;

    private Object theProxy;

    /**
       @param aServiceInterface the class of the type of service you are
       looking for.  Class is usually an interface class.
     */
    public Lookup(Class aServiceInterface) {
        Class[] myServiceTypes = new Class[] {aServiceInterface};
        theTemplate = new ServiceTemplate(null, myServiceTypes, null);
    }

    /**
       Having created a Lookup (which means it now knows what type of service
       you require), invoke this method to attempt to locate a service
       of that type.  The result should be cast to the interface of the
       service you originally specified to the constructor.

       @return proxy for the service type you requested - could be an rmi
       stub or an intelligent proxy.
     */
    Object getService() {
        synchronized(this) {
            if (theDiscoverer == null) {

                try {
                    theDiscoverer =
                        new LookupDiscovery(LookupDiscovery.ALL_GROUPS);
                    theDiscoverer.addDiscoveryListener(this);
                } catch (IOException anIOE) {
                    System.err.println("Failed to init lookup");
                    anIOE.printStackTrace(System.err);
                }
            }
        }

        return waitForProxy();
    }

    /**
       Location of a service causes the creation of some threads.  Call this
       method to shut those threads down either before exiting or after a
       proxy has been returned from getService().
     */
    void terminate() {
        synchronized(this) {
            if (theDiscoverer != null)
                theDiscoverer.terminate();
        }
    }

    /**
       Caller of getService ends up here, blocked until we find a proxy.

       @return the newly downloaded proxy
     */
    private Object waitForProxy() {
        synchronized(this) {
            while (theProxy == null) {

                try {
                    wait();
                } catch (InterruptedException anIE) {
                }
            }

            return theProxy;
        }
    }

    /**
       Invoked to inform a blocked client waiting in waitForProxy that
       one is now available.

       @param aProxy the newly downloaded proxy
     */
    private void signalGotProxy(Object aProxy) {
        synchronized(this) {
            if (theProxy == null) {
                theProxy = aProxy;
                notify();
            }
        }
    }

    /**
       Everytime a new ServiceRegistrar is found, we will be called back on
       this interface with a reference to it.  We then ask it for a service
       instance of the type specified in our constructor.
     */
    public void discovered(DiscoveryEvent anEvent) {
        synchronized(this) {
            if (theProxy != null)
                return;
        }

        ServiceRegistrar[] myRegs = anEvent.getRegistrars();

        for (int i = 0; i < myRegs.length; i++) {
            ServiceRegistrar myReg = myRegs[i];

            Object myProxy = null;

            try {
                myProxy = myReg.lookup(theTemplate);

                if (myProxy != null) {
                    signalGotProxy(myProxy);
                    break;
                }
            } catch (RemoteException anRE) {
                System.err.println("ServiceRegistrar barfed");
                anRE.printStackTrace(System.err);
            }
        }
    }

    /**
       When a ServiceRegistrar "disappears" due to network partition etc.
       we will be advised via a call to this method - as we only care about
       new ServiceRegistrars, we do nothing here.
     */
    public void discarded(DiscoveryEvent anEvent) {
    }
}

Моя клиентская программа пытается просто найти запись службы JavaSpacesMessageEntry в, а затем получает сообщение и распечатывает его.Вот клиентская программа:

import net.jini.space.JavaSpace;

public class SpaceClient {
   public static void main(String argv[]) {
      try {
         MessageEntry msg = new MessageEntry();
         msg.content = "Hello JavaSpaces wordls!";
         System.out.println("Searching for JavaSpaces...");
         Lookup finder = new Lookup(JavaSpace.class);
         JavaSpace space = (JavaSpace) finder.getService();
         System.out.println("JavaSpaces discovered.");
         System.out.println("Writing into JavaSpaces...");
         space.write(msg, null, 60*60*1000);
         MessageEntry template = new MessageEntry();
         System.out.println("Reading message from JavaSpaces...");
         MessageEntry result = (MessageEntry) space.read(template, null, Long.MAX_VALUE);
         System.out.println("Message: "+result.content);
      } catch(Exception e) {
         e.printStackTrace();
      }
   }
}

И, конечно, это класс MessageEntry:

import net.jini.core.entry.*;

public class MessageEntry implements Entry {
   public String content;

   public MessageEntry() {
   }

   public MessageEntry(String content) {
     this.content = content;
   }

   public String toString() {
     return "MessageContent: " + content;
   }
}

EDIT2: я обнаружил на двух компьютерах с Windows.После этого я попробовал комбинацию Windows - Ubuntu, и она не работает.Может быть, есть какие-то проблемы с сетью?Когда я пингую друг друга, все в порядке.Возможно, есть некоторые проблемы с DNS в Ubuntu ..

EDIT3: Windows - Ubuntu работает, если служба JavaSpaces запущена в Windows, а клиентская программа в Ubuntu.Когда я пытаюсь сделать обратное, для запуска службы JavaSpaces в Ubuntu и запуска клиента в Windows возникает ошибка.Очевидно, что есть некоторые проблемы с Ubuntu.Ubuntu установил OpenJDK, установленный по умолчанию.Я установил Oracle JDK, установил JAVA_HOME и поместил JAVA_HOME / bin в переменную PATH.Интересно, может быть, есть какая-то проблема с разными версиями Java, возможно, я не использую правильную.

Ответы [ 3 ]

2 голосов
/ 24 августа 2011

Возможно, что регистратор служб, который вы используете (на хосте biske-Inspiron-1525 на порту 4160), обнаруживает неправильное имя своего хоста (без имени домена) и поэтому отправляет объявления с коротким именем хоста.Поэтому, после обнаружения регистратора службы, возможно, что впоследствии клиент пытается установить соединение с регистратором службы, он не может разрешить имя хоста, если он находится в другом домене.

Чтобы гарантировать, что регистратор службывыполняется с правильным именем хоста, попробуйте запустить его с помощью следующего атрибута командной строки:

-Dcom.sun.jini.reggie.unicastDiscoveryHost="biske-Inspiron-1525.and.its.domain"
1 голос
/ 24 августа 2011

Похоже, что вы выполняете одноадресное обнаружение для определенного хоста и порта и что вы не можете найти этот хост.

Предполагая, что вы можете разрешить имя biske-Inspiron-1525 с помощью DNS, попробуйте удалить часть ": 4160" и посмотреть, удастся ли выполнить одноадресный поиск.

Вот пример кода, который я использую для поиска службы. Это немного сложнее, потому что я реализую ServiceDiscoveryListener и таким образом обрабатываю обнаружение сервисов. Я фактически держу список служб и динамически переключаюсь между ними, когда один из них выходит из строя, но я убрал эту часть из примера. Я также использую часть конфигурации Jini, которую я объясню позже. Сервисный интерфейс, который я здесь использую, называется «TheService»:

public class JiniClient implements ServiceDiscoveryListener {

private TheService service = null;

private Class[] serviceClasses;
private ServiceTemplate serviceTemplate;

public JiniClient(String[] configFiles) throws ConfigurationException {

    Configuration config = ConfigurationProvider.getInstance(configFiles,
            getClass().getClassLoader());


    // Set the security manager
    System.setSecurityManager(new RMISecurityManager());        

    // Define the service we are interested in.
    serviceClasses = new Class[] {TheService.class};
    serviceTemplate = new ServiceTemplate(null, serviceClasses, null);

    // Build a cache of all discovered services and monitor changes
    ServiceDiscoveryManager serviceMgr = null;

    DiscoveryManagement mgr = null;
    try {
        mgr = (DiscoveryManagement)config.getEntry(
                getClass().getName(), // component
                "discoveryManager",                 // name
                DiscoveryManagement.class);          // type

        if (null == mgr) {
            throw new ConfigurationException("entry for component " +
                    getClass().getName() + " name " +
                    "discoveryManager must be non-null");
        }
    } catch (Exception e) {
        /* This will catch both NoSuchEntryException and 
         * ConfigurationException. Putting them both
         * below just to make that clear.
         */
        if( (e instanceof NoSuchEntryException) || 
                (e instanceof ConfigurationException)) {
            // default value
            try {
                System.err.println("Warning, using default multicast discover.");
                mgr = new LookupDiscoveryManager(LookupDiscovery.ALL_GROUPS,
                        null,  // unicast locators
                        null); // DiscoveryListener
            } catch(IOException ioe) {
                e.printStackTrace();
        throw new RuntimeException("Unable to create lookup discovery manager: " + e.toString());
            }
        } 
    }

    try {
        serviceMgr = new ServiceDiscoveryManager(mgr, new LeaseRenewalManager());
    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException("Unable to create service discovery manager: " + e.toString());
    }

    try {
        serviceMgr.createLookupCache(serviceTemplate, 
                                                null,  // no filter
                                                this); // listener
    } catch(Exception e) {
        e.printStackTrace();
        throw new RuntimeException("Unable to create serviceCache: " + e.getMessage());
    }
}

public void serviceAdded(ServiceDiscoveryEvent evt) {
       /* Called when a service is discovered */
    ServiceItem postItem = evt.getPostEventServiceItem();
    //System.out.println("Service appeared: " +
    //         postItem.service.getClass().toString());

    if(postItem.service instanceof TheService) {
        /* You may be looking for multiple services. 
                     * The serviceAdded method will be called for each
                     * so you can use instanceof to figure out if 
                     * this is the one you want.
                     */
        service = (TheService)postItem.service;

    }       
}

public void serviceRemoved(ServiceDiscoveryEvent evt) {
/* This notifies you of when a service goes away. 
     * You could keep a list of services and then remove this 
     * service from the list. 
 */ 
}

public void serviceChanged(ServiceDiscoveryEvent evt) {
/* Likewise, this is called when a service changes in some way. */  

}

Система конфигурации позволяет динамически настраивать метод обнаружения, чтобы вы могли переключаться на обнаружение определенных одноадресных или многоадресных систем без изменения приложения. Вот пример файла конфигурации обнаружения одноадресной рассылки, который вы можете передать конструктору вышеуказанных объектов:

import net.jini.core.discovery.LookupLocator;
import net.jini.discovery.LookupDiscoveryManager;
import net.jini.discovery.LookupDiscovery;

com.company.JiniClient {
    discoveryManager = new LookupDiscoveryManager(
        LookupDiscovery.ALL_GROUPS,
        new LookupLocator[] { new LookupLocator("jini://biske-Inspiron-1525.mycompany.com")},
        null,
        this); // the current config
}
0 голосов
/ 22 сентября 2011

Я нашел решение!Это был вопрос DNS.В Ubuntu мой файл / etc / hosts был:

192.168.1.3 biske-Inspiron-1525 # Added by NetworkManager
127.0.0.1   localhost.localdomain   localhost
::1 biske-Inspiron-1525 localhost6.localdomain6 localhost6
127.0.1.1   biske-Inspiron-1525

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

Я только что удалил строку 127.0.1.1 biske-Inspiron-1525 и теперь он работает нормально.Мелочь была разрушена миллионами моих нервов:)

...