Path: blob/master/test/jdk/javax/management/MBeanServer/PreDeregisterDeadlockTest.java
51504 views
/*1* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 631866426* @summary Test deadlock in MBeanRegistration.preDeregister method27* @author Eamonn McManus28*29* @run clean PreDeregisterDeadlockTest30* @run build PreDeregisterDeadlockTest31* @run main PreDeregisterDeadlockTest32*/3334import java.util.concurrent.*;35import javax.management.*;3637public class PreDeregisterDeadlockTest {38public static interface BlibbyMBean {}3940public static class Blibby implements BlibbyMBean, MBeanRegistration {41public Blibby(MBeanServer mbs, ObjectName otherName) {42this.mbs = mbs;43this.otherName = otherName;44}4546public ObjectName preRegister(MBeanServer mbs, ObjectName on) {47return on;48}4950public void postRegister(Boolean done) {}5152public void preDeregister() {53if (otherName == null)54return;55try {56Thread t = new Thread() {57public void run() {58try {59mbs.unregisterMBean(otherName);60} catch (Throwable e) {61e.printStackTrace(System.out);62fail(e.toString());63}64}65};66t.start();67t.join(5000L);68if (t.isAlive())69fail("Deadlock detected");70} catch (Throwable e) {71e.printStackTrace(System.out);72fail(e.toString());73}74}7576public void postDeregister() {}7778private final MBeanServer mbs;79private final ObjectName otherName;80}8182public static interface BlobbyMBean {}8384public static class Blobby implements BlobbyMBean, MBeanRegistration {85public Blobby(MBeanServer mbs, Semaphore semaphore) {86this.mbs = mbs;87this.semaphore = semaphore;88}8990public ObjectName preRegister(MBeanServer mbs, ObjectName on) {91this.objectName = on;92return on;93}9495public void postRegister(Boolean done) {}9697public void preDeregister() throws Exception {98Thread t = new Thread() {99public void run() {100try {101mbs.unregisterMBean(objectName);102fail("Nested unregister succeeded");103} catch (InstanceNotFoundException e) {104semaphore.release();105} catch (Throwable e) {106e.printStackTrace(System.out);107fail(e.toString());108}109}110};111t.start();112// Give the thread a chance to block so we are really113// testing parallelism. (On slow machines we might not114// really be testing it but we should be covered by our115// faster machines.)116Thread.sleep(500L);117}118119public void postDeregister() {}120121private final MBeanServer mbs;122private ObjectName objectName;123private final Semaphore semaphore;124}125126public static void main(String[] args) throws Exception {127MBeanServer mbs = MBeanServerFactory.newMBeanServer();128ObjectName on1 = new ObjectName("a:type=Blibby,name=\"1\"");129ObjectName on2 = new ObjectName("a:type=Blibby,name=\"2\"");130131// Test 1: preDeregister starts a thread which unregisters a132// different MBean: this must not deadlock133mbs.registerMBean(new Blibby(mbs, on2), on1);134mbs.registerMBean(new Blibby(mbs, null), on2);135mbs.unregisterMBean(on1);136137// Test 2: preDeregister starts a thread which tries to138// unregister the same MBean: this thread should block until139// the original thread succeeds in unregistering, then140// get an InstanceNotFoundException. We wait for it to141// complete here, using the semaphore.142Semaphore semaphore = new Semaphore(0);143mbs.registerMBean(new Blobby(mbs, semaphore), on1);144mbs.unregisterMBean(on1);145boolean ok = semaphore.tryAcquire(1, 5, TimeUnit.SECONDS);146if (!ok)147fail("Second unregister thread did not complete");148149if (failure == null)150System.out.println("OK: Test passed");151else152throw new Exception("TEST FAILED: " + failure);153}154155private static void fail(String why) {156System.out.println("FAILED: " + why);157failure = why;158}159160private static volatile String failure;161}162163164