2012-05-02 26 views
3

私はRMIサーバーとクライアントを持っています。サーバーとクライアントは、相互にRMI呼び出しを行うことができます。クライアントがサーバーに接続した後、サーバーはクライアント上で数百のメソッド呼び出しをすばやく連続して実行することがあります。RMIメソッド呼び出しが断続的に失敗する原因は何ですか?

Server-Clientメソッドコールの膨大なバッチの最後に、RMIはServer-Clientからの接続を確立できないと主張しているため、失敗します成功します。このプロジェクトはかなり大きい(約50Kライン)であるので、私は、実際のコードを投稿することはできませんが、ここでスローされます例外の完全なスタックトレースです:

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: 
java.net.SocketException: Connection reset 
at sun.rmi.server.UnicastServerRef.dispatch(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 Source) 
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source) 
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source) 
at sun.rmi.server.UnicastRef.invoke(Unknown Source) 
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source) 
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source) 
at $Proxy0.findClassDefinition(Unknown Source) 
at com.fabric.network.NetworkClassLoader.findClass(NetworkClassLoader.java:111) 
at java.lang.ClassLoader.loadClass(Unknown Source) 
at com.fabric.network.NetworkClassLoader.loadClass(NetworkClassLoader.java:131) 
at java.lang.ClassLoader.loadClass(Unknown Source) 
at com.fabric.network.MessageSocket$CustomObjectInputStream.resolveClass(MessageSocket.java:171) 
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.defaultReadFields(Unknown Source) 
at java.io.ObjectInputStream.readSerialData(Unknown Source) 
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
at java.io.ObjectInputStream.readObject0(Unknown Source) 
at java.io.ObjectInputStream.defaultReadFields(Unknown Source) 
at java.io.ObjectInputStream.readSerialData(Unknown Source) 
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
at java.io.ObjectInputStream.readObject0(Unknown Source) 
at java.io.ObjectInputStream.readObject(Unknown Source) 
at com.fabric.network.MessageSocket.receive(MessageSocket.java:118) 
at com.fabric.application.driver.NodeRemoteDriver$IncomingMessageThread.run(NodeRemoteDriver.java:205) 
Caused by: java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: 
java.net.SocketException: Connection reset 
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source) 
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source) 
at sun.rmi.server.UnicastRef.invoke(Unknown Source) 
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source) 
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source) 
at $Proxy2.findClassDefinition(Unknown Source) 
at com.fabric.network.ClassDefinitionCache.findClassDefinition(ClassDefinitionCache.java:78) 
at com.fabric.management.host.NodeManagementServices.findClassDefinition(NodeManagementServices.java:231) 
at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at sun.rmi.server.UnicastServerRef.dispatch(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 Source) 
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 
Caused by: java.net.SocketException: Connection reset 
at java.net.SocketInputStream.read(Unknown Source) 
at java.io.BufferedInputStream.fill(Unknown Source) 
at java.io.BufferedInputStream.read(Unknown Source) 
at java.io.DataInputStream.readByte(Unknown Source) 
... 21 more 

は私が多くを提供することはできません、再度申し訳ありませんコードの方法ですが、必ずしもコードの修正を求めているわけではありません。なぜこれが起こっているのかということを頭の中に入れたいだけです。

EDIT

は、完全なスタックトレースを追加しました。

+0

あなたを助けてくれるかもしれません:http://docs.oracle.com/javase/jndi/tutorial/objects/storing/remote.html –

+0

私の質問はちょっとばかなかもしれませんが、クライアントに例外があるかどうかチェックしましたか側? –

+0

@MartinPrakashはい、そうです。これはクライアント側の例外です。 – EJP

答えて

6

だから、ほとんどすべての私の髪を引き出した後、RMIがあまりにも多くのポートを開こうとしていたことが判明しました。私はフードの中でカスタムRMISocketFactoryの実装を使用しています。このカスタム実装はシングルトンなので、hashCode()equals()を実装する必要はないと私は考えました。確かに非常に痛い間違い...

RMIは、作成する必要があるソケットが、ソケットを作成した工場と同等ではないRMISocketFactoryによって作成されるとRMIが判断した場合、ソケットを再使用しませんそれは再利用したい。 RMIは、このチェックを実行するためにequals()hashCode()に依存しています。これらの2つのメソッドをカスタムソケットファクトリで正しく実装すると、これらの断続的な問題は解決されました。

この問題の説明はここで見つけることができます:任意のレートで

http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/faq.html

を、これを見て取るためのすべてのおかげで、私は確かにあなたの時間を感謝します!

追加情報

が判明、私が使っていたServerSocketも削除されている接続に貢献した着信接続要求のためのキュースペースの外に走っていました。より大きなnewConnectionQueueSizeのコンストラクタnew ServerSocket(port, newConnectionQueueSize, bindAddress)を使用することで、この問題も解決されました。

関連する問題