使用 JMX API 来创建和配置 JDBC 提供程序和数据源
如果应用程序需要使用 Java™ 数据库连接 (JDBC) API 来访问关系数据库,那么您可以单独使用 Java 管理扩展 (JMX) API 来创建必需的 JDBC 提供程序和数据源对象。或者,可以将 JMX API 与 wsadmin 脚本编制工具配合使用。
关于此任务

示例
使用 JMX API 来创建访问关系数据库所必需的配置对象。 此代码样本演示了如何使用 WebSphere® Application Server MBean 来创建和配置从企业应用程序访问关系数据库所必需的对象。这些对象包括:支持 XA 或不支持 XA 的 JDBC 提供程序、数据源、认证别名以及(可选)容器管理的持久性 (CMP) 连接工厂。可以在以下源代码的头注释中找到有关配置这些选项的详细信息。该样本还演示了如何使用数据源 MBean 来将配置更改重新装入到正在运行的服务器中。
![[AIX Solaris HP-UX Linux Windows]](../images/dist.gif)
![[IBM i]](../images/iseries.gif)
![[z/OS]](../images/ngzos.gif)
/**
* COPYRIGHT LICENSE: This information contains sample code provided in
* source code form. You may copy, modify, and distribute this sample
* program in any form without payment to IBM for the purposes of
* developing, using, marketing or distributing application programs
* conforming to the application programming interface for the operating
* platform for which the sample code is written. Notwithstanding anything
* to the contrary, IBM PROVIDES THE SAMPLE SOURCE CODE ON AN "AS IS" BASIS
* AND IBM DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT
* LIMITED TO, ANY IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY,
* SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND ANY
* WARRANTY OR CONDITION OF NON-INFRINGEMENT. IBM SHALL NOT BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING
* OUT OF THE USE OR OPERATION OF THE SAMPLE SOURCE CODE. IBM HAS NO
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR
* MODIFICATIONS TO THE SAMPLE SOURCE CODE.
*
* © Copyright IBM Corp. 2011.
* All Rights Reserved. Licensed Materials - Property of IBM.
*/
import java.util.Properties;
import java.util.Set;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import com.ibm.websphere.management.AdminClient;
import com.ibm.websphere.management.AdminClientFactory;
import com.ibm.websphere.management.Session;
import com.ibm.websphere.management.configservice.ConfigServiceHelper;
import com.ibm.websphere.management.configservice.SystemAttributes;
import com.ibm.websphere.management.exception.ConnectorException;
/**
* This sample code demonstrates the use of the WebSphere JMX APIs to create
* a DB2 jdbc provider and data source with an authentication alias.
* This sample code may be configured to:
* - Create either node or server scoped objects
* - Create either an XA or non-XA jdbc provider
* - Create a connection factory so the data source may be used by CMP beans,
* otherwise the data source may be used by BMP beans, session beans, or
* servlets
* These are configured by setting the value of class constants
* (see "Program configuration settings" below)
* The jdbc provider, data source and CMP connection factory (if configured)
* are created using predefined templates, which is a best practice.
* Note: there are templates which will create both the jdbc provider and a
* data source at once, this sample intentionally creates both objects
* separately for thoroughness
*
* To compile and run this program, put the admin client bundle
* was_install_root\runtimes\com.ibm.ws.admin.client_9.0.jar
* on the classpath in addition to the classfile that was obtained when
* this source file was built.
*
* Once compiled, this program is run in it's own JVM and
* uses the WebSphere Admin Client API to interact with a WebSphere
* Application Server either locally or remotely to create the
* JDBC resources discussed above.
*/
public class JDBCResourcesWithJMX {
// program configuration settings
// if true, an XA capable jdbc provider is created, otherwise non-XA
private static final boolean createXAJDBCProvider = true;
// if true, a CMP connection factory will be created for use by CMP beans,
// otherwise the data source created can be used with BMP beans, session
// beans, or servlets
private static final boolean createCMPConnectionFactory = true;
// if true, create node-scoped objects, otherwise create server
private static final boolean createNodeScopedCfgObjs = true;
// end program configuration settings
private static final String jdbcProviderName =
"Sample DB2 JDBC Provider";
private static final String jdbcProviderTemplateNameXA =
"DB2 Using IBM JCC Driver Provider Only (XA)";
private static final String jdbcProviderTemplateName =
"DB2 Using IBM JCC Driver Provider Only";
// an alias for authentication data
private static final String authDataAlias = "db2admin";
private static final String authAliasDescription =
"Sample authentication alias";
private static final String authAliasUserID = "db2admin"; // user ID
private static final String authAliasPassword = "db2admin"; // password
private static final String dataSourceProviderTemplateNameXA =
"DB2 Using IBM JCC Driver - XA DataSource";
private static final String dataSourceHelperClassName =
"com.ibm.websphere.rsadapter.DB2DataStoreHelper";
private static final String cmpConnFactTemplateName =
"CMPConnectorFactory";
// display name for data source(DS)and connection factory(CF)
private static final String dataSourceName = "SampleDataSource";
private static final String dataSourceTemplateName =
"DB2 Using IBM JCC Driver - DataSource";
@SuppressWarnings("unused")
private static final String dbName = "SamplesDB"; // the database name
public static void main(String[] args) {
JDBCResourcesWithJMX cds = new JDBCResourcesWithJMX();
try {
cds.run(args);
}
catch (Exception ex) {
System.out.println("Caught exception: " + ex);
ex.printStackTrace();
}
}
/**
* Creates a jdbc provider, data source, authentication alias and connection
* factory, if so configured. Neither the data source or conn factory, if
* created, is bound into namespace until the server is restarted or an
* application using it is started
*/
private void run(String[] args) throws Exception {
// Initialize the AdminClient.
Properties adminProps = new Properties();
adminProps.setProperty(AdminClient.CONNECTOR_TYPE,
AdminClient.CONNECTOR_TYPE_SOAP);
adminProps.setProperty(AdminClient.CONNECTOR_HOST, "localhost");
adminProps.setProperty(AdminClient.CONNECTOR_PORT, "8880");
AdminClient adminClient =
AdminClientFactory.createAdminClient(adminProps);
Session session = new Session();
// use node scope to create config objects
ObjectName scope = null;
if (createNodeScopedCfgObjs) {
scope = ConfigServiceHelper.createObjectName(null, "Node", null);
}
else { // unless server scope is configured
scope = ConfigServiceHelper.createObjectName(null, "Server",
"server1");
}
// retrieve the ConfigService MBean
ObjectName configServiceMBean =
retrieveJMXMBean(adminClient, "ConfigService");
// invoke mbean queryConfigObjects operation
// to find either a server or node
ObjectName[] matches = (ObjectName[])adminClient.invoke(
configServiceMBean,
"queryConfigObjects",
// parameters for operation
new Object[] {session, null, scope, null},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"javax.management.ObjectName",
"javax.management.ObjectName",
"javax.management.QueryExp"});
scope = matches[0]; // use the first server or node object found
// create a jdbc provider at the specified scope
ObjectName jdbcProv =
createJDBCProvider(adminClient, session, scope,
configServiceMBean);
// create an authentication alias for the data source
createAuthAlias(adminClient, session, configServiceMBean);
// Retrieve built-in WebSphere Relational Resource Adapter (RRA) at
// same scope as above
ObjectName rra =
ConfigServiceHelper.createObjectName(null, "J2CResourceAdapter",
null);
// invoke mbean queryConfigObjects operation
matches = (ObjectName[])adminClient.invoke(
configServiceMBean,
"queryConfigObjects",
// parameters for operation
new Object[] {session, scope, rra, null},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"javax.management.ObjectName",
"javax.management.ObjectName",
"javax.management.QueryExp"});
rra = matches[0]; // use the first object found at this scope
// create a data source using the jdbc provider
ObjectName dataSource =
createDataSource(adminClient, session, scope, jdbcProv, rra,
configServiceMBean);
// if configured to do so, create a Connection Factory on the
// built-in WebSphere RRA for use by CMP beans
if (createCMPConnectionFactory) {
createConnectionFactory(adminClient, session, rra, dataSource,
configServiceMBean);
}
// invoke mbean save operation to persist the changes
// to the configuration repository, if platform is ND
// will also need to perform a node sync
adminClient.invoke(
configServiceMBean,
"save",
// parameters for operation
new Object[] {session, false},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"boolean"});
System.out.println("Configuration changes saved");
// reload data source MBean
reload(adminClient, session);
}
/**
* Use the ConfigService MBean to create an authentication alias
*/
private void createAuthAlias(AdminClient adminClient, Session session,
ObjectName configServiceMBean) throws Exception {
// Find the parent security object
ObjectName security =
ConfigServiceHelper.createObjectName(null, "Security", null);
// invoke mbean queryConfigObjects operation
Object result = adminClient.invoke(
configServiceMBean,
"queryConfigObjects",
// parameters for operation
new Object[] {session, null, security, null},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"javax.management.ObjectName",
"javax.management.ObjectName",
"javax.management.QueryExp"});
security = ((ObjectName[])result)[0];
// Prepare the attribute list
AttributeList authAliasAttrs = new AttributeList();
authAliasAttrs.add(new Attribute("alias", authDataAlias));
authAliasAttrs.add(new Attribute("userId", authAliasUserID));
authAliasAttrs.add(new Attribute("password", authAliasPassword));
authAliasAttrs.add(
new Attribute("description", authAliasDescription));
// invoke jmx createConfigData operation
result = adminClient.invoke(configServiceMBean, "createConfigData",
// parameters for operation
new Object[] {session, security, "authDataEntries",
"JAASAuthData", authAliasAttrs},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"javax.management.ObjectName",
"java.lang.String",
"java.lang.String",
"javax.management.AttributeList"});
System.out.println("Created authorization alias: " + authDataAlias);
}
/*
* Use the ConfigService MBean to create a CMP connection factory
* on the built-in WebSphere RRA
*/
private void createConnectionFactory(AdminClient adminClient,
Session session, ObjectName rra, ObjectName dataSource,
ObjectName configServiceMBean)
throws Exception {
// Prepare the attribute list
AttributeList cfAttrs = new AttributeList();
cfAttrs.add(new Attribute("name", dataSourceName + "_CF"));
cfAttrs .add(new Attribute("authMechanismPreference",
"BASIC_PASSWORD"));
cfAttrs.add(new Attribute("authDataAlias", authDataAlias));
cfAttrs.add(new Attribute("cmpDatasource", dataSource));
// invoke jmx queryTemplates operation
Object result = adminClient.invoke(
configServiceMBean,
"queryTemplates",
// parameters for operation
new Object[] {session, "CMPConnectorFactory",},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"java.lang.String"});
// find the template with the display name attribute that you want
ObjectName connFactTemplate = null;
if (result != null) {
ObjectName[] templates = (ObjectName[])result;
for (ObjectName template: templates) {
if (cmpConnFactTemplateName.equals(template.getKeyProperty(
SystemAttributes._WEBSPHERE_CONFIG_DATA_DISPLAY_NAME))) {
connFactTemplate = template;
}
}
}
// use the template found above to create the CMP connection factory
// invoke jmx createConfigDataByTemplate operation
adminClient.invoke(
configServiceMBean,
"createConfigDataByTemplate",
// parameters for operation
new Object[] {session, rra, "CMPConnectorFactory",
cfAttrs, connFactTemplate},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"javax.management.ObjectName",
"java.lang.String",
"javax.management.AttributeList",
"javax.management.ObjectName"
});
System.out.println("Created CMP Connection factory: " +
dataSourceName + "_CF");
}
/**
* Use the ConfigService MBean to create a data source at the
* specified scope from one of the predefined templates
*/
private ObjectName createDataSource(AdminClient adminClient,
Session session, ObjectName scope, ObjectName jdbcProv,
ObjectName rra, ObjectName configServiceMBean)
throws Exception {
// the template name to use based on whether this example is
// configured to use an XA data source or not
String templateName = dataSourceProviderTemplateNameXA;
if (!createXAJDBCProvider) {
templateName = dataSourceTemplateName;
}
// the attribute DataSource.relationResourceAdapter is required
// in addition to the attributes in the template
AttributeList dsAttrs = new AttributeList();
dsAttrs.add(new Attribute("name", dataSourceName));
// override some other props in the template
dsAttrs.add(new Attribute("description", dataSourceName));
dsAttrs.add(new Attribute("jndiName", "jdbc/" + dataSourceName));
dsAttrs.add(new Attribute("datasourceHelperClassname",
dataSourceHelperClassName));
// link to the built-in WebSphere RRA
dsAttrs.add(new Attribute("relationalResourceAdapter", rra));
dsAttrs.add(new Attribute("authDataAlias", authDataAlias));
// invoke jmx queryTemplates operation
Object result = adminClient.invoke(
configServiceMBean,
"queryTemplates",
// parameters for operation
new Object[] {session, "DataSource"},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"java.lang.String"});
// find the template with the display name attribute that you want
ObjectName db2Template = null;
if (result != null) {
ObjectName[] templates = (ObjectName[])result;
for (ObjectName template: templates) {
if (templateName.equals(template.getKeyProperty(
SystemAttributes._WEBSPHERE_CONFIG_DATA_DISPLAY_NAME))) {
db2Template = template;
}
}
}
// use the template found above to create the data source
// invoke jmx createConfigDataByTemplate operation
ObjectName dataSource = (ObjectName)adminClient.invoke(
configServiceMBean,
"createConfigDataByTemplate",
// parameters for operation
new Object[] {session, jdbcProv, "DataSource",
dsAttrs, db2Template},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"javax.management.ObjectName",
"java.lang.String",
"javax.management.AttributeList",
"javax.management.ObjectName"
});
System.out.println("Created data source: " + dataSourceName +
" at " + (createNodeScopedCfgObjs ? "node" : "server") +
" scope");
return dataSource;
}
/**
* Get the DataSourceCfgHelper MBean and call reload() on it
* This causes the newly created configuration objects to
* be available.
*/
private void reload(AdminClient adminClient, Session session)
throws Exception {
// retrieve the DataSourceCfgHelper MBean
ObjectName mBean =
retrieveJMXMBean(adminClient, "DataSourceCfgHelper");
// call the reload operation
Object result =
adminClient.invoke(
mBean,
"reload",
new Object[] {},
new String[] {});
if (result != null) {
System.err.println(
"DataSourceCfgHelper MBean reload operation failed: "
+ result);
}
else {
System.out.println("Reloaded DataSourceCfgHelper MBean");
}
}
/**
* Use the ConfigService MBean to create a jdbc provider at the specified
* scope from one of the predefined templates
*/
private ObjectName createJDBCProvider(
AdminClient adminClient, Session session, ObjectName scope,
ObjectName configServiceMBean) throws Exception {
// the template name to use based on whether this example is
// configured to use an XA jdbc provider or not
String templateName = jdbcProviderTemplateNameXA;
if (!createXAJDBCProvider) {
templateName = jdbcProviderTemplateName;
}
// invoke jmx queryTemplates operation
Object result = adminClient.invoke(
configServiceMBean,
"queryTemplates",
// parameters for operation
new Object[] {session, "JDBCProvider"},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"java.lang.String"});
// find the template with the display name attribute that you want
ObjectName db2Template = null;
if (result != null) {
ObjectName[] templates = (ObjectName[])result;
for (ObjectName template: templates) {
if (templateName.equals(template.getKeyProperty(
SystemAttributes._WEBSPHERE_CONFIG_DATA_DISPLAY_NAME))) {
db2Template = template;
}
}
}
// the attribute JDBCProvider.name is required in addition
// to the attributes in the template
AttributeList provAttrs = new AttributeList();
provAttrs.add(new Attribute("name", jdbcProviderName
+ (createXAJDBCProvider ? " (XA)" : "")));
// override the description in the template
provAttrs.add(new Attribute("description", jdbcProviderName
+ (createXAJDBCProvider ? " (XA)" : "")));
// use the template found above to create the jdbc provider
// invoke jmx createConfigDataByTemplate operation
ObjectName jdbcProvider = (ObjectName)adminClient.invoke(
configServiceMBean,
"createConfigDataByTemplate",
// parameters for operation
new Object[] {session, scope, "JDBCProvider",
provAttrs, db2Template},
// signature of bean method to invoke
new String[] {"com.ibm.websphere.management.Session",
"javax.management.ObjectName",
"java.lang.String",
"javax.management.AttributeList",
"javax.management.ObjectName"
});
System.out.println("Created JDBC provider: " + jdbcProviderName
+ (createXAJDBCProvider ? " (XA)" : "") +
" at " + (createNodeScopedCfgObjs ? "node" : "server") +
" scope");
return jdbcProvider;
}
// find the specified MBean
@SuppressWarnings("unchecked")
private ObjectName retrieveJMXMBean(AdminClient adminClient,
String beanName)
throws MalformedObjectNameException, ConnectorException {
// retrieve the ConfigService MBean
ObjectName mBean = null;
ObjectName queryName =
new ObjectName("WebSphere:type=" + beanName + ",*");
Set names = adminClient.queryNames(queryName, null);
if (!names.isEmpty()) {
mBean = (ObjectName) names.iterator().next();
}
return mBean;
}
}