Finding Custom MBeans in WLST

4 03 2010

My collegue Ron DiFrango recently wrote a blog about exposing custom MBeans within the WebLogic container. Both Ron and myself experienced similar frustrations when trying to work with custom MBeans and his blog is a must read if you’re having difficulty finding yours.

Once the container is setup as directed in Ron’s blog, you’ll quickly notice that several of WLST’s APIs for navigating do not work in the custom tree; most notably is the find API. The lack of a find API is especially troubling when you have MBeans such as ones for EHCache that use the memory location as part of the unique identifier, for example:

net.sf.ehcache:type=CacheStatistics,CacheManager=net.sf.ehcache.CacheManager@6c20c8,name=com.ericmiles.fishing.Angler

This value will change from server start to server start making programmatic navigation to this bean an issue. We’ll need to create our own finder method that we can reuse when we need to find custom MBeans such as these.

We’re in a Jython environment so Python and Java functionality are both available to leverage. I don’t have much experience with python, so most of my scripting in WLST has Java leanings. Here is a simple custom finder method I have written:

# function to help locate a mbean(s)
# that match a specific name
def findMBean(prefix, name):
        # get a listing of everything in the current directory
        mydirs = ls(returnMap='true');

        found = [];
                
        # we're going to use a regular expression for our test
        pattern = java.util.regex.Pattern.compile(str(escape(prefix)) + str('.*name=') + str(escape(name)) + str('.*$'));
                
        # loop through the listing
        for mydir in mydirs:
                x = java.lang.String(mydir);
                matcher = pattern.matcher(x);
                # if we find a match, add it to the found list
                while matcher.find():
                        found.append(x);
                
        return found;

At a high level, this method searches a specific directory tree (non-recursively) for a bean that matches a specific prefix and naming pattern and returns these references in a list. Let’s decompose the contents of the method.

On line 5 of the listing, we are calling the WLST API ls(returnMap=true) to perform a directory listing on the current tree which will return a reference to an object we can work with, rather than merely directing output to the console.

On line 10 of the listing, we are compiling our regular expression for pattern matching use. The prefix parameter is usually a domain specific naming convention, that helps uniquely identify the MBean. The name is the name of the object. Using the sample EHCache MBean name previously identified, in this example the prefix would be net.sf.ehcache:type=CacheStatistics,CacheManager and the name would be com.ericmiles.fishing.Angler. By using this prefix variable, we should be able to find any MBean we need to within the custom tree. The call to escape() is merely performing some escaping of the string to prepare it for regex use.

On lines 13 through 18, we’re looping through all the found objects in the current tree and checking for matches against our regular expression. If a match is found, we add it to our return list. Here is a sample listing of how we could use this method to locate an MBean in a known location within our tree.

#change to the custom tree
custom();
cd('net.sf.ehcache');
mybean = findMBean('net.sf.ehcache:type=Cache,CacheManager', 'net.sf.ehcache:type=Cache,CacheManager');

#do something with your bean

The call to escape prepares the string for regex creation.That’s all there is to it. Notice how we changed into the appropriate tree with the cd() call. This method could have been written to recursively look through all trees in the custom tree, however I didn’t want the overhead associated with that. With this limitation known, you must navigate to the appropriate location within the custom tree to find your bean.


Actions

Information

4 responses

25 06 2010
Gerhard

Thanks for the post, that’s quite helpful. I like the idea of using regular expressions in this context.

One comment: I surrounded the ls statement with redirect(‘/dev/null’,’false’) and redirect(‘/dev/null’,’true’) to suppress the unwanted output of the ls statement.

25 06 2010
Eric Miles

Thanks Gerhard.

Great tip on redirecting output to /dev/null, I had no idea that API was available. Will keep that in my pocket for future use!

28 06 2011
Will

Alternatively, if you need a way that is cross platform:

#
# Quiet List Functionality
#

class NullOutputStream(java.io.OutputStream):
”’ Output Stream that sinks all output. ”’
def write(self, *args): # Use arbitrary argument list to override all overloaded write methods.
”’ Sink the write. ”’
pass

def qls(mbeanPath = None, returnType = ‘c’):
”’ Quiet List. Execute list returning data without printing to screen. See help(‘ls’) for more details. ”’
oldOut = System.out
try:
System.setOut(PrintStream(NullOutputStream()))
if mbeanPath != None:
return ls(mbeanPath, returnMap=’true’, returnType=returnType)
else:
return ls(returnMap=’true’, returnType=returnType)
finally:
System.setOut(oldOut)

#
# Example Usage
#

# Print the server’s edit attributes

connect(‘weblogic’, ‘welcome1’, ‘t3://localhost:7001’)

print ‘Attributes:’
svrAttrList = qls(‘edit:/Servers/’ + serverName, returnType=’a’)
for svrAttr in svrAttrList:
print ‘ ‘ + svrAttr

disconnect();

28 06 2011
Will

Sorry you will need to sort the “Quiet List Functionality” indenting for it to work 😦

Leave a reply to Gerhard Cancel reply