わかりました、これはかなり簡単だと確信していますが、私はJavaにかなり慣れていません(私は.NETの少年です:P)、ここで見つけたすべての推奨事項に従って成功しなかった後、一歩下がって尋ねる。
クライアント、サーバー、および共通のインターフェースが定義されている共通のプロジェクトで単純な rmi プロジェクトを開始しようとしています。サーバー コードを実装したばかりで、それを実行してすべてが正常かどうかを確認しようとすると、java.lang.ClassNotFoundException が発生します。
同様の問題についていくつかの回答をたどった後、私の問題は、プロジェクトとは異なる場所で実行されている rmiregistry に起因していると確信しています。
次のコードを使用して、レジストリ コードベースを設定します。
public class Utils {
public static final String CODEBASE = "java.rmi.server.codebase";
public static void setCodeBase(Class<?> c) {
String ruta = c.getProtectionDomain().getCodeSource().getLocation().toString();
String path = System.getProperty(CODEBASE);
if (path != null && !path.isEmpty()) {
ruta = path + " " + ruta;
}
System.setProperty(CODEBASE, ruta);
}
}
次に、このメイン クラスを使用してサーバー コードを開始しようとします。
public class MainRegulador {
public static void main(String[] args) throws AccessException, RemoteException, NotBoundException {
Utils.setCodeBase(IRegulador.class);
Registry registro = null;
Remote proxy = null;
try {
Regulador myReg = new Regulador();
proxy = UnicastRemoteObject.exportObject(myReg, 36510);
registro = LocateRegistry.getRegistry();
registro.rebind("Distribuidor", proxy); //this is the line where exception is thrown
System.out.println("El Regulador está corriendo. Pulse ENTER para finalizar el proceso.");
System.in.read();
} catch(Exception ex) {
System.out.println("No se ha logrado inicializar el Registrador");
System.out.println(ex.getMessage());
} finally {
if (registro != null && proxy != null) {
registro.unbind("Distribuidor");
UnicastRemoteObject.unexportObject(proxy, true);
}
}
}
}
しかし、実行すると、常に IRegulador インターフェイスで java.lang.ClassNotFoundException が発生します。
楽しい部分:
- java.rmi.server.codebase の値をコンソールに出力しました。IRegulador インターフェイスが定義されているプロジェクトの bin フォルダーを指しています。(ファイル:/F:/Practicas%20y%20dem%c3%a1s/Sistemas%20Distribuidos/common/bin/)
- 明らかに、そのプロジェクトはサーバープロジェクト(Regulador)のクラスパスにも設定されています
- ワークスペースと rmiregistry が異なるディスク上にある
- それにもかかわらず、Utils クラスは IRegulador インターフェイスと同じプロジェクトにあり、例外がスローされる前に実行されるため (java.rmi.server.codebase が正しく設定されているため)、グローバル クラスパスの問題ではないようです。
呼び出す前にrmiregistryのクラスパスを設定しようとしましたが(一部の回答では直接推奨されていませんが)、何も変わりませんでした。また、Regulador プロジェクトの bin フォルダーから rmiregistry.exe を起動しようとしましたが、何も変更されていないようです。
.NET のバックグラウンドを持つ私は、これらのクラスパスの問題が紛らわしいといつも思っていました。この問題は、予想以上に多くの時間を消費し始めています。どうしても助けが必要です。
更新: IRegulador.class からコードベースに渡される URL に問題があると考え始めています。それをWindowsエクスプローラーに貼り付けると、SOはそれを見つけることができないため、レジストリがルートに到達するのを妨げる構造上の問題で構築されていると思います:
file:/F:/Practicas%20y%20dem%c3%a1s/Sistemas%20Distribuidos/common/bin/
更新 2: パス ルートが複雑すぎる可能性があると考えたので、単純化して直線以外の文字を削除することにしました。現在、コードベースの値は
file:/F:/Practicas/SD/common/bin/
ただし、問題は解決しません。rmiregistry がそのフォルダーに到達できない理由がわかりません。
次に、プロジェクト全体を rmiregistry が実行される同じディスクに移動し、何かが変更されるかどうかを確認することにしました。しかし、何も変わらず、同じ問題です。