The AdminControl scripting object gives you the ability to call operations and to read and modify the attributes of an MBean. MBeans only come to life when the code that they instrument is loaded on a running server, so if all of your servers are stopped, you will not be able to use AdminControl with MBeans.
In order to do anything, you have pass a parameter that tells the AdminControl scripting object which MBean we want. There are several acceptable data types for this parameter. The data type you choose determines which AdminControl methods you can use. For a Jython script writer, it is very difficult to even know that there are different data types because, to a script writer, they all look the same.
In this article, we will talk about the different data types you can use to specify an MBean and how each data type affects the code you can write.
Data Type and Example |
Details |
string |
This is arguably the most common way to describe an MBean. The text in the variable called "d" is the string representation of the name(s) of zero or more MBeans. Do not confuse this string with an ObjectName. If queryNames() returns more than one name, you will probably want to use splitlines() to break the string into an array of strings.
You almost always pass this method one or more name / value pairs followed by a ",*" Don't put any spaces anywhere in this string. The "*" is a wild card character. It is extremely rare to call this method without it. The more name / value pairs you specify, the fewer MBean names you get back.
|
d = AdminControl.queryNames( 'type=Server,*' ) |
Use a string to specify the MBean(s) names that you want. You will get a string containing zero or more names when you use this call |
ObjectName |
This is a Java data type. Its fully qualified name is javax.management.ObjectName It contains a description of an MBean that has two parts - a domain and a collection of key/value pairs. See the examples later in this article. The domain is the part before the colon. The key/value pairs are separated by commas. Calling the toString() method of this Java data type will produce the string that looks like the output from AdminControl.queryNames() in the row above. In this case, looks are very deceiving. |
x = AdminControl.makeObjectName( 'type=Server,*' ) |
x will hold an ObjectName. x and d might look the same but they hold very different data types. |
ObjectInstance |
This is a Java data type. Think of this as a wrapper around an actual MBean. It is an instance of the Java data type javax.management.ObjectInstance There are several ways to obtain an ObJectInstance |
i = AdminControl.getObjectInstance( x ) |
This call returns one ObjectInstance |
HashSet |
This is a Java data type. It will hold zero or more ObjectInstances |
m = AdminControl.queryMBeans( d ) |
This call could return more than one ObjectInstance. The ObjectInstances are returned inside a java.util.HashSet |
As you can see, there are four different data types that tell the AdminControl scripting object which MBean you want to work with.
There is a little bit of confusion about what we have to pass to AdminControl and what we get back from the various AdminControl methods because IBM literature is not always as clear as we might wish.
In addition, when we display a string or an ObjectName or an ObjectInstance or a HashSet on a Jython console, we often get very similar displays on our consoles.
Let's run some code, examine the result and draw some conclusions. I copied and pasted from my WAS environment. Your display might look quite a bit different depending on how you have configured your WAS installation.
wsadmin>d = AdminControl.queryNames( 'type=Server,*' )
wsadmin>d
'WebSphere:name=dmgr,process=dmgr,platform=proxy,node=BossNode,j2eeType=J2EEServer,version=7.0.0.0,
type=Server,mbeanIdentifier=cells/KevinCell/nodes/BossNode/servers/dmgr/server.xml#Server_1,
cell=KevinCell,spec=1.0,processType=DeploymentManager'
wsadmin>print d
WebSphere:name=dmgr,process=dmgr,platform=proxy,node=BossNode,j2eeType=J2EEServer,version=7.0.0.0,
type=Server,mbeanIdentifier=cells/KevinCell/nodes/BossNode/servers/dmgr/server.xml#Server_1,
cell=KevinCell,spec=1.0,processType=DeploymentManager
wsadmin>type( d )
<jclass org.python.core.PyString at 1147552870>
AdminControl.queryNames( 'type=Server,*' ) returns an ordinary string. This string is the string representation of the name of an MBean.
It is not an MBean nor is is an MBean ObjectName. It is a string.
The vast majority of scripts pass this string representation of the name of an MBean to various AdminControl methods.
If we type d on a console line by itself, we can see quotes around the value that d holds. On the other hand, if we type print d, we see that same value without quotes.
That will become important in a moment. Notice as well that the Jython language tells us that d holds a PyString. Now, let us use the string representation of the name of an MBean to create an ObjectName for that MBean.
wsadmin>x = AdminControl.makeObjectName( d )
wsadmin>x
WebSphere:name=dmgr,process=dmgr,platform=proxy,node=BossNode,j2eeType=J2EEServer,version=7.0.0.0,
type=Server,mbeanIdentifier=cells/KevinCell/nodes/BossNode/servers/dmgr/server.xml#Server_1,
cell=KevinCell,spec=1.0,processType=DeploymentManager
wsadmin>print x
WebSphere:name=dmgr,process=dmgr,platform=proxy,node=BossNode,j2eeType=J2EEServer,version=7.0.0.0,
type=Server,mbeanIdentifier=cells/KevinCell/nodes/BossNode/servers/dmgr/server.xml#Server_1,
cell=KevinCell,spec=1.0,processType=DeploymentManager
wsadmin>type( x )
<jclass org.python.core.PyJavaInstance at 623387944>
wsadmin>x.getClass().getName()
'javax.management.ObjectName'
When we look at the values in d, a string, and in x, an ObJectName, those values look very, very similar. If we say print d and print x, the results we see look exactly the same.
But when we call type( x ) and type( d ) we get very different results.
PyJavaInstance says that x really is a Java object. We can call getClass().getName() on any Java object to find out what kind of class we have instantiated.
As you can see, we have an ObjectName. Notice that the Jython function type() did not tell us exactly what kind of Java object x is.
We had to call x.getClass().getName() to discover that x holds an ObjectName.
We can take this a giant step further, but we have to write some Jython code.
#listJavaMethods
#For a given Java object, list the signatures of the methods you can call
#parameters:
# object - MUST evaluate as a Java class or you get a whomping fat exception
def listJavaMethods( object ):
print object, "is", type( object )
array = object.getClass().getMethods()
for m in array:
print m
I put this code in a module called "disassemble". The really important code is object.getClass().getMethods() As long as we pass this method something that really is a Java object, we will get a list of all the methods that this object can execute. (Anybody interested in all the details should look up a topic called "introspection" in the Java programing language.)
Let's call this method for our variable x
wsadmin>disassemble.listJavaMethods( x )
WebSphere:name=dmgr,process=dmgr,platform=proxy,node=BossNode,j2eeType=J2EEServer,version=7.0.0.0,
type=Server,mbeanIdentifier=cells/KevinCell/nodes/BossNode/servers/dmgr/server.xml#Server_1,
cell=KevinCell,spec=1.0,processType=DeploymentManager is org.python.core.PyJavaInstance
public boolean javax.management.ObjectName.equals(java.lang.Object)
public int javax.management.ObjectName.hashCode()
public java.lang.String javax.management.ObjectName.toString()
public boolean javax.management.ObjectName.isPattern()
public boolean javax.management.ObjectName.isDomainPattern()
public boolean javax.management.ObjectName.isPropertyPattern()
public boolean javax.management.ObjectName.isPropertyListPattern()
public boolean javax.management.ObjectName.isPropertyValuePattern()
public boolean javax.management.ObjectName.isPropertyValuePattern(java.lang.String)
throws java.lang.NullPointerException,java.lang.IllegalArgumentException
public java.lang.String javax.management.ObjectName.getCanonicalName()
public java.lang.String javax.management.ObjectName.getDomain()
public java.lang.String javax.management.ObjectName.getKeyProperty(java.lang.String)
throws java.lang.NullPointerException
public java.util.Hashtable javax.management.ObjectName.getKeyPropertyList()
public java.lang.String javax.management.ObjectName.getKeyPropertyListString()
public java.lang.String javax.management.ObjectName.getCanonicalKeyPropertyListString()
public boolean javax.management.ObjectName.apply(javax.management.ObjectName)
throws java.lang.NullPointerException
public void javax.management.ObjectName.setMBeanServer(javax.management.MBeanServer)
public int javax.management.ObjectName.compareTo(javax.management.ObjectName)
public int javax.management.ObjectName.compareTo(java.lang.Object)
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public static javax.management.ObjectName javax.management.ObjectName.getInstance(java.lang.String)
throws javax.management.MalformedObjectNameException,java.lang.NullPointerException
public static javax.management.ObjectName javax.management.ObjectName.getInstance(java.lang.String,
java.lang.String,
java.lang.String)
throws javax.management.MalformedObjectNameException,java.lang.NullPointerException
public static javax.management.ObjectName javax.management.ObjectName.getInstance(java.lang.String,
java.util.Hashtable)
throws javax.management.MalformedObjectNameException,java.lang.NullPointerException
public static javax.management.ObjectName javax.management.ObjectName.getInstance(
javax.management.ObjectName)
throws java.lang.NullPointerException
public static java.lang.String javax.management.ObjectName.quote(java.lang.String)
throws java.lang.NullPointerException
public static java.lang.String javax.management.ObjectName.unquote(java.lang.String)
throws java.lang.IllegalArgumentException,java.lang.NullPointerException
Compare this print out to Sun's specification for an ObjectName.
Of course, we cannot call disassemble.listJavaMethods( d ) because d holds a Python string. Now, let us examine an ObjectInstance.
wsadmin>i = AdminControl.getObjectInstance( x )
wsadmin>i
javax.management.modelmbean.RequiredModelMBean[WebSphere:name=dmgr,process=dmgr,platform=proxy,
node=BossNode,j2eeType=J2EEServer,version=7.0.0.0,type=Server,
mbeanIdentifier=cells/KevinCell/nodes/BossNode/servers/dmgr/server.xml
#Server_1,cell=KevinCell,spec=1.0,processType=DeploymentManager]
wsadmin>type( i )
<jclass org.python.core.PyJavaInstance at 623387944>
wsadmin>print i.getClass().getName()
javax.management.ObjectInstance
wsadmin>print i.getClassName()
javax.management.modelmbean.RequiredModelMBean
Like an ObjectName, an ObjectInstance is a Java object. The Jython language will tell you as much.
Notice, though, that displaying the contents of i will mislead you into thinking that i holds an MBean. It does not.
It holds a wrapper object, an ObjectInstance. There is no way to get hold of an actual MBean without writing some Java code.
We can prove that we have an ObjectInstance by typing print i.getClass().getName()
There are several things that an ObjectInstance could envelop.
When we print i.getClassName() we find that this ObjectInstance envelops an MBean.
Now, let us examine what happens when we do something that retrieves more than one ObjectInstance.
wsadmin>m = AdminControl.queryMBeans( 'process=dmgr,*' )
wsadmin>type(m)
<jclass org.python.core.PyJavaInstance at 623387944>
wsadmin>m.getClass().getName()
'java.util.HashSet'
wsadmin>m.size()
122
wsadmin>a = m.toArray()
wsadmin>type(a)
<jclass org.python.core.PyArray at 1988392580>
wsadmin>len(a)
122
wsadmin>iter = m.iterator()
wsadmin>type( iter )
<jclass org.python.core.PyJavaInstance at 623387944>
wsadmin>iter.getClass().getName()
'java.util.HashMap$KeyIterator'
wsadmin>type( iter.next() )
<jclass org.python.core.PyJavaInstance at 623387944>
wsadmin>iii = iter.next()
wsadmin>type( iii )
<jclass org.python.core.PyJavaInstance at 623387944>
wsadmin>iii.getClass().getName()
'javax.management.ObjectInstance'
wsadmin>iii
javax.management.modelmbean.RequiredModelMBean[WebSphere:name=TaskManagement,process=dmgr,
platform=common,node=BossNode,version=7.0.0.0,type=TaskManagement,mbeanIdentifier=TaskManagement,
cell=KevinCell,spec=1.0]
wsadmin>type( a[1] )
<jclass org.python.core.PyJavaInstance at 623387944>
wsadmin>a[1].getClass().getName()
'javax.management.ObjectInstance'
wsadmin>a[1]
javax.management.modelmbean.RequiredModelMBean[WebSphere:name=TaskManagement,process=dmgr,
platform=common,node=BossNode,version=7.0.0.0,type=TaskManagement,mbeanIdentifier=TaskManagement,
cell=KevinCell,spec=1.0]
By specifying a query string of 'process=NameOfAnyServerInYourCell', you pretty much guarantee that you will get lots of things that represent actual MBeans. In my case, I got 122 of them.
AdminControl.queryMBeans() returns a HashSet holding zero or more ObjectInstances.
As we saw earlier, AdminControl.queryNames() returns a string holding zero or more string representations of names of MBeans.
Newline characters separate each name in the string. At this point, we can choose to either deal with the HashSet in Java or deal with an array in Jython. m holds the HashSet. a holds a Jython array.
Both m and a hold the same information. The elements in each are ObjectInstances. How do we know about HashSet methods like size() and iterate()? We print those method names and signatures out.
wsadmin>disassemble.listJavaMethods(m)
public java.lang.Object java.util.HashSet.clone()
public boolean java.util.AbstractSet.equals(java.lang.Object)
public int java.util.AbstractSet.hashCode()
public java.lang.String java.util.AbstractCollection.toString()
public void java.util.HashSet.clear()
public boolean java.util.HashSet.contains(java.lang.Object)
public boolean java.util.AbstractCollection.containsAll(java.util.Collection)
public boolean java.util.HashSet.isEmpty()
public java.util.Iterator java.util.HashSet.iterator()
public int java.util.HashSet.size()
public java.lang.Object[] java.util.AbstractCollection.toArray()
public java.lang.Object[] java.util.AbstractCollection.toArray(java.lang.Object[])
public final native java.lang.Class java.lang.Object.getClass()
I left a lot of stuff out of the listing above, but you can see that size() and iterator() and toString() and toArray()
are all methods from the HashSet. You can call them just as if they were Jython methods.
wsadmin>disassemble.listJavaMethods( iter )
java.util.HashMap$KeyIterator@17191719 is org.python.core.PyJavaInstance
public java.lang.String java.lang.Object.toString()
public boolean java.util.HashMap$AbstractMapIterator.hasNext()
public final void java.util.HashMap$AbstractMapIterator.remove()
public java.lang.Object java.util.HashMap$KeyIterator.next()
public final native java.lang.Class java.lang.Object.getClass()
Again, we omitted some methods that were not interesting.
The two methods that matter for an iterator are hasNext() and next()
|