My collegue Ron DiFrango recently wrote a blog about exposing custom MBeans within the WebLogic container. Both Ron and I 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:

// full name
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=CacheStatistics,CacheManager', 'com.ericmiles.fishing.Angler');
 
//do something with your bean

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.