8058865: JMX Test Refactoring

Reviewed-by: jbachorik
This commit is contained in:
Olivier Lagneau 2015-12-18 17:42:06 +01:00
parent 80015b7586
commit 1a8918d371
46 changed files with 8303 additions and 0 deletions

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.util.ArrayList;
import javax.management.AttributeNotFoundException;
import javax.management.BadAttributeValueExpException;
import javax.management.BadBinaryOpValueExpException;
import javax.management.BadStringOperationException;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.IntrospectionException;
import javax.management.InvalidApplicationException;
import javax.management.InvalidAttributeValueException;
import javax.management.JMException;
import javax.management.JMRuntimeException;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanRegistrationException;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.OperationsException;
import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
import javax.management.ServiceNotFoundException;
import javax.management.StringValueExp;
import javax.management.modelmbean.InvalidTargetObjectTypeException;
import javax.management.modelmbean.XMLParseException;
import javax.management.monitor.MonitorSettingException;
import javax.management.openmbean.InvalidKeyException;
import javax.management.openmbean.InvalidOpenTypeException;
import javax.management.openmbean.KeyAlreadyExistsException;
import javax.management.openmbean.OpenDataException;
import javax.management.relation.InvalidRelationIdException;
import javax.management.relation.InvalidRelationServiceException;
import javax.management.relation.InvalidRelationTypeException;
import javax.management.relation.InvalidRoleInfoException;
import javax.management.relation.InvalidRoleValueException;
import javax.management.relation.RelationException;
import javax.management.relation.RelationNotFoundException;
import javax.management.relation.RelationServiceNotRegisteredException;
import javax.management.relation.RelationTypeNotFoundException;
import javax.management.relation.RoleInfoNotFoundException;
import javax.management.relation.RoleNotFoundException;
import javax.management.remote.JMXProviderException;
import javax.management.remote.JMXServerErrorException;
/**
* |----- Original Description Coming From Tonga Original Source Code -------|
* | |
* | That class creates an ArrayList and fill it with an instance of each of |
* | the Exception class of the JMX API. |
* | It's dedicated to use by ExceptionTest. |
* |-------------------------------------------------------------------------|
*/
public class ExceptionFactory {
public static final ArrayList<Exception> exceptions =
new ArrayList<Exception>();
static {
String mes = "SQE";
exceptions.add(new AttributeNotFoundException());
exceptions.add(new BadAttributeValueExpException(mes));
exceptions.add(new BadBinaryOpValueExpException(new StringValueExp(mes)));
exceptions.add(new BadStringOperationException(mes));
exceptions.add(new InstanceAlreadyExistsException());
exceptions.add(new InstanceNotFoundException());
exceptions.add(new IntrospectionException());
exceptions.add(new InvalidApplicationException(mes));
exceptions.add(new InvalidAttributeValueException());
exceptions.add(new JMException());
exceptions.add(new JMRuntimeException());
exceptions.add(new ListenerNotFoundException());
exceptions.add(new MalformedObjectNameException());
exceptions.add(new MBeanException(new Exception(mes), mes));
exceptions.add(new MBeanRegistrationException(new Exception(mes), mes));
exceptions.add(new NotCompliantMBeanException());
exceptions.add(new OperationsException());
exceptions.add(new ReflectionException(new Exception(mes), mes));
exceptions.add(new RuntimeErrorException(new Error(mes), mes));
exceptions.add(new RuntimeMBeanException(new RuntimeException(mes), mes));
exceptions.add(new RuntimeOperationsException(new RuntimeException(mes), mes));
exceptions.add(new ServiceNotFoundException());
exceptions.add(new InvalidTargetObjectTypeException());
exceptions.add(new XMLParseException());
exceptions.add(new MonitorSettingException());
exceptions.add(new InvalidKeyException());
exceptions.add(new InvalidOpenTypeException());
exceptions.add(new KeyAlreadyExistsException());
exceptions.add(new OpenDataException());
exceptions.add(new InvalidRelationIdException());
exceptions.add(new InvalidRelationServiceException());
exceptions.add(new InvalidRelationTypeException());
exceptions.add(new InvalidRoleInfoException());
exceptions.add(new InvalidRoleValueException());
exceptions.add(new RelationException());
exceptions.add(new RelationNotFoundException());
exceptions.add(new RelationServiceNotRegisteredException());
exceptions.add(new RelationTypeNotFoundException());
exceptions.add(new RoleInfoNotFoundException());
exceptions.add(new RoleNotFoundException());
exceptions.add(new JMXProviderException());
exceptions.add(new JMXServerErrorException(mes, new Error(mes)));
ExceptionTest.Utils.debug(ExceptionTest.Utils.DEBUG_STANDARD,
"DataFactory::updateMap: Initialized" +
" an ArrayList with the " +
exceptions.size() + " exceptions of the JMX API");
}
}

View File

@ -0,0 +1,372 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8058865
* @summary Checks that exceptions are correctly wired (compared to reference).
* @author Olivier Lagneau
* @modules java.management
* @run main/othervm/timeout=300 -DDEBUG_STANDARD ExceptionTest
*/
import java.util.Map;
import java.util.HashMap;
import java.util.Properties;
import java.lang.reflect.Method;
import java.lang.management.ManagementFactory;
import javax.management.ObjectName;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
public class ExceptionTest {
/*
* First Debug properties and arguments are collect in expected
* map (argName, value) format, then calls original test's run method.
*/
public static void main(String args[]) throws Exception {
System.out.println("=================================================");
// Parses parameters
Utils.parseDebugProperties();
Map<String, Object> map = Utils.parseParameters(args) ;
// Run test
ExceptionTest test = new ExceptionTest();
test.run(map);
}
public void run(Map<String, Object> args) {
System.out.println("ExceptionTest::run: Start");
int errorCount = 0;
JMXConnectorServer cs = null;
JMXConnector cc = null;
try {
// JMX MbeanServer used inside single VM as if remote.
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
cs.start();
JMXServiceURL addr = cs.getAddress();
cc = JMXConnectorFactory.connect(addr);
MBeanServerConnection mbsc = cc.getMBeanServerConnection();
// ----
ObjectName objName =
new ObjectName(ExceptionThrower.EXCEPTION_THROWER_NAME);
System.out.println("ExceptionTest::run: Create and register MBean " + objName);
mbsc.createMBean("ExceptionThrower", objName);
System.out.println("---- OK\n");
// ----
System.out.println("ExceptionTest::run: Ask for exception(s)");
Object[] throwExceptionParam = new Object[1];
String[] throwExceptionSig = new String[]{"int"};
for (int i = 0; i < ExceptionFactory.exceptions.size(); i++) {
throwExceptionParam[0] = new Integer(i);
Exception ex =
(Exception)mbsc.invoke(objName,
"throwException", throwExceptionParam, throwExceptionSig);
if ( ! matches(ex, ExceptionFactory.exceptions.get(i)) ) {
errorCount++;
System.out.println("ExceptionTest::run: (ERROR) Received \n["
+ ex + "]\nin place of\n["
+ ExceptionFactory.exceptions.get(i) + "]");
} else {
System.out.println("OK [" + ex + "]");
}
}
System.out.println("---- DONE\n");
} catch (Exception e) {
Utils.printThrowable(e, true);
throw new RuntimeException();
} finally {
try {
// Close JMX Connector Client
cc.close();
// Stop connertor server
cs.stop();
} catch (Exception e) {
Utils.printThrowable(e, true);
throw new RuntimeException(
"Unable to either close connector client or stop connector server");
}
}
if (errorCount == 0) {
System.out.println("ExceptionTest::run: Done without any error");
} else {
System.out.println("ExceptionTest::run: Done with " + errorCount
+ " error(s)");
throw new RuntimeException("errorCount = " + errorCount);
}
System.out.println("ExceptionTest::run: Done");
}
// Check both Exception are identical.
// That means:
// - none is null.
// - they are of the same Class.
// - if their respective messages aren't null they're equal.
// - if the message of one is null the message of the other is null too.
private boolean matches(Exception ex, Exception refex) {
if ( ex == null || refex == null ) {
System.out.println("(ERROR) Called with one or more null parameter; check "
+ ex + " against " + refex);
return false;
}
String exClass = ex.getClass().getName();
String refexClass = refex.getClass().getName();
if ( ! exClass.equals(refexClass) ) {
System.out.println("(ERROR) Class names don't match; check ["
+ exClass + "] against [" + refexClass + "]");
return false;
}
String exMes = ex.getMessage();
String refexMes = refex.getMessage();
if ( exMes != null && refexMes != null ) {
if ( ! exMes.equals(refexMes) ) {
System.out.println("(ERROR) Non null messages don't match; check ["
+ exMes + "] against [" + refexMes + "]");
return false;
}
} else if ( (exMes == null && refexMes != null)
|| (exMes != null && refexMes == null) ) {
System.out.println("(ERROR) Messages don't match; check [" + exMes
+ "] against [" + refexMes + "]");
}
return true;
}
// Utility inner class coming from JMX Tonga test suite.
// Also used by ExceptionFactory.
static class Utils {
// DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
static final String DEBUG_HEADER = "[debug] ";
// DEBUG levels
static int selectedDebugLevel = 0;
static final int DEBUG_STANDARD = 1;
static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
static void parseDebugProperties() {
int level = 0;
Properties p = System.getProperties();
// get selected levels
if (p.getProperty("DEBUG_STANDARD") != null) {
level |= DEBUG_STANDARD;
}
if (p.getProperty("DEBUG_VERBOSE") != null) {
level |= DEBUG_VERBOSE;
}
if (p.getProperty("DEBUG_ALL") != null) {
level |= DEBUG_ALL;
}
selectedDebugLevel = level;
}
/**
* Reproduces the original parsing and collection of test parameters
* from the DTonga JMX test suite.
*
* Collects passed args and returns them in a map(argname, value) structure,
* which will be then propagated as necessary to various called methods.
*/
static Map<String, Object> parseParameters(String args[])
throws Exception {
debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
HashMap<String, Object> map = new HashMap<>();
for ( int i = 0; i < args.length; i++ ) {
if ( args[i].trim().startsWith("-") ) {
if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
debug(DEBUG_STANDARD,
"TestRoot::parseParameters: added in map = " +
args[i] +
" with value " +
args[i+1]) ;
map.put(args[i].trim(), args[i+1].trim()) ;
} else if ((i+1) < args.length && args[i+1].startsWith("-") ||
(i+1) == args.length ) {
debug(DEBUG_STANDARD,
"TestRoot::parseParameters: added in map = " +
args[i] +
" with null value") ;
map.put(args[i].trim(), null) ;
} else {
System.out.println(
"TestRoot::parseParameters: (WARNING) not added in map = " +
args[i]) ;
}
}
}
debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
return map ;
}
/**
* This method is to be used in all tests to print anything
* that is temporary.
* Printing is done only when debug is activated by the property DEBUG.
* Printing depends also on the DEBUG_LEVEL property.
* Here it encapsulates a System.out.println.
*/
static void debug(int level, String line) {
if ((selectedDebugLevel & level) != 0) {
System.out.println(DEBUG_HEADER + line);
}
}
/**
* Do print stack trace when withStack is true.
* Does try to call getTargetException() and getTargetError() then
* print embedded stacks in the case of an Exception wrapping
* another Exception or an Error. Recurse until no more wrapping
* is found.
*/
static void printThrowable(Throwable theThro, boolean withStack) {
try {
if (withStack) {
theThro.printStackTrace(System.out);
}
if (theThro instanceof Exception) {
Exception t = (Exception) theThro;
Method target = null;
String blank = " ";
try {
target = t.getClass().getMethod("getTargetException",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetException method could be there or not
}
System.out.println(blank + t.getClass() + "==>" + t.getMessage());
while (target != null) {
try {
t = (Exception) target.invoke(t,
(java.lang.Object[]) null);
} catch (Exception ee) {
t = null;
}
try {
if (t != null) {
blank = blank + " ";
System.out.println(blank + t.getClass() + "==>" +
t.getMessage());
try {
target =
t.getClass().getMethod("getTargetException",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetException method could be there or not }
}
} else {
target = null;
}
} catch (Exception ee) {
target = null;
}
}
// We may have exceptions wrapping an Error then it is
// getTargetError that is likely to be called
try {
target = ((Exception) theThro).getClass().getMethod("getTargetError",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetError method could be there or not
}
Throwable err = theThro;
while (target != null) {
try {
err = (Error) target.invoke(err,
(java.lang.Object[]) null);
} catch (Exception ee) {
err = null;
}
try {
if (err != null) {
blank = blank + " ";
System.out.println(blank + err.getClass() + "==>" +
err.getMessage());
if (withStack) {
err.printStackTrace(System.out);
}
try {
target = err.getClass().getMethod("getTargetError",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetError method could be there or not
}
} else {
target = null;
}
} catch (Exception ee) {
target = null;
}
}
} else {
System.out.println("Throwable is : " + theThro);
}
} catch (Throwable x) {
System.out.println("Exception : raised in printException : " + x);
}
}
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
/**
* This class defines a simple standard MBean.
*/
public class ExceptionThrower implements ExceptionThrowerMBean {
public static final String EXCEPTION_THROWER_NAME
= "sqe:type=ExceptionThrower";
public Exception throwException(int exceptionIndex) {
return ExceptionFactory.exceptions.get(exceptionIndex);
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
/**
* This interface defines a simple standard MBean.
*/
public interface ExceptionThrowerMBean {
public Exception throwException(int exceptionIndex);
}

View File

@ -0,0 +1,530 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.management.Descriptor;
import javax.management.ImmutableDescriptor;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationEmitter;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;
/**
* Class Basic
* Basic Description
*/
public class Basic implements BasicMXBean, NotificationEmitter,
MBeanRegistration {
public static final String EXCEPTION_MESSAGE = "from Basic";
public static final String NOTIFICATION_MESSAGE = "from Basic";
/** Attribute : IntAtt */
private int intAtt = 0;
/** Attribute : IntegerAtt */
private Integer integerAtt = 0;
/** Attribute : BoolAtt */
private boolean boolAtt = false;
/** Attribute : BooleanAtt */
private Boolean booleanAtt = false;
/** Attribute : StringAtt */
private String stringAtt = null;
/** Attribute : DateAtt */
private Date dateAtt = null;
/** Attribute : ObjectNameAtt */
private ObjectName objectNameAtt = null;
/** Attribute : NotifDescriptorAsMapAtt */
private Map<String, String> notifDescriptorAsMapAtt = null;
/** Attribute : NotifDescriptorAtt */
private Descriptor notifDescriptorAtt = null;
/** Attribute : SqeParameter */
private SqeParameter sqeParameterAtt = null;
/* Creates a new instance of Basic */
@SqeDescriptorKey("CONSTRUCTOR Basic")
public Basic() {
}
/* Creates a new instance of Basic */
@SqeDescriptorKey("CONSTRUCTOR Basic")
public Basic(
@SqeDescriptorKey("CONSTRUCTOR PARAMETER SqeParameter") SqeParameter param) {
}
/**
* Get int attribute
*/
public int getIntAtt() {
return intAtt;
}
/**
* Set int attribute
*/
public void setIntAtt(int value) {
intAtt = value;
}
/**
* Get Integer attribute
*/
public Integer getIntegerAtt() {
return integerAtt;
}
/**
* Set Integer attribute
*/
public void setIntegerAtt(Integer value) {
integerAtt = value;
}
/**
* Get boolean attribute
*/
public boolean getBoolAtt() {
return boolAtt;
}
/**
* Set boolean attribute
*/
public void setBoolAtt(boolean value) {
boolAtt = value;
}
/**
* Get Boolean attribute
*/
public Boolean getBooleanAtt() {
return booleanAtt;
}
/**
* Set Boolean attribute
*/
public void setBooleanAtt(Boolean value) {
booleanAtt = value;
}
/**
* Get String attribute
*/
public String getStringAtt() {
return stringAtt;
}
/**
* Set String attribute
*/
public void setStringAtt(String value) {
stringAtt = value;
}
/**
* Get Date attribute
*/
public Date getDateAtt() {
return dateAtt;
}
/**
* Set Date attribute
*/
public void setDateAtt(Date value) {
dateAtt = value;
}
/**
* Get ObjectName attribute
*/
public ObjectName getObjectNameAtt() {
return objectNameAtt;
}
/**
* Set ObjectName attribute
*/
public void setObjectNameAtt(ObjectName value) {
objectNameAtt = value;
}
/**
* Get SqeParameter attribute
*/
public SqeParameter getSqeParameterAtt() throws Exception {
if (sqeParameterAtt == null) {
sqeParameterAtt = new SqeParameter();
sqeParameterAtt.setGlop("INITIALIZED");
}
return sqeParameterAtt;
}
/**
* Set SqeParameter attribute
*/
public void setSqeParameterAtt(SqeParameter value) {
sqeParameterAtt = value;
}
/**
* Get the Descriptor used to build the NotificationInfo
* of emitted notifications.
*/
public Map<String, String> getNotifDescriptorAsMapAtt() {
if (notifDescriptorAsMapAtt == null) {
initNotifDescriptorAtt();
}
return notifDescriptorAsMapAtt;
}
/**
* Set the Descriptor used to build the NotificationInfo
* of emitted notifications.
* <br>A Map<String, Object> would better fit Descriptor needs but then
* it is not convertible according the MXBean specification so the MBean
* registration fails.
* As we plan to test our custom Descriptor finds its way into
* the metadata of emitted notifications, String is good enough.
*/
public void setNotifDescriptorAsMapAtt(Map<String, String> value) {
notifDescriptorAsMapAtt = new HashMap<String, String>(value);
notifDescriptorAtt = new ImmutableDescriptor(value);
}
/**
* Do nothing
*/
public void doNothing() {
// I said NOTHING !
}
/**
* Do take SqeParameter as a parameter
*/
public void doWeird(SqeParameter param) {
}
/**
* Throw an Exception
*/
public void throwException() throws Exception {
throw new Exception(EXCEPTION_MESSAGE);
}
/**
* Throw an Error
*/
public void throwError() {
throw new InternalError(EXCEPTION_MESSAGE);
}
/**
* Reset all attributes
*/
public void reset() {
intAtt = 0;
integerAtt = 0;
boolAtt = false;
booleanAtt = Boolean.FALSE;
stringAtt = null;
dateAtt = null;
objectNameAtt = null;
}
/**
* Returns the weather for the coming days
* @param verbose <code>boolean</code> verbosity
* @throws java.lang.Exception <code>storm</code>
* @return <code>ObjectName</code>
*/
public Weather getWeather(boolean verbose)
throws java.lang.Exception {
return Weather.SUNNY;
}
// Starting here are the 4 methods of MBeanRegistration interface.
// We use that to grab the ObjectName the MBean is registered with.
//
public ObjectName preRegister(MBeanServer server, ObjectName name)
throws Exception {
// Grab a reference on the MBeanServer we're registered in.
mbs = server;
// Compute the name we're registered with.
if (name != null) {
mbeanName = name;
return name;
} else {
mbeanName =
new ObjectName("sqe:type=" + Basic.class.getName());
return mbeanName;
}
}
public void postRegister(Boolean registrationDone) {
// Do nothing
}
public void preDeregister() throws Exception {
// Do nothing
}
public void postDeregister() {
// Do nothing
}
/**
* Send one Notification of the provided notifType type.
*/
public void sendNotification(String notifType) {
Notification notification = null;
if (notifType.equals(NOTIF_TYPE_0)) {
notification = new Notification(NOTIF_TYPE_0,
mbeanName,
seqNumber,
NOTIFICATION_MESSAGE);
} else if (notifType.equals(NOTIF_TYPE_1)) {
notification = new SqeNotification(NOTIF_TYPE_1,
mbeanName,
seqNumber,
NOTIFICATION_MESSAGE);
}
seqNumber++;
broadcaster.sendNotification(notification);
}
/**
* That method starts a set of threads, each thread sends a given number of
* notifications.
* The number of threads can be set via the attribute numOfNotificationSenders.
* The number of notification sent by each thread can be set via
* the attribute numOfNotificationSenderLoops.
* Depending on the parameter customNotification we send either custom
* notification(s) or MBeanServer registration and unregistration notification(s).
* When customNotification=true the total number of notification(s) sent is
* (numOfNotificationSenders * numOfNotificationSenderLoops). They are
* sequentially of type NOTIF_TYPE_0 then NOTIF_TYPE_1 and so on.
*
* When customNotification=false the total number of notification(s) sent is
* (numOfNotificationSenders * numOfNotificationSenderLoops) registration
* notification(s)
* +
* (numOfNotificationSenders * numOfNotificationSenderLoops) unregistration
* notification(s)
*
* @throws java.lang.Exception
*/
public void sendNotificationWave(boolean customNotification) throws
Exception {
// Build the set of notification sender.
Collection<Callable<Integer>> tasks =
new HashSet<Callable<Integer>>(numOfNotificationSenders);
for (int i = 1; i <= numOfNotificationSenders; i++) {
tasks.add(new NotifSender(numOfNotificationSenderLoops,
customNotification, i));
}
// Start all notification sender in parallel.
ExecutorService execServ = null;
try {
execServ = Executors.newFixedThreadPool(numOfNotificationSenders);
List<Future<Integer>> taskHandlers = execServ.invokeAll(tasks);
checkNotifSenderThreadStatus(taskHandlers);
} finally {
if (!execServ.isShutdown()) {
execServ.shutdown();
}
}
}
public void setNumOfNotificationSenders(int value) {
numOfNotificationSenders = value;
}
public void setNumOfNotificationSenderLoops(int value) {
numOfNotificationSenderLoops = value;
}
/**
* MBean Notification support
* You shouldn't update these methods
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">
public void addNotificationListener(NotificationListener listener,
NotificationFilter filter,
Object handback)
throws IllegalArgumentException {
broadcaster.addNotificationListener(listener, filter, handback);
}
public MBeanNotificationInfo[] getNotificationInfo() {
if (notifDescriptorAtt == null) {
initNotifDescriptorAtt();
}
return new MBeanNotificationInfo[]{
new MBeanNotificationInfo(new String[]{
NOTIF_TYPE_0
},
javax.management.Notification.class.getName(),
"Standard JMX Notification",
notifDescriptorAtt),
new MBeanNotificationInfo(new String[]{
NOTIF_TYPE_1
},
SqeNotification.class.getName(),
"SQE Notification",
notifDescriptorAtt)
};
}
public void removeNotificationListener(NotificationListener listener)
throws ListenerNotFoundException {
broadcaster.removeNotificationListener(listener);
}
public void removeNotificationListener(NotificationListener listener,
NotificationFilter filter,
Object handback)
throws ListenerNotFoundException {
broadcaster.removeNotificationListener(listener, filter, handback);
}
// </editor-fold>
private synchronized long getNextSeqNumber() {
return seqNumber++;
}
private void initNotifDescriptorAtt() {
String key = "CRABE";
String value = "TAMBOUR";
notifDescriptorAtt =
new ImmutableDescriptor(new String[]{key + "=" + value});
notifDescriptorAsMapAtt =
new HashMap<String, String>();
notifDescriptorAsMapAtt.put(key, value);
}
private void checkNotifSenderThreadStatus(
List<Future<Integer>> taskHandlers)
throws Exception {
String msgTag = "Basic::checkNotifSenderThreadStatus: ";
// Grab back status of each notification sender.
for (Future<Integer> f : taskHandlers) {
if (f.isCancelled()) {
String message = msgTag +
"---- ERROR : One thread has been cancelled";
System.out.println(message);
throw new RuntimeException(message);
} else {
Integer effectiveNumOfLoops = f.get();
if (effectiveNumOfLoops != numOfNotificationSenderLoops) {
String message = msgTag + "---- ERROR : One thread did " +
effectiveNumOfLoops + " loops in place of " +
numOfNotificationSenderLoops;
System.out.println(message);
throw new RuntimeException(message);
}
}
}
}
//
private int numOfNotificationSenderLoops = 2;
private int numOfNotificationSenders = 13;
private class NotifSender implements Callable<Integer> {
private int cycles;
private boolean customNotification;
private int senderID;
public NotifSender(int cycles, boolean customNotification, int id) {
this.cycles = cycles;
this.customNotification = customNotification;
this.senderID = id;
}
public Integer call() throws Exception {
int callsDone = 0;
try {
for (int i = 1; i <= cycles; i++) {
if (customNotification) {
if (i % 2 == 0) {
sendNotification(NOTIF_TYPE_0);
} else {
sendNotification(NOTIF_TYPE_1);
}
} else {
ObjectName mbeanName = new ObjectName("SQE:type=" +
mbeanClassName + ",senderID=" + senderID);
mbs.createMBean(mbeanClassName, mbeanName);
mbs.unregisterMBean(mbeanName);
}
callsDone++;
}
} catch (Exception e) {
System.out.println("NotifSender::call: (ERROR) Thread [" + senderID +
"] failed after " + callsDone + " cycles");
throw e;
}
return Integer.valueOf(callsDone);
}
}
//
private long seqNumber;
private final NotificationBroadcasterSupport broadcaster =
new NotificationBroadcasterSupport();
private ObjectName mbeanName;
private MBeanServer mbs;
private String mbeanClassName = "Simple";
/**
* Notification types definitions. To use when creating JMX Notifications.
*/
public static final String NOTIF_TYPE_0 =
"sqe.notification.a.type";
public static final String NOTIF_TYPE_1 =
"sqe.notification.b.type";
}

View File

@ -0,0 +1,203 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.util.Date;
import java.util.Map;
import javax.management.ObjectName;
/**
* Interface BasicMBean
* Basic Description
*/
@SqeDescriptorKey("INTERFACE BasicMXBean")
public interface BasicMXBean
{
/**
* Get int attribute
*/
@SqeDescriptorKey("ATTRIBUTE intAtt")
public int getIntAtt();
/**
* Set int attribute
*/
@SqeDescriptorKey("ATTRIBUTE intAtt")
public void setIntAtt(int value);
/**
* Get Integer attribute
*/
@SqeDescriptorKey("ATTRIBUTE integerAtt")
public Integer getIntegerAtt();
/**
* Set Integer attribute
*/
@SqeDescriptorKey("ATTRIBUTE integerAtt")
public void setIntegerAtt(Integer value);
/**
* Get boolean attribute
*/
@SqeDescriptorKey("ATTRIBUTE boolAtt")
public boolean getBoolAtt();
/**
* Set boolean attribute
*/
@SqeDescriptorKey("ATTRIBUTE boolAtt")
public void setBoolAtt(boolean value);
/**
* Get Boolean attribute
*/
@SqeDescriptorKey("ATTRIBUTE booleanAtt")
public Boolean getBooleanAtt();
/**
* Set Boolean attribute
*/
@SqeDescriptorKey("ATTRIBUTE booleanAtt")
public void setBooleanAtt(Boolean value);
/**
* Get String attribute
*/
@SqeDescriptorKey("ATTRIBUTE stringAtt")
public String getStringAtt();
/**
* Set String attribute
*/
@SqeDescriptorKey("ATTRIBUTE stringAtt")
public void setStringAtt(String value);
/**
* Get Date attribute
*/
@SqeDescriptorKey("ATTRIBUTE dateAtt")
public Date getDateAtt();
/**
* Set Date attribute
*/
@SqeDescriptorKey("ATTRIBUTE dateAtt")
public void setDateAtt(Date value);
/**
* Get ObjectName attribute
*/
@SqeDescriptorKey("ATTRIBUTE objectNameAtt")
public ObjectName getObjectNameAtt();
/**
* Set ObjectName attribute
*/
@SqeDescriptorKey("ATTRIBUTE objectNameAtt")
public void setObjectNameAtt(ObjectName value);
/**
* Get SqeParameter attribute
*/
@SqeDescriptorKey("ATTRIBUTE sqeParameterAtt")
public SqeParameter getSqeParameterAtt() throws Exception;
/**
* Set SqeParameter attribute
*/
@SqeDescriptorKey("ATTRIBUTE sqeParameterAtt")
public void setSqeParameterAtt(SqeParameter value);
/**
* Set NumOfNotificationSenders attribute
*/
@SqeDescriptorKey("ATTRIBUTE NumOfNotificationSenders")
public void setNumOfNotificationSenders(int value);
/**
* Set NumOfNotificationSenderLoops attribute
*/
@SqeDescriptorKey("ATTRIBUTE NumOfNotificationSenderLoops")
public void setNumOfNotificationSenderLoops(int value);
/**
* do nothing
*
*/
@SqeDescriptorKey("OPERATION doNothing")
public void doNothing();
/**
* Do take SqeParameter as a parameter
*/
@SqeDescriptorKey("OPERATION doWeird")
public void doWeird(@SqeDescriptorKey("METHOD PARAMETER")SqeParameter param);
/**
* throw an Exception
*
*/
@SqeDescriptorKey("OPERATION throwException")
public void throwException() throws Exception;
/**
* throw an Error
*
*/
@SqeDescriptorKey("OPERATION throwError")
public void throwError();
/**
* reset all attributes
*
*/
@SqeDescriptorKey("OPERATION reset")
public void reset();
/**
* returns the weather for the coming days
*
* @param verbose <code>boolean</code> verbosity
* @return <code>ObjectName</code>
*/
@SqeDescriptorKey("OPERATION getWeather")
public Weather getWeather(@SqeDescriptorKey("METHOD PARAMETER")boolean verbose)
throws java.lang.Exception;
public enum Weather {
CLOUDY, SUNNY
}
@SqeDescriptorKey("ATTRIBUTE notifDescriptorAsMapAtt")
public Map<String, String> getNotifDescriptorAsMapAtt();
@SqeDescriptorKey("ATTRIBUTE notifDescriptorAsMapAtt")
public void setNotifDescriptorAsMapAtt(Map<String, String> value);
@SqeDescriptorKey("OPERATION sendNotification")
public void sendNotification(@SqeDescriptorKey("METHOD PARAMETER")String notifType);
@SqeDescriptorKey("OPERATION sendNotificationWave")
public void sendNotificationWave(boolean customNotification) throws Exception;
}

View File

@ -0,0 +1,245 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8058865
* @summary Checks correct exception and error events from NotificationListener
* @author Olivier Lagneau
* @modules java.management
* @library /lib/testlibrary
* @compile Basic.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanExceptionHandlingTest -timeForNotificationInSeconds 3
*/
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.MBeanException;
import javax.management.MBeanServerDelegate;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.RuntimeErrorException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
public class MXBeanExceptionHandlingTest implements NotificationListener {
private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
private long timeForNotificationInSeconds = 3L;
private int numOfNotifications = 2;
private BlockingQueue<Notification> notifList = null;
/*
* First Debug properties and arguments are collect in expected
* map (argName, value) format, then calls original test's run method.
*/
public static void main(String args[]) throws Exception {
System.out.println("=================================================");
// Parses parameters
Utils.parseDebugProperties();
Map<String, Object> map = Utils.parseParameters(args) ;
// Run test
MXBeanExceptionHandlingTest test = new MXBeanExceptionHandlingTest();
test.run(map);
}
protected void parseArgs(Map<String, Object> args) throws Exception {
String arg = null;
// Init timeForNotificationInSeconds
// It is the maximum time in seconds we wait for a notification.
arg = (String)args.get("-timeForNotificationInSeconds") ;
if (arg != null) {
timeForNotificationInSeconds = (new Long(arg)).longValue();
}
}
public void run(Map<String, Object> args) {
System.out.println("MXBeanExceptionHandlingTest::run: Start") ;
int errorCount = 0 ;
try {
parseArgs(args);
notifList = new ArrayBlockingQueue<Notification>(numOfNotifications);
// JMX MbeanServer used inside single VM as if remote.
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
JMXConnectorServer cs =
JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
cs.start();
JMXServiceURL addr = cs.getAddress();
JMXConnector cc = JMXConnectorFactory.connect(addr);
MBeanServerConnection mbsc = cc.getMBeanServerConnection();
// ----
System.out.println("Add me as notification listener");
mbsc.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME,
this, null, null);
System.out.println("---- OK\n") ;
// ----
System.out.println("Create and register the MBean");
ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
System.out.println("---- OK\n") ;
// ----
System.out.println("Call method throwException on our MXBean");
try {
mbsc.invoke(objName, "throwException", null, null);
errorCount++;
System.out.println("(ERROR) Did not get awaited MBeanException") ;
} catch (MBeanException mbe) {
System.out.println("(OK) Got awaited MBeanException") ;
Throwable cause = mbe.getCause();
if ( cause instanceof java.lang.Exception ) {
System.out.println("(OK) Cause is of the right class") ;
String mess = cause.getMessage();
if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) {
System.out.println("(OK) Cause message is fine") ;
} else {
errorCount++;
System.out.println("(ERROR) Cause has message "
+ cause.getMessage()
+ " as we expect "
+ Basic.EXCEPTION_MESSAGE) ;
}
} else {
errorCount++;
System.out.println("(ERROR) Cause is of class "
+ cause.getClass().getName()
+ " as we expect java.lang.Exception") ;
}
} catch (Exception e) {
errorCount++;
System.out.println("(ERROR) Did not get awaited MBeanException but "
+ e) ;
Utils.printThrowable(e, true);
}
System.out.println("---- DONE\n") ;
// ----
System.out.println("Call method throwError on our MXBean");
try {
mbsc.invoke(objName, "throwError", null, null);
errorCount++;
System.out.println("(ERROR) Did not get awaited RuntimeErrorException") ;
} catch (RuntimeErrorException ree) {
System.out.println("(OK) Got awaited RuntimeErrorException") ;
Throwable cause = ree.getCause();
if ( cause instanceof java.lang.InternalError ) {
System.out.println("(OK) Cause is of the right class") ;
String mess = cause.getMessage();
if ( mess.equals(Basic.EXCEPTION_MESSAGE ) ) {
System.out.println("(OK) Cause message is fine") ;
} else {
errorCount++;
System.out.println("(ERROR) Cause has message "
+ cause.getMessage()
+ " as we expect "
+ Basic.EXCEPTION_MESSAGE) ;
}
} else {
errorCount++;
System.out.println("(ERROR) Cause is of class "
+ cause.getClass().getName()
+ " as we expect java.lang.InternalError") ;
}
} catch (Exception e) {
errorCount++;
System.out.println("(ERROR) Did not get awaited RuntimeErrorException but "
+ e) ;
Utils.printThrowable(e, true);
}
System.out.println("---- DONE\n") ;
// ----
System.out.println("Unregister the MBean");
mbsc.unregisterMBean(objName);
System.out.println("---- OK\n") ;
Thread.sleep(timeForNotificationInSeconds * 1000);
int numOfReceivedNotif = notifList.size();
if ( numOfReceivedNotif == numOfNotifications ) {
System.out.println("(OK) We received "
+ numOfNotifications
+ " Notifications") ;
} else {
errorCount++;
System.out.println("(ERROR) We received "
+ numOfReceivedNotif
+ " Notifications in place of "
+ numOfNotifications) ;
}
} catch(Exception e) {
Utils.printThrowable(e, true) ;
throw new RuntimeException(e);
}
if ( errorCount == 0 ) {
System.out.println("MXBeanExceptionHandlingTest::run: Done without any error") ;
} else {
System.out.println("MXBeanExceptionHandlingTest::run: Done with "
+ errorCount
+ " error(s)") ;
throw new RuntimeException("errorCount = " + errorCount);
}
}
public void handleNotification(Notification notification, Object handback) {
System.out.println("MXBeanExceptionHandlingTest::handleNotification: Received "
+ notification);
notifList.add(notification);
}
}

View File

@ -0,0 +1,638 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8058865
* @summary Test all MXBeans available by default on the platform
* @author Olivier Lagneau
* @modules java.management
* @library /lib/testlibrary
* @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest1
*/
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.CompilationMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryManagerMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import javax.management.JMX;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
public class MXBeanInteropTest1 {
/*
* First Debug properties and arguments are collect in expected
* map (argName, value) format, then calls original test's run method.
*/
public static void main(String args[]) throws Exception {
System.out.println("=================================================");
// Parses parameters
Utils.parseDebugProperties();
Map<String, Object> map = Utils.parseParameters(args) ;
// Run test
MXBeanInteropTest1 test = new MXBeanInteropTest1();
test.run(map);
}
public void run(Map<String, Object> args) {
System.out.println("MXBeanInteropTest1::run: Start") ;
int errorCount = 0 ;
try {
// JMX MbeanServer used inside single VM as if remote.
// MBeanServer mbs = MBeanServerFactory.newMBeanServer();
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
JMXConnectorServer cs =
JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
cs.start();
JMXServiceURL addr = cs.getAddress();
JMXConnector cc = JMXConnectorFactory.connect(addr);
MBeanServerConnection mbsc = cc.getMBeanServerConnection();
// Print out registered java.lang.management MXBeans found
// in the remote jvm.
printMBeans(mbsc) ;
// For each possible kind of JDK 5 defined MXBean, we retrieve its
// MBeanInfo and print it and we call all getters and print
// their output.
errorCount += doClassLoadingMXBeanTest(mbsc) ;
errorCount += doMemoryMXBeanTest(mbsc) ;
errorCount += doThreadMXBeanTest(mbsc) ;
errorCount += doRuntimeMXBeanTest(mbsc) ;
errorCount += doOperatingSystemMXBeanTest(mbsc) ;
errorCount += doCompilationMXBeanTest(mbsc) ;
errorCount += doGarbageCollectorMXBeanTest(mbsc) ;
errorCount += doMemoryManagerMXBeanTest(mbsc) ;
errorCount += doMemoryPoolMXBeanTest(mbsc) ;
// Terminate the JMX Client
cc.close();
} catch(Exception e) {
Utils.printThrowable(e, true) ;
throw new RuntimeException(e);
}
if ( errorCount == 0 ) {
System.out.println("MXBeanInteropTest1::run: Done without any error") ;
} else {
System.out.println("MXBeanInteropTest1::run: Done with "
+ errorCount
+ " error(s)") ;
throw new RuntimeException("errorCount = " + errorCount);
}
}
/**
* Prints all MBeans of domain java.lang.
* They are MBeans related to the JSR 174 that defines
* package java.lang.management.
*/
private static void printMBeans(MBeanServerConnection mbsc) throws Exception {
ObjectName filterName = new ObjectName("java.lang:*");
Set<ObjectName> set = mbsc.queryNames(filterName, null);
if ( set.size() == 0 ) {
throw new RuntimeException("(ERROR) No MBean found with filter "
+ filterName);
}
System.out.println("---- MBeans found in domain java.lang :");
for (Iterator<ObjectName> iter = set.iterator(); iter.hasNext(); ) {
System.out.println(iter.next().toString());
}
System.out.println("\n") ;
}
private final int doClassLoadingMXBeanTest(MBeanServerConnection mbsc) {
int errorCount = 0 ;
System.out.println("---- ClassLoadingMXBean") ;
try {
ObjectName classLoadingName =
new ObjectName(ManagementFactory.CLASS_LOADING_MXBEAN_NAME) ;
MBeanInfo mbInfo = mbsc.getMBeanInfo(classLoadingName);
errorCount += checkNonEmpty(mbInfo);
System.out.println("getMBeanInfo\t\t"
+ mbInfo);
ClassLoadingMXBean classLoading = null;
classLoading = JMX.newMXBeanProxy(mbsc,
classLoadingName,
ClassLoadingMXBean.class) ;
System.out.println("getLoadedClassCount\t\t"
+ classLoading.getLoadedClassCount());
System.out.println("getTotalLoadedClassCount\t\t"
+ classLoading.getTotalLoadedClassCount());
System.out.println("getUnloadedClassCount\t\t"
+ classLoading.getUnloadedClassCount());
System.out.println("isVerbose\t\t"
+ classLoading.isVerbose());
System.out.println("---- OK\n") ;
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++ ;
System.out.println("---- ERROR\n") ;
}
return errorCount ;
}
private final int doMemoryMXBeanTest(MBeanServerConnection mbsc) {
int errorCount = 0 ;
System.out.println("---- MemoryMXBean") ;
try {
ObjectName memoryName =
new ObjectName(ManagementFactory.MEMORY_MXBEAN_NAME) ;
MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryName);
errorCount += checkNonEmpty(mbInfo);
System.out.println("getMBeanInfo\t\t"
+ mbInfo);
MemoryMXBean memory = null ;
memory =
JMX.newMXBeanProxy(mbsc,
memoryName,
MemoryMXBean.class,
true) ;
System.out.println("getMemoryHeapUsage\t\t"
+ memory.getHeapMemoryUsage());
System.out.println("getNonHeapMemoryHeapUsage\t\t"
+ memory.getNonHeapMemoryUsage());
System.out.println("getObjectPendingFinalizationCount\t\t"
+ memory.getObjectPendingFinalizationCount());
System.out.println("isVerbose\t\t"
+ memory.isVerbose());
System.out.println("---- OK\n") ;
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++ ;
System.out.println("---- ERROR\n") ;
}
return errorCount ;
}
private final int doThreadMXBeanTest(MBeanServerConnection mbsc) {
int errorCount = 0 ;
System.out.println("---- ThreadMXBean") ;
try {
ObjectName threadName =
new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME) ;
MBeanInfo mbInfo = mbsc.getMBeanInfo(threadName);
errorCount += checkNonEmpty(mbInfo);
System.out.println("getMBeanInfo\t\t" + mbInfo);
ThreadMXBean thread = null ;
thread =
JMX.newMXBeanProxy(mbsc,
threadName,
ThreadMXBean.class) ;
System.out.println("findMonitorDeadlockedThreads\t\t"
+ thread.findMonitorDeadlockedThreads());
long[] threadIDs = thread.getAllThreadIds() ;
System.out.println("getAllThreadIds\t\t"
+ threadIDs);
for ( long threadID : threadIDs ) {
System.out.println("getThreadInfo long\t\t"
+ thread.getThreadInfo(threadID));
System.out.println("getThreadInfo long, int\t\t"
+ thread.getThreadInfo(threadID, 2));
}
System.out.println("getThreadInfo long[]\t\t"
+ thread.getThreadInfo(threadIDs));
System.out.println("getThreadInfo long[], int\t\t"
+ thread.getThreadInfo(threadIDs, 2));
System.out.println("getDaemonThreadCount\t\t"
+ thread.getDaemonThreadCount());
System.out.println("getPeakThreadCount\t\t"
+ thread.getPeakThreadCount());
System.out.println("getThreadCount\t\t"
+ thread.getThreadCount());
System.out.println("getTotalStartedThreadCount\t\t"
+ thread.getTotalStartedThreadCount());
boolean supported = thread.isThreadContentionMonitoringSupported() ;
System.out.println("isThreadContentionMonitoringSupported\t\t"
+ supported);
if ( supported ) {
System.out.println("isThreadContentionMonitoringEnabled\t\t"
+ thread.isThreadContentionMonitoringEnabled());
}
supported = thread.isThreadCpuTimeSupported() ;
System.out.println("isThreadCpuTimeSupported\t\t"
+ supported);
if ( supported ) {
System.out.println("isThreadCpuTimeEnabled\t\t"
+ thread.isThreadCpuTimeEnabled());
for (long id : threadIDs) {
System.out.println("getThreadCpuTime(" + id + ")\t\t"
+ thread.getThreadCpuTime(id));
System.out.println("getThreadUserTime(" + id + ")\t\t"
+ thread.getThreadUserTime(id));
}
}
supported = thread.isCurrentThreadCpuTimeSupported() ;
System.out.println("isCurrentThreadCpuTimeSupported\t\t"
+ supported);
if ( supported ) {
System.out.println("getCurrentThreadCpuTime\t\t"
+ thread.getCurrentThreadCpuTime());
System.out.println("getCurrentThreadUserTime\t\t"
+ thread.getCurrentThreadUserTime());
}
thread.resetPeakThreadCount() ;
System.out.println("---- OK\n") ;
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++ ;
System.out.println("---- ERROR\n") ;
}
return errorCount ;
}
private final int doRuntimeMXBeanTest(MBeanServerConnection mbsc) {
int errorCount = 0 ;
System.out.println("---- RuntimeMXBean") ;
try {
ObjectName runtimeName =
new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME) ;
MBeanInfo mbInfo = mbsc.getMBeanInfo(runtimeName);
errorCount += checkNonEmpty(mbInfo);
System.out.println("getMBeanInfo\t\t" + mbInfo);
RuntimeMXBean runtime = null;
runtime =
JMX.newMXBeanProxy(mbsc,
runtimeName,
RuntimeMXBean.class) ;
System.out.println("getClassPath\t\t"
+ runtime.getClassPath());
System.out.println("getInputArguments\t\t"
+ runtime.getInputArguments());
System.out.println("getLibraryPath\t\t"
+ runtime.getLibraryPath());
System.out.println("getManagementSpecVersion\t\t"
+ runtime.getManagementSpecVersion());
System.out.println("getName\t\t"
+ runtime.getName());
System.out.println("getSpecName\t\t"
+ runtime.getSpecName());
System.out.println("getSpecVendor\t\t"
+ runtime.getSpecVendor());
System.out.println("getSpecVersion\t\t"
+ runtime.getSpecVersion());
System.out.println("getStartTime\t\t"
+ runtime.getStartTime());
System.out.println("getSystemProperties\t\t"
+ runtime.getSystemProperties());
System.out.println("getUptime\t\t"
+ runtime.getUptime());
System.out.println("getVmName\t\t"
+ runtime.getVmName());
System.out.println("getVmVendor\t\t"
+ runtime.getVmVendor());
System.out.println("getVmVersion\t\t"
+ runtime.getVmVersion());
boolean supported = runtime.isBootClassPathSupported() ;
System.out.println("isBootClassPathSupported\t\t"
+ supported);
if ( supported ) {
System.out.println("getBootClassPath\t\t"
+ runtime.getBootClassPath());
}
System.out.println("---- OK\n") ;
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++ ;
System.out.println("---- ERROR\n") ;
}
return errorCount ;
}
private final int doOperatingSystemMXBeanTest(MBeanServerConnection mbsc) {
int errorCount = 0 ;
System.out.println("---- OperatingSystemMXBean") ;
try {
ObjectName operationName =
new ObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME) ;
MBeanInfo mbInfo = mbsc.getMBeanInfo(operationName);
errorCount += checkNonEmpty(mbInfo);
System.out.println("getMBeanInfo\t\t" + mbInfo);
OperatingSystemMXBean operation = null ;
operation =
JMX.newMXBeanProxy(mbsc,
operationName,
OperatingSystemMXBean.class) ;
System.out.println("getArch\t\t"
+ operation.getArch());
System.out.println("getAvailableProcessors\t\t"
+ operation.getAvailableProcessors());
System.out.println("getName\t\t"
+ operation.getName());
System.out.println("getVersion\t\t"
+ operation.getVersion());
System.out.println("---- OK\n") ;
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++ ;
System.out.println("---- ERROR\n") ;
}
return errorCount ;
}
private final int doCompilationMXBeanTest(MBeanServerConnection mbsc) {
int errorCount = 0 ;
System.out.println("---- CompilationMXBean") ;
try {
ObjectName compilationName =
new ObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME);
if ( mbsc.isRegistered(compilationName) ) {
MBeanInfo mbInfo = mbsc.getMBeanInfo(compilationName);
errorCount += checkNonEmpty(mbInfo);
System.out.println("getMBeanInfo\t\t" + mbInfo);
CompilationMXBean compilation = null ;
compilation =
JMX.newMXBeanProxy(mbsc,
compilationName,
CompilationMXBean.class) ;
System.out.println("getName\t\t"
+ compilation.getName());
boolean supported =
compilation.isCompilationTimeMonitoringSupported() ;
System.out.println("isCompilationTimeMonitoringSupported\t\t"
+ supported);
if ( supported ) {
System.out.println("getTotalCompilationTime\t\t"
+ compilation.getTotalCompilationTime());
}
}
System.out.println("---- OK\n") ;
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++ ;
System.out.println("---- ERROR\n") ;
}
return errorCount ;
}
private final int doGarbageCollectorMXBeanTest(MBeanServerConnection mbsc) {
int errorCount = 0 ;
System.out.println("---- GarbageCollectorMXBean") ;
try {
ObjectName filterName =
new ObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE
+ ",*");
Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
ObjectName garbageName = iter.next() ;
System.out.println("-------- " + garbageName) ;
MBeanInfo mbInfo = mbsc.getMBeanInfo(garbageName);
errorCount += checkNonEmpty(mbInfo);
System.out.println("getMBeanInfo\t\t" + mbInfo);
GarbageCollectorMXBean garbage = null ;
garbage =
JMX.newMXBeanProxy(mbsc,
garbageName,
GarbageCollectorMXBean.class) ;
System.out.println("getCollectionCount\t\t"
+ garbage.getCollectionCount());
System.out.println("getCollectionTime\t\t"
+ garbage.getCollectionTime());
}
System.out.println("---- OK\n") ;
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++ ;
System.out.println("---- ERROR\n") ;
}
return errorCount ;
}
private final int doMemoryManagerMXBeanTest(MBeanServerConnection mbsc) {
int errorCount = 0 ;
System.out.println("---- MemoryManagerMXBean") ;
try {
ObjectName filterName =
new ObjectName(ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE
+ ",*");
Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
ObjectName memoryManagerName = iter.next() ;
System.out.println("-------- " + memoryManagerName) ;
MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryManagerName);
System.out.println("getMBeanInfo\t\t" + mbInfo);
errorCount += checkNonEmpty(mbInfo);
MemoryManagerMXBean memoryManager = null;
memoryManager =
JMX.newMXBeanProxy(mbsc,
memoryManagerName,
MemoryManagerMXBean.class) ;
System.out.println("getMemoryPoolNames\t\t"
+ Arrays.deepToString(memoryManager.getMemoryPoolNames()));
System.out.println("getName\t\t"
+ memoryManager.getName());
System.out.println("isValid\t\t"
+ memoryManager.isValid());
}
System.out.println("---- OK\n") ;
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++ ;
System.out.println("---- ERROR\n") ;
}
return errorCount ;
}
private final int doMemoryPoolMXBeanTest(MBeanServerConnection mbsc) {
int errorCount = 0 ;
System.out.println("---- MemoryPoolMXBean") ;
try {
ObjectName filterName =
new ObjectName(ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE
+ ",*");
Set<ObjectName> onSet = mbsc.queryNames(filterName, null);
for (Iterator<ObjectName> iter = onSet.iterator(); iter.hasNext(); ) {
ObjectName memoryPoolName = iter.next() ;
System.out.println("-------- " + memoryPoolName) ;
MBeanInfo mbInfo = mbsc.getMBeanInfo(memoryPoolName);
errorCount += checkNonEmpty(mbInfo);
System.out.println("getMBeanInfo\t\t" + mbInfo);
MemoryPoolMXBean memoryPool = null;
memoryPool =
JMX.newMXBeanProxy(mbsc,
memoryPoolName,
MemoryPoolMXBean.class,
true) ;
System.out.println("getCollectionUsage\t\t"
+ memoryPool.getCollectionUsage());
System.out.println("getMemoryManagerNames\t\t"
+ Arrays.deepToString(memoryPool.getMemoryManagerNames()));
System.out.println("getName\t\t"
+ memoryPool.getName());
System.out.println("getPeakUsage\t\t"
+ memoryPool.getPeakUsage());
System.out.println("getType\t\t"
+ memoryPool.getType());
System.out.println("getUsage\t\t"
+ memoryPool.getUsage());
System.out.println("isValid\t\t"
+ memoryPool.isValid());
boolean supported = memoryPool.isUsageThresholdSupported() ;
System.out.println("isUsageThresholdSupported\t\t"
+ supported);
if ( supported ) {
System.out.println("getUsageThreshold\t\t"
+ memoryPool.getUsageThreshold());
System.out.println("isUsageThresholdExceeded\t\t"
+ memoryPool.isUsageThresholdExceeded());
System.out.println("getUsageThresholdCount\t\t"
+ memoryPool.getUsageThresholdCount());
}
supported = memoryPool.isCollectionUsageThresholdSupported() ;
System.out.println("isCollectionUsageThresholdSupported\t\t"
+ supported);
if ( supported ) {
System.out.println("getCollectionUsageThreshold\t\t"
+ memoryPool.getCollectionUsageThreshold());
System.out.println("getCollectionUsageThresholdCount\t\t"
+ memoryPool.getCollectionUsageThresholdCount());
System.out.println("isCollectionUsageThresholdExceeded\t\t"
+ memoryPool.isCollectionUsageThresholdExceeded());
}
memoryPool.resetPeakUsage();
}
System.out.println("---- OK\n") ;
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++ ;
System.out.println("---- ERROR\n") ;
}
return errorCount ;
}
private int checkNonEmpty(MBeanInfo mbi) {
if ( mbi.toString().length() == 0 ) {
System.out.println("(ERROR) MBeanInfo is empty !");
return 1;
} else {
return 0;
}
}
}

View File

@ -0,0 +1,217 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8058865
* @summary Checks access to test MXBean
* @author Olivier Lagneau
* @modules java.management
* @library /lib/testlibrary
* @compile Basic.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest2
*/
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.management.Attribute;
import javax.management.JMX;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanServer;
import java.lang.management.ManagementFactory;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
public class MXBeanInteropTest2 {
private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
/*
* First Debug properties and arguments are collect in expected
* map (argName, value) format, then calls original test's run method.
*/
public static void main(String args[]) throws Exception {
System.out.println("=================================================");
// Parses parameters
Utils.parseDebugProperties();
Map<String, Object> map = Utils.parseParameters(args) ;
// Run test
MXBeanInteropTest2 test = new MXBeanInteropTest2();
test.run(map);
}
public void run(Map<String, Object> args) {
System.out.println("MXBeanInteropTest2::run: Start") ;
int errorCount = 0 ;
try {
// JMX MbeanServer used inside single VM as if remote.
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
JMXConnectorServer cs =
JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
cs.start();
JMXServiceURL addr = cs.getAddress();
JMXConnector cc = JMXConnectorFactory.connect(addr);
MBeanServerConnection mbsc = cc.getMBeanServerConnection();
// Prints all MBeans whatever the domain is.
printMBeans(mbsc) ;
// Call test body
errorCount += doBasicMXBeanTest(mbsc) ;
// Terminate the JMX Client
cc.close();
} catch(Exception e) {
Utils.printThrowable(e, true) ;
throw new RuntimeException(e);
}
if ( errorCount == 0 ) {
System.out.println("MXBeanInteropTest2::run: Done without any error") ;
} else {
System.out.println("MXBeanInteropTest2::run: Done with "
+ errorCount
+ " error(s)") ;
throw new RuntimeException("errorCount = " + errorCount);
}
}
/**
* Prints all MBeans whatever the domain is.
*/
private static void printMBeans(MBeanServerConnection mbsc) throws Exception {
Set<ObjectName> set = mbsc.queryNames(null, null);
System.out.println("---- MBeans found :");
for (Iterator<ObjectName> iter = set.iterator(); iter.hasNext(); ) {
System.out.println(iter.next().toString());
}
System.out.println("\n") ;
}
private final int doBasicMXBeanTest(MBeanServerConnection mbsc) {
int errorCount = 0 ;
System.out.println("---- doBasicMXBeanTest") ;
try {
ObjectName objName =
new ObjectName("sqe:type=BasicMXBean") ;
mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
MBeanInfo mbInfo = mbsc.getMBeanInfo(objName);
printMBeanInfo(mbInfo);
System.out.println("---- OK\n") ;
System.out.println("getMBeanInfo\t\t"
+ mbInfo);
System.out.println("---- OK\n") ;
System.out.println("Check mxbean field in the MBeanInfo");
String mxbeanField =
(String)mbInfo.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD);
if ( mxbeanField == null || ! mxbeanField.equals("true")) {
System.out.println("---- ERROR : Improper mxbean field value "
+ mxbeanField);
errorCount++;
}
System.out.println("---- OK\n") ;
System.out.println("Set attribute ObjectNameAtt");
Attribute att = new Attribute("ObjectNameAtt", objName);
mbsc.setAttribute(objName, att);
ObjectName value =
(ObjectName)mbsc.getAttribute(objName, "ObjectNameAtt");
if ( ! value.equals(objName) ) {
errorCount++;
System.out.println("---- ERROR : setAttribute failed, got "
+ value
+ " while expecting "
+ objName);
}
System.out.println("---- OK\n") ;
System.out.println("Call operation doNothing");
mbsc.invoke(objName, "doNothing", null, null);
System.out.println("---- OK\n") ;
System.out.println("Call operation getWeather");
Object weather = mbsc.invoke(objName,
"getWeather",
new Object[]{Boolean.TRUE},
new String[]{"boolean"});
System.out.println("Weather is " + weather);
System.out.println("---- OK\n") ;
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++ ;
System.out.println("---- ERROR\n") ;
}
return errorCount ;
}
private void printMBeanInfo(MBeanInfo mbInfo) {
System.out.println("Description " + mbInfo.getDescription());
for (MBeanConstructorInfo ctor : mbInfo.getConstructors()) {
System.out.println("Constructor " + ctor.getName());
}
for (MBeanAttributeInfo att : mbInfo.getAttributes()) {
System.out.println("Attribute " + att.getName()
+ " [" + att.getType() + "]");
}
for (MBeanOperationInfo oper : mbInfo.getOperations()) {
System.out.println("Operation " + oper.getName());
}
for (MBeanNotificationInfo notif : mbInfo.getNotifications()) {
System.out.println("Notification " + notif.getName());
}
}
}

View File

@ -0,0 +1,329 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8058865
* @summary Checks correct collection of MXBean's class after unregistration
* @author Olivier Lagneau
* @modules java.management
* @library /lib/testlibrary
* @run main/othervm/timeout=300 MXBeanLoadingTest1
*/
import java.lang.ref.WeakReference;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Map;
import javax.management.Attribute;
import javax.management.JMX;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MXBean;
import javax.management.ObjectName;
import javax.management.loading.PrivateMLet;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
public class MXBeanLoadingTest1 {
public static void main(String[] args) throws Exception {
MXBeanLoadingTest1 test = new MXBeanLoadingTest1();
test.run((Map<String, Object>)null);
}
public void run(Map<String, Object> args) {
System.out.println("MXBeanLoadingTest1::run: Start") ;
try {
System.out.println("We ensure no reference is retained on MXBean class"
+ " after it is unregistered. We take time to perform"
+ " some little extra check of Descriptors, MBean*Info.");
ClassLoader myClassLoader = MXBeanLoadingTest1.class.getClassLoader();
if (!(myClassLoader instanceof URLClassLoader)) {
String message = "(ERROR) Test's class loader is not " +
"a URLClassLoader";
System.out.println(message);
throw new RuntimeException(message);
}
URLClassLoader myURLClassLoader = (URLClassLoader) myClassLoader;
URL[] urls = myURLClassLoader.getURLs();
PrivateMLet mlet = new PrivateMLet(urls, null, false);
Class<?> shadowClass = mlet.loadClass(TestMXBean.class.getName());
if (shadowClass == TestMXBean.class) {
String message = "(ERROR) MLet got original TestMXBean, not shadow";
System.out.println(message);
throw new RuntimeException(message);
}
shadowClass = null;
MBeanServer mbs = MBeanServerFactory.createMBeanServer();
ObjectName mletName = new ObjectName("x:type=mlet");
mbs.registerMBean(mlet, mletName);
ObjectName testName = new ObjectName("x:type=test");
mbs.createMBean(Test.class.getName(), testName, mletName);
// That test fails because the MXBean instance is accessed via
// a delegate OpenMBean which has
ClassLoader testLoader = mbs.getClassLoaderFor(testName);
if (testLoader != mlet) {
System.out.println("MLet " + mlet);
String message = "(ERROR) MXBean's class loader is not MLet: "
+ testLoader;
System.out.println(message);
throw new RuntimeException(message);
}
testLoader = null;
// Cycle get/set/get of the attribute of type Luis.
// We check the set is effective.
CompositeData cd_B = (CompositeData)mbs.getAttribute(testName, "B");
CompositeType compType_B = cd_B.getCompositeType();
CompositeDataSupport cds_B =
new CompositeDataSupport(compType_B,
new String[]{"something"},
new Object[]{Integer.valueOf(13)});
Attribute myAtt = new Attribute("B", cds_B);
mbs.setAttribute(testName, myAtt);
CompositeData cd_B2 = (CompositeData)mbs.getAttribute(testName, "B");
if ( ((Integer)cd_B2.get("something")).intValue() != 13 ) {
String message = "(ERROR) The setAttribute of att B did not work;"
+ " expect Luis.something = 13 but got "
+ cd_B2.get("something");
System.out.println(message);
throw new RuntimeException(message);
}
MBeanInfo info = mbs.getMBeanInfo(testName);
String mxbeanField =
(String)info.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD);
if ( mxbeanField == null || ! mxbeanField.equals("true")) {
String message = "(ERROR) Improper mxbean field value "
+ mxbeanField;
System.out.println(message);
throw new RuntimeException(message);
}
// Check the 2 attributes.
MBeanAttributeInfo[] attrs = info.getAttributes();
if ( attrs.length == 2 ) {
for (MBeanAttributeInfo mbai : attrs) {
String originalTypeFieldValue =
(String)mbai.getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD);
OpenType<?> openTypeFieldValue =
(OpenType<?>)mbai.getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD);
if ( mbai.getName().equals("A") ) {
if ( !mbai.isReadable() || !mbai.isWritable()
|| mbai.isIs()
|| !mbai.getType().equals("int") ) {
String message = "(ERROR) Unexpected MBeanAttributeInfo for A "
+ mbai;
System.out.println(message);
throw new RuntimeException(message);
}
if ( ! originalTypeFieldValue.equals("int") ) {
String message = "(ERROR) Unexpected originalType in Descriptor for A "
+ originalTypeFieldValue;
System.out.println(message);
throw new RuntimeException(message);
}
if ( ! openTypeFieldValue.equals(SimpleType.INTEGER) ) {
String message = "(ERROR) Unexpected openType in Descriptor for A "
+ originalTypeFieldValue;
System.out.println(message);
throw new RuntimeException(message);
}
} else if ( mbai.getName().equals("B") ) {
if ( !mbai.isReadable() || !mbai.isWritable()
|| mbai.isIs()
|| !mbai.getType().equals("javax.management.openmbean.CompositeData") ) {
String message = "(ERROR) Unexpected MBeanAttributeInfo for B "
+ mbai;
System.out.println(message);
throw new RuntimeException(message);
}
if ( ! originalTypeFieldValue.equals(Luis.class.getName()) ) {
String message = "(ERROR) Unexpected originalType in Descriptor for B "
+ originalTypeFieldValue;
System.out.println(message);
throw new RuntimeException(message);
}
if ( ! openTypeFieldValue.equals(compType_B) ) {
String message = "(ERROR) Unexpected openType in Descriptor for B "
+ compType_B;
System.out.println(message);
throw new RuntimeException(message);
}
} else {
String message = "(ERROR) Unknown attribute name";
System.out.println(message);
throw new RuntimeException(message);
}
}
} else {
String message = "(ERROR) Unexpected MBeanAttributeInfo array"
+ Arrays.deepToString(attrs);
System.out.println(message);
throw new RuntimeException(message);
}
// Check the MXBean operation.
MBeanOperationInfo[] ops = info.getOperations();
// The impact is ACTION_INFO as for a standard MBean it is UNKNOWN,
// logged 6320104.
if (ops.length != 1 || !ops[0].getName().equals("bogus")
|| ops[0].getSignature().length > 0
|| !ops[0].getReturnType().equals("void")) {
String message = "(ERROR) Unexpected MBeanOperationInfo array "
+ Arrays.deepToString(ops);
System.out.println(message);
throw new RuntimeException(message);
}
String originalTypeFieldValue =
(String)ops[0].getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD);
OpenType<?> openTypeFieldValue =
(OpenType<?>)ops[0].getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD);
if ( ! originalTypeFieldValue.equals("void") ) {
String message = "(ERROR) Unexpected originalType in Descriptor for bogus "
+ originalTypeFieldValue;
System.out.println(message);
throw new RuntimeException(message);
}
if ( ! openTypeFieldValue.equals(SimpleType.VOID) ) {
String message = "(ERROR) Unexpected openType in Descriptor for bogus "
+ originalTypeFieldValue;
System.out.println(message);
throw new RuntimeException(message);
}
// Check there is 2 constructors.
if (info.getConstructors().length != 2) {
String message = "(ERROR) Wrong number of constructors " +
"in introspected bean: " +
Arrays.asList(info.getConstructors());
System.out.println(message);
throw new RuntimeException(message);
}
// Check MXBean class name.
if (!info.getClassName().endsWith("Test")) {
String message = "(ERROR) Wrong info class name: " +
info.getClassName();
System.out.println(message);
throw new RuntimeException(message);
}
mbs.unregisterMBean(testName);
mbs.unregisterMBean(mletName);
WeakReference<PrivateMLet> mletRef =
new WeakReference<PrivateMLet>(mlet);
mlet = null;
System.out.println("MXBean registered and unregistered, waiting for " +
"garbage collector to collect class loader");
for (int i = 0; i < 10000 && mletRef.get() != null; i++) {
System.gc();
Thread.sleep(1);
}
if (mletRef.get() == null)
System.out.println("(OK) class loader was GC'd");
else {
String message = "(ERROR) Class loader was not GC'd";
System.out.println(message);
throw new RuntimeException(message);
}
} catch(Exception e) {
Utils.printThrowable(e, true) ;
throw new RuntimeException(e);
}
System.out.println("MXBeanLoadingTest1::run: Done without any error") ;
}
// I agree the use of the MXBean annotation and the MXBean suffix for the
// interface name are redundant but however harmless.
//
@MXBean(true)
public static interface TestMXBean {
public void bogus();
public int getA();
public void setA(int a);
public Luis getB();
public void setB(Luis mi);
}
public static class Test implements TestMXBean {
private Luis luis = new Luis() ;
public Test() {}
public Test(int x) {}
public void bogus() {}
public int getA() {return 0;}
public void setA(int a) {}
public Luis getB() {return this.luis;}
public void setB(Luis luis) {this.luis = luis;}
}
public static class Luis {
private int something = 0;
public Luis() {}
public int getSomething() {return something;}
public void setSomething(int v) {something = v;}
public void doNothing() {}
}
}

View File

@ -0,0 +1,385 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8058865
* @summary Checks MXBean proper registration both as its implementation class and interface
* @author Olivier Lagneau
* @modules java.management
* @library /lib/testlibrary
* @compile Basic.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanNotifTest -numOfNotifications 239 -timeForNotificationInSeconds 4
*/
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.lang.management.ManagementFactory;
import javax.management.Attribute;
import javax.management.Descriptor;
import javax.management.ImmutableDescriptor;
import javax.management.MBeanServer;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
public class MXBeanNotifTest implements NotificationListener {
private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
private static String BASIC_MXBEAN_INTERFACE_NAME = "BasicMXBean";
private long timeForNotificationInSeconds = 3L;
private int numOfNotifications = 1;
private BlockingQueue<Notification> notifList = null;
private int numOfNotifDescriptorElements = 13;
/*
* First Debug properties and arguments are collect in expected
* map (argName, value) format, then calls original test's run method.
*/
public static void main(String args[]) throws Exception {
System.out.println("=================================================");
// Parses parameters
Utils.parseDebugProperties();
Map<String, Object> map = Utils.parseParameters(args) ;
// Run test
MXBeanNotifTest test = new MXBeanNotifTest();
test.run(map);
}
protected void parseArgs(Map<String, Object> args) throws Exception {
String arg = null;
// Init numOfNotifications
// It is the number of notifications we should trigger and check.
arg = (String)args.get("-numOfNotifications") ;
if (arg != null) {
numOfNotifications = (new Integer(arg)).intValue();
}
// Init timeForNotificationInSeconds
// It is the maximum time in seconds we wait for each notification.
arg = (String)args.get("-timeForEachNotificationInSeconds") ;
if (arg != null) {
timeForNotificationInSeconds = (new Long(arg)).longValue();
}
}
public void run(Map<String, Object> args) {
System.out.println("MXBeanNotifTest::run: Start") ;
int errorCount = 0 ;
try {
parseArgs(args);
notifList = new ArrayBlockingQueue<Notification>(numOfNotifications);
// JMX MbeanServer used inside single VM as if remote.
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
JMXConnectorServer cs =
JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
cs.start();
JMXServiceURL addr = cs.getAddress();
JMXConnector cc = JMXConnectorFactory.connect(addr);
MBeanServerConnection mbsc = cc.getMBeanServerConnection();
// ----
System.out.println("MXBeanNotifTest::run: Create and register the MBean");
ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
System.out.println("---- OK\n") ;
// ----
System.out.println("MXBeanNotifTest::run: Add me as notification listener");
mbsc.addNotificationListener(objName, this, null, null);
// ----
System.out.println("MXBeanNotifTest::run: Retrieve the Descriptor"
+ " that should be in MBeanNotificationInfo");
TabularData tabData =
(TabularData)mbsc.getAttribute(objName, "NotifDescriptorAsMapAtt");
Map<String, String> descrMap = new HashMap<>();
for (Iterator<?> it = tabData.values().iterator(); it.hasNext(); ) {
CompositeData compData = (CompositeData)it.next();
descrMap.put((String)compData.get("key"),
(String)compData.get("value"));
}
Descriptor refNotifDescriptor = new ImmutableDescriptor(descrMap);
System.out.println("---- OK\n") ;
// ----
// Because the MBean holding the targeted attribute is MXBean, we
// should use for the setAttribute a converted form for the
// attribute value as described by the MXBean mapping rules.
// This explains all that lovely stuff for creating a
// TabularDataSupport.
//
// WARNING : the MBeanInfo of the MXBean used on opposite side
// is computed when the MBean is registered.
// It means the Descriptor considered for the MBeanNotificationInfo
// is not the one we set in the lines below, it is too late.
// However, we check that set is harmless when we check
// the MBeanNotificationInfo.
//
System.out.println("MXBeanNotifTest::run: Set a Map<String, String>"
+ " attribute");
String typeName =
"java.util.Map<java.lang.String,java.lang.String>";
String[] keyValue = new String[] {"key", "value"};
OpenType<?>[] openTypes =
new OpenType<?>[] {SimpleType.STRING, SimpleType.STRING};
CompositeType rowType = new CompositeType(typeName, typeName,
keyValue, keyValue, openTypes);
TabularType tabType = new TabularType(typeName, typeName,
rowType, new String[]{"key"});
TabularDataSupport convertedDescrMap =
new TabularDataSupport(tabType);
for (int i = 0; i < numOfNotifDescriptorElements; i++) {
Object[] descrValue = {"field" + i, "value" + i};
CompositeData data =
new CompositeDataSupport(rowType, keyValue, descrValue);
convertedDescrMap.put(data);
}
Attribute descrAtt =
new Attribute("NotifDescriptorAsMapAtt", convertedDescrMap);
mbsc.setAttribute(objName, descrAtt);
System.out.println("---- OK\n") ;
// ----
System.out.println("MXBeanNotifTest::run: Compare the Descriptor from"
+ " the MBeanNotificationInfo against a reference");
MBeanInfo mbInfo = mbsc.getMBeanInfo(objName);
errorCount += checkMBeanInfo(mbInfo, refNotifDescriptor);
System.out.println("---- DONE\n") ;
// ----
System.out.println("Check isInstanceOf(Basic)");
if ( ! mbsc.isInstanceOf(objName, BASIC_MXBEAN_CLASS_NAME) ) {
errorCount++;
System.out.println("---- ERROR isInstanceOf returned false\n") ;
} else {
System.out.println("---- OK\n") ;
}
// ----
System.out.println("Check isInstanceOf(BasicMXBean)");
if ( ! mbsc.isInstanceOf(objName, BASIC_MXBEAN_INTERFACE_NAME) ) {
errorCount++;
System.out.println("---- ERROR isInstanceOf returned false\n") ;
} else {
System.out.println("---- OK\n") ;
}
// ----
System.out.println("MXBeanNotifTest::run: Ask for "
+ numOfNotifications + " notification(s)");
Object[] sendNotifParam = new Object[1];
String[] sendNotifSig = new String[]{"java.lang.String"};
for (int i = 0; i < numOfNotifications; i++) {
// Select which type of notification we ask for
if ( i % 2 == 0 ) {
sendNotifParam[0] = Basic.NOTIF_TYPE_0;
} else {
sendNotifParam[0] = Basic.NOTIF_TYPE_1;
}
// Trigger notification emission
mbsc.invoke(objName,
"sendNotification",
sendNotifParam,
sendNotifSig);
// Wait for it then check it when it comes early enough
Notification notif =
notifList.poll(timeForNotificationInSeconds,
TimeUnit.SECONDS) ;
// The very first notification is likely to come in slower than
// all the others. Because that test isn't targeting the speed
// notifications are delivered with, we prefer to secure it.
if (i == 0 && notif == null) {
System.out.println("MXBeanNotifTest::run: Wait extra "
+ timeForNotificationInSeconds + " second(s) the "
+ " very first notification");
notif = notifList.poll(timeForNotificationInSeconds,
TimeUnit.SECONDS);
}
if ( notif == null ) {
errorCount++;
System.out.println("---- ERROR No notification received"
+ " within allocated " + timeForNotificationInSeconds
+ " second(s) !");
} else {
errorCount +=
checkNotification(notif,
(String)sendNotifParam[0],
Basic.NOTIFICATION_MESSAGE,
objName);
}
}
int toc = 0;
while ( notifList.size() < 2 && toc < 10 ) {
Thread.sleep(499);
toc++;
}
System.out.println("---- DONE\n") ;
} catch(Exception e) {
Utils.printThrowable(e, true) ;
throw new RuntimeException(e);
}
if ( errorCount == 0 ) {
System.out.println("MXBeanNotifTest::run: Done without any error") ;
} else {
System.out.println("MXBeanNotifTest::run: Done with "
+ errorCount
+ " error(s)") ;
throw new RuntimeException("errorCount = " + errorCount);
}
}
private int checkMBeanInfo(MBeanInfo mbi, Descriptor refDescr) {
MBeanNotificationInfo[] notifsInfo = mbi.getNotifications();
int res = 0;
for (MBeanNotificationInfo mbni : notifsInfo) {
if ( mbni.getDescriptor().equals(refDescr) ) {
System.out.println("(OK)");
} else {
System.out.println("(ERROR) Descriptor of the notification is "
+ mbni.getDescriptor()
+ " as we expect "
+ refDescr);
res++;
}
}
return res;
}
private int checkNotification(Notification notif,
String refType,
String refMessage,
ObjectName refSource) {
int res = 0;
Utils.debug(Utils.DEBUG_VERBOSE,
"\t getSource " + notif.getSource());
Utils.debug(Utils.DEBUG_VERBOSE,
"\t getMessage " + notif.getMessage());
Utils.debug(Utils.DEBUG_VERBOSE,
"\t getSequenceNumber " + notif.getSequenceNumber());
Utils.debug(Utils.DEBUG_VERBOSE,
"\t getTimeStamp " + notif.getTimeStamp());
Utils.debug(Utils.DEBUG_VERBOSE,
"\t getType " + notif.getType());
Utils.debug(Utils.DEBUG_VERBOSE,
"\t getUserData " + notif.getUserData());
if ( ! notif.getType().equals(refType) ) {
res++;
System.out.println("(ERROR) Type is not "
+ refType + " in notification\n" + notif);
} else {
if ( notif.getType().equals(Basic.NOTIF_TYPE_0)
&& ! (notif instanceof javax.management.Notification) ) {
res++;
System.out.println("(ERROR) Notification is not instance of "
+ " javax.management.Notification but rather "
+ notif.getClass().getName());
} else if ( notif.getType().equals(Basic.NOTIF_TYPE_1)
&& ! (notif instanceof SqeNotification) ) {
res++;
System.out.println("(ERROR) Notification is not instance of "
+ " javasoft.sqe.jmx.share.SqeNotification but rather "
+ notif.getClass().getName());
}
}
if ( ! notif.getMessage().equals(refMessage) ) {
res++;
System.out.println("(ERROR) Message is not "
+ refMessage + " in notification\n" + notif);
}
if ( ! notif.getSource().equals(refSource) ) {
res++;
System.out.println("(ERROR) Source is not "
+ refSource + " in notification\n" + notif);
}
return res;
}
public void handleNotification(Notification notification, Object handback) {
Utils.debug(Utils.DEBUG_VERBOSE,
"MXBeanNotifTest::handleNotification: Received "
+ notification);
notifList.add(notification);
}
}

View File

@ -0,0 +1,277 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8058865
* @summary Checks that a serialized instance is not transmitted from an MXBean.
* All the communication should be done via Open Types
* @author Olivier Lagneau
* @modules java.management
* @library /lib/testlibrary
* @compile Basic.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanWeirdParamTest
*/
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.lang.Process;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.JDKToolFinder;
public class MXBeanWeirdParamTest {
private static String BASIC_MXBEAN_CLASS_NAME = "Basic";
private static final String CLIENT_CLASS_MAIN =
"MXBeanWeirdParamTest$ClientSide";
private JMXConnectorServer cs;
/*
* First Debug properties and arguments are collect in expected
* map (argName, value) format, then calls original test's run method.
*/
public static void main(String args[]) throws Exception {
System.out.println("=================================================");
// Parses parameters
Utils.parseDebugProperties();
Map<String, Object> map = Utils.parseParameters(args) ;
// Run test
MXBeanWeirdParamTest test = new MXBeanWeirdParamTest();
test.run(map);
}
/*
* Create the MBeansServe side of the test and returns its address
*/
private JMXServiceURL createServerSide() throws Exception {
final int NINETY_SECONDS = 90;
// We will use the platform mbean server
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
cs.start();
Utils.waitReady(cs, NINETY_SECONDS);
JMXServiceURL addr = cs.getAddress();
return addr;
}
/*
* Creating command-line for running subprocess JVM:
*
* JVM command line is like:
* {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
*
* {defaultopts} are the default java options set by the framework.
*
*/
private List<String> buildCommandLine() {
List<String> opts = new ArrayList<>();
opts.add(JDKToolFinder.getJDKTool("java"));
opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
// We need to set WEIRD_PARAM propertty on the client-side
opts.add("-DWEIRD_PARAM");
opts.add("-cp");
opts.add(System.getProperty("test.class.path", "test.class.path"));
opts.add(CLIENT_CLASS_MAIN);
return opts;
}
/**
* Runs MXBeanWeirdParamTest$ClientSide with the passed options and redirects
* subprocess standard I/O to the current (parent) process. This provides a
* trace of what happens in the subprocess while it is runnning (and before
* it terminates).
*
* @param serviceUrlStr string representing the JMX service Url to connect to.
*/
private int runClientSide(String serviceUrlStr) throws Exception {
// Building command-line
List<String> opts = buildCommandLine();
opts.add(serviceUrlStr);
// Launch separate JVM subprocess
int exitCode = 0;
String[] optsArray = opts.toArray(new String[0]);
ProcessBuilder pb = new ProcessBuilder(optsArray);
Process p = ProcessTools.startProcess("MXBeanWeirdParamTest$ClientSide", pb);
// Handling end of subprocess
try {
exitCode = p.waitFor();
if (exitCode != 0) {
System.out.println(
"Subprocess unexpected exit value of [" + exitCode +
"]. Expected 0.\n");
}
} catch (InterruptedException e) {
System.out.println("Parent process interrupted with exception : \n " + e + " :" );
// Parent thread unknown state, killing subprocess.
p.destroyForcibly();
throw new RuntimeException(
"Parent process interrupted with exception : \n " + e + " :" );
} finally {
return exitCode;
}
}
public void run(Map<String, Object> args) throws Exception {
System.out.println("MXBeanWeirdParamTest::run: Start") ;
int errorCount = 0;
try {
// Initialise the server side
JMXServiceURL urlToUse = createServerSide();
// Run client side
errorCount = runClientSide(urlToUse.toString());
if ( errorCount == 0 ) {
System.out.println("MXBeanWeirdParamTest::run: Done without any error") ;
} else {
System.out.println("MXBeanWeirdParamTest::run: Done with "
+ errorCount
+ " error(s)") ;
throw new RuntimeException("errorCount = " + errorCount);
}
cs.stop();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
private static class ClientSide {
public static void main(String args[]) throws Exception {
int errorCount = 0 ;
String msgTag = "ClientSide::main: ";
try {
// Get a connection to remote mbean server
JMXServiceURL addr = new JMXServiceURL(args[0]);
JMXConnector cc = JMXConnectorFactory.connect(addr);
MBeanServerConnection mbsc = cc.getMBeanServerConnection();
// ----
System.out.println(msgTag + "Create and register the MBean");
ObjectName objName = new ObjectName("sqe:type=Basic,protocol=rmi") ;
mbsc.createMBean(BASIC_MXBEAN_CLASS_NAME, objName);
System.out.println(msgTag +"---- OK\n") ;
// ----
System.out.println(msgTag +"Get attribute SqeParameterAtt on our MXBean");
Object result = mbsc.getAttribute(objName, "SqeParameterAtt");
System.out.println(msgTag +"(OK) Got result of class "
+ result.getClass().getName());
System.out.println(msgTag +"Received CompositeData is " + result);
System.out.println(msgTag +"---- OK\n") ;
// ----
// We use the value returned by getAttribute to perform the invoke.
System.out.println(msgTag +"Call operation doWeird on our MXBean [1]");
mbsc.invoke(objName, "doWeird",
new Object[]{result},
new String[]{"javax.management.openmbean.CompositeData"});
System.out.println(msgTag +"---- OK\n") ;
// ----
// We build the CompositeData ourselves that time.
System.out.println(msgTag +"Call operation doWeird on our MXBean [2]");
String typeName = "SqeParameter";
String[] itemNames = new String[] {"glop"};
OpenType<?>[] openTypes = new OpenType<?>[] {SimpleType.STRING};
CompositeType rowType = new CompositeType(typeName, typeName,
itemNames, itemNames, openTypes);
Object[] itemValues = {"HECTOR"};
CompositeData data =
new CompositeDataSupport(rowType, itemNames, itemValues);
TabularType tabType = new TabularType(typeName, typeName,
rowType, new String[]{"glop"});
TabularDataSupport tds = new TabularDataSupport(tabType);
tds.put(data);
System.out.println(msgTag +"Source CompositeData is " + data);
mbsc.invoke(objName, "doWeird",
new Object[]{data},
new String[]{"javax.management.openmbean.CompositeData"});
System.out.println(msgTag +"---- OK\n") ;
// ----
System.out.println(msgTag +"Unregister the MBean");
mbsc.unregisterMBean(objName);
System.out.println(msgTag +"---- OK\n") ;
// Terminate the JMX Client
cc.close();
} catch(Exception e) {
Utils.printThrowable(e, true) ;
errorCount++;
throw new RuntimeException(e);
} finally {
System.exit(errorCount);
}
}
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.management.DescriptorKey;
/**
* That annotation is usable everywhere DescriptorKey is (and even more).
* It is for use to test that you can retrieve the SqeDescriptorKey into the
* appropriate Descriptor instances as built by the JMX runtime.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface SqeDescriptorKey {
@DescriptorKey("sqeDescriptorKey")
String value();
// List descriptor fields that may be added or may be updated
// when retrieving an MBeanInfo using a JMXWS connection compared to the
// MBeanInfo returned by a local MBeanServer.
// The annotation format is :
// <descriptorFieldName>=<descriptorFieldValue>
// The values actually handled by the test suite are :
// openType=SimpleType.VOID
@DescriptorKey("descriptorFields")
String[] descriptorFields() default {};
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import javax.management.Notification;
/**
* Could hold someday a specific semantic.
* For now it is used to have a Notification which of another class, no more.
*/
public class SqeNotification extends Notification {
/** Creates a new instance of SqeNotification */
public SqeNotification(String type, Object source, long sequenceNumber) {
super(type, source, sequenceNumber);
}
/** Creates a new instance of SqeNotification */
public SqeNotification(String type, Object source, long sequenceNumber,
long timeStamp) {
super(type, source, sequenceNumber, timeStamp);
}
/** Creates a new instance of SqeNotification */
public SqeNotification(String type, Object source, long sequenceNumber,
long timeStamp, String message) {
super(type, source, sequenceNumber, timeStamp, message);
}
/** Creates a new instance of SqeNotification */
public SqeNotification(String type, Object source, long sequenceNumber,
String message) {
super(type, source, sequenceNumber, message);
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.io.Serializable;
/**
* That class is to use as an MBean operation parameter or returned value.
* The property Glop with its public getter + setter is only there to be
* reconstructible following MXBean specification, so that SqeParameter can be
* used for what it is designed to.
*/
public class SqeParameter implements Serializable {
private static boolean weird;
private String glop;
static {
if ( System.getProperty("WEIRD_PARAM") != null ) {
weird = true;
}
}
/**
* Creates a new instance of SqeParameter.
* <br>When the Java property WEIRD_PARAM is set, that constructor
* throws an exception.
* <br>That can be used to ensure the class is instantiated on server side
* but never on client side.
*/
public SqeParameter() throws Exception {
if ( weird ) {
throw new Exception();
}
}
public String getGlop() {
return glop;
}
public void setGlop(String value) {
glop = value;
}
}

View File

@ -0,0 +1,241 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.util.Map;
import java.util.HashMap;
import java.util.Properties;
import java.lang.reflect.Method;
import javax.management.remote.JMXConnectorServerMBean;
// utility class for MXBean* tests coming from JMX Tonga test suite
class Utils {
// DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
private static final String DEBUG_HEADER = "[debug] ";
// DEBUG levels
private static int selectedDebugLevel = 0;
static final int DEBUG_STANDARD = 1;
static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
static void parseDebugProperties() {
int level = 0;
Properties p = System.getProperties();
// get selected levels
if (p.getProperty("DEBUG_STANDARD") != null) {
level |= DEBUG_STANDARD;
}
if (p.getProperty("DEBUG_VERBOSE") != null) {
level |= DEBUG_VERBOSE;
}
if (p.getProperty("DEBUG_ALL") != null) {
level |= DEBUG_ALL;
}
selectedDebugLevel = level;
}
/**
* Reproduces the original parsing and collection of test parameters
* from the DTonga JMX test suite.
*
* Collects passed args and returns them in a map(argname, value) structure,
* which will be then propagated as necessary to various called methods.
*/
static Map<String, Object> parseParameters(String args[])
throws Exception {
Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
HashMap<String, Object> map = new HashMap<>();
for ( int i = 0; i < args.length; i++ ) {
if ( args[i].trim().startsWith("-") ) {
if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
Utils.debug(DEBUG_STANDARD,
"TestRoot::parseParameters: added in map = " +
args[i] +
" with value " +
args[i+1]) ;
map.put(args[i].trim(), args[i+1].trim()) ;
} else if ((i+1) < args.length && args[i+1].startsWith("-") ||
(i+1) == args.length ) {
Utils.debug(DEBUG_STANDARD,
"TestRoot::parseParameters: added in map = " +
args[i] +
" with null value") ;
map.put(args[i].trim(), null) ;
} else {
System.out.println(
"TestRoot::parseParameters: (WARNING) not added in map = " +
args[i]) ;
}
}
}
Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
return map ;
}
/**
* This method is to be used in all tests to print anything
* that is temporary.
* Printing is done only when debug is activated by the property DEBUG.
* Printing depends also on the DEBUG_LEVEL property.
* Here it encapsulates a System.out.println.
*/
public static void debug(int level, String line) {
if ((selectedDebugLevel & level) != 0) {
System.out.println(DEBUG_HEADER + line);
}
}
/**
* Do print stack trace when withStack is true.
* Does try to call getTargetException() and getTargetError() then
* print embedded stacks in the case of an Exception wrapping
* another Exception or an Error. Recurse until no more wrapping
* is found.
*/
public static void printThrowable(Throwable theThro, boolean withStack) {
try {
if (withStack) {
theThro.printStackTrace(System.out);
}
if (theThro instanceof Exception) {
Exception t = (Exception) theThro;
Method target = null;
String blank = " ";
try {
target = t.getClass().getMethod("getTargetException",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetException method could be there or not
}
System.out.println(blank + t.getClass() + "==>" + t.getMessage());
while (target != null) {
try {
t = (Exception) target.invoke(t,
(java.lang.Object[]) null);
} catch (Exception ee) {
t = null;
}
try {
if (t != null) {
blank = blank + " ";
System.out.println(blank + t.getClass() + "==>" +
t.getMessage());
try {
target =
t.getClass().getMethod("getTargetException",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetException method could be there or not }
}
} else {
target = null;
}
} catch (Exception ee) {
target = null;
}
}
// We may have exceptions wrapping an Error then it is
// getTargetError that is likely to be called
try {
target = ((Exception) theThro).getClass().getMethod("getTargetError",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetError method could be there or not
}
Throwable err = theThro;
while (target != null) {
try {
err = (Error) target.invoke(err,
(java.lang.Object[]) null);
} catch (Exception ee) {
err = null;
}
try {
if (err != null) {
blank = blank + " ";
System.out.println(blank + err.getClass() + "==>" +
err.getMessage());
if (withStack) {
err.printStackTrace(System.out);
}
try {
target = err.getClass().getMethod("getTargetError",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetError method could be there or not
}
} else {
target = null;
}
} catch (Exception ee) {
target = null;
}
}
} else {
System.out.println("Throwable is : " + theThro);
}
} catch (Throwable x) {
System.out.println("Exception : raised in printException : " + x);
}
}
/**
* Wait up to maxTimeInSeconds second(s) the given JMX connector server
* comes up (which means isActive returns true).
* If it fails to do so we throw a RunTime exception.
*/
public static void waitReady(JMXConnectorServerMBean server,
int maxTimeInSeconds) throws Exception {
int elapsed = 0;
while (!server.isActive() && elapsed < maxTimeInSeconds) {
Thread.sleep(1000);
elapsed++;
}
if (server.isActive()) {
String message = "Utils::waitReady: JMX connector server came up";
if ( elapsed == 0) {
message += " immediately";
} else {
message += " after " + elapsed + " seconds";
}
message += " [" + server.getAddress() + "]";
Utils.debug(DEBUG_STANDARD, message);
} else {
String message = "Utils::waitReady: (ERROR) JMX connector" +
" server didn't come up after " + elapsed + " seconds [" +
server.getAddress() + "]";
System.out.println(message);
throw new RuntimeException(message);
}
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
public abstract class QueryData {
protected int intValue = 9;
protected long longValue = 9L;
protected Integer integerValue = Integer.valueOf(9);
protected boolean booleanValue = true;
protected double doubleValue = 9D;
protected float floatValue = 9.0F;
protected String stringValue = "9";
}

View File

@ -0,0 +1,328 @@
/*
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.util.ArrayList;
import javax.management.Query;
import javax.management.QueryExp;
import javax.management.ValueExp;
/**
* Class used for building QueryExp instances of all every possible type
* in terms of JMX API members; note that several JMX classes are private
* and appears in the JDK API only by their serial form.
* Comments in each case of the big switch in method getQuery() details which
* API member we cover with a given query.
*/
public class QueryFactory extends QueryData {
private String mbeanClassName = "";
private String primitiveIntAttName = "IntAtt";
private String primitiveLongAttName = "LongAtt";
private String integerAttName = "IntegerAtt";
private String primitiveBooleanAttName = "BooleanAtt";
private String primitiveDoubleAttName = "DoubleAtt";
private String primitiveFloatAttName = "FloatAtt";
private String stringAttName = "StringAtt";
private ArrayList<QueryExp> queries = new ArrayList<QueryExp>();
/**
* Creates a new instance of QueryFactory.
* The name is the fully qualified class name of an MBean.
* There is severe constraints on that MBean that must:
* <ul>
* <li>extend QueryData in order to inherit attribute values.
* <li>define a RW attribute IntAtt of type int
* initialized to QueryData.longValue
* <li>define a RW attribute LongAtt of type long
* initialized to QueryData.intValue
* <li>define a RW attribute IntegerAtt of type Integer
* initialized to QueryData.integerValue
* <li>define a RW attribute BooleanAtt of type boolean
* initialized to QueryData.booleanValue
* <li>define a RW attribute DoubleAtt of type double
* initialized to QueryData.doubleValue
* <li>define a RW attribute FloatAtt of type float
* initialized to QueryData.floatValue
* <li>define a RW attribute StringAtt of type String
* initialized to QueryData.stringValue
* </ul>
*/
public QueryFactory(String name) {
this.mbeanClassName = name;
}
/**
* Returns the highest index value the method getQuery supports.
* WARNING : returns 0 if buildQueries haven't been called first !
*/
public int getSize() {
return queries.size();
}
/**
* Populates an ArrayList of QueryExp.
* Lowest index is 1.
* Highest index is returned by getSize().
* <br>The queries numbered 1 to 23 allow to cover all the underlying
* Java classes of the JMX API used to build queries.
*/
public void buildQueries() {
if ( queries.size() == 0 ) {
int smallerIntValue = intValue - 1;
int biggerIntValue = intValue + 1;
// case 1:
// True if the MBean is of class mbeanClassName
// We cover javax.management.InstanceOfQueryExp
queries.add(Query.isInstanceOf(Query.value(mbeanClassName)));
// case 2:
// True if the MBean is of class mbeanClassName
// We cover javax.management.MatchQueryExp and
// javax.management.ClassAttributeValueExp
queries.add(Query.match(Query.classattr(),
Query.value(mbeanClassName)));
// case 3:
// True if an attribute named primitiveIntAttName of type int has
// the value intValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to EQ and javax.management.NumericValueExp
queries.add(Query.eq(Query.attr(primitiveIntAttName),
Query.value(intValue)));
// case 4:
// True if an attribute named primitiveLongAttName of type long has
// the value longValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to EQ and javax.management.NumericValueExp
queries.add(Query.eq(Query.attr(primitiveLongAttName),
Query.value(longValue)));
// case 5:
// True if an attribute named primitiveDoubleAttName of type double
// has the value doubleValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to EQ and javax.management.NumericValueExp
queries.add(Query.eq(Query.attr(primitiveDoubleAttName),
Query.value(doubleValue)));
// case 6:
// True if an attribute named primitiveFloatAttName of type float
// has the value floatValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to EQ and javax.management.NumericValueExp
queries.add(Query.eq(Query.attr(primitiveFloatAttName),
Query.value(floatValue)));
// case 7:
// True if an attribute named primitiveIntAttName of type int is
// hold by an MBean of class mbeanClassName and has
// the value intValue
// We cover javax.management.QualifiedAttributeValueExp
queries.add(Query.eq(Query.attr(mbeanClassName, primitiveIntAttName),
Query.value(intValue)));
// case 8:
// True if an attribute named stringAttName of type String has
// the value stringValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to EQ and javax.management.StringValueExp
queries.add(Query.eq(Query.attr(stringAttName),
Query.value(stringValue)));
// case 9:
// True if an attribute named integerAttName of type Integer has
// the value integerValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to EQ and javax.management.NumericValueExp
queries.add(Query.eq(Query.attr(integerAttName),
Query.value(integerValue)));
// case 10:
// True if an attribute named primitiveBooleanAttName of type boolean
// has the value booleanValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to EQ and javax.management.BooleanValueExp
queries.add(Query.eq(Query.attr(primitiveBooleanAttName),
Query.value(booleanValue)));
// case 11:
// True if an attribute named primitiveIntAttName of type int has
// not the value smallerIntValue
// We cover javax.management.NotQueryExp
queries.add(Query.not(Query.eq(Query.attr(primitiveIntAttName),
Query.value(smallerIntValue))));
// case 12:
// True if either
// an attribute named primitiveIntAttName of type int has
// the value intValue
// or
// an attribute named primitiveLongAttName of type long has
// the value longValue
// We cover javax.management.OrQueryExp
queries.add(Query.or(
Query.eq(Query.attr(primitiveIntAttName),
Query.value(intValue)),
Query.eq(Query.attr(primitiveLongAttName),
Query.value(longValue))));
// case 13:
// True if
// an attribute named primitiveIntAttName of type int has
// the value intValue
// and
// an attribute named primitiveLongAttName of type long has
// the value longValue
// We cover javax.management.AndQueryExp
queries.add(Query.and(
Query.eq(Query.attr(primitiveIntAttName),
Query.value(intValue)),
Query.eq(Query.attr(primitiveLongAttName),
Query.value(longValue))));
// case 14:
// True if an attribute named primitiveIntAttName of type int has
// the value intValue
// We cover javax.management.InQueryExp
ValueExp[] inArray = {Query.value(intValue)};
queries.add(Query.in(Query.attr(primitiveIntAttName), inArray));
// case 15:
// True if an attribute named primitiveIntAttName of type int has
// its value in between smallerIntValue and biggerIntValue
// We cover javax.management.BetweenRelQueryExp
queries.add(Query.between(Query.attr(primitiveIntAttName),
Query.value(smallerIntValue),
Query.value(biggerIntValue)));
// case 16:
// True if an attribute named primitiveIntAttName of type int has
// a value greater than smallerIntValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to GT
queries.add(Query.gt(Query.attr(primitiveIntAttName),
Query.value(smallerIntValue)));
// case 17:
// True if an attribute named primitiveIntAttName of type int has
// a value greater or equal to smallerIntValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to GE
queries.add(Query.geq(Query.attr(primitiveIntAttName),
Query.value(smallerIntValue)));
// case 18:
// True if an attribute named primitiveIntAttName of type int has
// a value smaller than biggerIntValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to LT
queries.add(Query.lt(Query.attr(primitiveIntAttName),
Query.value(biggerIntValue)));
// case 19:
// True if an attribute named primitiveIntAttName of type int has
// a value smaller or equal to biggerIntValue
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to LE
queries.add(Query.leq(Query.attr(primitiveIntAttName),
Query.value(biggerIntValue)));
// case 20:
// True if an attribute named primitiveIntAttName of type int has
// a value equal to intValue minus zero
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to MINUS
queries.add(Query.eq(Query.attr(primitiveIntAttName),
Query.minus(Query.value(intValue), Query.value(0))));
// case 21:
// True if an attribute named primitiveIntAttName of type int has
// a value equal to intValue plus zero
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to PLUS
queries.add(Query.eq(Query.attr(primitiveIntAttName),
Query.plus(Query.value(intValue), Query.value(0))));
// case 22:
// True if an attribute named primitiveIntAttName of type int has
// a value equal to intValue divided by one
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to DIV
queries.add(Query.eq(Query.attr(primitiveIntAttName),
Query.div(Query.value(intValue), Query.value(1))));
// case 23:
// True if an attribute named primitiveIntAttName of type int has
// a value equal to intValue multiplicated by one
// We cover javax.management.BinaryRelQueryExp with
// a relOp equal to TIMES
queries.add(Query.eq(Query.attr(primitiveIntAttName),
Query.times(Query.value(intValue), Query.value(1))));
// case 24:
// That query is a complex one that combines within a big AND
// queries with index 2 to 23 inclusive. But because a List is
// zero based, we must decrement all indexes by 1 when retrieving
// any previously stored query.
QueryExp q2_3 = Query.and(queries.get(2-1), queries.get(3-1));
QueryExp q4_5 = Query.and(queries.get(4-1), queries.get(5-1));
QueryExp q6_7 = Query.and(queries.get(6-1), queries.get(7-1));
QueryExp q8_9 = Query.and(queries.get(8-1), queries.get(9-1));
QueryExp q10_11 = Query.and(queries.get(10-1), queries.get(11-1));
QueryExp q12_13 = Query.and(queries.get(12-1), queries.get(13-1));
QueryExp q14_15 = Query.and(queries.get(14-1), queries.get(15-1));
QueryExp q16_17 = Query.and(queries.get(16-1), queries.get(17-1));
QueryExp q18_19 = Query.and(queries.get(18-1), queries.get(19-1));
QueryExp q20_21 = Query.and(queries.get(20-1), queries.get(21-1));
QueryExp q22_23 = Query.and(queries.get(22-1), queries.get(23-1));
QueryExp q2_5 = Query.and(q2_3, q4_5);
QueryExp q6_9 = Query.and(q6_7, q8_9);
QueryExp q10_13 = Query.and(q10_11, q12_13);
QueryExp q14_17 = Query.and(q14_15, q16_17);
QueryExp q18_21 = Query.and(q18_19, q20_21);
QueryExp q2_9 = Query.and(q2_5, q6_9);
QueryExp q10_17 = Query.and(q10_13, q14_17);
QueryExp q18_23 = Query.and(q18_21, q22_23);
QueryExp q2_17 = Query.and(q2_9, q10_17);
queries.add(Query.and(q2_17, q18_23));
// case 25:
// Complex query mixing AND and OR.
queries.add(Query.or(q6_9, q18_23));
}
}
/**
* Returns a QueryExp taken is the ArrayList populated by buildQueries().
* Lowest index is 1.
* Highest index is returned by getSize().
* <br>The queries numbered 1 to 23 allow to cover all the underlying
* Java classes of the JMX API used to build queries.
*/
public QueryExp getQuery(int index) {
return queries.get(index - 1);
}
}

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import javax.management.remote.JMXServiceURL ;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.StandardMBean;
/**
* This class defines an MBean that can be registered and used on client side
* to handle informations or properties of the remote server.
*
* For example, this MBean can store IOR addresses
* of RMI/IIOP connector(s) used in a test.
*
* That MBean might not be used for testing purpose itself.
*/
public class ServerDelegate implements ServerDelegateMBean, MBeanRegistration {
private MBeanServer mbeanServer = null;
private List<JMXServiceURL> addresses = null;
private String port;
private static String javaVersion = System.getProperty("java.version");
private int sqeJmxwsCredentialsProviderCallCount = 0;
private String jmxwsCredentialsProviderUrl = null;
private int testJMXAuthenticatorCallCount = 0;
private Principal testJMXAuthenticatorPrincipal = null;
@SqeDescriptorKey("NO PARAMETER CONSTRUCTOR ServerDelegate")
public ServerDelegate() {
addresses = new ArrayList<JMXServiceURL>();
}
public ObjectName preRegister(MBeanServer server, ObjectName name)
throws Exception {
// Initialize MBeanServer attribute
mbeanServer = server;
return name;
}
public void postRegister(Boolean registrationDone) {
}
public void preDeregister() throws Exception {
}
public void postDeregister() {
}
public void addAddress(JMXServiceURL url) {
addresses.add(url) ;
}
public List<JMXServiceURL> getAddresses() {
return addresses ;
}
public void setPort(String p) {
port = p ;
}
public String getPort() {
return port ;
}
public String getJavaVersion() {
return javaVersion;
}
public void sqeJmxwsCredentialsProviderCalled() {
sqeJmxwsCredentialsProviderCallCount++;
}
public int getSqeJmxwsCredentialsProviderCallCount() {
return sqeJmxwsCredentialsProviderCallCount;
}
public void setJmxwsCredentialsProviderUrl(String url) {
jmxwsCredentialsProviderUrl = url;
}
public String getJmxwsCredentialsProviderUrl() {
return jmxwsCredentialsProviderUrl;
}
public void testJMXAuthenticatorCalled() {
testJMXAuthenticatorCallCount++;
}
public int getTestJMXAuthenticatorCallCount() {
return testJMXAuthenticatorCallCount;
}
public void setTestJMXAuthenticatorPrincipal(Principal principal) {
testJMXAuthenticatorPrincipal = principal;
}
public String getTestJMXAuthenticatorPrincipalString() {
if ( testJMXAuthenticatorPrincipal != null ) {
return testJMXAuthenticatorPrincipal.toString();
}
return null;
}
/**
* Instantiates and registers a StandardMBean in the MBean server.
*
* @param implementationClassName
* The implementation class name of the MBean.
* @param interfaceClassName
* The management interface class name of the MBean.
* @param isMXBean
* If true, the resultant MBean is an MXBean.
* @param name
* The object name of the StandardMBean.
*/
@SuppressWarnings("unchecked")
public void createStandardMBean(
String implementationClassName,
String interfaceClassName,
boolean isMXBean,
ObjectName name)
throws Exception {
Object implementation =
Class.forName(implementationClassName).newInstance();
Class<Object> interfaceClass = interfaceClassName == null ? null :
(Class<Object>)Class.forName(interfaceClassName);
// Create the StandardMBean
StandardMBean standardMBean = new StandardMBean(
implementation,
interfaceClass,
isMXBean);
// Register the StandardMBean
mbeanServer.registerMBean(standardMBean, name);
}
/**
* Instantiates and registers a StandardMBean in the MBean server.
* The object will use standard JMX design pattern to determine
* the management interface associated with the given implementation.
*/
@SuppressWarnings("unchecked")
public void createStandardMBean(
String implementationClassName,
boolean isMXBean,
ObjectName name)
throws Exception {
createStandardMBean(implementationClassName, null, isMXBean, name);
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.security.Principal;
import java.util.List;
import javax.management.remote.JMXServiceURL ;
import javax.management.ObjectName;
@SqeDescriptorKey("INTERFACE ServerDelegateMBean")
public interface ServerDelegateMBean {
@SqeDescriptorKey("ATTRIBUTE Address")
public void addAddress(JMXServiceURL url);
@SqeDescriptorKey("ATTRIBUTE Address")
public List<JMXServiceURL> getAddresses();
public String getPort();
public void setPort(String p);
public String getJavaVersion();
public void sqeJmxwsCredentialsProviderCalled();
public int getSqeJmxwsCredentialsProviderCallCount();
public void setJmxwsCredentialsProviderUrl(String url);
public String getJmxwsCredentialsProviderUrl();
public void testJMXAuthenticatorCalled();
public int getTestJMXAuthenticatorCallCount();
public void setTestJMXAuthenticatorPrincipal(Principal principal);
public String getTestJMXAuthenticatorPrincipalString();
public void createStandardMBean(
String implementationClassName,
String interfaceClassName,
boolean isMXBean,
ObjectName name)
throws Exception;
public void createStandardMBean(
String implementationClassName,
boolean isMXBean,
ObjectName name)
throws Exception;
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.management.DescriptorKey;
/**
* That annotation is usable everywhere DescriptorKey is (and even more).
* It is for use to test that you can retrieve the SqeDescriptorKey into the
* appropriate Descriptor instances as built by the JMX runtime.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface SqeDescriptorKey {
@DescriptorKey("sqeDescriptorKey")
String value();
// List descriptor fields that may be added or may be updated
// when retrieving an MBeanInfo using a JMXWS connection compared to the
// MBeanInfo returned by a local MBeanServer.
// The annotation format is :
// <descriptorFieldName>=<descriptorFieldValue>
// The values actually handled by the test suite are :
// openType=SimpleType.VOID
@DescriptorKey("descriptorFields")
String[] descriptorFields() default {};
}

View File

@ -0,0 +1,471 @@
/*
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8058865
* @summary Tests most of the existing query types.
* @author Olivier Lagneau
* @modules java.management
* @compile TestQuery.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SupportedQueryTypesTest -mbeanClassName TestQuery
*/
import java.util.Map ;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.lang.reflect.Method;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MBeanServerConnection;
import javax.management.ObjectInstance;
import javax.management.ObjectName ;
import javax.management.QueryExp;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
public class SupportedQueryTypesTest {
protected String mbeanClassName = null;
private MBeanServerConnection mbsc = null;
/*
* First Debug properties and arguments are collect in expected
* map (argName, value) format, then calls original test's run method.
*/
public static void main(String args[]) throws Exception {
System.out.println("=================================================");
// Parses parameters
Utils.parseDebugProperties();
Map<String, Object> map = Utils.parseParameters(args) ;
// Run test
SupportedQueryTypesTest test = new SupportedQueryTypesTest();
test.run(map);
}
public void run(Map<String, Object> args) {
int errorCount = 0;
ObjectName on = null;
ObjectName serverDelegateObjectName = null;
JMXConnectorServer cs = null;
JMXConnector cc = null;
System.out.println("SupportedQueryTypesTest::run: Start") ;
try {
// JMX MbeanServer used inside single VM as if remote.
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
cs.start();
JMXServiceURL addr = cs.getAddress();
cc = JMXConnectorFactory.connect(addr);
mbsc = cc.getMBeanServerConnection();
// Create and register the ServerDelegate MBean on the remote MBeanServer
String serverDelegateClassName = ServerDelegate.class.getName();
serverDelegateObjectName =
new ObjectName("defaultDomain:class=" + serverDelegateClassName);
mbsc.createMBean(serverDelegateClassName, serverDelegateObjectName);
// Retrieve the MBean class name
mbeanClassName = (String) args.get("-mbeanClassName") ;
on = new ObjectName("defaultDomain:class=" + mbeanClassName);
// Create and register the MBean on the remote MBeanServer
System.out.println("SupportedQueryTypesTest::run: CREATE " +
mbeanClassName + " on the remote MBeanServer with name "
+ on);
mbsc.createMBean(mbeanClassName, on);
// Create a QueryFactory and setup which query we'll use.
QueryFactory queries = new QueryFactory(mbeanClassName);
queries.buildQueries();
int maxIndex = queries.getSize();
int minIndex = 1;
// Create a reference Set<ObjectName> to check later on
// the queryNames() results
Set<ObjectName> referenceNameSet = new HashSet<ObjectName>();
referenceNameSet.add(on);
// Create a reference Set<ObjectInstance> to check later on
// the queryMBeans() results
ObjectInstance oi = new ObjectInstance(on, mbeanClassName);
Set<ObjectInstance> referenceInstanceSet =
new HashSet<ObjectInstance>();
referenceInstanceSet.add(oi);
// Perform the queryNames and queryMBeans requests
for (int i = minIndex; i <= maxIndex; i++ ) {
QueryExp query = queries.getQuery(i);
System.out.println("----");
System.out.println("SupportedQueryTypesTest::run: Query # " + i);
System.out.println("query " + query);
errorCount +=
doQueryNames(query, referenceNameSet);
errorCount +=
doQueryMBeans(query, referenceInstanceSet);
}
} catch(Exception e) {
Utils.printThrowable(e, true);
errorCount++;
} finally {
// Do unregister the MBean
try {
if (mbsc.isRegistered(on)) {
mbsc.unregisterMBean(on);
}
if (mbsc.isRegistered(serverDelegateObjectName)) {
mbsc.unregisterMBean(serverDelegateObjectName);
}
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++;
}
try {
// Close JMX Connector Client
cc.close();
// Stop connertor server
cs.stop();
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++;
}
}
System.out.println("");
System.out.println("SupportedQueryTypesTest::run: Done") ;
// Handle result
if (errorCount == 0) {
System.out.println("SupportedQueryTypesTest::run: (OK)");
} else {
String message = "SupportedQueryTypesTest::run: (ERROR) Got " +
+ errorCount + " error(s)";
System.out.println(message);
throw new RuntimeException(message);
}
}
private int doQueryNames(QueryExp query, Set<ObjectName> referenceSet) {
int errorCount = 0;
System.out.println(" <*> Perform queryNames call ");
try {
// Call queryNames on the remote MBeanServer
Set<ObjectName> remoteSet = mbsc.queryNames(null, query);
// Compare the 2 Set<ObjectName>
errorCount += checkSet(remoteSet, referenceSet);
// Cleaning
remoteSet.clear();
} catch (Exception e) {
Utils.printThrowable(e, true);
errorCount++;
}
if ( errorCount == 0 ) {
System.out.println("\t(OK)");
} else {
System.out.println("\t(ERROR) Query failed");
}
return errorCount;
}
private int doQueryMBeans(QueryExp query, Set<ObjectInstance> referenceSet) {
int errorCount = 0;
System.out.println(" <*> Perform queryMBeans call ");
try {
// Call queryMBeans on the remote MBeanServer
Set<ObjectInstance> remoteSet = mbsc.queryMBeans(null, query);
// Compare the 2 Set<ObjectInstance>
errorCount += checkSet(remoteSet, referenceSet);
// Cleaning
remoteSet.clear();
} catch (Exception e) {
Utils.printThrowable(e, true);
errorCount++;
}
if ( errorCount == 0 ) {
System.out.println("\t(OK)");
} else {
System.out.println("\t(ERROR) Query failed");
}
return errorCount;
}
/**
* Pretty print of a Set content.
* When the Set isn't empty, toString() is called on each element.
* <br>The variable's name used to hold that Set is given via the setName
* parameter and used in the output.
*/
private static void printSet(Set<?> printableSet, String setName) {
if ( printableSet.size() == 0 ) {
System.out.println("The Set " + setName + " is empty");
} else {
System.out.println("The Set " + setName + " contains :");
for (Iterator<?> it = printableSet.iterator(); it.hasNext();) {
Object elem = it.next();
System.out.println("\t" + elem.toString());
}
}
}
/**
* This method check the Set remoteSet is equal to
* the reference Set referenceSet,
* which means same size and content (order doesn't matter).
* <br>It returns 0 when the check is fine, otherwise 1.
*/
private int checkSet(Set<?> remoteSet, Set<?> referenceSet) {
if ( ! remoteSet.equals(referenceSet) ) {
System.out.println("SupportedQueryTypesTest::checkSet:"
+ " (ERROR) Set aren't as expected");
printSet(remoteSet, "remoteSet");
printSet(referenceSet, "referenceSet");
return 1;
} else {
return 0;
}
}
// Utility inner class coming from JMX Tonga test suite.
private static class Utils {
// DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
static final String DEBUG_HEADER = "[debug] ";
// DEBUG levels
static int selectedDebugLevel = 0;
static final int DEBUG_STANDARD = 1;
static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
static void parseDebugProperties() {
int level = 0;
Properties p = System.getProperties();
// get selected levels
if (p.getProperty("DEBUG_STANDARD") != null) {
level |= DEBUG_STANDARD;
}
if (p.getProperty("DEBUG_VERBOSE") != null) {
level |= DEBUG_VERBOSE;
}
if (p.getProperty("DEBUG_ALL") != null) {
level |= DEBUG_ALL;
}
selectedDebugLevel = level;
}
/**
* Reproduces the original parsing and collection of test parameters
* from the DTonga JMX test suite.
*
* Collects passed args and returns them in a map(argname, value) structure,
* which will be then propagated as necessary to various called methods.
*/
static Map<String, Object> parseParameters(String args[])
throws Exception {
debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
HashMap<String, Object> map = new HashMap<>();
for ( int i = 0; i < args.length; i++ ) {
if ( args[i].trim().startsWith("-") ) {
if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
debug(DEBUG_STANDARD,
"TestRoot::parseParameters: added in map = " +
args[i] +
" with value " +
args[i+1]) ;
map.put(args[i].trim(), args[i+1].trim()) ;
} else if ((i+1) < args.length && args[i+1].startsWith("-") ||
(i+1) == args.length ) {
debug(DEBUG_STANDARD,
"TestRoot::parseParameters: added in map = " +
args[i] +
" with null value") ;
map.put(args[i].trim(), null) ;
} else {
System.out.println(
"TestRoot::parseParameters: (WARNING) not added in map = " +
args[i]) ;
}
}
}
debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
return map ;
}
/**
* This method is to be used in all tests to print anything
* that is temporary.
* Printing is done only when debug is activated by the property DEBUG.
* Printing depends also on the DEBUG_LEVEL property.
* Here it encapsulates a System.out.println.
*/
static void debug(int level, String line) {
if ((selectedDebugLevel & level) != 0) {
System.out.println(DEBUG_HEADER + line);
}
}
/**
* Do print stack trace when withStack is true.
* Does try to call getTargetException() and getTargetError() then
* print embedded stacks in the case of an Exception wrapping
* another Exception or an Error. Recurse until no more wrapping
* is found.
*/
static void printThrowable(Throwable theThro, boolean withStack) {
try {
if (withStack) {
theThro.printStackTrace(System.out);
}
if (theThro instanceof Exception) {
Exception t = (Exception) theThro;
Method target = null;
String blank = " ";
try {
target = t.getClass().getMethod("getTargetException",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetException method could be there or not
}
System.out.println(blank + t.getClass() + "==>" + t.getMessage());
while (target != null) {
try {
t = (Exception) target.invoke(t,
(java.lang.Object[]) null);
} catch (Exception ee) {
t = null;
}
try {
if (t != null) {
blank = blank + " ";
System.out.println(blank + t.getClass() + "==>" +
t.getMessage());
try {
target =
t.getClass().getMethod("getTargetException",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetException method could be there or not }
}
} else {
target = null;
}
} catch (Exception ee) {
target = null;
}
}
// We may have exceptions wrapping an Error then it is
// getTargetError that is likely to be called
try {
target = ((Exception) theThro).getClass().getMethod("getTargetError",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetError method could be there or not
}
Throwable err = theThro;
while (target != null) {
try {
err = (Error) target.invoke(err,
(java.lang.Object[]) null);
} catch (Exception ee) {
err = null;
}
try {
if (err != null) {
blank = blank + " ";
System.out.println(blank + err.getClass() + "==>" +
err.getMessage());
if (withStack) {
err.printStackTrace(System.out);
}
try {
target = err.getClass().getMethod("getTargetError",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetError method could be there or not
}
} else {
target = null;
}
} catch (Exception ee) {
target = null;
}
}
} else {
System.out.println("Throwable is : " + theThro);
}
} catch (Throwable x) {
System.out.println("Exception : raised in printException : " + x);
}
}
}
}

View File

@ -0,0 +1,167 @@
/*
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
/**
* Class TestQuery
* MBean used for testing the types wired when using QueryExp.
* It is heavily linked to QueryFactory.
*/
public class TestQuery extends QueryData implements TestQueryMBean {
/**
* Attribute : BooleanAtt
*/
private boolean booleanAtt = booleanValue;
/**
* Attribute : DoubleAtt
*/
private double doubleAtt = doubleValue;
/**
* Attribute : FloatAtt
*/
private float floatAtt = floatValue;
/**
* Attribute : IntAtt
*/
private int intAtt = intValue;
/**
* Attribute : IntegerAtt
*/
private Integer integerAtt = integerValue;
/**
* Attribute : LongAtt
*/
private long longAtt = longValue;
/**
* Attribute : StringAtt
*/
private String stringAtt = stringValue;
public TestQuery() {
}
/**
* Get Att of type boolean
*/
public boolean getBooleanAtt() {
return booleanAtt;
}
/**
* Set Att of type boolean
*/
public void setBooleanAtt(boolean value) {
booleanAtt = value;
}
/**
* Get Att of type double
*/
public double getDoubleAtt() {
return doubleAtt;
}
/**
* Set Att of type double
*/
public void setDoubleAtt(double value) {
doubleAtt = value;
}
/**
* Get Att of type float
*/
public float getFloatAtt() {
return floatAtt;
}
/**
* Set Att of type float
*/
public void setFloatAtt(float value) {
floatAtt = value;
}
/**
* Get Att of type int
*/
public int getIntAtt() {
return intAtt;
}
/**
* Set Att of type int
*/
public void setIntAtt(int value) {
intAtt = value;
}
/**
* Get Att of type Integer
*/
public Integer getIntegerAtt() {
return integerAtt;
}
/**
* Set Att of type Integer
*/
public void setIntegerAtt(Integer value) {
integerAtt = value;
}
/**
* Get Att of type long
*/
public long getLongAtt() {
return longAtt;
}
/**
* Set Att of type long
*/
public void setLongAtt(long value) {
longAtt = value;
}
/**
* Get Att of type String
*/
public String getStringAtt() {
return stringAtt;
}
/**
* Set Att of type String
*/
public void setStringAtt(String value) {
stringAtt = value;
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
/**
* Interface TestQueryMBean
* MBean used for testing the types wired when using QueryExp.
* It is heavily linked to QueryFactory.
*/
public interface TestQueryMBean
{
/**
* Get Att of type boolean
*/
public boolean getBooleanAtt();
/**
* Set Att of type boolean
*/
public void setBooleanAtt(boolean value);
/**
* Get Att of type double
*/
public double getDoubleAtt();
/**
* Set Att of type double
*/
public void setDoubleAtt(double value);
/**
* Get Att of type float
*/
public float getFloatAtt();
/**
* Set Att of type float
*/
public void setFloatAtt(float value);
/**
* Get Att of type int
*/
public int getIntAtt();
/**
* Set Att of type int
*/
public void setIntAtt(int value);
/**
* Get Att of type Integer
*/
public Integer getIntegerAtt();
/**
* Set Att of type Integer
*/
public void setIntegerAtt(Integer value);
/**
* Get Att of type long
*/
public long getLongAtt();
/**
* Set Att of type long
*/
public void setLongAtt(long value);
/**
* Get Att of type String
*/
public String getStringAtt();
/**
* Set Att of type String
*/
public void setStringAtt(String value);
}

View File

@ -0,0 +1,613 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8058865
* @summary Checks various authentication behavior from remote jmx client
* @author Olivier Lagneau
* @modules java.management
* @library /lib/testlibrary
* @compile Simple.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedGetException
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username4 -Dpassword=password4 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedGetException -expectedSetException
* @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException
*/
import java.io.File;
import java.util.Map ;
import java.util.HashMap ;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory ;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.Attribute ;
import javax.management.ObjectName ;
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.JDKToolFinder;
public class AuthorizationTest {
static final String SERVER_CLASS_NAME = "AuthorizationTest";
static final String CLIENT_CLASS_NAME = "AuthorizationTest$ClientSide";
static final String CLIENT_CLASS_MAIN = CLIENT_CLASS_NAME;
static final String USERNAME_PROPERTY = "username";
static final String PASSWORD_PROPERTY = "password";
private JMXConnectorServer cs;
/*
* First Debug properties and arguments are collect in expected
* map (argName, value) format, then calls original test's run method.
*/
public static void main(String args[]) throws Exception {
System.out.println("=================================================");
// Parses parameters
Utils.parseDebugProperties();
// Supported parameters list format is :
// "MainClass [-server <param-spec> ...] [-client <param-spec> ...]
// with <param-spec> either "-parami valuei" or "-parami"
HashMap<String, Object> serverMap = new HashMap<>() ;
int clientArgsIndex =
Utils.parseServerParameters(args, SERVER_CLASS_NAME, serverMap);
// Extract and records client params
String[] clientParams = null;
if (clientArgsIndex < args.length) {
int clientParamsSize = args.length - clientArgsIndex;
clientParams = new String[clientParamsSize];
System.arraycopy(args, clientArgsIndex, clientParams, 0, clientParamsSize);
} else {
clientParams = new String[0];
}
// Run test
AuthorizationTest test = new AuthorizationTest();
test.run(serverMap, clientParams);
}
/*
* Create the MBeansServer side of the test and returns its address
*/
private JMXServiceURL createServerSide(Map<String, Object> serverMap)
throws Exception {
final int NINETY_SECONDS = 90;
System.out.println("AuthorizationTest::createServerSide: Start") ;
MBeanServer mbs = MBeanServerFactory.newMBeanServer();
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
// Creates connection environment from server side params
HashMap<String, Object> env = new HashMap<>();
String value = null;
if ((value = (String)serverMap.get("-mapType")) != null) {
if (value.contains("x.access.file")) {
String accessFileStr = System.getProperty("test.src") +
File.separator + "access.properties";
env.put("jmx.remote.x.access.file", accessFileStr);
System.out.println("Added " + accessFileStr + " file as jmx.remote.x.access.file");
}
if (value.contains("x.password.file")) {
String passwordFileStr = System.getProperty("test.src") +
File.separator + "password.properties";
env.put("jmx.remote.x.password.file", passwordFileStr);
System.out.println("Added " + passwordFileStr + " file as jmx.remote.x.password.file");
}
}
if (serverMap.containsKey("-populate")) {
String populateClassName = "Simple";
ObjectName on =
new ObjectName("defaultDomain:class=Simple");
Utils.debug(Utils.DEBUG_STANDARD, "create and register Simple MBean") ;
mbs.createMBean(populateClassName, on);
}
cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
cs.start();
Utils.waitReady(cs, NINETY_SECONDS);
JMXServiceURL addr = cs.getAddress();
System.out.println("AuthorizationTest::createServerSide: Done.") ;
return addr;
}
/*
* Creating command-line for running subprocess JVM:
*
* JVM command line is like:
* {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
*
* {defaultopts} are the default java options set by the framework.
*
*/
private List<String> buildCommandLine(String args[]) {
List<String> opts = new ArrayList<>();
opts.add(JDKToolFinder.getJDKTool("java"));
opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
String usernameValue = System.getProperty(USERNAME_PROPERTY);
if (usernameValue != null) {
opts.add("-D" + USERNAME_PROPERTY + "=" + usernameValue);
}
String passwordValue = System.getProperty(PASSWORD_PROPERTY);
if (passwordValue != null) {
opts.add("-D" + PASSWORD_PROPERTY + "=" + passwordValue);
}
opts.add("-cp");
opts.add(System.getProperty("test.class.path", "test.class.path"));
opts.add(CLIENT_CLASS_MAIN);
opts.addAll(Arrays.asList(args));
return opts;
}
/**
* Runs AuthorizationTest$ClientSide with the passed options and redirects
* subprocess standard I/O to the current (parent) process. This provides a
* trace of what happens in the subprocess while it is runnning (and before
* it terminates).
*
* @param serviceUrlStr string representing the JMX service Url to connect to.
*/
private int runClientSide(String args[], String serviceUrlStr) throws Exception {
// Building command-line
List<String> opts = buildCommandLine(args);
opts.add("-serviceUrl");
opts.add(serviceUrlStr);
// Launch separate JVM subprocess
int exitCode = 0;
String[] optsArray = opts.toArray(new String[0]);
ProcessBuilder pb = new ProcessBuilder(optsArray);
Process p = ProcessTools.startProcess("AuthorizationTest$ClientSide", pb);
// Handling end of subprocess
try {
exitCode = p.waitFor();
if (exitCode != 0) {
System.out.println(
"Subprocess unexpected exit value of [" + exitCode +
"]. Expected 0.\n");
}
} catch (InterruptedException e) {
System.out.println("Parent process interrupted with exception : \n " + e + " :" );
// Parent thread unknown state, killing subprocess.
p.destroyForcibly();
throw new RuntimeException(
"Parent process interrupted with exception : \n " + e + " :" );
} finally {
if (p.isAlive()) {
p.destroyForcibly();
}
return exitCode;
}
}
public void run(Map<String, Object> serverArgs, String clientArgs[]) {
System.out.println("AuthorizationTest::run: Start") ;
int errorCount = 0;
try {
// Initialise the server side
JMXServiceURL urlToUse = createServerSide(serverArgs);
// Run client side
errorCount = runClientSide(clientArgs, urlToUse.toString());
if ( errorCount == 0 ) {
System.out.println("AuthorizationTest::run: Done without any error") ;
} else {
System.out.println("AuthorizationTest::run: Done with "
+ errorCount
+ " error(s)") ;
throw new RuntimeException("errorCount = " + errorCount);
}
cs.stop();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
private static class ClientSide {
private JMXConnector cc = null;
private MBeanServerConnection mbsc = null;
public static void main(String args[]) throws Exception {
// Parses parameters
Utils.parseDebugProperties();
// Supported parameters list format is : "MainClass [-client <param-spec> ...]
// with <param-spec> either "-parami valuei" or "-parami"
HashMap<String, Object> clientMap = new HashMap<>() ;
Utils.parseClientParameters(args, CLIENT_CLASS_NAME, clientMap);
// Run test
ClientSide test = new ClientSide();
test.run(clientMap);
}
public void run(Map<String, Object> args) {
int errorCount = 0 ;
try {
boolean expectedCreateException =
(args.containsKey("-expectedCreateException")) ? true : false ;
boolean expectedGetException =
(args.containsKey("-expectedGetException")) ? true : false ;
boolean expectedSetException =
(args.containsKey("-expectedSetException")) ? true : false ;
boolean expectedInvokeException =
(args.containsKey("-expectedInvokeException")) ? true : false ;
// JSR262 (see bug 6440374)
// There is no special JSR262 protocol operation for connect.
// The first request sent initiate the connection.
// In the JSR262 current implementation, getDefaultDomain is sent to
// the server in order to get the server part of the connection ID.
// => the connection may fail if no access permission on get requests.
boolean expectedConnectException =
(args.containsKey("-expectedConnectException")) ? true : false ;
// Before connection,
// remove the element of the Map with null values (not supported by RMI)
// See bug 4982668
args.remove("-expectedCreateException");
args.remove("-expectedGetException");
args.remove("-expectedSetException");
args.remove("-expectedInvokeException");
args.remove("-expectedConnectException");
// Here do connect to the JMX Server
String username = System.getProperty("username");
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::run: CONNECT on behalf of \"" + username + "\"");
doConnect(args, expectedConnectException);
// If the connection did not fail, perform some requests.
// At this stage the mbeanserver connection is up and running
if (mbsc != null) {
ObjectName on = new ObjectName("defaultDomain:class=Simple");
// Create request
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::run: CREATE on behalf of \"" +
username + "\"");
errorCount += doCreateRequest(mbsc,
new ObjectName("defaultDomain:class=Simple,user=" + username),
expectedCreateException);
// Get request
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::run: GET on behalf of \"" +
username + "\"");
errorCount += doGetRequest(mbsc, on, expectedGetException);
// Set request
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::run: SET on behalf of \"" +
username + "\"");
errorCount += doSetRequest(mbsc, on, expectedSetException);
// Invoke request
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::run: INVOKE on behalf of \"" +
username + "\"");
errorCount += doInvokeRequest(mbsc, on, expectedInvokeException);
}
} catch(Exception e) {
Utils.printThrowable(e, true) ;
errorCount++;
} finally {
// Terminate the JMX Client
try {
cc.close();
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++;
}
}
System.out.println("ClientSide::run: Done") ;
// Handle result
if (errorCount == 0) {
System.out.println("ClientSide::run: (OK) authorization test succeeded.");
} else {
String message = "AuthorizationTest$ClientSide::run: (ERROR) " +
" authorization test failed with " +
errorCount + " error(s)";
System.out.println(message);
throw new RuntimeException(message);
}
}
protected void doConnect(Map<String, Object> args,
boolean expectedException) {
String msgTag = "ClientSide::doConnect";
boolean throwRuntimeException = false;
String message = "";
try {
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::doConnect: Connect the client");
// Collect connection environment
HashMap<String, Object> env = new HashMap<>();
Object value = args.get("-mapType");
if (value != null) {
String username = System.getProperty("username");
String password = System.getProperty("password");
Utils.debug(Utils.DEBUG_STANDARD,
msgTag + "add \"jmx.remote.credentials\" = \"" +
username + "\", \"" + password + "\"");
env.put("jmx.remote.credentials",
new String[] { username , password });
}
// Get a connection to remote mbean server
JMXServiceURL addr = new JMXServiceURL((String)args.get("-serviceUrl"));
cc = JMXConnectorFactory.connect(addr,env);
mbsc = cc.getMBeanServerConnection();
if (expectedException) {
message = "ClientSide::doConnect: (ERROR) " +
"Connect did not fail with expected SecurityException";
System.out.println(message);
throwRuntimeException = true;
} else {
System.out.println("ClientSide::doConnect: (OK) Connect succeed");
}
} catch(Exception e) {
Utils.printThrowable(e, true);
if (expectedException) {
if (e instanceof java.lang.SecurityException) {
System.out.println("ClientSide::doConnect: (OK) " +
"Connect failed with expected SecurityException");
} else {
message = "ClientSide::doConnect: (ERROR) " +
"Create failed with " + e.getClass() +
" instead of expected SecurityException";
System.out.println(message);
throwRuntimeException = true;
}
} else {
message = "ClientSide::doConnect: (ERROR) " +
"Connect failed";
System.out.println(message);
throwRuntimeException = true;
}
}
// If the connection failed, or if the connection succeeded but should not,
// no need to go further => throw RuntimeException and exit the test
if (throwRuntimeException) {
throw new RuntimeException(message);
}
}
protected int doCreateRequest(MBeanServerConnection mbsc,
ObjectName on,
boolean expectedException) {
int errorCount = 0;
try {
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::doCreateRequest: Create and register the MBean") ;
mbsc.createMBean("Simple", on) ;
if (expectedException) {
System.out.println("ClientSide::doCreateRequest: " +
"(ERROR) Create did not fail with expected SecurityException");
errorCount++;
} else {
System.out.println("ClientSide::doCreateRequest: (OK) Create succeed") ;
}
} catch(Exception e) {
Utils.printThrowable(e, true) ;
if (expectedException) {
if (e instanceof java.lang.SecurityException) {
System.out.println("ClientSide::doCreateRequest: " +
"(OK) Create failed with expected SecurityException") ;
} else {
System.out.println("ClientSide::doCreateRequest: " +
"(ERROR) Create failed with " +
e.getClass() + " instead of expected SecurityException");
errorCount++;
}
} else {
System.out.println("ClientSide::doCreateRequest: " +
"(ERROR) Create failed");
errorCount++;
}
}
return errorCount;
}
protected int doGetRequest(MBeanServerConnection mbsc,
ObjectName on,
boolean expectedException) {
int errorCount = 0;
try {
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::doGetRequest: Get attributes of the MBean") ;
mbsc.getAttribute(on, "Attribute");
if (expectedException) {
System.out.println("ClientSide::doGetRequest: " +
"(ERROR) Get did not fail with expected SecurityException");
errorCount++;
} else {
System.out.println("ClientSide::doGetRequest: (OK) Get succeed") ;
}
} catch(Exception e) {
Utils.printThrowable(e, true) ;
if (expectedException) {
if (e instanceof java.lang.SecurityException) {
System.out.println("ClientSide::doGetRequest: " +
"(OK) Get failed with expected SecurityException") ;
} else {
System.out.println("ClientSide::doGetRequest: " +
"(ERROR) Get failed with " +
e.getClass() + " instead of expected SecurityException");
errorCount++;
}
} else {
System.out.println("ClientSide::doGetRequest: (ERROR) Get failed");
errorCount++;
}
}
return errorCount;
}
protected int doSetRequest(MBeanServerConnection mbsc,
ObjectName on,
boolean expectedException) {
int errorCount = 0;
try {
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::doSetRequest: Set attributes of the MBean") ;
Attribute attribute = new Attribute("Attribute", "My value") ;
mbsc.setAttribute(on, attribute) ;
if (expectedException) {
System.out.println("ClientSide::doSetRequest: " +
"(ERROR) Set did not fail with expected SecurityException");
errorCount++;
} else {
System.out.println("ClientSide::doSetRequest: (OK) Set succeed") ;
}
} catch(Exception e) {
Utils.printThrowable(e, true) ;
if (expectedException) {
if (e instanceof java.lang.SecurityException) {
System.out.println("ClientSide::doSetRequest: " +
"(OK) Set failed with expected SecurityException") ;
} else {
System.out.println("ClientSide::doSetRequest: " +
"(ERROR) Set failed with " +
e.getClass() + " instead of expected SecurityException");
errorCount++;
}
} else {
System.out.println("ClientSide::doSetRequest: (ERROR) Set failed");
errorCount++;
}
}
return errorCount;
}
protected int doInvokeRequest(MBeanServerConnection mbsc,
ObjectName on,
boolean expectedException) {
int errorCount = 0;
try {
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::doInvokeRequest: Invoke operations on the MBean") ;
mbsc.invoke(on, "operation", null, null) ;
if (expectedException) {
System.out.println("ClientSide::doInvokeRequest: " +
"(ERROR) Invoke did not fail with expected SecurityException");
errorCount++;
} else {
System.out.println("ClientSide::doInvokeRequest: (OK) Invoke succeed") ;
}
} catch(Exception e) {
Utils.printThrowable(e, true) ;
if (expectedException) {
if (e instanceof java.lang.SecurityException) {
System.out.println("ClientSide::doInvokeRequest: " +
"(OK) Invoke failed with expected SecurityException") ;
} else {
System.out.println("ClientSide::doInvokeRequest: " +
" (ERROR) Invoke failed with " +
e.getClass() + " instead of expected SecurityException");
errorCount++;
}
} else {
System.out.println("ClientSide::doInvokeRequest: " +
"(ERROR) Invoke failed");
errorCount++;
}
}
return errorCount;
}
}
}

View File

@ -0,0 +1,213 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.security.AccessControlContext;
import java.security.AccessController;
import javax.security.auth.Subject;
import java.security.Principal;
import java.util.Iterator;
import java.util.Set;
import javax.management.MBeanRegistration ;
import javax.management.MBeanServer ;
import javax.management.ObjectName ;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationListener;
import javax.management.Notification;
public class MBS_Light extends NotificationBroadcasterSupport
implements MBS_LightMBean, MBeanRegistration, NotificationListener
{
private RjmxMBeanParameter param = null ;
private String aString = "notset" ;
private int anInt = 0 ;
private MBeanServer mbs = null ;
private ObjectName objname = null ;
private Exception anException = null ;
private Error anError = null ;
private int count = 0;
private SimpleListener listener = new SimpleListener();
@SqeDescriptorKey("NO PARAMETER CONSTRUCTOR MBS_Light")
public MBS_Light() {
}
@SqeDescriptorKey("ONE RjmxMBeanParameter PARAMETER CONSTRUCTOR MBS_Light")
public MBS_Light(@SqeDescriptorKey("CONSTRUCTOR PARAMETER param")
RjmxMBeanParameter param) {
this.param = param ;
}
@SqeDescriptorKey("ONE String PARAMETER CONSTRUCTOR MBS_Light")
public MBS_Light(@SqeDescriptorKey("CONSTRUCTOR PARAMETER param")String param) {
this.aString = param ;
}
// Getter for property param
public RjmxMBeanParameter getParam() {
return this.param ;
}
// Setter for property param
public void setParam(RjmxMBeanParameter param) {
this.param = param ;
}
// Getter for property aString
public String getAstring() {
return this.aString ;
}
// Setter for property aString
public void setAstring(String aString) {
this.aString = aString ;
}
// Getter for property anInt
public int getAnInt() {
return this.anInt ;
}
// Setter for property anInt
public void setAnInt(int anInt) {
this.anInt = anInt ;
}
// Getter for property anException
public Exception getAnException() {
return this.anException ;
}
// Setter for property anException
public void setAnException(Exception anException) {
this.anException = anException ;
}
// Getter for property anError
public Error getAnError() {
return this.anError ;
}
// Setter for property anError
public void setAnError(Error anError) {
this.anError = anError ;
}
// An operation
public RjmxMBeanParameter operate1(String name) {
return new RjmxMBeanParameter(name) ;
}
// An operation
public String operate2(RjmxMBeanParameter param) {
return param.name ;
}
// An operation
public void throwError() {
throw new Error("JSR-160-ERROR");
}
// An operation
public void throwException() throws Exception {
throw new Exception("JSR-160-EXCEPTION");
}
// MBeanRegistration method
public void postDeregister() {
}
// MBeanRegistration method
public void postRegister(Boolean registrationDone) {
}
// MBeanRegistration method
public void preDeregister()
throws Exception
{
}
// MBeanRegistration method
public ObjectName preRegister(MBeanServer server, ObjectName name)
throws Exception
{
this.mbs = server ;
if ( name == null ) {
this.objname = new ObjectName("protocol:class=MBS_Light") ;
}
else {
this.objname = name ;
}
return this.objname ;
}
public synchronized void handleNotification(Notification notification,
Object handback) {
Utils.debug(Utils.DEBUG_STANDARD,
"MBS_Light::handleNotification: " + notification);
listener.handleNotification(notification, handback);
}
// Send a notification
public void sendNotification() {
Notification notification =
new Notification("JSR160-TCK-NOTIFICATION", this, count++);
sendNotification(notification);
}
public Object waitForNotificationHB() {
return listener.waitForNotificationHB();
}
// Receive multi notifications and send back handbacks
public synchronized Object[] waitForMultiNotifications(String nb) {
return listener.waitForMultiNotifications(Integer.valueOf(nb).intValue());
}
// Receive a notification
public synchronized String waitForNotification() {
return listener.waitForNotification();
}
// Is the notification received
public synchronized Boolean notificationReceived() {
return Boolean.valueOf(listener.isNotificationReceived());
}
// The authorization Id
public String getAuthorizationId() {
AccessControlContext acc = AccessController.getContext();
Subject subject = Subject.getSubject(acc);
Set<Principal> principals = subject.getPrincipals();
Iterator<Principal> i = principals.iterator();
StringBuffer buffer = new StringBuffer();
while(i.hasNext()) {
Principal p = i.next();
buffer.append(p.getName());
if(i.hasNext())
buffer.append(" ");
}
return buffer.toString();
}
}

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
@SqeDescriptorKey("INTERFACE MBS_LightMBean")
public interface MBS_LightMBean {
// Getter for property param
@SqeDescriptorKey("ATTRIBUTE Param")
public RjmxMBeanParameter getParam() ;
// Setter for property param
@SqeDescriptorKey("ATTRIBUTE Param")
public void setParam(RjmxMBeanParameter param) ;
// Getter for property aString
@SqeDescriptorKey("ATTRIBUTE Astring")
public String getAstring() ;
// Setter for property aString
@SqeDescriptorKey("ATTRIBUTE Astring")
public void setAstring(String aString) ;
// Getter for property anInt
@SqeDescriptorKey("ATTRIBUTE AnInt")
public int getAnInt() ;
// Setter for property anInt
@SqeDescriptorKey("ATTRIBUTE AnInt")
public void setAnInt(int anInt) ;
// Getter for property anException
@SqeDescriptorKey("ATTRIBUTE AnException")
public Exception getAnException() ;
// Setter for property anException
@SqeDescriptorKey("ATTRIBUTE AnException")
public void setAnException(Exception anException) ;
// Getter for property anError
@SqeDescriptorKey("ATTRIBUTE AnError")
public Error getAnError() ;
// Setter for property anError
@SqeDescriptorKey("ATTRIBUTE AnError")
public void setAnError(Error anError) ;
// An operation
@SqeDescriptorKey("OPERATION operate1")
public RjmxMBeanParameter operate1(
@SqeDescriptorKey("OPERATION PARAMETER name")String name) ;
// An operation
@SqeDescriptorKey("OPERATION operate2")
public String operate2(
@SqeDescriptorKey("OPERATION PARAMETER param")RjmxMBeanParameter param) ;
// Throws an error
@SqeDescriptorKey("OPERATION throwError")
public void throwError();
// Throws an exception
@SqeDescriptorKey("OPERATION throwException")
public void throwException() throws Exception;
// Send a notification
@SqeDescriptorKey("OPERATION sendNotification")
public void sendNotification();
// Receive a notification and return the type
@SqeDescriptorKey("OPERATION waitForNotification")
public String waitForNotification();
// Receive a notification and return the HandBack
@SqeDescriptorKey("OPERATION waitForNotificationHB")
public Object waitForNotificationHB();
// Receive multi notifications and return the HandBacks
@SqeDescriptorKey("OPERATION waitForMultiNotifications")
public Object[] waitForMultiNotifications(
@SqeDescriptorKey("OPERATION PARAMETER nb")String nb);
// Is the notification received
@SqeDescriptorKey("OPERATION notificationReceived")
public Boolean notificationReceived();
// Return the current authorization Id
@SqeDescriptorKey("OPERATION getAuthorizationId")
public String getAuthorizationId();
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.io.Serializable ;
/**
* That class is used to modelize a parameter to be used as MBean property
* value or MBean operation parameter or returned value.
*/
public class RjmxMBeanParameter implements Serializable {
public String name = "unset" ;
public RjmxMBeanParameter() {
}
public RjmxMBeanParameter(String name) {
this.name = name ;
}
public boolean equals(Object obj) {
if ( this.name.equals(((RjmxMBeanParameter)obj).name) ) {
return true ;
} else {
return false ;
}
}
}

View File

@ -0,0 +1,800 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 8058865
* @summary Checks various secure ways of connecting from remote jmx client
* @author Olivier Lagneau
* @modules java.management
* @library /lib/testlibrary
* @compile MBS_Light.java ServerDelegate.java TestSampleLoginModule.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=UNKNOWN_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials -expectedThrowable java.lang.SecurityException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=WRONG_password SecurityTest -server -mapType x.password.file -client -mapType credentials -expectedThrowable java.lang.SecurityException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dsusername=TestJMXAuthenticatorUsername -Dspassword=TestJMXAuthenticatorPassword -Dusername=TestJMXAuthenticatorUsername -Dpassword=TestJMXAuthenticatorPassword SecurityTest -server -mapType x.authenticator -client -mapType credentials
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dsusername=TestJMXAuthenticatorUsername -Dspassword=TestJMXAuthenticatorPassword -Dusername=AnotherTestJMXAuthenticatorUsername -Dpassword=TestJMXAuthenticatorPassword SecurityTest -server -mapType x.authenticator -client -mapType credentials -expectedThrowable java.lang.SecurityException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.PasswordFileAuthentication -client -mapType credentials
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config.UNKNOWN -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.PasswordFileAuthentication -client -mapType credentialss -expectedThrowable java.lang.SecurityException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dpassword.file=password.properties -Dusername=usernameFileLoginModule -Dpassword=passwordFileLoginModule SecurityTest -server -mapType x.login.config.UnknownAuthentication -client -mapType credentials -expectedThrowable java.lang.SecurityException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dsusername=usernameSampleLoginModule -Dspassword=passwordSampleLoginModule -Dpassword.file=password.properties -Dusername=usernameSampleLoginModule -Dpassword=passwordSampleLoginModule SecurityTest -server -mapType x.login.config.SampleLoginModule -client -mapType credentials
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dlogin.config.file=${test.src}/login.config -Dsusername=usernameSampleLoginModule -Dspassword=passwordSampleLoginModule -Dpassword.file=password.properties -Dusername=AnotherUsernameSampleLoginModule -Dpassword=passwordSampleLoginModule SecurityTest -server -mapType x.login.config.SampleLoginModule -client -mapType credentials -expectedThrowable java.lang.SecurityException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword WRONG_password -expectedThrowable java.io.IOException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl -keystore keystoreAgent -keystorepassword glopglop -client -expectedThrowable java.io.IOException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -keystore keystoreClient -keystorepassword glopglop -truststore truststoreClient -truststorepassword glopglop
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -keystore keystoreClient -keystorepassword WRONG_password -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -truststore truststoreAgent -truststorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.need.client.authentication -keystore keystoreAgent -keystorepassword glopglop -client -keystore keystoreClient -keystorepassword glopglop -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_MD5 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.md5 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_SHA SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.md5 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledCipherSuites=SSL_RSA_WITH_RC4_128_MD5 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.cipher.suites.sha -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=SSLv3 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.sslv3 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=TLSv1 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.sslv3 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Djavax.rmi.ssl.client.enabledProtocols=SSLv3 SecurityTest -server -mapType rmi.client.socket.factory.ssl;rmi.server.socket.factory.ssl.enabled.protocols.tlsv1 -keystore keystoreAgent -keystorepassword glopglop -client -truststore truststoreClient -truststorepassword glopglop -expectedThrowable java.io.IOException
*/
import java.io.File;
import java.util.Map ;
import java.util.HashMap ;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory ;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.Attribute ;
import javax.management.ObjectName ;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
import java.security.Security;
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.JDKToolFinder;
public class SecurityTest {
static final String SERVER_CLASS_NAME = "SecurityTest";
static final String CLIENT_CLASS_NAME = "SecurityTest$ClientSide";
static final String CLIENT_CLASS_MAIN = CLIENT_CLASS_NAME;
static final String USERNAME_PROPERTY = "username";
static final String PASSWORD_PROPERTY = "password";
static final String SERVER_DELEGATE_MBEAN_NAME =
"defaultDomain:class=ServerDelegate";
static final String RMI_SERVER_SOCKET_FACTORY_SSL = "rmi.server.socket.factory.ssl";
static final String RMI_CLIENT_SOCKET_FACTORY_SSL = "rmi.client.socket.factory.ssl";
static final String KEYSTORE_PROPNAME = "javax.net.ssl.keyStore";
static final String KEYSTORE_PWD_PROPNAME = "javax.net.ssl.keyStorePassword";
static final String TRUSTSTORE_PROPNAME = "javax.net.ssl.trustStore";
static final String TRUSTSTORE_PWD_PROPNAME = "javax.net.ssl.trustStorePassword";
static final String RMI_SSL_CLIENT_ENABLEDCIPHERSUITES =
"javax.rmi.ssl.client.enabledCipherSuites";
static final String RMI_SSL_CLIENT_ENABLEDPROTOCOLS =
"javax.rmi.ssl.client.enabledProtocols";
private JMXConnectorServer cs;
// Construct and set keyStore properties from given map
static void setKeyStoreProperties(Map<String, Object> map) {
String keyStore = (String) map.get("-keystore");
keyStore = buildSourcePath(keyStore);
System.setProperty(KEYSTORE_PROPNAME, keyStore);
System.out.println("keyStore location = \"" + keyStore + "\"");
String password = (String) map.get("-keystorepassword");
System.setProperty(KEYSTORE_PWD_PROPNAME, password);
System.out.println("keyStore password = " + password);
}
// Construct and set trustStore properties from given map
static void setTrustStoreProperties(Map<String, Object> map) {
String trustStore = (String) map.get("-truststore");
trustStore = buildSourcePath(trustStore);
System.setProperty(TRUSTSTORE_PROPNAME, trustStore);
System.out.println("trustStore location = \"" + trustStore + "\"");
String password = (String) map.get("-truststorepassword");
System.setProperty(TRUSTSTORE_PWD_PROPNAME, password);
System.out.println("trustStore password = " + password);
}
/*
* First Debug properties and arguments are collect in expected
* map (argName, value) format, then calls original test's run method.
*/
public static void main(String args[]) throws Exception {
System.out.println("=================================================");
// Parses parameters
Utils.parseDebugProperties();
// Supported parameters list format is :
// "MainClass [-server <param-spec> ...] [-client <param-spec> ...]
// with <param-spec> either "-parami valuei" or "-parami"
HashMap<String, Object> serverMap = new HashMap<>() ;
int clientArgsIndex =
Utils.parseServerParameters(args, SERVER_CLASS_NAME, serverMap);
// Extract and records client params
String[] clientParams = null;
if (clientArgsIndex < args.length) {
int clientParamsSize = args.length - clientArgsIndex;
clientParams = new String[clientParamsSize];
System.arraycopy(args, clientArgsIndex, clientParams, 0, clientParamsSize);
} else {
clientParams = new String[0];
}
// Run test
SecurityTest test = new SecurityTest();
test.run(serverMap, clientParams);
}
// Return full path of filename in the test sopurce directory
private static String buildSourcePath(String filename) {
return System.getProperty("test.src") + File.separator + filename;
}
/*
* Collects security run params for server side.
*/
private HashMap<String, Object> setServerSecurityEnv(Map<String, Object> map)
throws Exception {
// Creates Authentication environment from server side params
HashMap<String, Object> env = new HashMap<>();
// Retrieve and set keystore and truststore config if any
if (map.containsKey("-keystore") &&
map.get("-keystore") != null) {
setKeyStoreProperties(map);
}
System.out.println("Done keystore properties");
if (map.containsKey("-truststore") &&
map.get("-truststore") != null) {
setTrustStoreProperties(map);
}
System.out.println("Done truststore properties");
String value = null;
if ((value = (String)map.get("-mapType")) != null) {
// Case of remote password file with all authorized credentials
if (value.contains("x.password.file")) {
String passwordFileStr = buildSourcePath("password.properties");
env.put("jmx.remote.x.password.file", passwordFileStr);
System.out.println("Added " + passwordFileStr +
" file as jmx.remote.x.password.file");
}
// Case of dedicated authenticator class : TestJMXAuthenticator
if (value.contains("x.authenticator")) {
env.put("jmx.remote.authenticator", new TestJMXAuthenticator()) ;
System.out.println(
"Added \"jmx.remote.authenticator\" = TestJMXAuthenticator");
}
// Case of security config file with standard Authentication
if (value.contains("x.login.config.PasswordFileAuthentication")) {
String loginConfig = System.getProperty("login.config.file");
// Override the default JAAS configuration
System.setProperty("java.security.auth.login.config",
"file:" + loginConfig);
System.out.println("Overrided default JAAS configuration with " +
"\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
env.put("jmx.remote.x.login.config", "PasswordFileAuthentication") ;
System.out.println(
"Added \"jmx.remote.x.login.config\" = " +
"\"PasswordFileAuthentication\"") ;
// redirects "password.file" property to file in ${test.src}
String passwordFileStr =
buildSourcePath(System.getProperty("password.file"));
System.setProperty("password.file", passwordFileStr);
System.out.println(
"Redirected \"password.file\" property value to = " +
passwordFileStr) ;
}
// Case of security config file with unexisting athentication config
if (value.contains("x.login.config.UnknownAuthentication")) {
String loginConfig = System.getProperty("login.config.file");
// Override the default JAAS configuration
System.setProperty("java.security.auth.login.config",
"file:" + loginConfig);
System.out.println("Overrided default JAAS configuration with " +
"\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
env.put("jmx.remote.x.login.config", "UnknownAuthentication") ;
System.out.println(
"Added \"jmx.remote.x.login.config\" = " +
"\"UnknownAuthentication\"") ;
// redirects "password.file" property to file in ${test.src}
String passwordFileStr =
buildSourcePath(System.getProperty("password.file"));
System.setProperty("password.file", passwordFileStr);
System.out.println(
"Redirected \"password.file\" property value to = " +
passwordFileStr) ;
}
// Case of security config file with dedicated login module
if (value.contains("x.login.config.SampleLoginModule")) {
String loginConfig = System.getProperty("login.config.file");
// Override the default JAAS configuration
System.setProperty("java.security.auth.login.config",
"file:" + loginConfig);
System.out.println("Overrided default JAAS configuration with " +
"\"java.security.auth.login.config\" = \"" + loginConfig + "\"") ;
env.put("jmx.remote.x.login.config", "SampleLoginModule") ;
System.out.println(
"Added \"jmx.remote.x.login.config\" = " +
"\"SampleLoginModule\"") ;
}
// Simple rmi ssl authentication
if (value.contains(RMI_CLIENT_SOCKET_FACTORY_SSL)) {
env.put("jmx.remote.rmi.client.socket.factory",
new SslRMIClientSocketFactory()) ;
System.out.println(
"Added \"jmx.remote.rmi.client.socket.factory\"" +
" = SslRMIClientSocketFactory") ;
}
if (value.contains(RMI_SERVER_SOCKET_FACTORY_SSL)) {
if (value.contains(
"rmi.server.socket.factory.ssl.need.client.authentication")) {
// rmi ssl authentication with client authentication
env.put("jmx.remote.rmi.server.socket.factory",
new SslRMIServerSocketFactory(null, null, true)) ;
System.out.println(
"Added \"jmx.remote.rmi.server.socket.factory\"" +
" = SslRMIServerSocketFactory with client authentication") ;
} else if (value.contains("rmi.server.socket.factory.ssl.enabled.cipher.suites.md5")) {
// Allows all ciphering and protocols for testing purpose
Security.setProperty("jdk.tls.disabledAlgorithms", "");
env.put("jmx.remote.rmi.server.socket.factory",
new SslRMIServerSocketFactory(
new String[] {"SSL_RSA_WITH_RC4_128_MD5"}, null, false));
System.out.println(
"Added \"jmx.remote.rmi.server.socket.factory\"" +
" = SslRMIServerSocketFactory with SSL_RSA_WITH_RC4_128_MD5 cipher suite");
} else if (value.contains("rmi.server.socket.factory.ssl.enabled.cipher.suites.sha")) {
// Allows all ciphering and protocols for testing purpose
Security.setProperty("jdk.tls.disabledAlgorithms", "");
env.put("jmx.remote.rmi.server.socket.factory",
new SslRMIServerSocketFactory(
new String[] { "SSL_RSA_WITH_RC4_128_SHA" }, null, false)) ;
System.out.println(
"Added \"jmx.remote.rmi.server.socket.factory\"" +
" = SslRMIServerSocketFactory with SSL_RSA_WITH_RC4_128_SHA cipher suite") ;
} else if (value.contains("rmi.server.socket.factory.ssl.enabled.protocols.sslv3")) {
// Allows all ciphering and protocols for testing purpose
Security.setProperty("jdk.tls.disabledAlgorithms", "");
env.put("jmx.remote.rmi.server.socket.factory",
new SslRMIServerSocketFactory(null, new String[] {"SSLv3"}, false)) ;
System.out.println(
"Added \"jmx.remote.rmi.server.socket.factory\"" +
" = SslRMIServerSocketFactory with SSLv3 protocol") ;
} else if (value.contains("rmi.server.socket.factory.ssl.enabled.protocols.tlsv1")) {
// Allows all ciphering and protocols for testing purpose
Security.setProperty("jdk.tls.disabledAlgorithms", "");
env.put("jmx.remote.rmi.server.socket.factory",
new SslRMIServerSocketFactory(null, new String[] {"TLSv1"}, false)) ;
System.out.println(
"Added \"jmx.remote.rmi.server.socket.factory\"" +
" = SslRMIServerSocketFactory with TLSv1 protocol") ;
} else {
env.put("jmx.remote.rmi.server.socket.factory",
new SslRMIServerSocketFactory());
System.out.println(
"Added \"jmx.remote.rmi.server.socket.factory\"" +
" = SslRMIServerSocketFactory");
}
}
}
return env;
}
/*
* Create the MBeansServer side of the test and returns its address
*/
private JMXServiceURL createServerSide(Map<String, Object> serverMap)
throws Exception {
final int NINETY_SECONDS = 90;
System.out.println("SecurityTest::createServerSide: Start") ;
// Prepare server side security env
HashMap<String, Object> env = setServerSecurityEnv(serverMap);
// Create and start mbean server and connector server
MBeanServer mbs = MBeanServerFactory.newMBeanServer();
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
cs.start();
// Waits availibility of connector server
Utils.waitReady(cs, NINETY_SECONDS);
JMXServiceURL addr = cs.getAddress();
System.out.println("SecurityTest::createServerSide: Done.") ;
return addr;
}
/*
* Creating command-line for running subprocess JVM:
*
* JVM command line is like:
* {test_jdk}/bin/java {defaultopts} -cp {test.class.path} {testopts} main
*
* {defaultopts} are the default java options set by the framework.
*
*/
private List<String> buildCommandLine(String args[]) {
System.out.println("SecurityTest::buildCommandLine: Start") ;
List<String> opts = new ArrayList<>();
opts.add(JDKToolFinder.getJDKTool("java"));
opts.addAll(Arrays.asList(jdk.testlibrary.Utils.getTestJavaOpts()));
// We need to forward some properties to the client side
opts.add("-Dtest.src=" + System.getProperty("test.src"));
String usernameValue = System.getProperty(USERNAME_PROPERTY);
if (usernameValue != null) {
System.out.println("SecurityTest::buildCommandLine: "+
" forward username property to client side");
opts.add("-D" + USERNAME_PROPERTY + "=" + usernameValue);
}
String passwordValue = System.getProperty(PASSWORD_PROPERTY);
if (passwordValue != null) {
System.out.println("SecurityTest::buildCommandLine: "+
" forward password property to client side");
opts.add("-D" + PASSWORD_PROPERTY + "=" + passwordValue);
}
String enabledCipherSuites =
System.getProperty(RMI_SSL_CLIENT_ENABLEDCIPHERSUITES);
if (enabledCipherSuites != null) {
System.out.println("SecurityTest::buildCommandLine: "+
" forward enabledCipherSuites property to client side");
opts.add("-D" + RMI_SSL_CLIENT_ENABLEDCIPHERSUITES +
"=" + enabledCipherSuites);
}
String enabledProtocols =
System.getProperty(RMI_SSL_CLIENT_ENABLEDPROTOCOLS);
if (enabledProtocols != null) {
System.out.println("SecurityTest::buildCommandLine: "+
" forward enabledProtocols property to client side");
opts.add("-D" + RMI_SSL_CLIENT_ENABLEDPROTOCOLS +
"=" + enabledProtocols);
}
opts.add("-cp");
opts.add(System.getProperty("test.class.path", "test.class.path"));
opts.add(CLIENT_CLASS_MAIN);
opts.addAll(Arrays.asList(args));
System.out.println("SecurityTest::buildCommandLine: Done.") ;
return opts;
}
/**
* Runs SecurityTest$ClientSide with the passed options and redirects
* subprocess standard I/O to the current (parent) process. This provides a
* trace of what happens in the subprocess while it is runnning (and before
* it terminates).
*
* @param serviceUrlStr string representing the JMX service Url to connect to.
*/
private int runClientSide(String args[], String serviceUrlStr) throws Exception {
System.out.println("SecurityTest::runClientSide: Start") ;
// Building command-line
List<String> opts = buildCommandLine(args);
opts.add("-serviceUrl");
opts.add(serviceUrlStr);
// Launch separate JVM subprocess
int exitCode = 0;
String[] optsArray = opts.toArray(new String[0]);
ProcessBuilder pb = new ProcessBuilder(optsArray);
Process p = ProcessTools.startProcess("SecurityTest$ClientSide", pb);
// Handling end of subprocess
try {
exitCode = p.waitFor();
if (exitCode != 0) {
System.out.println(
"Subprocess unexpected exit value of [" + exitCode +
"]. Expected 0.\n");
}
} catch (InterruptedException e) {
System.out.println("Parent process interrupted with exception : \n " + e + " :" );
// Parent thread unknown state, killing subprocess.
p.destroyForcibly();
throw new RuntimeException(
"Parent process interrupted with exception : \n " + e + " :" );
} finally {
if (p.isAlive()) {
p.destroyForcibly();
}
System.out.println("SecurityTest::runClientSide: Done") ;
return exitCode;
}
}
public void run(Map<String, Object> serverArgs, String clientArgs[]) {
System.out.println("SecurityTest::run: Start") ;
int errorCount = 0;
try {
// Initialise the server side
JMXServiceURL urlToUse = createServerSide(serverArgs);
// Run client side
errorCount = runClientSide(clientArgs, urlToUse.toString());
if ( errorCount == 0 ) {
System.out.println("SecurityTest::run: Done without any error") ;
} else {
System.out.println(
"SecurityTest::run: Done with " + errorCount + " error(s)");
throw new RuntimeException("errorCount = " + errorCount);
}
cs.stop();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
private static class ClientSide {
private JMXConnector cc = null;
private MBeanServerConnection mbsc = null;
public static void main(String args[]) throws Exception {
// Parses parameters
Utils.parseDebugProperties();
// Supported parameters list format is : "MainClass [-client <param-spec> ...]
// with <param-spec> either "-parami valuei" or "-parami"
HashMap<String, Object> clientMap = new HashMap<>() ;
Utils.parseClientParameters(args, CLIENT_CLASS_NAME, clientMap);
// Run test
ClientSide test = new ClientSide();
test.run(clientMap);
}
public void run(Map<String, Object> args) {
System.out.println("ClientSide::run: Start");
int errorCount = 0;
try {
// Setup client side parameters
HashMap<String, Object> env = new HashMap<>();
// If needed allows all ciphering and protocols for testing purpose
if (System.getProperty(RMI_SSL_CLIENT_ENABLEDCIPHERSUITES) != null) {
Security.setProperty("jdk.tls.disabledAlgorithms", "");
}
// If needed allows all ciphering and protocols for testing purpose
if (System.getProperty(RMI_SSL_CLIENT_ENABLEDPROTOCOLS) != null) {
Security.setProperty("jdk.tls.disabledAlgorithms", "");
}
// Retrieve and set keystore and truststore config if any
if (args.containsKey("-keystore") &&
args.get("-keystore") != null) {
SecurityTest.setKeyStoreProperties(args);
}
if (args.containsKey("-truststore") &&
args.get("-truststore") != null) {
SecurityTest.setTrustStoreProperties(args);
}
Object value = args.get("-mapType");
if ((value != null) &&
value.equals("credentials")) {
String username = System.getProperty("username");
String password = System.getProperty("password");
Utils.debug(Utils.DEBUG_STANDARD,
"add \"jmx.remote.credentials\" = \"" +
username + "\", \"" + password + "\"");
env.put("jmx.remote.credentials",
new String[] { username , password });
}
String expectedThrowable = (String) args.get("-expectedThrowable");
String authCallCountName = "-expectedAuthenticatorCallCount";
int authCallCountValue = 0;
if (args.containsKey(authCallCountName)) {
authCallCountValue =
(new Integer((String) args.get(authCallCountName))).intValue();
}
try {
// Get a connection to remote mbean server
JMXServiceURL addr = new JMXServiceURL((String)args.get("-serviceUrl"));
cc = JMXConnectorFactory.connect(addr,env);
mbsc = cc.getMBeanServerConnection();
// In case we should have got an exception
if (expectedThrowable != null) {
System.out.println("ClientSide::run: (ERROR) " +
" Connect did not fail with expected " + expectedThrowable);
errorCount++;
} else {
System.out.println("ClientSide::run: (OK) Connect succeed");
}
} catch (Throwable e) {
Utils.printThrowable(e, true);
if (expectedThrowable != null) {
if (Utils.compareThrowable(e, expectedThrowable)) {
System.out.println("ClientSide::run: (OK) " +
"Connect failed with expected " + expectedThrowable);
} else {
System.out.println("ClientSide::run: (ERROR) Connect failed with " +
e.getClass() + " instead of expected " +
expectedThrowable);
errorCount++;
}
} else {
System.out.println("ClientSide::run: (ERROR) " +
"Connect failed with exception");
errorCount++;
}
}
// Depending on the client state,
// perform some requests
if (mbsc != null && errorCount == 0) {
// Perform some little JMX requests
System.out.println("ClientSide::run: Start sending requests");
doRequests();
// In case authentication has been used we check how it did.
if (authCallCountValue != 0) {
errorCount += checkAuthenticator(mbsc, authCallCountValue);
}
}
} catch (Exception e) {
Utils.printThrowable(e, true);
errorCount++;
} finally {
// Terminate the JMX Client if any
if (cc != null) {
try {
cc.close();
} catch (Exception e) {
Utils.printThrowable(e, true) ;
errorCount++;
}
}
}
System.out.println("ClientSide::run: Done");
// Handle result
if (errorCount != 0) {
throw new RuntimeException();
}
}
private void doRequests() throws Exception {
// Send some requests to the remote JMX server
ObjectName objName1 =
new ObjectName("TestDomain:class=MBS_Light,rank=1");
String mbeanClass = "MBS_Light";
Exception exception = new Exception("MY TEST EXCEPTION");
Attribute attException = new Attribute("AnException", exception);
Error error = new Error("MY TEST ERROR");
Attribute attError = new Attribute("AnError", error);
String opParamString = "TOTORO";
RjmxMBeanParameter opParam = new RjmxMBeanParameter(opParamString);
Object[] params1 = {opParamString};
String[] sig1 = {"java.lang.String"};
Object[] params2 = {opParam};
String[] sig2 = {"RjmxMBeanParameter"};
// Create and register the MBean
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::doRequests: Create and register the MBean");
mbsc.createMBean(mbeanClass, objName1);
if (!mbsc.isRegistered(objName1)) {
throw new Exception("Unable to register an MBean");
}
// Set attributes of the MBean
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::doRequests: Set attributes of the MBean");
mbsc.setAttribute(objName1, attException);
mbsc.setAttribute(objName1, attError);
// Get attributes of the MBean
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::doRequests: Get attributes of the MBean");
Exception retException =
(Exception) mbsc.getAttribute(objName1,"AnException");
if (!retException.getMessage().equals(exception.getMessage())) {
System.out.println("Expected = " + exception);
System.out.println("Got = " + retException);
throw new Exception("Attribute AnException not as expected");
}
Error retError = (Error) mbsc.getAttribute(objName1, "AnError");
if (!retError.getMessage().equals(error.getMessage())) {
System.out.println("Expected = " + error);
System.out.println("Got = " + retError);
throw new Exception("Attribute AnError not as expected");
}
// Invoke operations on the MBean
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::doRequests: Invoke operations on the MBean");
RjmxMBeanParameter res1 =
(RjmxMBeanParameter) mbsc.invoke(objName1, "operate1", params1, sig1);
if (!res1.equals(opParam)) {
System.out.println("Expected = " + opParam);
System.out.println("Got = " + res1);
throw new Exception("Operation operate1 behaved badly");
}
String res2 =
(String) mbsc.invoke(objName1, "operate2", params2, sig2);
if (!res2.equals(opParamString)) {
System.out.println("Expected = " + opParamString);
System.out.println("Got = " + res2);
throw new Exception("Operation operate2 behaved badly");
}
// Unregister the MBean
Utils.debug(Utils.DEBUG_STANDARD,
"ClientSide::doRequests: Unregister the MBean");
mbsc.unregisterMBean(objName1);
if (mbsc.isRegistered(objName1)) {
throw new Exception("Unable to unregister an MBean");
}
}
/**
* Make some check about the instance of TestJMXAuthenticator.
* The authenticator is supposed to have set some properties on
* a ServerDelegate MBean.
* We compare the number of times it has been called with the expected value.
* We also check the Principal that has been given to the authenticator
* was not null.
* That method is of use to authentication with the JSR 262.
* @param mbs
* @param expectedAuthenticatorCallCount
* @return The number of errors encountered.
* @throws java.lang.Exception
*/
protected int checkAuthenticator(MBeanServerConnection mbs,
int expectedAuthenticatorCallCount) throws Exception {
int errorCount = 0;
// Ensure the authenticator has been called the right number
// of times.
int callCount =
((Integer) mbs.getAttribute(
new ObjectName(SERVER_DELEGATE_MBEAN_NAME),
"TestJMXAuthenticatorCallCount")).intValue();
if (callCount == expectedAuthenticatorCallCount) {
System.out.println("---- OK Authenticator has been called "
+ expectedAuthenticatorCallCount + " time");
} else {
errorCount++;
System.out.println("---- ERROR Authenticator has been called " + callCount
+ " times in place of " + expectedAuthenticatorCallCount);
}
// Ensure the provider has been called with
// a non null Principal.
String principalString =
(String) mbs.getAttribute(
new ObjectName(SERVER_DELEGATE_MBEAN_NAME),
"TestJMXAuthenticatorPrincipalString");
if (principalString == null) {
errorCount++;
System.out.println("---- ERROR Authenticator has been called"
+ " with a null Principal");
} else {
if (principalString.length() > 0) {
System.out.println("---- OK Authenticator has been called"
+ " with the Principal " + principalString);
} else {
errorCount++;
System.out.println("---- ERROR Authenticator has been called"
+ " with an empty Principal");
}
}
return errorCount;
}
}
}

View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;
import javax.management.remote.JMXServiceURL ;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.StandardMBean;
/**
* This class defines an MBean that can be registered and used on client side
* to handle informations or properties of the remote server.
*
* For example, this MBean can store IOR addresses
* of RMI/IIOP connector(s) used in a test.
*
* That MBean might not be used for testing purpose itself.
*/
public class ServerDelegate implements ServerDelegateMBean, MBeanRegistration {
private MBeanServer mbeanServer = null;
private List<JMXServiceURL> addresses = null;
private String port;
private static String javaVersion = System.getProperty("java.version");
private int sqeJmxwsCredentialsProviderCallCount = 0;
private String jmxwsCredentialsProviderUrl = null;
private int testJMXAuthenticatorCallCount = 0;
private Principal testJMXAuthenticatorPrincipal = null;
@SqeDescriptorKey("NO PARAMETER CONSTRUCTOR ServerDelegate")
public ServerDelegate() {
addresses = new ArrayList<JMXServiceURL>();
}
public ObjectName preRegister(MBeanServer server, ObjectName name)
throws Exception {
// Initialize MBeanServer attribute
mbeanServer = server;
return name;
}
public void postRegister(Boolean registrationDone) {
}
public void preDeregister() throws Exception {
}
public void postDeregister() {
}
public void addAddress(JMXServiceURL url) {
addresses.add(url) ;
}
public List<JMXServiceURL> getAddresses() {
return addresses ;
}
public void setPort(String p) {
port = p ;
}
public String getPort() {
return port ;
}
public String getJavaVersion() {
return javaVersion;
}
public void sqeJmxwsCredentialsProviderCalled() {
sqeJmxwsCredentialsProviderCallCount++;
}
public int getSqeJmxwsCredentialsProviderCallCount() {
return sqeJmxwsCredentialsProviderCallCount;
}
public void setJmxwsCredentialsProviderUrl(String url) {
jmxwsCredentialsProviderUrl = url;
}
public String getJmxwsCredentialsProviderUrl() {
return jmxwsCredentialsProviderUrl;
}
public void testJMXAuthenticatorCalled() {
testJMXAuthenticatorCallCount++;
}
public int getTestJMXAuthenticatorCallCount() {
return testJMXAuthenticatorCallCount;
}
public void setTestJMXAuthenticatorPrincipal(Principal principal) {
testJMXAuthenticatorPrincipal = principal;
}
public String getTestJMXAuthenticatorPrincipalString() {
if ( testJMXAuthenticatorPrincipal != null ) {
return testJMXAuthenticatorPrincipal.toString();
}
return null;
}
/**
* Instantiates and registers a StandardMBean in the MBean server.
*
* @param implementationClassName
* The implementation class name of the MBean.
* @param interfaceClassName
* The management interface class name of the MBean.
* @param isMXBean
* If true, the resultant MBean is an MXBean.
* @param name
* The object name of the StandardMBean.
*/
@SuppressWarnings("unchecked")
public void createStandardMBean(
String implementationClassName,
String interfaceClassName,
boolean isMXBean,
ObjectName name)
throws Exception {
Object implementation =
Class.forName(implementationClassName).newInstance();
Class<Object> interfaceClass = interfaceClassName == null ? null :
(Class<Object>)Class.forName(interfaceClassName);
// Create the StandardMBean
StandardMBean standardMBean = new StandardMBean(
implementation,
interfaceClass,
isMXBean);
// Register the StandardMBean
mbeanServer.registerMBean(standardMBean, name);
}
/**
* Instantiates and registers a StandardMBean in the MBean server.
* The object will use standard JMX design pattern to determine
* the management interface associated with the given implementation.
*/
@SuppressWarnings("unchecked")
public void createStandardMBean(
String implementationClassName,
boolean isMXBean,
ObjectName name)
throws Exception {
createStandardMBean(implementationClassName, null, isMXBean, name);
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.security.Principal;
import java.util.List;
import javax.management.remote.JMXServiceURL ;
import javax.management.ObjectName;
@SqeDescriptorKey("INTERFACE ServerDelegateMBean")
public interface ServerDelegateMBean {
@SqeDescriptorKey("ATTRIBUTE Address")
public void addAddress(JMXServiceURL url);
@SqeDescriptorKey("ATTRIBUTE Address")
public List<JMXServiceURL> getAddresses();
public String getPort();
public void setPort(String p);
public String getJavaVersion();
public void sqeJmxwsCredentialsProviderCalled();
public int getSqeJmxwsCredentialsProviderCallCount();
public void setJmxwsCredentialsProviderUrl(String url);
public String getJmxwsCredentialsProviderUrl();
public void testJMXAuthenticatorCalled();
public int getTestJMXAuthenticatorCallCount();
public void setTestJMXAuthenticatorPrincipal(Principal principal);
public String getTestJMXAuthenticatorPrincipalString();
public void createStandardMBean(
String implementationClassName,
String interfaceClassName,
boolean isMXBean,
ObjectName name)
throws Exception;
public void createStandardMBean(
String implementationClassName,
boolean isMXBean,
ObjectName name)
throws Exception;
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
//import java.beans.ConstructorProperties;
import javax.management.ConstructorParameters;
/**
* This class defines a simple standard MBean.
*/
public class Simple implements SimpleMBean {
private String attribute = "initial_value";
private boolean operationInvoked = false;
private boolean operation2Invoked = false;
@SqeDescriptorKey("NO PARAMETER CONSTRUCTOR Simple")
public Simple() {
}
@SqeDescriptorKey("TWO PARAMETERS CONSTRUCTOR Simple")
@ConstructorParameters({"unused1", "unused2"})
public Simple(@SqeDescriptorKey("CONSTRUCTOR PARAMETER unused1")int unused1,
@SqeDescriptorKey("CONSTRUCTOR PARAMETER unused2")int unused2) {
}
public String getAttribute() {
return attribute;
}
public void setAttribute(String s) {
attribute = s;
}
public boolean getOperationInvoked() {
return operationInvoked;
}
public boolean getOperation2Invoked() {
return operation2Invoked;
}
public void operation() {
operationInvoked = true;
return;
}
public String operation2(int i) {
operation2Invoked = true;
return String.valueOf(i);
}
public void reset() {
attribute = "initial_value";
operationInvoked = false;
operation2Invoked = false;
}
}

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
// JDK
import java.util.Vector;
// JMX
import javax.management.NotificationListener;
import javax.management.Notification;
public class SimpleListener implements NotificationListener {
private boolean received = false;
private String type = null;
private Object handback = null;
private Vector<Object> handbacks = new Vector<Object>();
private int nbrec = 0;
public synchronized void handleNotification(Notification notification,
Object handback) {
Utils.debug(Utils.DEBUG_STANDARD,
"SimpleListener::handleNotification :" + notification);
try {
received = true;
type = notification.getType();
this.handback = handback;
handbacks.add(handback);
nbrec++;
notify();
} catch(Exception e) {
System.out.println("(ERROR) SimpleListener::handleNotification :"
+ " Caught exception "
+ e) ;
}
}
public synchronized boolean isNotificationReceived() {
boolean ret = received;
reset();
return ret;
}
public synchronized Object[] waitForMultiNotifications(int nb) {
while(true) {
if(nbrec < nb) {
Utils.debug(Utils.DEBUG_STANDARD,
"SimpleListener::waitForMultiNotifications wait");
try {
wait();
} catch(InterruptedException ie) {
// OK : we wait for being interrupted
}
Utils.debug(Utils.DEBUG_STANDARD,
"SimpleListener::waitForMultiNotifications wait over");
}
else
break;
}
Object[] ret = handbacks.toArray();
reset();
return ret;
}
private void reset() {
received = false;
handback = null;
handbacks.removeAllElements();
type = null;
}
public synchronized Object waitForNotificationHB() {
while(true) {
if(!received) {
Utils.debug(Utils.DEBUG_STANDARD,
"SimpleListener::waitForNotificationHB wait");
try {
wait();
} catch(InterruptedException ie) {
// OK : we wait for being interrupted
}
Utils.debug(Utils.DEBUG_STANDARD,
"SimpleListener::waitForNotificationHB received");
}
else
break;
}
Object ret = handback;
reset();
return ret;
}
public synchronized String waitForNotification() {
while(true) {
if(!received) {
Utils.debug(Utils.DEBUG_STANDARD,
"SimpleListener::waitForNotification wait");
try {
wait();
} catch(InterruptedException ie) {
// OK : we wait for being interrupted
}
Utils.debug(Utils.DEBUG_STANDARD,
"SimpleListener::waitForNotification received");
}
else
break;
}
String ret = type;
reset();
return ret;
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
/**
* This interface defines a simple standard MBean.
*/
@SqeDescriptorKey("INTERFACE SimpleMBean")
public interface SimpleMBean {
@SqeDescriptorKey("ATTRIBUTE Attribute")
public String getAttribute();
@SqeDescriptorKey("ATTRIBUTE Attribute")
public void setAttribute(String s);
@SqeDescriptorKey("ATTRIBUTE OperationInvoked")
public boolean getOperationInvoked();
@SqeDescriptorKey("ATTRIBUTE Operation2Invoked")
public boolean getOperation2Invoked();
// Void operation
// The associated MBeanOperationInfo is mapped to OpenMBeanOperationInfo
// => openType is added to the descriptor
@SqeDescriptorKey(value = "OPERATION operation",
descriptorFields = {"openType=SimpleType.VOID"})
public void operation();
@SqeDescriptorKey("OPERATION operation2")
public String operation2(int i);
// Void operation
// The associated MBeanOperationInfo is mapped to OpenMBeanOperationInfo
// => openType is added to the descriptor
@SqeDescriptorKey(value = "OPERATION reset",
descriptorFields = {"openType=SimpleType.VOID"})
public void reset();
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.management.DescriptorKey;
/**
* That annotation is usable everywhere DescriptorKey is (and even more).
* It is for use to test that you can retrieve the SqeDescriptorKey into the
* appropriate Descriptor instances as built by the JMX runtime.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface SqeDescriptorKey {
@DescriptorKey("sqeDescriptorKey")
String value();
// List descriptor fields that may be added or may be updated
// when retrieving an MBeanInfo using a JMXWS connection compared to the
// MBeanInfo returned by a local MBeanServer.
// The annotation format is :
// <descriptorFieldName>=<descriptorFieldValue>
// The values actually handled by the test suite are :
// openType=SimpleType.VOID
@DescriptorKey("descriptorFields")
String[] descriptorFields() default {};
}

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.security.Principal;
import javax.management.Attribute;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
public final class TestJMXAuthenticator implements JMXAuthenticator {
private String protocol = "";
private MBeanServer mbs = null;
public TestJMXAuthenticator() {
}
public TestJMXAuthenticator(String protocol) {
this.protocol = protocol;
}
public TestJMXAuthenticator(String protocol, MBeanServer mbs) {
this.protocol = protocol;
this.mbs = mbs;
}
public Subject authenticate(Object credentials) {
String credentials_username = "";
String credentials_password = "";
Principal aPrincipal = null;
credentials_username = ((String[]) credentials)[0];
credentials_password = ((String[]) credentials)[1];
String authenticated_username = System.getProperty("susername");
String authenticated_password = System.getProperty("spassword");
String principal = System.getProperty("principal");
System.out.println("TestJMXAuthenticator::authenticate: Start");
System.out.println("TestJMXAuthenticator::authenticate: credentials username = " +
credentials_username);
System.out.println("TestJMXAuthenticator::authenticate: credentials password = " +
credentials_password);
System.out.println("TestJMXAuthenticator::authenticate: authenticated username = " +
authenticated_username);
System.out.println("TestJMXAuthenticator::authenticate: authenticated password = " +
authenticated_password);
System.out.println("TestJMXAuthenticator::authenticate: principal used for " +
"authorization = " + principal);
if (credentials_username.equals(authenticated_username) &&
credentials_password.equals(authenticated_password)) {
System.out.println("TestJMXAuthenticator::authenticate: " +
"Authenticator should succeed");
} else {
System.out.println("TestJMXAuthenticator::authenticate: " +
"Authenticator should reject");
throw new SecurityException("TestJMXAuthenticator throws EXCEPTION");
}
// At this point, authentication has succeeded
// (no SecurityException thrown).
//
// If no authorization is required, the returned subject (empty or not)
// is useless.
// Otherwise, the returned subject must define a principal
// and authorization will be performed against this principal.
//
// Note that this custom JMXAuthenticator is used for test purpose and
// the username used to perform authentication may be different from the
// username used to perform authorization.
//
Subject subject = new Subject();
if (principal != null) {
System.out.println("TestJMXAuthenticator::authenticate: " +
"Add " + principal + " principal to the returned subject");
subject.getPrincipals().add(new JMXPrincipal(principal));
}
return subject;
}
}

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
public final class TestSampleLoginModule implements LoginModule {
private Subject subject;
private CallbackHandler callbackHandler;
private Map<String, ?> sharedState;
private Map<String, ?> options;
public TestSampleLoginModule() {
}
public void initialize(Subject subject,
CallbackHandler callbackHandler,
Map<String,?> sharedState,
Map<String,?> options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;
}
/*
* Authenticate the user by comparing the values of the java properties
* (username and password) against the values of the credentials.
* */
public boolean login() throws LoginException {
String credentials_username = null;
String credentials_password = null;
String authenticated_username = System.getProperty("susername");
String authenticated_password = System.getProperty("spassword");
System.out.println("TestSampleLoginModule::login: Start");
// First retreive the credentials {username, password} from
// the callback handler
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("username");
callbacks[1] = new PasswordCallback("password", false);
try {
callbackHandler.handle(callbacks);
credentials_username = ((NameCallback)callbacks[0]).getName();
credentials_password = new String(((PasswordCallback)callbacks[1]).
getPassword());
} catch (Exception e) {
throw new LoginException(e.toString());
}
System.out.println("TestSampleLoginModule::login: credentials username = " +
credentials_username);
System.out.println("TestSampleLoginModule::login: credentials password = " +
credentials_password);
System.out.println("TestSampleLoginModule::login: authenticated username = " +
authenticated_username);
System.out.println("TestSampleLoginModule::login: authenticated password = " +
authenticated_password);
if (credentials_username.equals(authenticated_username) &&
credentials_password.equals(authenticated_password)) {
System.out.println("TestSampleLoginModule::login: " +
"Authentication should succeed");
return true;
} else {
System.out.println("TestSampleLoginModule::login: " +
"Authentication should reject");
throw new LoginException("TestSampleLoginModule throws EXCEPTION");
}
}
public boolean commit() throws LoginException {
return true;
}
public boolean abort() throws LoginException {
return true;
}
public boolean logout() throws LoginException {
return true;
}
}

View File

@ -0,0 +1,424 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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.
*/
import java.util.Map;
import java.util.HashMap;
import java.util.Properties;
import java.util.StringTokenizer;
import java.lang.reflect.Method;
import javax.management.remote.JMXConnectorServerMBean;
// utility class for MXBean* tests coming from JMX Tonga test suite
class Utils {
private static final String SERVER_SIDE_NAME = "-server";
private static final String CLIENT_SIDE_NAME = "-client";
// DEBUG is printed depending on the DEBUG and DEBUG_LEVEL JAVA property
private static final String DEBUG_HEADER = "[debug] ";
// DEBUG levels
private static int selectedDebugLevel = 0;
static final int DEBUG_STANDARD = 1;
static final int DEBUG_VERBOSE = 2; // Mainly used for stress tests
static final int DEBUG_ALL = DEBUG_STANDARD | DEBUG_VERBOSE;
static void parseDebugProperties() {
int level = 0;
Properties p = System.getProperties();
// get selected levels
if (p.getProperty("DEBUG_STANDARD") != null) {
level |= DEBUG_STANDARD;
}
if (p.getProperty("DEBUG_VERBOSE") != null) {
level |= DEBUG_VERBOSE;
}
if (p.getProperty("DEBUG_ALL") != null) {
level |= DEBUG_ALL;
}
selectedDebugLevel = level;
}
/**
* Reproduces the original parsing and collection of test parameters
* from the DTonga JMX test suite.
*
* Collects passed args and returns them in a map(argname, value) structure,
* which will be then propagated as necessary to various called methods.
*/
static Map<String, Object> parseParameters(String args[])
throws Exception {
Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Start");
HashMap<String, Object> map = new HashMap<>();
for ( int i = 0; i < args.length; i++ ) {
if ( args[i].trim().startsWith("-") ) {
if ((i+1) < args.length && !args[i+1].startsWith("-") ) {
Utils.debug(DEBUG_STANDARD,
"TestRoot::parseParameters: added in map = " +
args[i] +
" with value " +
args[i+1]) ;
map.put(args[i].trim(), args[i+1].trim()) ;
} else if ((i+1) < args.length && args[i+1].startsWith("-") ||
(i+1) == args.length ) {
Utils.debug(DEBUG_STANDARD,
"TestRoot::parseParameters: added in map = " +
args[i] +
" with null value") ;
map.put(args[i].trim(), null) ;
} else {
System.out.println(
"TestRoot::parseParameters: (WARNING) not added in map = " +
args[i]) ;
}
}
}
Utils.debug(DEBUG_STANDARD, "TestRoot::parseParameters: Done") ;
return map ;
}
// Parse server parameters and put them in passed serverMap
static int parseServerParameters(String args[],
String serverSideName,
Map<String, Object> serverMap )
throws Exception {
Utils.debug(Utils.DEBUG_STANDARD,
serverSideName + "::parseServerParameters: Start");
int nextIndex = 0;
boolean seenServerFlag = false;
for ( int i = 0; i < args.length; i++ ) {
// Case of reaching "-server" flag parameter
if (args[i].equals(SERVER_SIDE_NAME)) {
if (!seenServerFlag) {
seenServerFlag = true;
continue;
} else {
// Already parsing server params, invalid params list
Utils.debug(Utils.DEBUG_STANDARD,
serverSideName + "::parseParameters: Invalid " +
args[i] + " parameter detected in " +
SERVER_SIDE_NAME + " parameters list");
nextIndex = -1;
throw new RuntimeException("Invalid Parameter list");
}
}
// Case of reaching "-client" flag parameter
if (args[i].equals(CLIENT_SIDE_NAME)) {
// While parsing server parameters, then parsing is done.
Utils.debug(Utils.DEBUG_STANDARD,
serverSideName + "::parseServerParameters: Parsing of " +
SERVER_SIDE_NAME + " parameters done.");
return i;
}
i = parseParamAtIndex(args, i, serverMap);
nextIndex = i;
}
Utils.debug(Utils.DEBUG_STANDARD,
serverSideName + "::parseServerParameters: Parsing of parameters done");
return nextIndex;
}
// Parse client parameters and put them in passed clientMap
static void parseClientParameters(String args[],
String clientSideName,
Map<String, Object> clientMap )
throws Exception {
Utils.debug(Utils.DEBUG_STANDARD,
clientSideName + "::parseClientParameters: Start");
boolean seenClientFlag = false;
for ( int i = 0; i < args.length; i++ ) {
// Case of reaching "-client" flag parameter
if (args[i].equals(CLIENT_SIDE_NAME)) {
if (!seenClientFlag) {
seenClientFlag = true;
continue;
} else {
// Already parsing client params, invalid params list
Utils.debug(Utils.DEBUG_STANDARD,
clientSideName + "::parseClientParameters: Invalid " +
CLIENT_SIDE_NAME + " parameter detected in " +
CLIENT_SIDE_NAME + " parameters list.");
throw new RuntimeException("Invalid parameter in " +
clientSideName + " parameter list");
}
}
// Case of reaching "-server" flag parameter
if (args[i].equals(SERVER_SIDE_NAME)) {
// While parsing client parameters, invalid parameter list.
Utils.debug(Utils.DEBUG_STANDARD,
clientSideName + "::parseClientParameters: Invalid " +
SERVER_SIDE_NAME + " parameter inside " +
CLIENT_SIDE_NAME + " parameters list.");
throw new RuntimeException("Invalid parameter in " +
clientSideName + " parameter list");
}
i = parseParamAtIndex(args, i, clientMap);
}
Utils.debug(Utils.DEBUG_STANDARD,
clientSideName + "::parseClientParameters: Parsing of parameters done.");
}
// Add param found at index to passed map
// We only accept either "-param value" or "-param" form.
// The "value" form is invalid but just ignored.
private static int parseParamAtIndex(String args[],
int index,
Map<String, Object> map) {
if (args[index].trim().startsWith("-") ) {
// Case of a "-param value" form
if ((index+1) < args.length && !args[index+1].startsWith("-") ) {
Utils.debug(Utils.DEBUG_STANDARD,
"TestRoot::parseParamAtIndex: added in map = "
+ args[index]
+ " with value "
+ args[index+1]) ;
// adding ("param", value) to the passed map
map.put(args[index].trim(), args[index+1].trim()) ;
// value should not be parsed a second time
return index+1;
}
// Case of a "-param" form (flag parameter)
else if (((index+1) < args.length && args[index+1].startsWith("-")) ||
(index+1) == args.length ) {
Utils.debug(Utils.DEBUG_STANDARD,
"TestRoot::parseParamAtIndex: added in map = "
+ args[index]
+ " with null value") ;
// adding ("param", null) to passed map
map.put(args[index].trim(), null) ;
}
} else {
// Unsupported "value" alone parameter
Utils.debug(Utils.DEBUG_STANDARD,
"TestRoot::parseParamAtIndex: invalid " +
" value-alone \"" + args[index] + "\" parameter." +
" Parameter ignored.");
}
return index;
}
/**
* This method is to be used in all tests to print anything
* that is temporary.
* Printing is done only when debug is activated by the property DEBUG.
* Printing depends also on the DEBUG_LEVEL property.
* Here it encapsulates a System.out.println.
*/
static void debug(int level, String line) {
if ((selectedDebugLevel & level) != 0) {
System.out.println(DEBUG_HEADER + line);
}
}
/**
* Do print stack trace when withStack is true.
* Does try to call getTargetException() and getTargetError() then
* print embedded stacks in the case of an Exception wrapping
* another Exception or an Error. Recurse until no more wrapping
* is found.
*/
static void printThrowable(Throwable theThro, boolean withStack) {
try {
if (withStack) {
theThro.printStackTrace(System.out);
}
if (theThro instanceof Exception) {
Exception t = (Exception) theThro;
Method target = null;
String blank = " ";
try {
target = t.getClass().getMethod("getTargetException",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetException method could be there or not
}
System.out.println(blank + t.getClass() + "==>" + t.getMessage());
while (target != null) {
try {
t = (Exception) target.invoke(t,
(java.lang.Object[]) null);
} catch (Exception ee) {
t = null;
}
try {
if (t != null) {
blank = blank + " ";
System.out.println(blank + t.getClass() + "==>" +
t.getMessage());
try {
target =
t.getClass().getMethod("getTargetException",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetException method could be there or not }
}
} else {
target = null;
}
} catch (Exception ee) {
target = null;
}
}
// We may have exceptions wrapping an Error then it is
// getTargetError that is likely to be called
try {
target = ((Exception) theThro).getClass().getMethod("getTargetError",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetError method could be there or not
}
Throwable err = theThro;
while (target != null) {
try {
err = (Error) target.invoke(err,
(java.lang.Object[]) null);
} catch (Exception ee) {
err = null;
}
try {
if (err != null) {
blank = blank + " ";
System.out.println(blank + err.getClass() + "==>" +
err.getMessage());
if (withStack) {
err.printStackTrace(System.out);
}
try {
target = err.getClass().getMethod("getTargetError",
(java.lang.Class<?>[]) null);
} catch (Exception ee) {
// OK: getTargetError method could be there or not
}
} else {
target = null;
}
} catch (Exception ee) {
target = null;
}
}
} else {
System.out.println("Throwable is : " + theThro);
}
} catch (Throwable x) {
System.out.println("Exception : raised in printException : " + x);
}
}
/**
* Wait up to maxTimeInSeconds second(s) the given JMX connector server
* comes up (which means isActive returns true).
* If it fails to do so we throw a RunTime exception.
*/
static void waitReady(JMXConnectorServerMBean server,
int maxTimeInSeconds) throws Exception {
int elapsed = 0;
while (!server.isActive() && elapsed < maxTimeInSeconds) {
Thread.sleep(1000);
elapsed++;
}
if (server.isActive()) {
String message = "Utils::waitReady: JMX connector server came up";
if ( elapsed == 0) {
message += " immediately";
} else {
message += " after " + elapsed + " seconds";
}
message += " [" + server.getAddress() + "]";
Utils.debug(DEBUG_STANDARD, message);
} else {
String message = "Utils::waitReady: (ERROR) JMX connector" +
" server didn't come up after " + elapsed + " seconds [" +
server.getAddress() + "]";
System.out.println(message);
throw new RuntimeException(message);
}
}
/**
* This method is used to compare the specified Throwable and possibly
* the derived causes to the specified String argument.
* The expected String argument format is :
* throwable_1;throwable_2;...;throwable_N
* where throwable_i can be :
* - either a throwable class name
* - or the "*" character meaning several unknown throwable class names
* This character must be followed by a throwable class name
*/
static boolean compareThrowable(
Throwable t,
String expectedThrowable) {
// First parse the expectedThrowable String
StringTokenizer tokenizer = new StringTokenizer(expectedThrowable, ";");
String token = null;
try {
while (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
if (!token.equals("*")) {
if (!Class.forName(token).isInstance(t)) {
return false;
}
} else {
token = tokenizer.nextToken();
while (!Class.forName(token).isInstance(t)) {
t = t.getCause();
if (t == null) {
return false;
}
}
}
t = t.getCause();
}
} catch (ClassNotFoundException cnfe) {
String msg = "Expected throwable class(es) " + expectedThrowable +
" cannot be located";
System.out.println(msg);
throw new IllegalArgumentException(msg);
}
return true;
}
}

View File

@ -0,0 +1,11 @@
# Access control file for SQE tests.
# Default username
SQE_username readwrite create Simple
# Functional authorization tests
username1 readwrite create Simple
username2 readonly
username3 readonly
username4 readwrite create Simple
username5 readwrite create Simple

View File

@ -0,0 +1,98 @@
// Standard extensions get all permissions by default
grant codeBase "file:${java.home}/lib/ext/*" {
permission java.security.AllPermission;
};
// default permissions granted to all domains
grant {
// Allows any thread to stop itself using the java.lang.Thread.stop()
// method that takes no argument.
// Note that this permission is granted by default only to remain
// backwards compatible.
// It is strongly recommended that you either remove this permission
// from this policy file or further restrict it to code sources
// that you specify, because Thread.stop() is potentially unsafe.
// See "http://java.sun.com/notes" for more information.
permission java.lang.RuntimePermission "stopThread";
// allows anyone to listen on un-privileged ports
permission java.net.SocketPermission "localhost:1024-", "listen";
// "standard" properies that can be read by anyone
permission java.util.PropertyPermission "java.version", "read";
permission java.util.PropertyPermission "java.vendor", "read";
permission java.util.PropertyPermission "java.vendor.url", "read";
permission java.util.PropertyPermission "java.class.version", "read";
permission java.util.PropertyPermission "os.name", "read";
permission java.util.PropertyPermission "os.version", "read";
permission java.util.PropertyPermission "os.arch", "read";
permission java.util.PropertyPermission "file.separator", "read";
permission java.util.PropertyPermission "path.separator", "read";
permission java.util.PropertyPermission "line.separator", "read";
permission java.util.PropertyPermission "java.specification.version", "read";
permission java.util.PropertyPermission "java.specification.vendor", "read";
permission java.util.PropertyPermission "java.specification.name", "read";
permission java.util.PropertyPermission "java.vm.specification.version", "read";
permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
permission java.util.PropertyPermission "java.vm.specification.name", "read";
permission java.util.PropertyPermission "java.vm.version", "read";
permission java.util.PropertyPermission "java.vm.vendor", "read";
permission java.util.PropertyPermission "java.vm.name", "read";
permission java.io.FilePermission "*","read,write";
};
grant codeBase "file:/-" {
permission java.security.AllPermission;
permission java.io.FilePermission "*","read,write";
};
grant principal javax.management.remote.JMXPrincipal "SQE_username" {
permission javax.management.MBeanServerPermission "*";
permission javax.management.MBeanPermission "Simple", "instantiate";
permission javax.management.MBeanPermission "Simple", "registerMBean";
};
grant principal javax.management.remote.JMXPrincipal "username1" {
//
// JMXPrincipals "username1" has all permissions.
//
permission java.security.AllPermission;
};
grant principal javax.management.remote.JMXPrincipal "username2" {
//
// JMXPrincipals "username2" has all permissions.
//
permission java.security.AllPermission;
};
grant principal javax.management.remote.JMXPrincipal "username3" {
//
// JMXPrincipals "username3" has some permissions.
//
permission javax.management.MBeanPermission "Simple", "instantiate";
permission javax.management.MBeanPermission "Simple", "registerMBean";
permission javax.management.MBeanPermission "Simple", "setAttribute";
permission javax.management.MBeanPermission "Simple", "invoke";
};
grant principal javax.management.remote.JMXPrincipal "username4" {
//
// JMXPrincipals "username4" has all permissions.
//
permission javax.management.MBeanPermission "Simple", "instantiate";
permission javax.management.MBeanPermission "Simple", "registerMBean";
permission javax.management.MBeanPermission "Simple", "invoke";
};
grant principal javax.management.remote.JMXPrincipal "username5" {
//
// JMXPrincipals "username5" has no permissions.
//
};

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,8 @@
PasswordFileAuthentication {
com.sun.jmx.remote.security.FileLoginModule required
passwordFile="${password.file}";
};
SampleLoginModule {
TestSampleLoginModule required;
};

View File

@ -0,0 +1,12 @@
# Password file for default SQE username.
SQE_username SQE_password
# Functional authorization tests
username1 password1
username2 password2
username3 password3
username4 password4
username5 password5
username6 password6
usernameFileLoginModule passwordFileLoginModule

Binary file not shown.

Binary file not shown.