Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java
38828 views
1
/*
2
* Copyright (c) 2001, 2016, 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 4017232 8046339
26
* @summary If, after returning a reference to a remote object in the current
27
* VM (which gets implicitly converted to a remote stub), the client fails to
28
* both send a DGC dirty call and to send a "DGC acknowledgment", the RMI
29
* runtime should eventually allow the remote object to be garbage collected,
30
* rather than pinning it indefinitely.
31
* @author Peter Jones
32
*
33
* @build DGCAckFailure DGCAckFailure_Stub
34
* @run main/othervm DGCAckFailure
35
*/
36
37
import java.io.*;
38
import java.net.*;
39
import java.lang.reflect.Field;
40
import java.lang.ref.*;
41
42
import java.rmi.*;
43
import java.rmi.server.*;
44
import java.util.Map;
45
46
import sun.rmi.transport.DGCAckHandler;
47
48
interface ReturnRemote extends Remote {
49
Object returnRemote() throws RemoteException;
50
}
51
52
public class DGCAckFailure implements ReturnRemote {
53
54
private static final long TIMEOUT = 20000;
55
private static final long ACK_TIMEOUT = TIMEOUT / 2;
56
57
public Object returnRemote() {
58
return new Wrapper(this);
59
}
60
61
public static void main(String[] args) throws Exception {
62
63
System.setProperty("sun.rmi.dgc.ackTimeout",
64
Long.toString(ACK_TIMEOUT));
65
66
/*
67
* Set a socket factory that has a hook for shutting down all client
68
* output (writes from client-created sockets and new connection
69
* attempts). We then use this hook right before a remote stub gets
70
* deserialized, so that the client will not be able to send a DGC
71
* dirty call, or a DGC acknowledgment. Without the DGC ack, we
72
* hope that the RMI runtime will still eventually allow the remote
73
* object to be garbage collected.
74
*/
75
RMISocketFactory.setSocketFactory(new TestSF());
76
System.err.println("test socket factory set");
77
78
Remote impl = new DGCAckFailure();
79
ReferenceQueue refQueue = new ReferenceQueue();
80
Reference weakRef = new WeakReference(impl, refQueue);
81
ReturnRemote stub =
82
(ReturnRemote) UnicastRemoteObject.exportObject(impl);
83
System.err.println("remote object exported; stub = " + stub);
84
85
try {
86
Object wrappedStub = stub.returnRemote();
87
System.err.println("invocation returned: " + wrappedStub);
88
89
impl = null;
90
stub = null; // in case 4114579 ever gets fixed
91
System.err.println("strong references to impl cleared");
92
93
System.err.println("waiting for weak reference notification:");
94
Reference ref = null;
95
for (int i = 0; i < 6; i++) {
96
System.gc();
97
ref = refQueue.remove(TIMEOUT / 5);
98
if (ref != null) {
99
break;
100
}
101
}
102
if (ref != weakRef) {
103
throw new RuntimeException("TEST FAILED: " +
104
"timed out, remote object not garbage collected");
105
}
106
107
// 8046339
108
// All DGCAckHandlers must be properly released after timeout
109
Thread.sleep(ACK_TIMEOUT + 100);
110
try {
111
Field field =
112
DGCAckHandler.class.getDeclaredField("idTable");
113
field.setAccessible(true);
114
Object obj = field.get(null);
115
Map<?,?> idTable = (Map<?,?>)obj;
116
117
if (!idTable.isEmpty()) {
118
throw new RuntimeException("TEST FAILED: " +
119
"DGCAckHandler.idTable isn't empty");
120
}
121
} catch (ReflectiveOperationException roe) {
122
throw new RuntimeException(roe);
123
}
124
125
System.err.println("TEST PASSED");
126
127
} finally {
128
try {
129
UnicastRemoteObject.unexportObject((Remote) weakRef.get(),
130
true);
131
} catch (Exception e) {
132
}
133
}
134
}
135
136
private static class Wrapper implements Serializable {
137
private final Remote obj;
138
Wrapper(Remote obj) { this.obj = obj; }
139
140
private void readObject(ObjectInputStream in)
141
throws IOException, ClassNotFoundException
142
{
143
TestSF.shutdownClientOutput();
144
System.err.println(
145
"Wrapper.readObject: SHUTTING DOWN CLIENT OUTPUT");
146
in.defaultReadObject();
147
}
148
149
public String toString() { return "Wrapper[" + obj + "]"; }
150
}
151
152
private static class TestSF extends RMISocketFactory {
153
154
private static volatile boolean shutdown = false;
155
static void shutdownClientOutput() { shutdown = true; }
156
157
public Socket createSocket(String host, int port) throws IOException {
158
if (shutdown) {
159
IOException e = new java.net.ConnectException(
160
"test socket factory rejecting client connection");
161
System.err.println(e);
162
// e.printStackTrace();
163
throw e;
164
} else {
165
return new TestSocket(host, port);
166
}
167
}
168
169
public ServerSocket createServerSocket(int port) throws IOException {
170
return new ServerSocket(port);
171
}
172
173
private static class TestSocket extends Socket {
174
TestSocket(String host, int port) throws IOException {
175
super(host, port);
176
}
177
public OutputStream getOutputStream() throws IOException {
178
return new TestOutputStream(super.getOutputStream());
179
}
180
}
181
182
private static class TestOutputStream extends FilterOutputStream {
183
TestOutputStream(OutputStream out) { super(out); }
184
public void write(int b) throws IOException {
185
if (shutdown) {
186
IOException e = new IOException(
187
"connection broken by test socket factory");
188
System.err.println(e);
189
// e.printStackTrace();
190
throw e;
191
} else {
192
super.write(b);
193
}
194
}
195
}
196
}
197
}
198
199