PageRenderTime 67ms CodeModel.GetById 39ms RepoModel.GetById 0ms app.codeStats 0ms

/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java

https://github.com/ikeji/openjdk7-jdk
Java | 173 lines | 104 code | 23 blank | 46 comment | 10 complexity | 386951bb4bea58bc9ca6c5955d7f5876 MD5 | raw file
  1. /*
  2. * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4. *
  5. * This code is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 only, as
  7. * published by the Free Software Foundation.
  8. *
  9. * This code is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. * version 2 for more details (a copy is included in the LICENSE file that
  13. * accompanied this code).
  14. *
  15. * You should have received a copy of the GNU General Public License version
  16. * 2 along with this work; if not, write to the Free Software Foundation,
  17. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18. *
  19. * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20. * or visit www.oracle.com if you need additional information or have any
  21. * questions.
  22. */
  23. /* @test
  24. * @bug 4017232
  25. * @summary If, after returning a reference to a remote object in the current
  26. * VM (which gets implicitly converted to a remote stub), the client fails to
  27. * both send a DGC dirty call and to send a "DGC acknowledgment", the RMI
  28. * runtime should eventually allow the remote object to be garbage collected,
  29. * rather than pinning it indefinitely.
  30. * @author Peter Jones
  31. *
  32. * @build DGCAckFailure
  33. * @build DGCAckFailure_Stub
  34. * @run main/othervm DGCAckFailure
  35. */
  36. import java.io.*;
  37. import java.net.*;
  38. import java.lang.ref.*;
  39. import java.rmi.*;
  40. import java.rmi.server.*;
  41. interface ReturnRemote extends Remote {
  42. Object returnRemote() throws RemoteException;
  43. }
  44. public class DGCAckFailure implements ReturnRemote {
  45. private static final long TIMEOUT = 20000;
  46. public Object returnRemote() {
  47. return new Wrapper(this);
  48. }
  49. public static void main(String[] args) throws Exception {
  50. System.setProperty("sun.rmi.dgc.ackTimeout", "10000");
  51. /*
  52. * Set a socket factory that has a hook for shutting down all client
  53. * output (writes from client-created sockets and new connection
  54. * attempts). We then use this hook right before a remote stub gets
  55. * deserialized, so that the client will not be able to send a DGC
  56. * dirty call, or a DGC acknowledgment. Without the DGC ack, we
  57. * hope that the RMI runtime will still eventually allow the remote
  58. * object to be garbage collected.
  59. */
  60. RMISocketFactory.setSocketFactory(new TestSF());
  61. System.err.println("test socket factory set");
  62. Remote impl = new DGCAckFailure();
  63. ReferenceQueue refQueue = new ReferenceQueue();
  64. Reference weakRef = new WeakReference(impl, refQueue);
  65. ReturnRemote stub =
  66. (ReturnRemote) UnicastRemoteObject.exportObject(impl);
  67. System.err.println("remote object exported; stub = " + stub);
  68. try {
  69. Object wrappedStub = stub.returnRemote();
  70. System.err.println("invocation returned: " + wrappedStub);
  71. impl = null;
  72. stub = null; // in case 4114579 ever gets fixed
  73. System.err.println("strong references to impl cleared");
  74. System.err.println("waiting for weak reference notification:");
  75. Reference ref = null;
  76. for (int i = 0; i < 6; i++) {
  77. System.gc();
  78. ref = refQueue.remove(TIMEOUT / 5);
  79. if (ref != null) {
  80. break;
  81. }
  82. }
  83. if (ref == weakRef) {
  84. System.err.println("TEST PASSED");
  85. } else {
  86. throw new RuntimeException("TEST FAILED: " +
  87. "timed out, remote object not garbage collected");
  88. }
  89. } finally {
  90. try {
  91. UnicastRemoteObject.unexportObject((Remote) weakRef.get(),
  92. true);
  93. } catch (Exception e) {
  94. }
  95. }
  96. }
  97. private static class Wrapper implements Serializable {
  98. private final Remote obj;
  99. Wrapper(Remote obj) { this.obj = obj; }
  100. private void readObject(ObjectInputStream in)
  101. throws IOException, ClassNotFoundException
  102. {
  103. TestSF.shutdownClientOutput();
  104. System.err.println(
  105. "Wrapper.readObject: SHUTTING DOWN CLIENT OUTPUT");
  106. in.defaultReadObject();
  107. }
  108. public String toString() { return "Wrapper[" + obj + "]"; }
  109. }
  110. private static class TestSF extends RMISocketFactory {
  111. private static volatile boolean shutdown = false;
  112. static void shutdownClientOutput() { shutdown = true; }
  113. public Socket createSocket(String host, int port) throws IOException {
  114. if (shutdown) {
  115. IOException e = new java.net.ConnectException(
  116. "test socket factory rejecting client connection");
  117. System.err.println(e);
  118. // e.printStackTrace();
  119. throw e;
  120. } else {
  121. return new TestSocket(host, port);
  122. }
  123. }
  124. public ServerSocket createServerSocket(int port) throws IOException {
  125. return new ServerSocket(port);
  126. }
  127. private static class TestSocket extends Socket {
  128. TestSocket(String host, int port) throws IOException {
  129. super(host, port);
  130. }
  131. public OutputStream getOutputStream() throws IOException {
  132. return new TestOutputStream(super.getOutputStream());
  133. }
  134. }
  135. private static class TestOutputStream extends FilterOutputStream {
  136. TestOutputStream(OutputStream out) { super(out); }
  137. public void write(int b) throws IOException {
  138. if (shutdown) {
  139. IOException e = new IOException(
  140. "connection broken by test socket factory");
  141. System.err.println(e);
  142. // e.printStackTrace();
  143. throw e;
  144. } else {
  145. super.write(b);
  146. }
  147. }
  148. }
  149. }
  150. }