Access Application MBean via Jython?

Is it possible to access an application MBeans directly with a jython wsadmin script?

We have an application that has an MBean intended to refresh a small data cache. The original intent was to write a servlet /jsp that could be accessed to refresh the cache, but because we are in a clustered environment, we never know which appServer will be hit by the jsp, and can't specifically direct the request to one clone or the other, since we're using a load balanced address to get to the app.

I was "thinking"  if we could access the mbean directly through wsadmin and direct our wsadmin script to hit the mbean on each appServer in the cluster, that might solve our issue.

Even if it's not the best way to address this particular issue, now I'm just curious if this can be done, and if so, I'd love to see an example of how.
Who is Participating?
BbouchConnect With a Mentor Author Commented:
Well, I still don't have a good answer to my original question, but I now understand why there was different behavior in our different environments.

In QA I had not enambled the following JVM argument:

Once i added this, I was able to run our refresh cache mbean through jconsole, but i still have not been able to figure out how to script it in jython.

Given we probably won't dig any deeper into this issue at this point, i'm going to close the question at this point and call it good. Thanks for all your help on this HonorGod. I really do appreciate it.
HonorGodSoftware EngineerCommented:

The challenge will be to determine how to find the MBean string name.

This is most commonly done by using the AdminControl.queryNames() method.
For example, to look at the first 50 characters of each of the active server MBeans, one could use something like this:

wsadmin>for bean in AdminControl.queryNames( 'type=Server,*' ).splitlines() :
wsadmin>  print bean[ :50 ]

Open in new window

HonorGodConnect With a Mentor Software EngineerCommented:
If you are going to be writing, or using Jython wsadmin scripts, you should seriously consider taking a look at: "WebSphere Application Server Administration Using Jython" from IBM Press books:
Firewall Management 201 with Professor Wool

In this whiteboard video, Professor Wool highlights the challenges, benefits and trade-offs of utilizing zero-touch automation for security policy change management. Watch and Learn!

BbouchAuthor Commented:
Thanks HonorGod. I actually have the book, I just didn't find information about this in there.   Feel free to direct me to the right place.

I've poked around a little bit with the syntax you gave, but I'm still not able to figure out what I am doing exactly.

SO, let me be a bit more specific.  From our developers, we have the following application installed:

According to the developer there an mbean is registered on server startup as "LLBCacheUtil:name=Promotions_v2_KeyValueCache"

I think the issue is I'm not sure what "type" to use when using AdminControl.queryNames.  I tried Application but that seemed to pull only the installed applications (not the Mbeans registered from within the application).

Is there a list of available "types" somewhere that I could reference for this kind of thing?
HonorGodSoftware EngineerCommented:
> I actually have the book ...

Great!  I hope that you find it helpful, and useful.

Well, the list of Types known to WebSphere can be obtained using AdminConfig.types() method (page 152 in the book).

If I want to locate the types that contain a specific substring, I use the findTypes() routine, below

An example use of which is:

wsadmin>findTypes( 'MBean' )
['ExtensionMBean', 'ExtensionMBeanProvider']

def findTypes( text ) :
  'findTypes( text ) - Returns the list of configuration types that containing the specified text.'
  result = [];
  for Type in AdminConfig.types().splitlines() :
    if Type.find( text ) > -1 :
      result.append( Type );
  return result;

Open in new window

HonorGodConnect With a Mentor Software EngineerCommented:
So, the question is, how do we locate a specific MBean that exists only within your application?

Well, the "help" for the AdminControl.queryNames() method isn't too helpful:

wsadmin>print 'queryNames' )
WASX7036I: Method: queryNames

        Arguments: object name

        Description: Returns a String containing the ObjectNames that match
        the input object name, which may be a wild card.

What we need to do is to figure out how to identify the MBeans associated with an application.
Once we do this, we will have a much better chance of trying to figure out which is the one that we actually want.

First, we can get the list of active MBeans using something like:

beans = AdminControl.queryNames( '*' ).splitlines()

The number that exist depend upon a number of factors:
- Are you using a single, stand-alone AppServer, or a Network Deployment environment?
- How many resources are defined, and active?
- How many applications are defined, and active?

In my case the number of beans happened to be a little over 300

wsadmin>len( beans )

So, how can we find the MBeans associated with our application?
Let's see if the application name is part of the MBean:

wsadmin>for app in AdminApp.list().splitlines() :
wsadmin>  count = 0
wsadmin>  for b in beans :
wsadmin>    if b.find( app ) > -1 :
wsadmin>      count += 1
wsadmin>  print '%3d %s' % ( count, app )
  5 DefaultApplication
  7 PlantsByWebSphere
  6 SamplesGallery
  5 ivtApp
  3 query

That looks pretty neat.  Let's see which MBeans exist for the Application named "query":

wsadmin>for b in beans :
wsadmin>  if b.find( 'query' ) > -1 :
wsadmin>    print b

In each MBean, we find a value like:


and, more importantly, a value of:


So, we can quickly, and easily list the MBeans associated with the query Application using a call like:

print AdminControl.queryNames( 'name=query,*' )

Once you have this list, you have a much better time figuring out which MBean is the one you want.

Does this help?
BbouchAuthor Commented:
I think that helped me find the one I need...   but I'm still not sure how to "use" it once I have found it...
HonorGodSoftware EngineerCommented:
Ah, given an MBean identifer, we can "ask it" what methods exist.

If you execute:


Notice the first few methods that exist, and the required parameter...
attributes              given an MBean, returns help for attributes
operations              given an MBean, returns help for operations
constructors            given an MBean, returns help for constructors
description             given an MBean, returns help for description
notifications           given an MBean, returns help for notifications
classname               given an MBean, returns help for classname
all                     given an MBean, returns help for all the above

Open in new window

HonorGodSoftware EngineerCommented:
So,  to find out what "attributes" an MBean has, all you need do (given the MBean name) is something like:

# Get the MBean names into two different variables

wsadmin>b1, b2 = AdminControl.queryNames( 'name=query,*' ).splitlines()

# Example use of Help.operations() to determine which methods exist, and their expected parameter lists, and any return value:

wsadmin>print Help.operations( b1 )
[Ljava.lang.String; getModules()
java.lang.String getImplementationVersion()
java.lang.String getEdition()
[Ljava.lang.String; getEventTypes()
java.lang.String getServer()
java.lang.String getDeploymentDescriptor()
java.lang.String getName()
java.lang.String getJavaVersion()
java.lang.String getJavaVendor()
java.lang.String getObjectNameStr()
boolean isStateManageable()
boolean isStatisticsProvider()
boolean isEventProvider()

# Example invocation of a method returning a boolean value:

wsadmin>print AdminControl.invoke( b1, 'isEventProvider' )

Open in new window

BbouchAuthor Commented:
Ok, I'm closer, but I'm still not 100% following ...

In my case I have the following MBean I think is the right one...


So, I had this:
b1 = AdminControl.queryNames( 'name=PromotionsManager,Server=MarketingW_TEST_c1,*').splitlines()
wsadmin>print b1

Open in new window

Then, I tried the following, with no luck:
wsadmin>print Help.operations( b1 )
WASX7015E: Exception running command: "Help.operations( b1 )"; exception information: exception from Jython:
Traceback (innermost last):
  File "<input>", line 1, in ?
TypeError: operations(): 1st arg can't be coerced to String

Open in new window

If I try assigning 2 variables to the original AdminControl.queryNames call It looks like:
wsadmin>b1, b2 = AdminControl.queryNames( 'name=PromotionsManager,Server=MarketingW_TEST_c1,*').splitlines()
WASX7015E: Exception running command: "b1, b2 = AdminControl.queryNames( 'name=PromotionsManager,Server=MarketingW_TEST_c1,*').splitlines()"; exception information: exception from Jython:
Traceback (innermost last):
  File "<input>", line 1, in ?
ValueError: unpack sequence too short

Open in new window

Clearly I am still missing something :(  Thoughts?
HonorGodConnect With a Mentor Software EngineerCommented:
You are really close!

When you use the string splitlines() method, it returns a list.  That's why you see the MBean name surrounded by single quotes (meaning it's a string), and enclosed in square brackets (meaning it's a list).

After you get the list of MBeans:

beans = AdminControl.queryNames( 'name=PromotionsManager,Server=MarketingW_TEST_c1,*').splitlines()

You can (and should) verify that you have one, and only one!

if len( beans ) != 1 :
  print 'We have a problem:  %d beans matched our query' % len( beans )
  # ... if you're in a routine/function, use return, otherwise use sys.exit() ...
else :
  bean = beans[ 0 ];
  print Help.operations( bean );

BbouchAuthor Commented:
Sory HonorGod, I know I'm making you work for these points, and if I could give you 10,000 I would :(

It's starting to look like I am NOT finding the Mbean I am looking for with this method.

I was speaking with one of the developers of the app, and they asked me to clarify, when I say MBean I'm actually referring to a JMX MBean, if that makes a difference...  Is there a special type that I should be looking at for these types of MBeans, and/or is what I am trying to accomplish still possible...?

Specifically, if it helps any, i got the following information from our developer:

the mbean is registered on server startup as "OURCacheUtil:name=Promotions_v2_KeyValueCache"

For what it's worth I tried:
wsadmin>beans = AdminControl.queryNames( '*' ).splitlines()
wsadmin>for b in beans:
wsadmin>   if b.find('KeyValueCache') > -1 :
wsadmin>      print b

Open in new window

but came back with no hits...  

I also tried b.find('CacheUtil') and didn't get anything.

HonorGodSoftware EngineerCommented:
Thanks for the compliments.  ;-)

If the call to find() always comes back with -1, then the specified (case sensitive) text does not exist.
You are doing the right kind of test.

Remember, if the Application isn't started, then no MBeans will exist.

Has the Application been started?

If you are not certain about the exact string (i.e., which characters may, or may not be uppercase), you can change this test:

if b.find( 'KeyValueCache' ) > -1 :

to something like this:

if b.lower().find( 'keyvaluecache' ) > -1 :

Note how the MBean name is converted to lowercase before the comparison / test is made, so all of the characters in the literal string need to be lowercase.

Does this make sense?
BbouchAuthor Commented:

The app is started.

I tried if b.lower().find( 'keyvaluecache' ) > -1 :
and that still didn't find what I was looking for.

Digging a little deeper, I found the developer can access this MBean through jconsole and it appears "out of the WebSphere realm" when you see it in the jconsole gui.  i.e. there is a WebSPhere folder that has a bunch of the stuff I am (loosely) familiar with...  and a separate folder at the same level that is labeled LLBCacheUtil.  Not sure if that is the root of my issues or not, but I will attach a screenshot  of the jconsole on a local developer machine to show what I mean...

 local jconsole screenshot
BbouchAuthor Commented:
ack.  uploaded wrong screenshot...  the one here is the one I meant to upload.. developer jconsole
HonorGodConnect With a Mentor Software EngineerCommented:
Ah... "out of the websphere realm"... that makes it very difficult (if not impossible) for wsadmin scripts to access... :-(

You might be able to access via some of the scripting object jmx related methods, but I'm not 100% certain about this (having never done this before).
BbouchAuthor Commented:
Ok. that DOES make sense. Any idea how the MBEan being registered as part of app startup would get "outside" WebSphere?
HonorGodSoftware EngineerCommented:
No, that's not something that I have seen before.

You probably have to ask your developers what they are doing, and how this is happening.
BbouchAuthor Commented:
Will do.  I'll post a comment with whatever we find. Thanks again for all your help!  Some of this is definitely starting to sink in. Coming from a perl background, getting up to speed on this stuff is turning out to be a  much longer process than I had hoped for.
HonorGodSoftware EngineerCommented:
Learning is a journey, not a destination.  ;-)
BbouchAuthor Commented:
After reviewing some more of the research, it looks like the way the MBean is registered is what was causing the issue.  The developers are going to look at a different method of registering the MBean which is supposed to make it accessible via wsadmin.
HonorGodSoftware EngineerCommented:
Wow, I would like to see what you learn.  Please let me know!

Thanks, and Happy New Year.
BbouchAuthor Commented:
We have a PMR open with IBM now. It appears on some application servers the MBEan is working as expected and on others (even within the same cluster) it is not.  PMR is to help understand why. I will update this thread when I find out more.  Thanks for your patience.
HonorGodSoftware EngineerCommented:
Thanks for sharing what you learn!
HonorGodSoftware EngineerCommented:
I'm sorry that we weren't able to more completely answer your question, but I appreciate your help, and assistance, and providing us with detail that I hope will be able to assist others.

Good luck & have a great day.
BbouchAuthor Commented:
HonorGod provided a lot of useful information in regards to accessing Application MBeans through Jython, but ultimately we weren't able to come to a final resolution to my overall issue which is accessing a specific MBean. I did find one issue with my configuration, which was included in my last comment, should anyone else be trying to figure out how to do something similar.
HonorGodSoftware EngineerCommented:
Thanks for the assist, the points, and the interesting question.

Good luck & have a great day.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.