2011-07-27 9 views
0

この記事の内容:http://java.sun.com/developer/technicalArticles/tools/JavaSpaces/は、JavaSpacesクライアントを実行する方法のチュートリアルです。 Eclipseでこれらのクラスを作成し、Launch-AllスクリプトとRunサンプルを開始しました。できます。 は、その後、私は実行可能なjarファイル(JavaSpaceClient.jar)にこれらのクラスをエクスポートして、次のコマンドを使用して、そのJARみました:それは正常に動作します-jar JavaSpaceClient.jar のjavaを、私は結果与える: は... A JavaSpace JavaSpaceの検索発見されました。 スペースにメッセージを書き込む... スペースからメッセージを読み取る... メッセージは次のとおりです:JavaSpaceが見つかりました!Jini/JavaSpacesの検出エラー

私の問題は、他のLANコンピュータでこのjarファイルを移動すると、同じコマンドを入力するとエラーが表示されます。 「... JavaSpaceの検索」

[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) 

私はちょうど書き込み、しばらくした後、これらのエラーメッセージが出力されます。ここでエラーです。 誰かがこのエラーで私を助けることができますか?

EDIT: 発見のために、私はインターネット上で見つけた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) { 
    } 
} 

を私のクライアントプログラムはへのJavaSpacesサービス書き込みMessageEntryを検索するために、単純にしようとすると、メッセージを取得し、それを出力します。ここでは、クライアントプログラムは次のとおりです。

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: 私は2台のWindowsコンピュータ上の発見をしました。 その後、私はWindows - Ubuntuのコンビネーションを試みましたが、うまくいきません。多分ネットワークの問題がありますか?私がお互いにpingをするとき、すべては大丈夫です。 UbuntuでDNSに関する問題が発生している可能性があります。

EDIT3: Windows - JavaSpacesサービスがWindows上で起動され、クライアントプログラムがUbuntu上にある場合、Ubuntuの組み合わせで動作します。逆にしようとすると、UbuntuでJavaSpacesサービスを実行し、Windowsでクライアントを実行するとエラーが発生します。 明らかにUbuntuには問題があります。 UbuntuにはデフォルトでOpenJDKがインストールされています。私はOracle JDKをインストールし、JAVA_HOMEを設定し、JAVA_HOME/binをPATH変数に入れました。おそらく、異なるバージョンのJavaにいくつかの問題があるのだろうか、おそらく私は正しいものを使用していないのかもしれない。

答えて

0

が、私は解決策を見つけました!それは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を削除したし、今では正常に動作します。 小さなものが私の神経の100万人を破壊しました:)

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-のInspiron-1525上で)実行されているサービスレジストラことは可能ですそれがホスト名を間違って(ドメイン名なしで)発見しているため、短いホスト名でアナウンスを送信しています。したがって、サービスレジストラを検出した後、クライアントがサービスレジストラへの接続を試みている可能性があります。これは、別のドメインにある場合はホスト名を解決できません。

は、サービスレジストラが正しいホスト名で実行されていることを確認するには、次のコマンドライン属性で実行してみてください:

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

このオプションでreggieを起動しましたが、JavaSpaceClientが "Looking for JavaSpace ..."を表示して何も起こりません。私はApache Riverを使用してこれらのサンプルを実行しています。 –

関連する問題