1/*
2 * Copyright (c) 2005, 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 6332349
26 * @summary Passing live remote references as part of the arguments of
27 * a remote invocation should not cause an AssertionError (on the
28 * second and subsequent attempts) when system assertions are enabled,
29 * nor should it cause the references to be pinned until a subsequent
30 * such remote invocation occurs (if the argument stream was not
31 * released cleanly because of a marshalling failure).
32 * @author Peter Jones
33 *
34 * @run main/othervm -esa PinLastArguments
35 */
36
37import java.io.NotSerializableException;
38import java.lang.ref.Reference;
39import java.lang.ref.WeakReference;
40import java.rmi.MarshalException;
41import java.rmi.Remote;
42import java.rmi.RemoteException;
43import java.rmi.server.UnicastRemoteObject;
44
45public class PinLastArguments {
46
47    public interface Ping extends Remote {
48        void ping(Object first, Object second) throws RemoteException;
49    }
50
51    private static class PingImpl implements Ping {
52        PingImpl() { }
53        public void ping(Object first, Object second) {
54            System.err.println("ping invoked: " + first + ", " + second);
55        }
56    }
57
58    public static void main(String[] args) throws Exception {
59        System.err.println("\nRegression test for bug 6332349\n");
60
61        Ping impl = new PingImpl();
62        Reference<?> ref = new WeakReference<Ping>(impl);
63        try {
64            Ping stub = (Ping) UnicastRemoteObject.exportObject(impl, 0);
65            Object notSerializable = new Object();
66            stub.ping(impl, null);
67            try {
68                stub.ping(impl, notSerializable);
69            } catch (MarshalException e) {
70                if (e.getCause() instanceof NotSerializableException) {
71                    System.err.println("ping invocation failed as expected");
72                } else {
73                    throw e;
74                }
75            }
76        } finally {
77            UnicastRemoteObject.unexportObject(impl, true);
78        }
79        impl = null;
80
81        // Might require multiple calls to System.gc() for weak-references
82        // processing to be complete. If the weak-reference is not cleared as
83        // expected we will hang here until timed out by the test harness.
84        while (true) {
85            System.gc();
86            Thread.sleep(20);
87            if (ref.get() == null) {
88                break;
89            }
90        }
91
92        System.err.println("TEST PASSED");
93    }
94}
95