1 /* 2 * Copyright (c) 1998, 2012, 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 24 /* @test 25 * @bug 4164696 26 * @summary The local garbage collector needs to inspect a client VM's heap 27 * often enough (even if the VM is idle) to detect unreachable live remote 28 * references, so that their server VMs can be informed that the client VM 29 * is no longer holding a reference; this facilitates the server VM invoking 30 * the remote object's unreferenced() method (if present), garbage collecting 31 * the remote object, and allowing the server VM to exit. This test focuses 32 * on the unreferenced() method being invoked: it tests that the callback 33 * method will be invoked within a reasonable time after the remote object is 34 * no longer remotely reachable. 35 * @author Peter Jones 36 * 37 * @library ../../../testlibrary 38 * @modules java.rmi/sun.rmi.registry 39 * java.rmi/sun.rmi.server 40 * java.rmi/sun.rmi.transport 41 * java.rmi/sun.rmi.transport.tcp 42 * @build TestLibrary FiniteGCLatency_Stub 43 * @run main/othervm/timeout=120 FiniteGCLatency 44 */ 45 46 import java.rmi.*; 47 import java.rmi.registry.*; 48 import java.rmi.server.*; 49 50 public class FiniteGCLatency implements Remote, Unreferenced { 51 52 private final static String BINDING = "FiniteGCLatency"; 53 private final static long GC_INTERVAL = 6000; 54 private final static long TIMEOUT = 50000; 55 56 private Object lock = new Object(); 57 private boolean unreferencedInvoked = false; 58 59 public void unreferenced() { 60 System.err.println("unreferenced() method invoked"); 61 synchronized (lock) { 62 unreferencedInvoked = true; 63 lock.notify(); 64 } 65 } 66 67 public static void main(String[] args) { 68 69 System.err.println("\nRegression test for bug 4164696\n"); 70 71 /* 72 * Set the interval that RMI will request for GC latency (before RMI 73 * gets initialized and this property is read) to an unrealistically 74 * small value, so that this test shouldn't have to wait too long. 75 */ 76 System.setProperty("sun.rmi.dgc.client.gcInterval", 77 String.valueOf(GC_INTERVAL)); 78 79 FiniteGCLatency obj = new FiniteGCLatency(); 80 81 try { 82 UnicastRemoteObject.exportObject(obj); 83 System.err.println("exported remote object"); 84 Registry registry1 = TestLibrary.createRegistryOnUnusedPort(); 85 int port = TestLibrary.getRegistryPort(registry1); 86 System.err.println("created registry"); 87 88 Registry registry = LocateRegistry.getRegistry("", port); 89 registry.bind(BINDING, obj); 90 System.err.println("bound remote object in registry"); 91 92 synchronized (obj.lock) { 93 registry.unbind(BINDING); 94 System.err.println("unbound remote object from registry; " + 95 "waiting for unreferenced() callback..."); 96 obj.lock.wait(TIMEOUT); 97 98 if (obj.unreferencedInvoked) { 99 System.err.println("TEST PASSED: unreferenced() invoked"); 100 } else { 101 throw new RuntimeException( 102 "TEST FAILED: unrefereced() not invoked after " + 103 ((double) TIMEOUT / 1000.0) + " seconds"); 104 } 105 } 106 107 } catch (Exception e) { 108 if (e instanceof RuntimeException) { 109 throw (RuntimeException) e; 110 } else { 111 throw new RuntimeException( 112 "TEST FAILED: unexpected exception: " + e.toString()); 113 } 114 } finally { 115 /* 116 * When all is said and done, try to unexport the remote object 117 * so that the VM has a chance to exit. 118 */ 119 try { 120 UnicastRemoteObject.unexportObject(obj, true); 121 } catch (RemoteException e) { 122 } 123 } 124 } 125 }