編集:Java™ TutorialsはRMI上でオブジェクトのデータ(具体的には、サーバ変数)を送信
サーバとクライアントが通信して戻って情報を渡すと述べ
、そのことを言います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
と表示されています。私は、クライアントがインプリメンテーションを認識せず、インターフェースだけを理解していることを理解していますが、テストのフィールドにアクセスする方法はありますか?私は元のコードに多くのフィールドを持っており、可能であれば、それぞれのゲッターを作成したくありません。
フィールドが多数ある場合は、それらを新しいクラスにカプセル化し、そのクラスのインスタンスを返すメソッド(インターフェイスクラスと実装クラスの両方)を書き込むことができます。このように、単一のリモートメソッドを呼び出すことによって、すべてのフィールドの値を取得することができます。 –
インターフェイスの静的な最終値にアクセスするために、RMIまたはインターフェイスのインスタンスを必要としません。あなたの質問は理にかなっていません。 – EJP
@EJP:私はインターフェイスの最終的な値にアクセスしようとしていません。私は(またはクライアントが)Testのサーバーインスタンス化で変数にアクセスしようとしています。 – Shahar