J2SE Version (please include all output from java -version flag): java version "1.4.2-beta" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-beta-b19) Java HotSpot(TM) Client VM (build 1.4.2-beta-b19, mixed mode) Does this problem occur on J2SE 1.3, 1.4 or 1.4.1? Yes / No (pick one) Yes (tested with 1.4.1) Operating System Configuration Information (be specific): Windows 2000, but it should also happen on other platforms. Hardware Configuration Information (be specific): regular P4 PC Bug Description: RMI reuses RMI connections even if I set sun.rmi.transport.connectionTimeout property to "0". Steps to Reproduce (be specific): Code to reproduce this bug is not trivial, but bugfix should be. If I make two consecutive RMI calls, same RMI connection is used (not always, but quite often), even if I set sun.rmi.transport.connectionTimeout property to zero. I need to set different timeouts for calls of different methods of the same remote object. As RMI lacks this functionality, I've made my own RMISocketFactory, that makes it possible - but connections should not be reused, to make it work. Please see the attachment "rmitest.jar" for test case. Steps to reproduce the problem: 1. Put rmitest.jar on the classpath. 2. Run rmitest.RmiServer 3. Run rmiTest.RmiClient The result is: Start --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 500 Got exception: java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: java.net.SocketTimeoutException: Read timed out java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: java.net.SocketTimeoutException: Read timed out at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:203) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133) at rmitest.RmiServer_Stub.rGetData(RmiServer_Stub.java:35) at rmitest.RmiClient.main(RmiClient.java:16) Caused by: java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:129) at java.io.BufferedInputStream.fill(BufferedInputStream.java:183) at java.io.BufferedInputStream.read(BufferedInputStream.java:201) at java.io.DataInputStream.readByte(DataInputStream.java:331) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:189) ... 3 more , as the response from RmiServer takes 1000ms, but RmiClient reused the socket and therefore crashed. If I uncomment the first sleep (the code in RmiClient looks like): Thread.sleep(1); TimeoutableRMISocketFactory.setTimeout(0, true); rmiServer.rGetData("To je tudi en test."); //Thread.sleep(1); //TimeoutableRMISocketFactory.setTimeout(100, true); rmiServer.rGetData("To je tudi en test."); , this is what I get: Start --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 0 Done. Actually - this is also wrong, as the second RMI call should be performed with the default timeout (500ms), but socket from the first RMI call was resused. If I ucomment also the second sleep, I get what this code really should do: Start --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 0 --> Created socket with soTimeout: 500 Got exception: java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: java.net.SocketTimeoutException: Read timed out java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: java.net.SocketTimeoutException: Read timed out at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:203) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133) at rmitest.RmiServer_Stub.rGetData(RmiServer_Stub.java:35) at rmitest.RmiClient.main(RmiClient.java:19) Caused by: java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:129) at java.io.BufferedInputStream.fill(BufferedInputStream.java:183) at java.io.BufferedInputStream.read(BufferedInputStream.java:201) at java.io.DataInputStream.readByte(DataInputStream.java:331) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:189) ... 3 more , and if I use the code like this: Thread.sleep(1); TimeoutableRMISocketFactory.setTimeout(0, true); rmiServer.rGetData("To je tudi en test."); Thread.sleep(1); TimeoutableRMISocketFactory.setTimeout(100, true); rmiServer.rGetData("To je tudi en test."); the result is also what I expected: Start --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 500 --> Created socket with soTimeout: 0 --> Created socket with soTimeout: 100 Got exception: java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: java.net.SocketTimeoutException: Read timed out java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: java.net.SocketTimeoutException: Read timed out at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:203) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133) at rmitest.RmiServer_Stub.rGetData(RmiServer_Stub.java:35) at rmitest.RmiClient.main(RmiClient.java:19) Caused by: java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:129) at java.io.BufferedInputStream.fill(BufferedInputStream.java:183) at java.io.BufferedInputStream.read(BufferedInputStream.java:201) at java.io.DataInputStream.readByte(DataInputStream.java:331) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:189) ... 3 more To make short things short: this is what I should get without calling Thread.sleep(1) in my code. This "workaround" is not really a workaround, as if the RmiClient was a multithreaded application, I couldn't rely on sleeping to disable connection reuse. Is there any other way to prevent RMI connection reuse, then setting sun.rmi.transport.connectionTimeout to zero?
|