2011-07-27 4 views
0

이 기사에 http://java.sun.com/developer/technicalArticles/tools/JavaSpaces/은 JavaSpaces 클라이언트를 실행하는 방법에 대한 자습서입니다. Eclipse에서이 클래스들을 작성하고, Launch-All 스크립트와 Run 예제를 시작했습니다. 그것은 작동합니다. 는 그 후 나는이 실행 항아리 (JavaSpaceClient.jar)에 이러한 클래스를 내 보낸 다음 명령으로 그 항아리 시도 : 그것은 잘 작동 -jar JavaSpaceClient.jar 자바, 내가 결과를 제공합니다 이 ... 자바 스페이스 자바 스페이스 검색 발견되었습니다. 공간에 메시지 작성 중 ... 공간에서 메시지 읽기 ... 메시지 읽기 : JavaSpace가 사용 가능합니다!Jini/JavaSpaces 검색 오류

제 문제는 다른 LAN 컴퓨터에서이 jar 파일을 옮길 때 동일한 명령을 입력 할 때 오류가 있음을 보여줍니다. "... 자바 스페이스 검색"

[email protected]:~/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) 

난 그냥 쓰고 잠시 후 이러한 오류 메시지를 출력 : 다음 오류가 발생합니다. 누군가이 오류와 관련하여 도움을 줄 수 있습니까?

편집 : 내가 인터넷에서 발견 한 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 ([email protected]) 
    @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) { 
    } 
} 

내 클라이언트 프로그램에 자바 스페이스 서비스 쓰기 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 :

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 클래스입니다 : 여기에 클라이언트 프로그램입니다 나는 두 개의 Windows 컴퓨터에서 발견했다. 그 후 나는 Windows - Ubuntu combiant를 시도했지만 작동하지 않습니다. 네트워크 문제가있을 수 있습니까? 내가 서로 핑 할 때 모든 것이 괜찮습니다. Ubuntu에 DNS 문제가있을 수 있습니다.

EDIT3 : Windows - JavaSpaces 서비스가 Windows에서 시작되고 클라이언트 프로그램이 Ubuntu에있는 경우 우분투 조합이 작동합니다. 역순으로하려고하면 JavaSpaces 서비스를 우분투에서 실행하고 Windows에서 클라이언트를 실행하면 오류가 발생합니다. 우분투에는 분명히 문제가 있습니다. 우분투에는 기본적으로 OpenJDK가 설치되어 있습니다. Oracle JDK를 설치하고 JAVA_HOME을 설정하고 JAVA_HOME/bin을 PATH 변수에 넣습니다. 다른 버전의 Java에 문제가있을 수 있습니다. 아마도 올바른 버전을 사용하고 있지 않을 수도 있습니다.

답변

0

내가 해결책을 발견! 그것이 DNS 문제였습니다. 우분투에서 내/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 - 인스-1525하고 지금은 잘 작동합니다. 작은 것이 내 신경의 백만 가지를 파괴했습니다.

1

특정 호스트와 포트에 대해 유니 캐스트 검색을 수행하고 있으며 해당 호스트를 찾을 수 없다고합니다.

biske-Inspiron-1525라는 이름을 DNS로 해결할 수 있다고 가정하면 ": 4160"부분을 제거하고 유니 캐스트 검색이 성공하는지 확인하십시오.

다음은 서비스를 검색하는 데 사용하는 코드의 예입니다. ServiceDiscoveryListener를 구현하고 그런 식으로 서비스 검색을 처리하기 때문에 좀 더 복잡합니다. 실제로 서비스 목록을 유지하고 하나가 실패 할 때 동적으로 전환하지만 예제에서 그 부분을 제거했습니다. 나는 또한 나중에 설명 할 Jini의 Configuration 부분을 사용하고있다.내가 여기에 사용하고 서비스 인터페이스는 "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

JavaSpaces를 도와 줄 사람이별로 없기 때문에 도와 주셔서 감사합니다. 내 질문을 편집했는데, 무엇을 바꾸라고 제안 할 수 있니? –

+0

예제 코드로 나의 응답을 업데이트했습니다. –

+0

사용중인 검색 코드를 보았습니다. 멀티 캐스트 검색을 사용하고있는 것처럼 보이지만 호스트를 찾을 때 문제가 발생합니다. @ beny23이 말한 것을 시도해보십시오. 또한 일종의 DNS 문제가 없는지 확인하기 위해 호스트 이름 대신 컴퓨터의 IP 주소로 유니 캐스트 검색을 지정하십시오. –

2

그것은 가능하다 당신이 (4160 포트에서 호스트 biske - 인스-1525에) 실행중인 서비스 등록 , 호스트 이름이 부정확하게 (도메인 이름없이) 발견되어 짧은 호스트 이름으로 공지 사항을 발송합니다. 따라서 서비스 등록자를 발견 한 후 클라이언트가 서비스 등록자에 연결하려고 시도하는 중이어서 다른 도메인에있는 경우 호스트 이름을 해석 할 수 없습니다.

이 서비스 등록이 올바른 호스트 이름으로 실행되고 있는지 확인하려면 다음 명령 줄 속성을 시작해보십시오 :

-Dcom.sun.jini.reggie.unicastDiscoveryHost="biske-Inspiron-1525.and.its.domain" 
+0

이 옵션으로 reggie를 시작했지만 JavaSpaceClient가 "Looking for JavaSpace ..."를 출력하고 아무 일도 일어나지 않습니다. 아파치 강을 사용하여이 예제를 실행 중이다. –

관련 문제