0

私の知る限り、クライアントに設定した RMI のコードベースはサーバーに渡されます。次に、サーバーはこのコードベースを使用して、サーバーのクラスパスにないクラスを見つけます。

必要なすべてのクラスがサーバーのクラスパスで利用可能である限り、リモート メソッドの呼び出しは正常に機能します。次に、必要なクラスをサーバーのクラスパスから削除しようとしましたが、代わりに、RMI クライアントの起動時に codebase プロパティで必要なクラスの新しい場所を指定しました。残念ながら、これにより ClassNotFoundException: java.lang.ClassNotFoundException: client.Pi が返されます。

スタックトレース:

java.rmi.ServerException: RemoteException occurred in server thread; nested exce
ption is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested excep
tion is:
java.lang.ClassNotFoundException: client.Pi
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Sou
rce)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Sour
ce)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknow
n Source)
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unkn
own Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at com.sun.proxy.$Proxy0.executeTask(Unknown Source)
at client.ComputePi.main(ComputePi.java:26)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested ex
ception is:
java.lang.ClassNotFoundException: client.Pi
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Sou
rce)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Sour
ce)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: client.Pi
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.rmi.server.LoaderHandler$Loader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClassForName(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at sun.rmi.server.LoaderHandler.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source)
at java.rmi.server.RMIClassLoader.loadClass(Unknown Source)
at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source)
... 11 more

サーバーの起動:

C:\TEMP\RMI\RMIDemo\src>java 
-cp C:\Users\samue_000\public_html\classes\compute.jar;C:\TEMP\RMI\RMIDemo\src 
-Djava.security.policy=server.policy 
-Djava.rmi.server.useCodebaseOnly=false  
engine.ComputeEngine

>> ComputeEngine bound

クライアントの開始:

C:\TEMP\RMI\RMIDemo\src>java 
-cp C:\Users\samue_000\public_html\classes\compute.jar;c:\Temp\RMI\RMIDemo\src;c:\temp 
-Djava.security.policy=client.policy 
-Djava.rmi.server.codebase=file:/C:/Users/samue_000/public_html/classes 
client.ComputePi

クライアントのクラスパス (c:\temp) 内には、クライアントも必要とする必要な client.Pi クラスがあります。このクラスがどこにあるかをサーバーに伝えるために、別のフォルダーにコピーを置き、このフォルダーを codebase プロパティで指定しました。そのクラスの正確な場所は C:/Users/samue_000/public_html/classes/client/Pi.class です。そのすべてが同じ物理マシン (VM なし) で実行されています。したがって、サーバーがクライアントからコードベースを取得せず、必要な client.Pi クラスをロードしない理由がわかりません。

この投稿を埋めすぎないように、投稿する情報を必要な部分に最小限に抑えようとしました。この問題を解決するためにさらに情報が必要な場合は、お知らせください。それは私を夢中にさせています。私はこの問題に何時間も何日も取り組んでいます...

編集:この記事で説明されているものとほぼ同じコードを使用しました。唯一の違いは、レジストリを個別に開始するのではなく、プログラムで rmi レジストリを作成することです。したがって、コード自体に問題はないはずです。Pi クラスがサーバーのクラスパスにある限り、問題なく動作します。しかし、Pi クラスがクライアントのコードベースとクラスパス内にのみ存在するとすぐに、それは機能しなくなります。

4

3 に答える 3

0

最後に / を省略しないでください。

-Djava.rmi.server.codebase=file:/C:/Users/samue_000/public_html/classes/ 
于 2020-05-24T14:06:30.283 に答える