/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6730926
* @summary Check behaviour of MBeanServer when postRegister and postDeregister
* throw exceptions.
* @author Daniel Fuchs
* @compile PostExceptionTest.java
* @run main PostExceptionTest
*/
import javax.management.*;
public class PostExceptionTest {
/**
* A test case where we instantiate an ExceptionalWombatMBean (or a
* subclass of it) which will throw the exception {@code t} from within
* the methods indicated by {@code where}
*/
public static class Case {
public final Throwable t;
}
}
// Various methods to create an instance of Case in a single line
// --------------------------------------------------------------
}
}
}
/**
* Here is the list of our test cases:
*/
};
"or postDeregister throw exceptions");
int failures = 0;
// We're going to test each cases, using each of the 4 createMBean
// forms + registerMBean in turn to create the MBean.
// Wich method is used to create the MBean is indicated by "how"
//
}
}
if (failures == 0)
else {
}
}
// Execute a test case composed of:
// mbs: The MBeanServer where the MBean will be registered,
// name: The name of that MBean
// how: How will the MBean be created/registered (which MBeanServer
// method)
// will be thrown
//
throws Exception {
int failures = 0;
try {
// Create the MBean
}
try {
// If the MBean is registered, unregister it
}
if (!isUnregistered) {
// if the MBean is still registered (preDeregister threw an
// exception) signify to the MBean that it now should stop
// throwing anaything and unregister it.
mbs.unregisterMBean(n);
}
// Now analyze the result. If we didn't ask the MBean to throw any
// exception then reg should be null.
reg);
throw new RuntimeException("Unexpected registration exception: "+
}
// If we didn't ask the MBean to throw any exception then unreg should
// also be null.
unreg);
throw new RuntimeException("Unexpected unregistration exception: "+
}
// If we asked the MBean to throw an exception in either of preRegister
// or postRegister, then reg should not be null.
"thrown by "+where);
throw new RuntimeException("Expected registration exception not " +
"thrown by "+where);
}
// If we asked the MBean not to throw any exception in preRegister
// then the MBean should have been registered, unregisterMBean should
// have been called.
// If we asked the MBean to throw an exception in either of preDeregister
// or postDeregister, then unreg should not be null.
"thrown by "+where);
throw new RuntimeException("Expected unregistration exception not " +
"thrown by "+where);
}
// If we asked the MBean to throw an exception in preRegister
// then the MBean should not have been registered.
if (isRegistered) {
throw new RuntimeException("MBean is still registered [" +
}
}
// If we asked the MBean not to throw an exception in preRegister,
// but to throw an exception in postRegister, then the MBean should
// have been registered.
if (!isRegistered) {
throw new RuntimeException("MBean is already unregistered [" +
}
}
// If we asked the MBean to throw an exception in preRegister,
// check that the exception we caught was as expected.
//
// If we asked the MBean to throw an exception in postRegister,
// check that the exception we caught was as expected.
// We don't do this check if we asked the MBean to also throw an
// exception in pre register, because postRegister will not have
// been called.
}
if (!isRegistered) return failures;
// The MBean was registered, so unregisterMBean was called. Check
// unregisterMBean exceptions...
//
// If we asked the MBean to throw an exception in preDeregister
// then the MBean should not have been deregistered.
if (isUnregistered) {
throw new RuntimeException("MBean is already unregistered [" +
}
}
// If we asked the MBean not to throw an exception in preDeregister,
// but to throw an exception in postDeregister, then the MBean should
// have been deregistered.
if (!isUnregistered) {
throw new RuntimeException("MBean is not unregistered [" +
}
}
// If we asked the MBean to throw an exception in preDeregister,
// check that the exception we caught was as expected.
//
// If we asked the MBean to throw an exception in postDeregister,
// check that the exception we caught was as expected.
// We don't do this check if we asked the MBean to also throw an
// exception in pre register, because postRegister will not have
// been called.
}
return failures;
}
/**
* This enum lists the 4 methods in MBeanRegistration.
*/
public static enum WHERE {
// Checks that an exception thrown by the MBeanServer correspond to
// what is expected when an MBean throws an exception in this
// MBeanRegistration method ("this" is one of the 4 enum values above)
//
throws Exception {
if (t instanceof RuntimeException) {
if (!(thrown instanceof RuntimeMBeanException)) {
thrown);
throw new Exception("Expected RuntimeMBeanException, got "+
thrown);
}
} else if (t instanceof Error) {
if (!(thrown instanceof RuntimeErrorException)) {
thrown);
throw new Exception("Expected RuntimeErrorException, got "+
thrown);
}
} else if (t instanceof Exception) {
if (!(thrown instanceof RuntimeMBeanException)) {
thrown);
throw new Exception("Expected RuntimeMBeanException, got "+
thrown);
}
"expected RuntimeException, " +
throw new Exception("Bad cause: " +
"expected RuntimeException, " +
}
}
if (!(thrown instanceof MBeanRegistrationException)) {
"MBeanRegistrationException, got "+
thrown);
throw new Exception("Expected " +
"MBeanRegistrationException, got "+
thrown);
}
"expected Exception, " +
throw new Exception("Bad cause: " +
"expected Exception, " +
}
}
}
}
}
/**
* This enum lists the 5 methods to create and register an
* ExceptionalWombat MBean
*/
public static enum CREATE {
CREATE1() {
// Creates an ExceptionalWombat MBean using createMBean form #1
ExceptionallyHackyWombat.t = t;
return server.createMBean(
ExceptionallyHackyWombat.class.getName(),
name);
}
},
CREATE2() {
// Creates an ExceptionalWombat MBean using createMBean form #2
ExceptionallyHackyWombat.t = t;
return server.createMBean(
ExceptionallyHackyWombat.class.getName(),
name, loaderName);
}
},
CREATE3() {
// Creates an ExceptionalWombat MBean using createMBean form #3
};
return server.createMBean(
}
},
CREATE4() {
// Creates an ExceptionalWombat MBean using createMBean form #4
};
return server.createMBean(
}
},
REGISTER() {
// Creates an ExceptionalWombat MBean using registerMBean
final ExceptionalWombat wombat =
new ExceptionalWombat(t, where);
}
};
// Creates an ExceptionalWombat MBean using the method denoted by this
// Enum value - one of CREATE1, CREATE2, CREATE3, CREATE4, or REGISTER.
// This is a bit of a hack - we use an MLet that delegates to the
// System ClassLoader so that we can use createMBean form #2 and #3
// while still using the same class loader (system).
// This is necessary to make the ExceptionallyHackyWombatMBean work ;-)
//
return name;
}
}
}
/**
*A Wombat MBean that can throw exceptions or errors in any of the
* MBeanRegistration methods.
*/
public static interface ExceptionalWombatMBean {
// Tells the MBean to stop throwing exceptions - we sometime
// need to call this at the end of the test so that we can
// actually unregister the MBean.
public void end();
}
/**
*A Wombat MBean that can throw exceptions or errors in any of the
* MBeanRegistration methods.
*/
public static class ExceptionalWombat
implements ExceptionalWombatMBean, MBeanRegistration {
private volatile boolean end=false;
}
if (throwable instanceof RuntimeException)
throw (RuntimeException)throwable;
}
throws Exception {
throw doThrow();
return name;
}
throw new RuntimeException(doThrow());
}
throw doThrow();
}
public void postDeregister() {
throw new RuntimeException(doThrow());
}
public void end() {
this.end=true;
}
}
/**
* This is a big ugly hack to call createMBean form #1 and #2 - where
* the empty constructor is used. Since we still want to supply parameters
* to the ExceptionalWombat super class, we temporarily store these
* parameter value in a static volatile before calling create MBean.
* Of course this only works because our test is sequential and single
* threaded, and nobody but our test uses this ExceptionallyHackyWombat.
*/
public static volatile Throwable t;
public ExceptionallyHackyWombat() {
super(t,w);
}
}
}