この同じタイトルでいくつかの質問がありましたが、いずれも私の問題を解決できませんでした。 https://docs.oracle.com/javase/tutorial/rmi/overview.htmlクライアント側のJava RMI ClassNotFoundException
私は1つのプロジェクトのすべてを置くことによって狂気自分自身を運転していたので、私は3つの別々のプロジェクト作成しました:私はここのチュートリアルに従うことをしようとしている
- サーバーを - >それはMain(Driver)クラスを持っています:ServerNodeはComputeを実装します
- クライアント - > Main(Driver) ute
考えているのは、両方のアプリケーションがInterfaces Task(クライアントがサーバーに送信する作業単位)とCompute(クライアントが使用するServerNodeのインターフェイスですコマンドに)。
サーバコード:
System.setProperty("java.security.policy","file:server.policy");
System.out.println(System.getProperty("java.security.policy"));
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
int port = 1099;
try {
LocateRegistry.createRegistry(port);
String name = "Compute"; // Name of the interface
Compute engine = new ServerNode(); // Implementor of Compute interface, ComputeEngine
Compute stub =
(Compute) UnicastRemoteObject.exportObject(engine, 0); // Create the stub the client will use
Registry registry = LocateRegistry.getRegistry(port);
registry.bind(name, stub); // Bind the "Compute" to the stub, so client can access it by "Compute"
System.out.println("ComputeEngine bound");
} catch (Exception e) {
System.err.println("ComputeEngine exception:");
e.printStackTrace();
}
クライアントコード:
System.out.println("Entering client");
String lookupName = "localhost";
System.setProperty("java.security.policy","file:client.policy");
System.out.println(System.getProperty("java.security.policy"));
System.setProperty("rmi.server.codebase", "file:/c:/Users/Brian/Documents/RMI_ClientSide/TestTask.class");
System.out.println(System.getProperty("rmi.server.codebase"));
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Compute";
Registry registry = LocateRegistry.getRegistry("localhost", 1099);
Compute comp99 = (Compute)registry.lookup("Compute");
System.out.println(comp99.executeTask(new TestTask()));
} catch (Exception e) {
System.err.println("ComputePi exception:");
e.printStackTrace();
}
私はそれはない...唯一のクライアントがTestTaskについて知っている必要がありますチュートリアル から、信じるように導かいます/共有する必要はありません。サーバーはインタフェースTaskについて知る必要があり、クライアントはそのインタフェースの実装者を与えます...私はクライアントのコードベースから具体的なコードをダウンロードするバックグラウンドを信じています。
私のディレクトリ構造が 1.ドキュメント/ RMI_ServiceSide 2.ドキュメント/ RMI_ClientSide 3.ドキュメントです/
は、今私は、プログラム、サーバーコードでrmiregisterを起動、代わりの上でそれを実行していますRMI_Sharedコマンドライン。私はそれが私の問題だとは思わないが、この時点(4時間のデバッグ後)にはわからない。私はそのコードでサーバーを起動することができます。
問題はクライアント側にあります。私は、クライアントのコードを実行しようとすると、私が手:
Entering client
file:client.policy
file:/c:/Users/Brian/Documents/RMI_ClientSide/TestTask.class
ComputePi exception:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: com.company.TestTask
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:355)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:276)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:162)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
at com.sun.proxy.$Proxy0.executeTask(Unknown Source)
at com.company.Main.main(Main.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: com.company.TestTask
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:315)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: com.company.TestTask
さてさて、私がTestTaskを実行しようとすると、レジストリは、それはそれを見つけることができない戻って来ることが表示されます。私は、-Djava.rmi.server.codebase = file:/ c:/ Users/Brian/Documents/RMI_ClientSide /コマンドライン引数と/またはSystem.setProperty( "rmi.server.codebase" "、"ファイル:/ c:/Users/Brian/Documents/RMI_ClientSide/TestTask.class ");
私はこれがrmiregistryの問題であるか、私のコードベースで正しく並べ替えをしなかったかどうかは分かりません。これはすべて1台のマシン上にあるので、なぜ問題が見つかっているのかわかりません。明示的には
...必要となるファイル: 1.クライアント - > RMI_ClientSide/binに/.../ Main.classとTestTask.class 2.サーバー - > RMI_ServerSide/binに/ .. Main.classとServerNode.class 3.共有 - > RMI_Shared/bin /.../ RMI_Shared.jar - > Task.classとComputeを含みます。クラス
私が言ったように、これらは、3つの別々のプロジェクトがありますが、パッケージ名は同じ...パッケージcom.companyです。偶然にも、各プロジェクトを作成するときにデフォルトの名前を変更しませんでした。それが重要かどうかはわかりません。 RMI_Shared.jarをサーバーとクライアントのプロジェクトにインポートするときは、確かにそうではありませんでした...どちらもうまくコンパイルされました。
私もTestTaskを含める必要があるだろう共有印象を与えた...しかし、必要なときに、レジストリがサーバにクラス定義を引き上げる必要があるとして、それは意味がないもう一つの答えは...そのように、Aクライアントはサーバまで任意のコードを実行できます(この単純な安全でないテストでは意図されています)。
私はこの実行を取得する任意の助けをいただければ幸いです。ありがとう!
EDITは:/私のプロジェクトのディレクトリ自体はただの文書があることを Codebase directory
注意私のコードベースフォルダの画像へのリンクを追加しました。クライアント、サーバー、およびヘルパー。
おかげ - https://docs.oracle.com/javase/tutorial/rmi/compiling.htmlの私の理解で、この紛争:この例は、3つのパッケージにインタフェース、リモートオブジェクトの実装、およびクライアントコードを分離: compute - 計算とタスクのインターフェイス engine - ComputeEngine実装クラス クライアント - ComputePiクライアントコードとPiタスクの実装 – user2770791
"Pi"クラスが "Task"を実装する方法に注意してください... Computeパッケージは共有パッケージですクライアントとサーバの両方のコンパイルでCompute.jarがどのように使用されるかに注意してください。しかし、サーバーはクライアントパッケージ( "Pi"の定義を含んでいます)を使用していません。これは、なぜ、タスクインタフェースを知っているときにサーバが具体的なTestTask実装を必要とするのかということです。レジストリ/ RMIがクライアントコードベースからそのコードを取得するはずですか? – user2770791
可能な場合、サーバーはクラスをクライアントコードベースから引き出しますが、クライアントのJVMコードベースは、クライアントファイルシステム内の場所を指すファイル:URLであり、サーバーでは何も意味しません。コードベースのURLは、通常HTTPまたはFTPです。 – EJP