2016-05-28 5 views
-2

編集Java™ TutorialsRMI上でオブジェクトのデータ(具体的には、サーバ変数)を送信

サーバとクライアントが通信して戻って情報を渡すと述べ

、そのことを言いますRMI

は、オブジェクトのクラス定義をロードするメカニズムも提供します。 は、オブジェクトのデータを送信する。

私は、「オブジェクトのデータは、」(例えば、以下に私のコードでTest.value、など)サーバーオブジェクトの変数が含まれることを期待していた - しかし、私が得た最初のコメントは、おそらく私が間違っていたことを示しています。私の元々の質問が続きます。

私は、RMI経由でクライアントに送信しているリモートオブジェクトにアクセスしようとしています。私はメソッドにアクセスできますが、インスタンス変数にはアクセスできません。代わりにインターフェイスのフィールドを取得します。私の質問は、私が実装し、サーバー上でクラスをインスタンス化すると、ゲッターを使わずに[public]フィールドにどのようにアクセスすればよいのでしょうか?私は、エラーや例外なしでスタブを送信することができますが、私が言ったように、私はサーバーのオブジェクトのフィールドにアクセスすることはできません。以下は、私のインターフェース、実装、サーバー、およびクライアントの簡略版です。

package test; 

import java.rmi.Remote; 
import java.rmi.RemoteException; 

public interface TESTint extends Remote { 

     double value = -22; 
     String shortName = "TESTint"; 

     double getValue() throws RemoteException; 
} 
package test; 

import java.rmi.RemoteException; 

public class Test implements TESTint { 

    public double value = -33; 
    public String shortName = "TestAccount"; 
    public int whole = 1; 

    public Test(String shortName) { 
     this.shortName = shortName; 
     print(shortName); 
    } 

    public double getValue() throws RemoteException { 
     return value; 
    } 

    public void print(Object o) { 
     System.out.println(shortName + ": " + o); 
    } 
} 
package test; 
import java.rmi.registry.LocateRegistry; 
import java.rmi.registry.Registry; 
import java.rmi.server.UnicastRemoteObject; 

public class RemoteTestMain { 
    Test test; 

    public static void main(String[] args) throws InterruptedException { 
     if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } 
     new RemoteTestMain(); 
    } // main 

    public RemoteTestMain() { 
     test = new Test("Charlie"); 
     Registry registry; 
     try { 
      registry = LocateRegistry.createRegistry(1234); 
      registry.list(); // will throw an exception if the registry does not already exist   
      print(test.shortName); // it gets it right here 
      print(test.value); // it gets it right here 
      TESTint r = (TESTint) UnicastRemoteObject.exportObject(test, 0); 
      registry.rebind("DCregistry", r); 
      print("test bound"); 
     } catch (java.rmi.RemoteException ex) { 
      print("Remote Exception at Server"); 
      ex.printStackTrace();; 
     } 
    } 

    public static void print(Object o) { 
     System.out.println("Server: " + o); 
    } 
} 
package test; 

import java.rmi.RemoteException; 
import java.rmi.registry.LocateRegistry; 
import java.rmi.registry.Registry; 

public class Client { 
    TESTint test; 

    public static void main(String[] args) { 
     try { 
      new Client(); 
     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } 
    } // main 

    private void init(int account) { 
     print("INITiating Account " + account);   
     try { 
      Registry registry = LocateRegistry.getRegistry(1234); 
      test = (TESTint) registry.lookup("DCregistry"); 
     } catch (Exception e) { 
      System.err.println("RMI exception:"); 
      e.printStackTrace(); 
     } 
     print("Short name : " + test.shortName); 
     print("value: " + test.value); 
     try { 
      print("Value through getter is " + test.getValue()); 
     } catch (RemoteException e) { 
      print("Could not get equity"); 
      e.printStackTrace(); 
     } 
    } // init(int account) 

    public Client() throws RemoteException { 
     if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } 
     init(2); 
    } 

    private static void print(Object o) { 
     System.out.println("GUI: " + o); 
    } 
} 

P.上記のクライアントコードでは、test.shortNameには下線が引かれており、EclipseにはThe static field TESTint.shortName should be accessed in a static wayと表示されています。私は、クライアントがインプリメンテーションを認識せず、インターフェースだけを理解していることを理解していますが、テストのフィールドにアクセスする方法はありますか?私は元のコードに多くのフィールドを持っており、可能であれば、それぞれのゲッターを作成したくありません。

+0

フィールドが多数ある場合は、それらを新しいクラスにカプセル化し、そのクラスのインスタンスを返すメソッド(インターフェイスクラスと実装クラスの両方)を書き込むことができます。このように、単一のリモートメソッドを呼び出すことによって、すべてのフィールドの値を取得することができます。 –

+0

インターフェイスの静的な最終値にアクセスするために、RMIまたはインターフェイスのインスタンスを必要としません。あなたの質問は理にかなっていません。 – EJP

+0

@EJP:私はインターフェイスの最終的な値にアクセスしようとしていません。私は(またはクライアントが)Testのサーバーインスタンス化で変数にアクセスしようとしています。 – Shahar

答えて

1

RMIは、Remote Method Invocationを表します。つまり、オブジェクトのメソッドをリモートで実行できます。メソッドの実装は、リモートシステムに存在します。パブリックであっても、リモートシステムに存在する実装クラスのインスタンス変数には決してアクセスできません。あなたはIntefaceによって公開されているpublicメソッドのみを実行できます。したがって、変数にアクセスするには、Intefaceクラスと実装クラスの両方でpublic gettterメソッドを追加する必要があります。

関連する問題