© Copyright International Business Machines Corporation 2003. All rights reserved.
The config service feature in WebSphere® Application Server V5 provides a JavaTM programming interface through which you can query or modify your WebSphere Application Server configuration. For instance, you can use config service to find all the servers in the cell, modify some server configuration parameters, or configure a new data source. In fact, config service can provide the same configuration-related functions which are available using the Web admin console (configuration tabs) and wsadmin scripting tool (AdminConfig commands). Therefore, you can write your own administrative program to configure your entire WebSphere Application Server environment using config service.
This article illustrates how to use config service through examples. While
this article is self-contained, you should first read Part 1 and Part 2 of this series to become familiar with WebSphere Application Server administration. The WebSphere Application Server config service javadoc is also a helpful document for this topic, with information on the packages
com.ibm.websphere.management.configservice and com.ibm.websphere.management.configservice.tasks, which contain all the config service APIs.
WebSphere Application Server configuration is composed of a set of XML
documents stored in the config directory under the WebSphere installation root directory. (More information
regarding the configuration directory structure and subordinate documents
can be found in Part 1.)
The term "config object" in this document refers to an XML element inside a configuration document that defines configurations of run time components in WebSphere Application Server. Below are two examples of config objects defined in config documents. As you can see, config objects may be nested, meaning a config object may contain other config objects.
Sample config object 1. Defines the configuration of a trace service component
<services XMI:type="traceservice:TraceService" XMI:id="TraceService_1" enable="true"
startupTraceSpecification="*=all=disabled" traceOutputType="SPECIFIED_FILE" traceFormat="BASIC"
memoryBufferSize="8">
<traceLog XMI:id="TraceLog_1" fileName="${SERVER_LOG_ROOT}/trace.log" rolloverSize="20"
maxNumberOfBackupFiles="1"/>
</services> |
Sample config object 2. Defines the configuration of a JVM
<processDefinition XMI:type="processexec:JavaProcessDef" XMI:id="JavaProcessDef_1"
executableName="${Java_HOME}/bin/Java" workingDirectory="${USER_INSTALL_ROOT}"
executableTargetKind="Java_CLASS" executableTarget="com.ibm.ws.runtime.WsServer">
<execution XMI:id="ProcessExecution_1"
processPriority="20" runAsUser="" runAsGroup=""/>
<ioRedirect XMI:id="OutputRedirect_1" stdoutFilename="${SERVER_LOG_ROOT}/native_stdout.log"
stderrFilename="${SERVER_LOG_ROOT}/native_stderr.log"/>
<monitoringPolicy XMI:id="MonitoringPolicy_1" maximumStartupAttempts="3" pingInterval="60"
pingTimeout="300" autoRestart="true" nodeRestartState="STOPPED"/>
<jvmEntries XMI:id="JavaVirtualMachine_1" verboseModeClass="false"
verboseModeGarbageCollection="false" verboseModeJNI="false" initialHeapSize="0"
maximumHeapSize="256" runHProf="false" hprofArguments=""
debugMode="false" debugArgs="-DJava.compiler=NONE -Xdebug -Xnoagent
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7777" genericJvmArguments="">
<classpath></classpath>
<bootClasspath></bootClasspath>
</jvmEntries>
</processDefinition>
|
Using config service by example
We will explain the basic programming model of config service using a simple
example, ConfigServiceExample1.Java, the code for which is available in
the Download section. When executed, this example will:
- read out the trace specification of a server,
- set a new trace mask, then
- save the change.
By making minor variations, you can use this code to easily query and modify most configuration information.
The major steps we will follow to use config service include:
- Obtain config service
- Create a session
- Identify config objects
- Obtain config object IDs
- Query and modify attribute values
- Query port information
- Save the changes
- Clean up the session
The first step is to get reference to ConfigService. Config service can run either inside a server, or outside the server in a standalone JVM. When config service runs inside a server, you can access it either remotely from a client process or locally inside the server process, as shown in Figure 1.
Figure 1. Obtaining config service

If config service runs inside the server...
- and your code runs outide the server, the code snippet below shows how to get a reference to config
service in a remote client process via an
AdminClientobject. Part 2 of this article series on Writing Your Own Administration Programs explains how you can obtain anAdminClientobject in detail.AdminClient adminClient = ....; // create a config service proxy object. ConfigService configService = new ConfigServiceProxy(adminClient);
- and your code runs inside the server, you can use the following line of code to obtain a reference to config service:
ConfigService configService = ConfigServiceFactory.getConfigService();
Figure 2. Standalone JVM
Config service can also run in a standalone JVM outside of the server (Figure 2). Typical reasons to run in this scenario include being able to modify the configuration during product installation, developing a configuration validation tool, etc. This is also especially useful should the configuration ever be too corrupted to start. The code snippet below shows how to run config service in a standalone JVM outside of the server.
//running config service with local mode
ConfigService configService = ConfigServiceFactory.getConfigService();
if (configService == null) {
Properties prop = new Properties();
prop.setProperty("location", "local");
configService = ConfigServiceFactory.createConfigService(true, prop);
} |
When running config service from a standalone JVM:
- You should call
createConfigServiceonly once during the entire lifetime of the JVM; there can be only one instance of config service in the entire JVM. ShouldcreateConfigServicebe called more than once, an exception is generated indicating another config service instance already exists. It's a good idea to try to get config service first, then callcreateConfigService()when its return value is null. - You must set the system property
com.ibm.ws.management.standaloneto true. If you want to modify config documents in a non-default location, you also need to set the location of the config directory through the system propertywas.repository.root.
Although config service can run in both server and standalone JVM, do not run both modes concurrently on the same config directory, since it's possible for concurrent updates from both modes to collide and break the integrity of the WebSphere Application Server configuration.
Config service supports the concept of sessions; that is, all queries and
modifications made through config service are not saved into the config
directory until a save command is issued. Since all ConfigService methods take a session parameter, you need to create a com.ibm.websphere.management.Session first before making any call, as shown here:
// create a session Session session = new Session(); |
Typically you create a session, perform several configuration changes,
then save all the changes made during the session at one time. The session parameter can be null, meaning that the method will create a separate
anonymous session, do the work and then save the session in one method
call. However, keep in mind that session creation is not cheap, so plan
to reuse the session whenever possible.
Config service uses javax.management.ObjectName
to uniquely identify config objects, in the same way that the JMX specification
uses ObjectName to uniquely identify MBeans registered in
MBeanServer. The following keys can be used in the ObjectName:
SystemAttributes._WEBSPHERE_CONFIG_DATA_ID | an opaque handler that uniquely identifies this config object |
SystemAttributes._WEBSPHERE_CONFIG_DATA_TYPE | the type of this config object, for instance DataSource, Server or ServerCluster etc. |
SystemAttributes._WEBSPHERE_CONFIG_DATA_DISPLAY_NAME | the name of this config object, for instance the name of a Server |
The ConfigServiceHelper class offers various helper methods to manipulate ObjectNames such as
constructing an ObjectName or retrieving information from an ObjectName.
For example, the class provides a getObjectLocation method to derive the location information from the ObjectName.
The resolve and queryConfigObjects methods are provided to obtain the IDs of config objects.
The line below shows how to get the ID for a server config object using the resolve method. It resolves the ID of the server (named gooddog), on the node
(named myNode). This method is an efficient way to locate config objects
easily. Refer to the JavaDoc for the detailed explanation of the search pattern syntax. Since it returns an array of config objects, you should always check the length of the returned array.
// query to get the server ObjectName server = configService.resolve(session, "Node=myNode:Server=gooddog")[0]; |
The queryConfigObjects method provides the scoped search functionality based on the config object
type, name or both; values for the scope can be a Cell, Node, Server, Application or Cluster config object. If null is specified for the scope to be searched, the
method will search the entire config directory, which can be expensive.
That said, the search algorithm is optimized to handle common scenarios,
such as listing all the servers or nodes or J2EE applications in a cell,
etc. The code lists TraceService components defined on the server, which
we got using the resolve method, above. Similar to resolve, this method also returns an array of config objects, since multiple config
objects can match the pattern.
// query to get the trace service component in server. ObjectName pattern = ConfigServiceHelper.createObjectName(null, "TraceService"); ObjectName traceService = configService.queryConfigObjects(session, server, pattern, null)[0]; |
5. Query and modify attribute values
Once you obtain the ID of a config object, you can use the getAttribute and setAttribute methods to query and modify various attribute values on that config object.
The code snippet below sets the startupTraceSpecification attribute with the new value *=all=enabled using the setAttribute method, then verifies the
change using the getAttribute method.
// set the server's trace specification to new value.
String newTrace = "*=all=enabled";
AttributeList attrList = new AttributeList();
attrList.add(new Attribute("startupTraceSpecification", newTrace));
configService.setAttributes(session, traceService, attrList); |
In this example, the returned value was converted from Object to String, since we knew its type ahead of time. In general, the type of the return
value depends on the type of the specified attribute.
It is common to query various port information using config service. For example, the ConfigServiceSample11 code (in the Download section) shows how to get the hostname and port number for the HTTP/HTTPS transport port, SOAP connector port, and name server bootstrap port. (The name server bootstrap port is also the port for the admin RMI connector.)
None of the changes made so far have been saved yet, so you will not see
any updates to the config directory until the save method is called:
// save the change. configService.save(session, false); |
It is not necessary to save after every configuration modification. The rule of thumb is to save the configuration when you are ready to publish the config updates you made within the session to the config directory, enabling the system to use the upated configuration. The main rationale for having the session concept is likely to prevent the failure of a partial configuration update from affecting the consistency and integrity of the whole configuration.
Since all the configuration changes made in a session are not pushed into
the config directory until you save the session, you also will not see
any unsaved configuration changes made in other concurrent session. When
users concurrently update the same configuration document through different
sessions, the conflict is detected by the save method. The boolean in the code is the
overwriteOnConflict flag, where a false value means that the call would fail if another user is concurrently modifying the same configuration document, and true means the call would overwrite the other's concurrent modification (dangerous,
since it could result an inconsistent configuration). You can also query
the list of conflicted documents with the getConflictDocuments method to help you decide whether to overrwrite with or discard your updates.
Call the discard method to release all the resources used by the session when you are done.
Failing to do so can waste resources and potentially cause a memory leak.
Put this line in at the end of your code, or wherever it is most appropriate:
configService.discard(session); |
In addition to releasing all the resources owned by the session, this method also discards all the changes made since the previous save. Therefore, it can also be used to throw away any unsaved changes if you choose note to complete the session, for example, in case of a failure.
Explore config object types and attributes
The previous section explained how to query and modify WebSphere Application Server configuration information. Here, we will see how to find information on all the supported config object types and their attributes.
There are four basic ways to get this information:
- use the WebSphere Configuration Documentation in WebSphere Application Server InfoCenter
- run the
$AdminConfig attributesand$AdminConfig typescommands in wsadmin - view the XML configuration document to see how the config objects are represented
- invoke the
getSupportedConfigObjectTypesandgetAttributesMetaInfomethods onConfigService.
Use AttributeList to represent configuration information
The javax.management.AttributeList class from the JMX specification is used to represent the configuration
information of config objects. An AttributeList is a collection of attribute objects which are name and value pairs. Since
AttributeList is a
generic data structure, ConfigServiceHelper offers several helper methods to construct and traverse AttributeList.
Any attribute list returned from config service contains two system attributes defined by config service:
SystemAttributes._WEBSPHERE_CONFIG_DATA_IDSystemAttributes._WEBSPHERE_CONFIG_DATA_TYPE.
The following sections discuss how AttributeList represents configuration information for various types of attributes.
If the attribute type is one of the simple Java types, such as String, Integer, Boolean etc, the value of the attribute is directly used in the attribute list. For example, the AttributeList that represents the
TraceService config object (shown below) contains an enable attribute with a Boolean value of true, and a startupTraceSpecification attribute with a string value *=all=disabled, etc
<services XMI:type="traceservice:TraceService" XMI:id="TraceService_1" enable="true"
startupTraceSpecification="*=all=disabled" traceOutputType="SPECIFIED_FILE" traceFormat="BASIC"
memoryBufferSize="8">
<traceLog XMI:id="TraceLog_1" fileName="${SERVER_LOG_ROOT}/trace.log" rolloverSize="20"
maxNumberOfBackupFiles="1"/>
</services> |
If the attribute type is complex, the attribute value is represented as
an AttributeList, i.e., a nested attribute list. The TraceService config object (shown above) has a complex type attribute traceLog, the value of which is a nested AttributeList with the attributes fileName, rolloverSize, etc.
If the attribute type is a collection, the attribute value in AttributeList is java.util.List. For instance, the DataSource config object in the resources.xml file (shown below) has a collection type attribute ResourceProperties, thus its attribute value is a list object and each element inside is
also an AttributeList that represents a ResourceProperty config object:
<factories XMI:type="resources.jdbc:DataSource" XMI:id="DataSource_1" name="Default Datasource"
jndiName="DefaultDatasource" description="Datasource for the WebSphere Default Application"
category="default" authMechanismPreference="BASIC_PASSWORD" statementCacheSize="0"
datasourceHelperClassname="com.ibm.websphere.rsadapter.CloudscapeDataStoreHelper"
relationalResourceAdapter="builtin_rra">
<propertySet XMI:id="DB2a-J2EEResourcePropertySet_1a">
<resourceProperties XMI:id="res_prop_template_DB2j_5_1" name="databaseName" type="java.lang.String"
value="${WAS_INSTALL_ROOT}/bin/DefaultDB" description="Location of Cloudscape default Database."/>
<resourceProperties XMI:id="res_prop_template_DB2j_5_2" name="remoteDataSourceProtocol"
type="java.lang.String" value=""/>
<resourceProperties XMI:id="res_prop_template_DB2j_5_3" name="shutdownDatabase"
type="java.lang.String" value=""/>
<resourceProperties XMI:id="res_prop_template_DB2j_5_4" name="dataSourceName" type="java.lang.String"
value=""/>
</propertySet>
<connectionPool XMI:id="ConnectionPool_1" connectionTimeout="1000" maxConnections="30" minConnections="1"
reapTime="180" unusedTimeout="1800" purgePolicy="FailingConnectionOnly"/>
</factories> |
While you can use the setAttributes method to modify the value of collection type attributes, the drawback
is that it replaces the whole collection rather than allowing you to modify
individual elements in the list. Still, the addElement and removeElement methods are provided to make finer modifications for collection type attributes.
See the JavaDoc for detailed information.
The createConfigData method can also be used to add a complex type element into a collection.
Basically, it creates a config object with the specified attribute list
and adds it at the end. The advantage of addElement here is that you can specify the position of the created object, while
the advantage of using createConfigData is that it returns the ID of the created config object, which you can
use to process the config object further.
The code snippet shown below from ConfigServiceSample2.Java (see Download) illustrates how to add a J2EEResourceProperty object into the propertySet for a DataSource config object:
// get the J2EEResourcePropertySet object
AttributeList value = configService.getAttributes(session, newDataSource, new String[]{"propertySet"}, false);
ObjectName propertySet = (ObjectName) ConfigServiceHelper.getAttributeValue(value, "propertySet");
// create a J2EEResourceProperty object and add into the list of resourceProperties.
attrList.clear();
ConfigServiceHelper.setAttributeValue(attrList, "name", "DatabaseName");
ConfigServiceHelper.setAttributeValue(attrList, "type", "Java.lang.String");
ConfigServiceHelper.setAttributeValue(attrList, "value", "myDatabase");
ObjectName prop = configService.createConfigData(session, propertySet, "resourceProperties",
"J2EEResourceProperty", attrList); |
The code above generates the following XML fragment in the DataSource config object:
<propertySet XMI:id="J2EEResourcePropertySet_1"> <resourceProperties XMI:id="res_prop_1" name="DatabaseName" type="Java.lang.String" value="myDatabase" /> </propertySet> |
Reference type attributes do not contain a value directly; instead they
refer to other config objects defined elsewhere, such as the relationalResourceAdapter attribute on the DataSource config object shown in the previous section. The ID of the referred config object is used as the value for any reference type attributes, in this case, the value of the relationalResourceAdapter attribute is the ID of the referred J2CResourceAdapter config object.
Create and delete config objects
The ConfigServiceSample2 code sample (see Download) illustrates how to create and delete a config object. This sample code:
- creates a
Server - creates a
JDBCProvider - creates a new
DataSource - deletes the
Servercreated above.
The following sections review these functions as they are coded in the sample, and discuss the concepts of relationship, template and scope.
In the sample code, a new Server config object is created using the createConfigData method. Typically, you only need to specify the name attribute. Config service will set up log directories and properly resolve
port conflicts. After creating the server, you can make further attribute
modifications using setAttributes method.
// query to get the config object ID for the node // where we want to create the new server. ObjectName node = configService.resolve(session, "Node=" + nodeName)[0]; // create a new application server. AttributeList attrList = new AttributeList(); ConfigServiceHelper.setAttributeValue(attrList, "name", serverName); ObjectName newServer = configService.createConfigData(session, node, "Server", "Server", attrList); |
The createConfigData method requires you to specify the parent and the attribute name of the
created config object. As described earlier, config objects can be nested,
which are modelled as attributes on the parent. However, since WebSphere
Application Server configuration data is stored in a group of configuration
documents, the parent and the new config object may reside in different
documents. In this case, a newly created config object can not be modelled
as attributes on a parent. For example, a Node config object logically
contains multiple Server config objects but the Node config object is stored
in a node.xml file, while Server config objects are stored in server.xml files, thus a Server is not an attribute of a Node. Config service uses
the term "relationship" to describe the logical containment relationship
among config objects that reside in different configuration documents.
Each relationship has a name and value:
- the name of a relationship describes the type of logical containment relationship among config objects
- the value of a relationship is a collection of related config objects, which may be empty.
When the parent and the new config object are in different configuration
documents, the relationship name should be used rather than the attribute
name for the createConfigData method. In the sample code, the first Server is the relationship name between the node and the newly created server.
Figure 3 shows the names of relationiships for a Node config object:
- parent
- Server
- JDBCProvider
- J2CResourceAdapter
- JMSProvider
- VariableMap.
Figure 3. Example relationships for node

The parent relationship associates a config object with its containing
config object, which in this case is a cell config object. Other relationships
associate a config object with whatever types of config objects it logically
contains. Typically, the relationship name describes the type of contained
config objects; the "server" relationship describes the servers
on the node, and so on. The code sample below shows how to get the cell
config object that contains the specified node, and how to get the servers
on that node. The set of relationships a config object has is determined
by its type. You can use getRelationship and getRelationships to obtain rel;ationship values.
// get the Cell config object. ObjectName cell = configService.getRelationship(session, node, "parent")[0]; // list servers on the node ObjectName[] servers = configService.getRelationship(session, node, "Server"); |
Create a JDBCProvider
Configuring a JDBCProvider is quite different from one database vendor
(and one implementation) to another, so config service provides the createConfigDataByTemplate method to enable you to specify a template for the created config object.
This method creates a blank config object, copies the configuration data
from the selected template to the created config object, then applies the
specified attribute values on top of it. You may specify a system defined
template (several are available for common database vendors and implementations)
or specify an existing config object to use as a template instead.
System defined templates are stored in the templates directory, under the config directory, and are used only during config object creation time. Config
service provides the queryTemplates method to query all the system defined templates. The sample code below queries all the JDBCProvider templates defined in the system, and uses the Cloudscape JDBC Provider 5.0 template to create a new JDBCProvider.
String jdbcProviderTemplateName = "Cloudscape JDBC Provider 5.0";
ObjectName[] templates = configService.queryTemplates(session, "JDBCProvider");
ObjectName match = null;
for (int i = 0; i < templates.length; i++) {
System.out.println("JDBCProvider template " + templates[i]);
if (jdbcProviderTemplateName.equals(ConfigServiceHelper.getDisplayName(templates[i]))) {
match = templates[i];
break;
}
}
System.out.println("found JDBCProvider template " + match);
// create an instance of embeded JDBC provider using template.
attrList.clear();
ConfigServiceHelper.setAttributeValue(attrList, "name", jdbcProviderName);
ObjectName jdbcProvider = configService.createConfigDataByTemplate(session, newServer, "JDBCProvider",
attrList, match); |
The code below creates a new DataSource using the JDBCProvider created above:
// create a JDBC data source for the application.
ConfigServiceHelper.setAttributeValue(attrList, "name", dataSourceName);
ConfigServiceHelper.setAttributeValue(attrList, "jndiName", "foo");
ObjectName newDataSource = configService.createConfigData(session, jdbcProvider, "DataSource",
"DataSource", attrList); |
You can use the deleteConfigData method to delete any config
object. Note that deleting a parent config object removes all the child config
objects as well. For instance, if you delete the JDBCProvider the
DataSources defined underneath are deleted implicitly.
Config service and administrative security
As part of the WebSphere Application Server V5 administrative programming model, all the config service methods are protected by the WebSphere administrative security infrastructure, in which several administrative roles are predefined: administrator, configurator, operator and monitor. (See the WebSphere 5.0 InfoCenter for descriptions of these roles and instructions on how to assign groups and users to these roles. Sections of particular value include: Planning to secure your environment, Role-based authorization and Assigning users to administrator roles.)
Regarding which administrative roles are required to invoke various config service methods, the general rule is that read only methods require only the monitor role, while the update methods require the configurator role. Due to the superseding nature of the relationship among these roles, users assigned as any admin role are allowed access to read only methods, while users assigned as an administrator or configurator are allowed to access update methods. In addition, the administrator role is required to access traditionally secure information (passwords, key files, etc.) to provide better protection to sensitive data.
The following are the read only methods:
- getAttribute
- getAttributes
- getAttributesMetaInfo
- getConflictDocuments
- getRelationship
- getRelationships
- getRelationshipsMetaInfo
- getSupportedConfigObjectTypes
- getUnsavedChanges
- queryConfigObjects
- queryTemplates
- resolve
- validate.
When config service runs outside the server, access control is not enforced, since the administrative security infrastructure runs inside the server. In this case, config documents are only protected by the file system access control mechanism, meaning you can read and modify the configuration through config service as long as you have the file system permission to access the config documents. However, this is not necessarily a security concern since the file system access control mechanism usually provides sufficient protection.
Assign users to admin roles using config service
Four naming roles are defined to control access to the JNDI namespace:
CosNamingRead, CosNamingWrite, CosNamingCreate and CosNamingDelete. (See
the section Role-based
authorization in the WebSphere Application Server 5.0 InfoCenter for more information
on these roles.) The users-to-admin roles mapping is stored in the naming-authz.xml file, and you can use similar logic to assigning users to admin roles. The only difference is that you should use naming role names instead of admin role names.
This article explained how to programmatically query and modify the WebSphere Application Server configuration using config service. An upcoming article in this series will show you how you can also programmatically install and manage your Web applications.
| Name | Size | Download method |
|---|---|---|
| configservice.zip | 100 KB | FTP |
Information about download methods
Qinhua Wang is an advisory software engineer with IBM working in the WebSphere Application Server development organization in Austin, Texas. She has been one of the leading developers on the WebSphere system administration team since WebSphere Application Server Version 3.5. The main focus of her work is WebSphere configuration. You can contact Qinhua at qwang@us.ibm.com .
Comments (Undergoing maintenance)





