1 /* 2 * Copyright (c) 1998, 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 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 * @build FiniteGCLatency 39 * @build FiniteGCLatency_Stub 40 * @run main/othervm/timeout=120 FiniteGCLatency 41 */ 42 43 import java.rmi.*; 44 import java.rmi.registry.*; 45 import java.rmi.server.*; 46 47 public class FiniteGCLatency implements Remote, Unreferenced { 48 49 private final static String BINDING = "FiniteGCLatency"; 50 private final static long GC_INTERVAL = 6000; 51 private final static long TIMEOUT = 50000; 52 53 private Object lock = new Object(); 54 private boolean unreferencedInvoked = false; 55 56 public void unreferenced() { 57 System.err.println("unreferenced() method invoked"); 58 synchronized (lock) { 59 unreferencedInvoked = true; 60 lock.notify(); 61 } 62 } 63 64 public static void main(String[] args) { 65 66 System.err.println("\nRegression test for bug 4164696\n"); 67 68 /* 69 * Set the interval that RMI will request for GC latency (before RMI 70 * gets initialized and this property is read) to an unrealistically 71 * small value, so that this test shouldn't have to wait too long. 72 */ 73 System.setProperty("sun.rmi.dgc.client.gcInterval", 74 String.valueOf(GC_INTERVAL)); 75 76 FiniteGCLatency obj = new FiniteGCLatency(); 77 78 try { 79 UnicastRemoteObject.exportObject(obj); 80 System.err.println("exported remote object"); 81 82 LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT); 83 System.err.println("created registry"); 84 85 Registry registry = LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT); 86 registry.bind(BINDING, obj); 87 System.err.println("bound remote object in registry"); 88 89 synchronized (obj.lock) { 90 registry.unbind(BINDING); 91 System.err.println("unbound remote object from registry; " + 92 "waiting for unreferenced() callback..."); 93 obj.lock.wait(TIMEOUT); 94 95 if (obj.unreferencedInvoked) { 96 System.err.println("TEST PASSED: unreferenced() invoked"); 97 } else { 98 throw new RuntimeException( 99 "TEST FAILED: unrefereced() not invoked after " + 100 ((double) TIMEOUT / 1000.0) + " seconds"); 101 } 102 } 103 104 } catch (Exception e) { 105 if (e instanceof RuntimeException) { 106 throw (RuntimeException) e; 107 } else { 108 throw new RuntimeException( 109 "TEST FAILED: unexpected exception: " + e.toString()); 110 } 111 } finally { 112 /* 113 * When all is said and done, try to unexport the remote object 114 * so that the VM has a chance to exit. 115 */ 116 try { 117 UnicastRemoteObject.unexportObject(obj, true); 118 } catch (RemoteException e) { 119 } 120 } 121 } 122 }