This chapter includes the following sections:
To understand the process of changing a WebLogic Server domain and activating the changes, see Managing Configuration Changes in Understanding Domain Configuration for Oracle WebLogic Server.
To edit MBean attributes:
For an example of editing MBeans and activating the edits, see Example: Changing the Administration Port.
To change the attribute values of existing MBeans, create new MBeans, or delete MBeans:
Save your changes by invoking the ConfigurationManagerMBean
save()
operation.
The code example in Example 5-1 changes the context path that you use to access the WebLogic Server Administration Console for a domain. This behavior is defined by the DomainMBean
ConsoleContextPath
attribute.
Note the following about the code example:
For information on how the class connects to the Edit MBean Server, see Make Remote Connections to an MBean Server.
To simplify the code for learning purposes, exception handling in Example 5-1 is minimal. See Best Practices: Recommended Pattern for Editing and Handling Exceptions.
Example 5-1 Example: Changing the Administration Console's Context Path
import java.io.IOException; import java.net.MalformedURLException; import java.util.Hashtable; import javax.management.Attribute; import javax.management.MBeanServerConnection; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import javax.naming.Context; public class EditWLSMBeans { private static MBeanServerConnection connection; private static JMXConnector connector; private static final ObjectName service; // Initializing the object name for EditServiceMBean // so it can be used throughout the class. static { try { service = new ObjectName( "com.bea:Name=EditService,Type=weblogic.management.mbeanservers. edit.EditServiceMBean"); } catch (MalformedObjectNameException e) { throw new AssertionError(e.getMessage()); } } /** * ---------------------------------------------------------- * Methods to start an edit session. * NOTE: Error handling is minimal to help you see the * main steps in editing MBeans. Your code should * include logic to catch and process exceptions. * ---------------------------------------------------------- */ /* * Initialize connection to the Edit MBean Server. */ public static void initConnection(String hostname, String portString, String username, String password) throws IOException, MalformedURLException { String protocol = "t3"; Integer portInteger = Integer.valueOf(portString); int port = portInteger.intValue(); String jndiroot = "/jndi/"; String mserver = "weblogic.management.mbeanservers.edit"; JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port, jndiroot + mserver); Hashtable h = new Hashtable(); h.put(Context.SECURITY_PRINCIPAL, username); h.put(Context.SECURITY_CREDENTIALS, password); h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "weblogic.management.remote"); connector = JMXConnectorFactory.connect(serviceURL, h); connection = connector.getMBeanServerConnection(); } /** * Start an edit session. */ public ObjectName startEditSession() throws Exception { // Get the object name for ConfigurationManagerMBean. ObjectName cfgMgr = (ObjectName) connection.getAttribute(service, "ConfigurationManager"); // Instruct MBeanServerConnection to invoke // ConfigurationManager.startEdit(int waitTime int timeout). // The startEdit operation returns a handle to DomainMBean, which is // the root of the edit hierarchy. ObjectName domainConfigRoot = (ObjectName) connection.invoke(cfgMgr,"startEdit", new Object[] { new Integer(60000), new Integer(120000) }, new String[] { "java.lang.Integer", "java.lang.Integer" }); if (domainConfigRoot == null) { // Couldn't get the lock throw new Exception("Somebody else is editing already"); } return domainConfigRoot; /** * ---------------------------------------------------------- * Methods to change MBean attributes. * ---------------------------------------------------------- */ /** * Modify the DomainMBean's ConsoleContextPath attribute. */ public void editConsoleContextPath(ObjectName cfgRoot) throws Exception { // The calling method passes in the object name for DomainMBean. // This method only needs to set the value of an attribute // in DomainMBean. Attribute adminport = new Attribute("ConsoleContextPath", new String( "secureConsoleContext")); connection.setAttribute(cfgRoot, adminport); System.out.println("Changed the Administration Console context path to " + "secureConsoleContext"); } /** * ---------------------------------------------------------- * Method to activate edits. * ---------------------------------------------------------- */ public ObjectName activate() throws Exception { // Get the object name for ConfigurationManagerMBean. ObjectName cfgMgr = (ObjectName) connection.getAttribute(service, "ConfigurationManager"); // Instruct MBeanServerConnection to invoke // ConfigurationManager.activate(long timeout). // The activate operation returns an ActivationTaskMBean. // You can use the ActivationTaskMBean to track the progress // of activating changes in the domain. ObjectName task = (ObjectName) connection.invoke(cfgMgr, "activate", new Object[] { new Long(120000) }, new String[] { "java.lang.Long" }); return task; } public static void main(String[] args) throws Exception { String hostname = args[0]; String portString = args[1]; String username = args[2]; String password = args[3]; EditWLSMBeans ewb = new EditWLSMBeans(); // Initialize a connection with the MBean server. initConnection(hostname, portString, username, password); // Get an object name for the Configuration Manager. ObjectName cfgMgr = (ObjectName) connection.getAttribute(service, "ConfigurationManager"); // Start an edit session. ObjectName cfgRoot = ewb.startEditSession(); // Edit the server log MBeans. ewb.editConsoleContextPath(cfgRoot); // Save and activate. connection.invoke(cfgMgr, "save", null, null); ewb.activate(); // Close the connection with the MBean server. connector.close(); } }
Table 5-1 describes all of the exception types that WebLogic Server can throw during edit operations. When WebLogic Server throws such an exception, the MBean server wraps the exception in javax.management.MBeanException
. (See MBeanException
in the Java SE 7 API Specification at http://docs.oracle.com/javase/7/docs/api/javax/management/MBeanException.html
.)
Table 5-1 Exception Types Thrown by Edit Operations
Exception Type | Thrown When |
---|---|
EditTimedOutException |
The request to start an edit session times out. |
NotEditorException |
You attempt to edit MBeans without having a lock or when an administrative user cancels your lock and starts an edit session. |
ValidationException |
You set an MBean attribute's value to the wrong data type, outside an allowed range, not one of a specified set of values, or incompatible with dependencies in other attributes. |
The following sections describe working with changes that you have made during an edit session:
WebLogic Server describes changes in a Change
object, which is of type javax.management.openmbean.CompositeType
. See CompositeType
in the Java SE 7 API Specification at http://docs.oracle.com/javase/7/docs/api/javax/management/openmbean/CompositeType.html
.
Through JMX, you can access information about the changes to a domain's configuration that have occurred during the current server session only. WebLogic Server maintains an archive of configuration files, but the archived data and comparisons of archive versions is not available through JMX.
For each change that you make to an MBean attribute, WebLogic Server creates a Change
object which contains information about the change. You can access these objects from the ConfigurationManagerMBean
Changes
attribute until you save the changes. See ConfigurationManagerMBean in MBean Reference for Oracle WebLogic Server.
Any unsaved changes are discarded when your edit session ends.
To list unsaved changes:
Example 5-2 Example Method that Lists Unsaved Changes
public void listUnsaved() throws Exception { ObjectName cfgMgr = (ObjectName) connection.getAttribute(service, "ConfigurationManager"); Object[] list = (Object[])connection.getAttribute(cfgMgr, "Changes"); int length = (int) list.length; for (int i = 0; i < length; i++) { System.out.println("Unsaved change: " + list[i].toString()); } }
The code in Example 5-2 creates a method that lists unsaved changes. It assumes that the calling method has already established a connection to the Edit MBean Server.
When anyone saves changes, WebLogic Server persists the changes in the pending configuration files. The changes remain in these files, even across multiple editing sessions, unless a user who has started an edit session invokes the ConfigurationManagerMBean
undoUnactivatedChanges()
operation, which reverts all unactivated changes from the pending files.
The ConfigurationManagerMBean
UnactivatedChanges
attribute contains Change
objects for both unsaved changes and changes that have been saved but not activated. (There is no attribute that contains only saved but unactivated changes.) See ConfigurationManagerMBean Unactivated Changes in MBean Reference for Oracle WebLogic Server.
To list changes that you have saved in the current editing session but not activated, or changes that your or others have saved in previous editing sessions but not activated:
Example 5-3 Example Method that Lists Unactivated Changes
public void listUnactivated() throws Exception { ObjectName cfgMgr = (ObjectName) connection.getAttribute(service, "ConfigurationManager"); Object[] list = (Object[])connection.getAttribute(cfgMgr, "UnactivatedChanges"); int length = (int) list.length; for (int i = 0; i < length; i++) { System.out.println("Unactivated changes: " + list[i].toString()); } }
The code in Example 5-3 creates a method that lists unactivated changes. It assumes that the calling method has already established a connection to the Edit MBean Server.
When you activate changes, WebLogic Server creates an instance of ActivationTaskMBean
, which contains one Change
object for each change that is being activated. You can access these ActivationTaskMBean
s from either of the following:
The ConfigurationManagerMBean
activate()
method returns an object name for the ActivationTaskMBean
that describes the current activation task.
The ConfigurationManagerMBean
CompletedActivationTasks
attribute can potentially contain a list of all ActivationTaskMBean
instances that have been created during the current Administration Server instantiation. See Listing All Activation Tasks Stored in Memory.
To list changes in the current activation task only:
Example 5-4 Example Method that Lists Changes in the Current Activation Task
public void activateAndList() throws Exception { ObjectName cfgMgr = (ObjectName) connection.getAttribute(service, "ConfigurationManager"); ObjectName task = (ObjectName) connection.invoke(cfgMgr, "activate", new Object[] { new Long(120000) }, new String[] { "java.lang.Long" }); Object[] changes = (Object[])connection.getAttribute(task, "Changes"); int i = (int) changes.length; for (int i = 0; i< i; i++) { System.out.println("Changes activated: " + changes[i].toString()); } }
The code in Example 5-4 creates a method that lists all changes activated in the current editing session. It assumes that the calling method has already established a connection to the Edit MBean Server.
ConfigurationManagerMBean
provides two operations for undoing changes made during an editing session:
undo
Reverts unsaved changes.
undoUnactivatedChanges
Reverts all changes, saved or unsaved, that have not yet been activated. If other users have saved changes in a previous editing session but not activated those changes, invoking the ConfigurationManagerMBean
undoUnactivatedChanges()
operation reverts those changes as well.
After you invoke this method, the pending configuration files are identical to the working configuration files that the active servers use.
To undo changes, start an edit session and invoke the ConfigurationManagerMBean
undo
or undoUnactivatedChanges
operation.
For example:
connection.invoke(cfgMgr, "undo", null, null);
In addition to maintaining a list of changes, each ActivationTaskMBean
that WebLogic Server creates when you invoke the activate
operation describes which user activated the changes, the status of the activation task, and the time at which the changes were activated.
The Administration Server maintains instances of ActivationTaskMBean
in memory only; they are not persisted and are destroyed when you shut down the Administration Server. Because the ActivationTaskMBean
instances contain a list of Change
objects (each of which describes a single change to an MBean attribute), they use a significant amount of memory. To save memory, by default the Administration Server maintains only a few of the most recent ActivationTaskMBean
instances in memory. To change the default, increase the value of the ConfigurationManagerMBean
CompletedActivationTasksCount
attribute.
The following sections describe working with instances of ActivationTaskMBean
:
When you invoke the activate
operation, WebLogic Server returns an ActivationTaskMBean
instance to represent the activation task.
The ActivationTaskMBean
State
attribute describes the status of the activation task. This attribute stores an int
value and ActivationTaskMBean
defines constants for each of the int
values. See ActivationTaskMBean in MBean Reference for Oracle WebLogic Server.
To list the status of the current activation task:
ConfigurationManagerMBean
activate(long timeout)
operation and assign the output to a variable of type ActivationTaskMBean
.ActivationTaskMBean
State
attribute.The ActivationTaskMBean
that the activate
operation returns describes only a single activation task. The Administration Server keeps this ActivationTaskMBean
in memory until you purge it (see Purging Completed Activation Tasks from Memory) or the number of activation tasks exceeds the value of the ConfigurationManagerMBean
CompletedActivationTasksCount
attribute.
To access all ActivationTaskMBean
instances that are currently stored in memory (see Example 5-5):
Example 5-5 Example Method that Lists All Activation Tasks in Memory
public void listActivated() throws Exception { ObjectName cfgMgr = (ObjectName) connection.getAttribute(service, "ConfigurationManager"); ObjectName[] list = (ObjectName[])connection.getAttribute(cfgMgr, "CompletedActivationTasks"); System.out.println("Listing completed activation tasks."); int length = (int) list.length; for (int i = 0; i < length; i++) { System.out.println("Activation task " + i); System.out.println("User who started activation: " + connection.getAttribute(list[i], "User")); System.out.println("Task state: " + connection.getAttribute(list[i], "State")); System.out.println("Start time: " + connection.getAttribute(list[i], "StartTime")); Object[] changes = (Object[])connection.getAttribute(list[i], "Changes"); int l = (int) changes.length; for (int y = 0; y < l; y++) { System.out.println("Changes activated: " + changes[y].toString()); } } }
Because the ActivationTaskMBean
instances contain a list of Change
objects (each of which describes a single change to an MBean attribute), they use a significant amount of memory.
If the Administration Server is running out of memory, you can purge completed activation tasks from memory. Then decrease the value of the ConfigurationManagerMBean
CompletedActivationTasksCount
attribute.
To purge completed activation tasks from memory, connect to the Edit MBean Server and invoke the ConfigurationManagerMBean
purgeCompletedActivationTasks
operation.
For example:
connection.invoke(cfgMgr, "purgeCompletedActivationTasks", null, null);
To prevent changes that could leave the pending configuration MBean hierarchy in an inconsistent state, only one user at a time can edit MBeans. When a user invokes the ConfigurationManagerMBean
startEdit
operation, the ConfigurationManagerMBean
prevents other users (locks) from starting edit sessions.
The following actions remove the lock:
The ConfigurationManagerMBean
activate
operation succeeds or times out.
You can use the ActivationTaskMBean
waitForTaskCompletion
operation to block until the activation process is complete.
The ConfigurationManagerMBean
stopEdit
operation succeeds.
A user with administrator privileges invokes the ConfigurationManagerMBean
cancelEdit
operation while another user has the lock.
For example, connection.invoke(cfgMgr, "cancelEdit", null, null);
An edit session has been started under a user identity and another process starts an edit session under the same user identity.
For example, if you use the WebLogic Server Administration Console to start an edit session and shortly afterwards use the WebLogic Scripting Tool (WLST) to start an edit session under the same user identity, the WLST session will remove the lock from your WebLogic Server Administration Console session.
To prevent another process from starting an edit session under your user identity, get an exclusive lock by passing a boolean
of value true
to the startEdit
operation. See startEdit(waitTimeInMillis, timeOutInMillis, exclusive)
in the MBean Reference for Oracle WebLogic Server.
All unsaved changes are lost when the lock is removed.
Oracle recommends that you organize your editing code into several try-catch blocks. Such an organization will enable you to catch specific types of errors and respond appropriately. For example, instead of abandoning the entire edit session if a change is invalid, your code can save the changes, throw an exception and exit without attempting to activate invalid changes.
JMX agents wrap all exceptions in a generic exception of type javax.management.MBeanException
. A JMX client can use the MBeanException.getTargetException()
to unwrap the wrapped exception.
Consider using the following structure (see the pseudo-code in Example 5-6):
A try block that connects to the Edit MBean Server, starts an edit session, and makes and saves changes.
After this try block, one catch block for each of the following types of exception wrapped within MBeanException
:
EditTimedOutException
This exception is thrown if the ConfigurationManagerMBean
startEdit()
operation cannot get a lock within the amount of time that you specify.
NotEditorException
This exception is thrown if the edit session times out or an administrator cancels your edit session. (See Managing Locks.)
ValidationException
This exception is thrown if you set a value in an MBean that is the wrong data type, outside an allowed range, not one of a specified set of values, or incompatible with dependencies in other attributes.
Within the code that handles ValidationException
, include a try block that either attempts to correct the validation error or stops the edit session by invoking the ConfigurationManagerMBean
stopEdit()
operation. If the try block stops the edit session, its catch block should ignore the NotEditorException
. This exception indicates that you no longer have a lock on the pending configuration MBean hierarchy; however, because you want to abandon changes and release your lock anyway, it is not an error condition for this exception to be thrown.
A try block that activates the changes that have been saved.
The ConfigurationManager
activate(long timeout)
operation returns an instance of ActivationTaskMBean
, which contains information about the activation task. Oracle recommends that you set the timeout period for activate()
to a minute and then check the value of the ActivationTaskMBean
State
attribute.
If State
contains the constant STATE_COMMITTED
, then your changes have been successfully activated in the domain. You can use a return
statement at this point to end your editing work. The lock that you created with startEdit()
releases after the activation task succeeds.
If State
contains a different value, the activation has not succeeded in the timeout period that you specified in activate(long timeout)
. You can get the value of the ActivationTaskMBean
Error
attribute to find out why.
After this try block, one catch block to catch the following type of wrapped exception:
NotEditorException
If this exception is thrown while trying to activate changes, your changes were not activated because your edit session timed out or was cancelled by an administrator.
(Optional) A try block that undoes the saved changes.
If your class does not return in the activation try block, then your activation task was not successful. If you do not want these saved changes to be activated by a future attempt to activate changes, then invoke the ConfigurationManagerMBean
undoUnactivatedChanges()
operation.
Otherwise, the pending configuration files retain your saved changes. The next time any user attempts to activate saved changes, WebLogic Server will attempt to activate your saved changes along with any other saved changes.
After this try block, one catch block to ignore the following type of wrapped exception:
NotEditorException
A try block to stop the edit session.
If your activation attempt fails and you are ready to abandon changes, there is no need to wait until your original timeout period to expire. You can stop editing immediately.
After this try block, one catch block to ignore the following type of exception:
NotEditorException
Throw the exception that is stored in the ActivationTaskMBean
Error
attribute.
Example 5-6 Code Outline for Editing and Exception Handling
try { //Initialize the connection and start the edit session ... ObjectName domainConfigRoot = (ObjectName) connection.invoke(cfgMgr, "startEdit", new Object[] { new Integer(30000), new Integer(300000) }, new String[] { "java.lang.Integer", "java.lang.Integer" }); // Modify the domain ... // Save your changes connection.invoke(cfgMgr, "save", null, null); } catch (MBeanException e) { Exception targetException = e.getTargetException(); if (targetException instanceof EditTimedOutException) { // Could not get the lock. Notify user ... throw new MyAppCouldNotStartEditException(e); } if (targetException instanceof NotEditorException) { ... throw new MyAppEditSessionFailed(e); } if (targetException instanceof ValidationException) { ... try { connection.invoke(cfgMgr, "stopEdit", null, null); // A wrapped NotEditorException here indicates that you no longer have a // lock on the pending configuration MBean hierarchy; however, // because you want to abandon changes and release your lock anyway, // it is not an error condition for this exception to be thrown // and you can safely ignore it. } catch (MBeanException e) { Exception targetException = e.getTargetException(); if (targetException instanceof NotEditorException) { //ignore } } throw new MyAppEditChangesInvalid(e); } else { throw MBeanException (e); } } // Changes have been saved, now activate them try { // Activate the changes ActivationTaskMBean task = (ObjectName) connection.invoke(cfgMgr, "activate", new Object[] { new Long(60000) }, new String[] { "java.lang.Long" }); // Everything worked, just return. String status = (String) connection.getAttribute(task, "State"); if (status.equals("4")) return; // If there is an activation error, use ActivationTaskMBean.getError // to get information about the error failure = connection.getAttribute(task, "Error"); // If you catch a wrapped NotEditorException, your changes were not activated // because your edit session ended or was cancelled by an administrator. // Throw the wrapped exception. } catch (MBeanException e) { Exception targetException = e.getTargetException(); if (targetException instanceof NotEditorException) { ... throw new MyAppEditSessionFailed(e); } } // If your class executes the remaining lines, it is because activating your // saved changes failed. // Optional: You can undo the saved changes that failed to activate. If you // do not undo your saved changes, they will be activated the next time // someone attempts to activate changes. // try { // { // connection.invoke(cfgMgr, "undoUnactivatedChanges", null, null); // catch(MBeanException e) { // Exception targetException = e.getTargetException(); // if (targetException instanceof NotEditorException) { // ... // throw new MyAppEditSessionFailed(e); // } // } // Stop the edit session try { connection.invoke(cfgMgr, "stopEdit", null, null); // If your activation attempt fails and you are ready to abandon // changes, there is no need to wait until your original timeout // period to expire. You can stop editing immediately // and you can safely ignore any wrapped NotEditorException. } catch (MBeanException e) { Exception targetException = e.getTargetException(); if (targetException instanceof NotEditorException) { //ignore } } ... // Output the information about the error that caused the activation to // fail. throw new MyAppEditSessionFailed(connection.getAttribute(task, "Error"));
To prevent unauthorized access to sensitive data such as passwords, some attributes in WebLogic Server configuration MBeans are encrypted. The attributes persist their values in the domain's config.xml
file as an encrypted string and represent the in-memory value in the form of an encrypted byte array. The names of encrypted attributes end with Encrypted
. For example, the ServerMBean
exposes the password that is used to secure access through the IIOP protocol in an attribute named DefaultIIOPPasswordEncrypted
. To support backwards compatibility, and to enable remote JMX clients to set passwords for WebLogic Server MBeans, each encrypted attribute provides a less secure means to encrypt and set its value.
The following sections describe how to work with encrypted attributes:
To use this technique (see Example 5-7):
Example 5-7 Example: Set the Value of an Encrypted Attribute (Recommended Technique)
public void editDefaultIIOPPassword(ObjectName cfgRoot) throws Exception { // Get the ServerMBean from the DomainMBean ObjectName server = (ObjectName) connection.invoke(cfgRoot, "lookupServer", new Object[] { "myserver" }, new String[] { "java.lang.String" }); // Get new password from standard in. Assign it to a byte array. System.out.println("Enter new password and press enter: "); byte userinput[] = new byte[10]; System.in.read(userinput); // Encrypt the byte array and set it as the encrypted // attribute value. Attribute newpassword = new Attribute("DefaultIIOPPasswordEncrypted", weblogic.management.EncryptionHelper.encrypt(userinput)); connection.setAttribute(server, newpassword); System.out.println("New password is set to: " + connection.getAttribute(server, "DefaultIIOPPasswordEncrypted")); // Clear the byte array. weblogic.management.EncryptionHelper.clear(userinput); }
Prior to 9.0, JMX clients used a different technique for setting encrypted values. JMX clients can continue to use this compatibility technique, and if you want to set encrypted values from a remote JMX client, this is the only technique available. The compatibility technique is less secure because it creates a String
that contains your unencrypted password. Even though WebLogic Server converts the String
to an encrypted byte array, the String
will remain in memory until it is garbage collected and the memory is reallocated.
To use the compatibility technique:
For example:
public void editDefaultIIOPPassword(ObjectName cfgRoot, String password) throws Exception { // Get the ServerMBean from the DomainMBean ObjectName server = (ObjectName) connection.invoke(cfgRoot, "lookupServer", new Object[]{"myserver"},new String[]{"java.lang.String"}); Attribute newpassword = new Attribute("DefaultIIOPPassword", "mypassword"); connection.setAttribute(server, newpassword); }
To make a backup copy of a password, use the getter method of the MBean's encrypted value to retrieve the encrypted byte array. Then write the value of the byte array to a file. WebLogic Server does not provide APIs or other utilities for decrypting values that it has encrypted.
If you need to restore the password value, you can load the saved value into a byte array and pass it as a parameter to the MBeanServerConnection.setAttribute
method (see Set the Value of an Encrypted Attribute (Recommended Technique)).
Note:
Because each WebLogic Sever domain uses its own encryption algorithm, you must back up and restore passwords separately for each domain even if the unencrypted value for the password is the same for all domains.
Instead of backing up the same encrypted password for each domain, you can use the getter method of an MBean's corresponding unencrypted value. This getter unencrypts the password and copies into a String
. The String
will not be erased from memory until it is garbage collected and the memory is reallocated.