Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/management/MBeanServer/PostExceptionTest.java
41149 views
1
/*
2
* Copyright (c) 2008, 2015, 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
/*
25
* @test
26
* @bug 6730926
27
* @summary Check behaviour of MBeanServer when postRegister and postDeregister
28
* throw exceptions.
29
* @author Daniel Fuchs
30
*
31
* @run main PostExceptionTest
32
*/
33
34
import javax.management.*;
35
import java.io.Serializable;
36
import java.net.URL;
37
import java.util.EnumSet;
38
import javax.management.loading.MLet;
39
40
public class PostExceptionTest {
41
42
/**
43
* A test case where we instantiate an ExceptionalWombatMBean (or a
44
* subclass of it) which will throw the exception {@code t} from within
45
* the methods indicated by {@code where}
46
*/
47
public static class Case {
48
public final Throwable t;
49
public final EnumSet<WHERE> where;
50
public Case(Throwable t,EnumSet<WHERE> where) {
51
this.t=t; this.where=where;
52
}
53
}
54
55
// Various methods to create an instance of Case in a single line
56
// --------------------------------------------------------------
57
58
public static Case caze(Throwable t, WHERE w) {
59
return new Case(t,EnumSet.of(w));
60
}
61
public static Case caze(Throwable t, EnumSet<WHERE> where) {
62
return new Case(t,where);
63
}
64
public static Case caze(Throwable t, WHERE w, WHERE... rest) {
65
return new Case(t,EnumSet.of(w,rest));
66
}
67
68
/**
69
* Here is the list of our test cases:
70
*/
71
public static Case[] cases ={
72
caze(new RuntimeException(),WHERE.PREREGISTER),
73
caze(new RuntimeException(),WHERE.POSTREGISTER),
74
caze(new RuntimeException(),WHERE.POSTREGISTER, WHERE.PREDEREGISTER),
75
caze(new RuntimeException(),WHERE.POSTREGISTER, WHERE.POSTDEREGISTER),
76
caze(new Exception(),WHERE.PREREGISTER),
77
caze(new Exception(),WHERE.POSTREGISTER),
78
caze(new Exception(),WHERE.POSTREGISTER, WHERE.PREDEREGISTER),
79
caze(new Exception(),WHERE.POSTREGISTER, WHERE.POSTDEREGISTER),
80
caze(new Error(),WHERE.PREREGISTER),
81
caze(new Error(),WHERE.POSTREGISTER),
82
caze(new Error(),WHERE.POSTREGISTER, WHERE.PREDEREGISTER),
83
caze(new Error(),WHERE.POSTREGISTER, WHERE.POSTDEREGISTER),
84
caze(new RuntimeException(),EnumSet.allOf(WHERE.class)),
85
caze(new Exception(),EnumSet.allOf(WHERE.class)),
86
caze(new Error(),EnumSet.allOf(WHERE.class)),
87
};
88
89
public static void main(String[] args) throws Exception {
90
System.out.println("Test behaviour of MBeanServer when postRegister " +
91
"or postDeregister throw exceptions");
92
MBeanServer mbs = MBeanServerFactory.newMBeanServer();
93
int failures = 0;
94
final ObjectName n = new ObjectName("test:type=Wombat");
95
96
// We're going to test each cases, using each of the 4 createMBean
97
// forms + registerMBean in turn to create the MBean.
98
// Wich method is used to create the MBean is indicated by "how"
99
//
100
for (Case caze:cases) {
101
for (CREATE how : CREATE.values()) {
102
failures+=test(mbs,n,how,caze.t,caze.where);
103
}
104
}
105
if (failures == 0)
106
System.out.println("Test passed");
107
else {
108
System.out.println("TEST FAILED: " + failures + " failure(s)");
109
System.exit(1);
110
}
111
}
112
113
// Execute a test case composed of:
114
// mbs: The MBeanServer where the MBean will be registered,
115
// name: The name of that MBean
116
// how: How will the MBean be created/registered (which MBeanServer
117
// method)
118
// t: The exception/error that the MBean will throw
119
// where: In which pre/post register/deregister method the exception/error
120
// will be thrown
121
//
122
private static int test(MBeanServer mbs, ObjectName name, CREATE how,
123
Throwable t, EnumSet<WHERE> where)
124
throws Exception {
125
System.out.println("-------<"+how+"> / <"+t+"> / "+ where + "-------");
126
127
int failures = 0;
128
ObjectInstance oi = null;
129
Exception reg = null; // exception thrown by create/register
130
Exception unreg = null; // exception thrown by unregister
131
try {
132
// Create the MBean
133
oi = how.create(t, where, mbs, name);
134
} catch (Exception xx) {
135
reg=xx;
136
}
137
final ObjectName n = (oi==null)?name:oi.getObjectName();
138
final boolean isRegistered = mbs.isRegistered(n);
139
try {
140
// If the MBean is registered, unregister it
141
if (isRegistered) mbs.unregisterMBean(n);
142
} catch (Exception xxx) {
143
unreg=xxx;
144
}
145
final boolean isUnregistered = !mbs.isRegistered(n);
146
if (!isUnregistered) {
147
// if the MBean is still registered (preDeregister threw an
148
// exception) signify to the MBean that it now should stop
149
// throwing anaything and unregister it.
150
JMX.newMBeanProxy(mbs, n, ExceptionalWombatMBean.class).end();
151
mbs.unregisterMBean(n);
152
}
153
154
// Now analyze the result. If we didn't ask the MBean to throw any
155
// exception then reg should be null.
156
if (where.isEmpty() && reg!=null) {
157
System.out.println("Unexpected registration exception: "+
158
reg);
159
throw new RuntimeException("Unexpected registration exception: "+
160
reg,reg);
161
}
162
163
// If we didn't ask the MBean to throw any exception then unreg should
164
// also be null.
165
if (where.isEmpty() && unreg!=null) {
166
System.out.println("Unexpected unregistration exception: "+
167
unreg);
168
throw new RuntimeException("Unexpected unregistration exception: "+
169
unreg,unreg);
170
}
171
172
// If we asked the MBean to throw an exception in either of preRegister
173
// or postRegister, then reg should not be null.
174
if ((where.contains(WHERE.PREREGISTER)
175
|| where.contains(WHERE.POSTREGISTER))&& reg==null) {
176
System.out.println("Expected registration exception not " +
177
"thrown by "+where);
178
throw new RuntimeException("Expected registration exception not " +
179
"thrown by "+where);
180
}
181
182
// If we asked the MBean not to throw any exception in preRegister
183
// then the MBean should have been registered, unregisterMBean should
184
// have been called.
185
// If we asked the MBean to throw an exception in either of preDeregister
186
// or postDeregister, then unreg should not be null.
187
if ((where.contains(WHERE.PREDEREGISTER)
188
|| where.contains(WHERE.POSTDEREGISTER))&& unreg==null
189
&& !where.contains(WHERE.PREREGISTER)) {
190
System.out.println("Expected unregistration exception not " +
191
"thrown by "+where);
192
throw new RuntimeException("Expected unregistration exception not " +
193
"thrown by "+where);
194
}
195
196
// If we asked the MBean to throw an exception in preRegister
197
// then the MBean should not have been registered.
198
if (where.contains(WHERE.PREREGISTER)) {
199
if (isRegistered) {
200
System.out.println("MBean is still registered [" +
201
where+
202
"]: "+name+" / "+reg);
203
throw new RuntimeException("MBean is still registered [" +
204
where+
205
"]: "+name+" / "+reg,reg);
206
}
207
}
208
209
// If we asked the MBean not to throw an exception in preRegister,
210
// but to throw an exception in postRegister, then the MBean should
211
// have been registered.
212
if (where.contains(WHERE.POSTREGISTER) &&
213
!where.contains(WHERE.PREREGISTER)) {
214
if (!isRegistered) {
215
System.out.println("MBean is already unregistered [" +
216
where+
217
"]: "+name+" / "+reg);
218
throw new RuntimeException("MBean is already unregistered [" +
219
where+
220
"]: "+name+" / "+reg,reg);
221
}
222
}
223
224
// If we asked the MBean to throw an exception in preRegister,
225
// check that the exception we caught was as expected.
226
//
227
if (where.contains(WHERE.PREREGISTER)) {
228
WHERE.PREREGISTER.check(reg, t);
229
} else if (where.contains(WHERE.POSTREGISTER)) {
230
// If we asked the MBean to throw an exception in postRegister,
231
// check that the exception we caught was as expected.
232
// We don't do this check if we asked the MBean to also throw an
233
// exception in pre register, because postRegister will not have
234
// been called.
235
WHERE.POSTREGISTER.check(reg, t);
236
}
237
238
if (!isRegistered) return failures;
239
240
// The MBean was registered, so unregisterMBean was called. Check
241
// unregisterMBean exceptions...
242
//
243
244
// If we asked the MBean to throw an exception in preDeregister
245
// then the MBean should not have been deregistered.
246
if (where.contains(WHERE.PREDEREGISTER)) {
247
if (isUnregistered) {
248
System.out.println("MBean is already unregistered [" +
249
where+
250
"]: "+name+" / "+unreg);
251
throw new RuntimeException("MBean is already unregistered [" +
252
where+
253
"]: "+name+" / "+unreg,unreg);
254
}
255
}
256
257
// If we asked the MBean not to throw an exception in preDeregister,
258
// but to throw an exception in postDeregister, then the MBean should
259
// have been deregistered.
260
if (where.contains(WHERE.POSTDEREGISTER) &&
261
!where.contains(WHERE.PREDEREGISTER)) {
262
if (!isUnregistered) {
263
System.out.println("MBean is not unregistered [" +
264
where+
265
"]: "+name+" / "+unreg);
266
throw new RuntimeException("MBean is not unregistered [" +
267
where+
268
"]: "+name+" / "+unreg,unreg);
269
}
270
}
271
272
// If we asked the MBean to throw an exception in preDeregister,
273
// check that the exception we caught was as expected.
274
//
275
if (where.contains(WHERE.PREDEREGISTER)) {
276
WHERE.PREDEREGISTER.check(unreg, t);
277
} else if (where.contains(WHERE.POSTDEREGISTER)) {
278
// If we asked the MBean to throw an exception in postDeregister,
279
// check that the exception we caught was as expected.
280
// We don't do this check if we asked the MBean to also throw an
281
// exception in pre register, because postRegister will not have
282
// been called.
283
WHERE.POSTDEREGISTER.check(unreg, t);
284
}
285
return failures;
286
}
287
288
/**
289
* This enum lists the 4 methods in MBeanRegistration.
290
*/
291
public static enum WHERE {
292
293
PREREGISTER, POSTREGISTER, PREDEREGISTER, POSTDEREGISTER;
294
295
// Checks that an exception thrown by the MBeanServer correspond to
296
// what is expected when an MBean throws an exception in this
297
// MBeanRegistration method ("this" is one of the 4 enum values above)
298
//
299
public void check(Exception thrown, Throwable t)
300
throws Exception {
301
if (t instanceof RuntimeException) {
302
if (!(thrown instanceof RuntimeMBeanException)) {
303
System.out.println("Expected RuntimeMBeanException, got "+
304
thrown);
305
throw new Exception("Expected RuntimeMBeanException, got "+
306
thrown);
307
}
308
} else if (t instanceof Error) {
309
if (!(thrown instanceof RuntimeErrorException)) {
310
System.out.println("Expected RuntimeErrorException, got "+
311
thrown);
312
throw new Exception("Expected RuntimeErrorException, got "+
313
thrown);
314
}
315
} else if (t instanceof Exception) {
316
if (EnumSet.of(POSTDEREGISTER,POSTREGISTER).contains(this)) {
317
if (!(thrown instanceof RuntimeMBeanException)) {
318
System.out.println("Expected RuntimeMBeanException, got "+
319
thrown);
320
throw new Exception("Expected RuntimeMBeanException, got "+
321
thrown);
322
}
323
if (! (thrown.getCause() instanceof RuntimeException)) {
324
System.out.println("Bad cause: " +
325
"expected RuntimeException, " +
326
"got <"+thrown.getCause()+">");
327
throw new Exception("Bad cause: " +
328
"expected RuntimeException, " +
329
"got <"+thrown.getCause()+">");
330
}
331
}
332
if (EnumSet.of(PREDEREGISTER,PREREGISTER).contains(this)) {
333
if (!(thrown instanceof MBeanRegistrationException)) {
334
System.out.println("Expected " +
335
"MBeanRegistrationException, got "+
336
thrown);
337
throw new Exception("Expected " +
338
"MBeanRegistrationException, got "+
339
thrown);
340
}
341
if (! (thrown.getCause() instanceof Exception)) {
342
System.out.println("Bad cause: " +
343
"expected Exception, " +
344
"got <"+thrown.getCause()+">");
345
throw new Exception("Bad cause: " +
346
"expected Exception, " +
347
"got <"+thrown.getCause()+">");
348
}
349
}
350
}
351
352
}
353
}
354
355
/**
356
* This enum lists the 5 methods to create and register an
357
* ExceptionalWombat MBean
358
*/
359
public static enum CREATE {
360
361
CREATE1() {
362
// Creates an ExceptionalWombat MBean using createMBean form #1
363
public ObjectInstance create(Throwable t, EnumSet<WHERE> where,
364
MBeanServer server, ObjectName name) throws Exception {
365
ExceptionallyHackyWombat.t = t;
366
ExceptionallyHackyWombat.w = where;
367
return server.createMBean(
368
ExceptionallyHackyWombat.class.getName(),
369
name);
370
}
371
},
372
CREATE2() {
373
// Creates an ExceptionalWombat MBean using createMBean form #2
374
public ObjectInstance create(Throwable t, EnumSet<WHERE> where,
375
MBeanServer server, ObjectName name) throws Exception {
376
ExceptionallyHackyWombat.t = t;
377
ExceptionallyHackyWombat.w = where;
378
final ObjectName loaderName = registerMLet(server);
379
return server.createMBean(
380
ExceptionallyHackyWombat.class.getName(),
381
name, loaderName);
382
}
383
},
384
CREATE3() {
385
// Creates an ExceptionalWombat MBean using createMBean form #3
386
public ObjectInstance create(Throwable t, EnumSet<WHERE> where,
387
MBeanServer server, ObjectName name) throws Exception {
388
final Object[] params = {t, where};
389
final String[] signature = {Throwable.class.getName(),
390
EnumSet.class.getName()
391
};
392
return server.createMBean(
393
ExceptionalWombat.class.getName(), name,
394
params, signature);
395
}
396
},
397
CREATE4() {
398
// Creates an ExceptionalWombat MBean using createMBean form #4
399
public ObjectInstance create(Throwable t, EnumSet<WHERE> where,
400
MBeanServer server, ObjectName name) throws Exception {
401
final Object[] params = {t, where};
402
final String[] signature = {Throwable.class.getName(),
403
EnumSet.class.getName()
404
};
405
return server.createMBean(
406
ExceptionalWombat.class.getName(), name,
407
registerMLet(server), params, signature);
408
}
409
},
410
REGISTER() {
411
// Creates an ExceptionalWombat MBean using registerMBean
412
public ObjectInstance create(Throwable t, EnumSet<WHERE> where,
413
MBeanServer server, ObjectName name) throws Exception {
414
final ExceptionalWombat wombat =
415
new ExceptionalWombat(t, where);
416
return server.registerMBean(wombat, name);
417
}
418
};
419
420
// Creates an ExceptionalWombat MBean using the method denoted by this
421
// Enum value - one of CREATE1, CREATE2, CREATE3, CREATE4, or REGISTER.
422
public abstract ObjectInstance create(Throwable t, EnumSet<WHERE> where,
423
MBeanServer server, ObjectName name) throws Exception;
424
425
// This is a bit of a hack - we use an MLet that delegates to the
426
// System ClassLoader so that we can use createMBean form #2 and #3
427
// while still using the same class loader (system).
428
// This is necessary to make the ExceptionallyHackyWombatMBean work ;-)
429
//
430
public ObjectName registerMLet(MBeanServer server) throws Exception {
431
final ObjectName name = new ObjectName("test:type=MLet");
432
if (server.isRegistered(name)) {
433
return name;
434
}
435
final MLet mlet = new MLet(new URL[0],
436
ClassLoader.getSystemClassLoader());
437
return server.registerMBean(mlet, name).getObjectName();
438
}
439
}
440
441
/**
442
*A Wombat MBean that can throw exceptions or errors in any of the
443
* MBeanRegistration methods.
444
*/
445
public static interface ExceptionalWombatMBean {
446
// Tells the MBean to stop throwing exceptions - we sometime
447
// need to call this at the end of the test so that we can
448
// actually unregister the MBean.
449
public void end();
450
}
451
452
/**
453
*A Wombat MBean that can throw exceptions or errors in any of the
454
* MBeanRegistration methods.
455
*/
456
public static class ExceptionalWombat
457
implements ExceptionalWombatMBean, MBeanRegistration {
458
459
private final Throwable throwable;
460
private final EnumSet<WHERE> where;
461
private volatile boolean end=false;
462
463
public ExceptionalWombat(Throwable t, EnumSet<WHERE> where) {
464
this.throwable=t; this.where=where;
465
}
466
private Exception doThrow() {
467
if (throwable instanceof Error)
468
throw (Error)throwable;
469
if (throwable instanceof RuntimeException)
470
throw (RuntimeException)throwable;
471
return (Exception)throwable;
472
}
473
public ObjectName preRegister(MBeanServer server, ObjectName name)
474
throws Exception {
475
if (!end && where.contains(WHERE.PREREGISTER))
476
throw doThrow();
477
return name;
478
}
479
480
public void postRegister(Boolean registrationDone) {
481
if (!end && where.contains(WHERE.POSTREGISTER))
482
throw new RuntimeException(doThrow());
483
}
484
485
public void preDeregister() throws Exception {
486
if (!end && where.contains(WHERE.PREDEREGISTER))
487
throw doThrow();
488
}
489
490
public void postDeregister() {
491
if (!end && where.contains(WHERE.POSTREGISTER))
492
throw new RuntimeException(doThrow());
493
}
494
495
public void end() {
496
this.end=true;
497
}
498
}
499
500
/**
501
* This is a big ugly hack to call createMBean form #1 and #2 - where
502
* the empty constructor is used. Since we still want to supply parameters
503
* to the ExceptionalWombat super class, we temporarily store these
504
* parameter value in a static volatile before calling create MBean.
505
* Of course this only works because our test is sequential and single
506
* threaded, and nobody but our test uses this ExceptionallyHackyWombat.
507
*/
508
public static class ExceptionallyHackyWombat extends ExceptionalWombat {
509
public static volatile Throwable t;
510
public static volatile EnumSet<WHERE> w;
511
public ExceptionallyHackyWombat() {
512
super(t,w);
513
}
514
}
515
516
}
517
518