1/*
2 * Copyright (c) 2000, 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 * @summary When an object is retrieved from a MarshalledObject, callbacks
26 * that were registered by objects in the graph for execution when the
27 * unmarshalling is done should get executed.  This is verified by way of
28 * an exported object's stub getting unmarshalled, and then garbage
29 * collected, in which case the impl's unreferenced() method should get
30 * invoked.
31 * @author Peter Jones
32 *
33 * @build MarshalledObjectGet_Stub
34 * @run main/othervm/timeout=120 MarshalledObjectGet
35 */
36
37import java.rmi.MarshalledObject;
38import java.rmi.Remote;
39import java.rmi.server.UnicastRemoteObject;
40import java.rmi.server.Unreferenced;
41
42public class MarshalledObjectGet implements Remote, Unreferenced {
43
44    private static final String BINDING = "MarshalledObjectGet";
45    private static final long GC_INTERVAL = 6000;
46    private static final long TIMEOUT = 50000;
47
48    private Object lock = new Object();
49    private boolean unreferencedInvoked;
50
51    public void unreferenced() {
52        System.err.println("unreferenced() method invoked");
53        synchronized (lock) {
54            unreferencedInvoked = true;
55            lock.notify();
56        }
57    }
58
59    public static void main(String[] args) {
60
61        System.err.println(
62            "\nTest to verify correction interaction of " +
63            "MarshalledObject.get and DGC registration\n");
64
65        /*
66         * Set the interval that RMI will request for GC latency (before RMI
67         * gets initialized and this property is read) to an unrealistically
68         * small value, so that this test shouldn't have to wait too long.
69         */
70        System.setProperty("sun.rmi.dgc.client.gcInterval",
71            String.valueOf(GC_INTERVAL));
72
73        MarshalledObjectGet obj = new MarshalledObjectGet();
74
75        try {
76            Remote stub = UnicastRemoteObject.exportObject(obj);
77            System.err.println("exported remote object");
78
79            MarshalledObject mobj = new MarshalledObject(stub);
80            Remote unmarshalledStub = (Remote) mobj.get();
81            System.err.println("unmarshalled stub from marshalled object");
82
83            synchronized (obj.lock) {
84                obj.unreferencedInvoked = false;
85
86                unmarshalledStub = null;
87                System.gc();
88                System.err.println("cleared unmarshalled stub");
89                System.err.println("waiting for unreferenced() callback " +
90                                   "(SHOULD happen)...");
91                obj.lock.wait(TIMEOUT);
92
93                if (obj.unreferencedInvoked) {
94                    // TEST PASSED
95                } else {
96                    throw new RuntimeException(
97                        "TEST FAILED: unrefereced() not invoked after " +
98                        ((double) TIMEOUT / 1000.0) + " seconds");
99                }
100            }
101
102            System.err.println("TEST PASSED");
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            if (obj != null) {
113                try {
114                    UnicastRemoteObject.unexportObject(obj, true);
115                } catch (Exception e) {
116                }
117            }
118        }
119    }
120}
121