Calling JMX MBean method from a shell script
The following command line JMX utilities are available:
- jmxterm - seems to be the most fully featured utility.
- cmdline-jmxclient - used in the WebArchive project seems very bare bones (and no development since 2006 it looks like)
- Groovy script and JMX - provides some really powerful JMX functionality but requires groovy and other library setup.
- JManage command line
functionality - (downside is
that it requires a running JManage
server to proxy commands through)
Groovy JMX Example:
import java.lang.management.*
import javax.management.ObjectName
import javax.management.remote.JMXConnectorFactory as JmxFactory
import javax.management.remote.JMXServiceURL as JmxUrl
def serverUrl = 'service:jmx:rmi:///jndi/rmi://localhost:9003/jmxrmi'
String beanName = "com.webwars.gameplatform.data:type=udmdataloadsystem,id=0"
def server = JmxFactory.connect(new JmxUrl(serverUrl)).MBeanServerConnection
def dataSystem = new GroovyMBean(server, beanName)
println "Connected to:\n$dataSystem\n"
println "Executing jmxForceRefresh()"
dataSystem.jmxForceRefresh();
cmdline-jmxclient example:
If you have an
- MBean: com.company.data:type=datasystem,id=0
With an Operation called:
- jmxForceRefresh()
Then you can write a simple bash script (assuming you download cmdline-jmxclient-0.10.3.jar and put in the same directory as your script):
#!/bin/bash
cmdLineJMXJar=./cmdline-jmxclient-0.10.3.jar
user=yourUser
password=yourPassword
jmxHost=localhost
port=9003
#No User and password so pass '-'
echo "Available Operations for com.company.data:type=datasystem,id=0"
java -jar ${cmdLineJMXJar} ${user}:${password} ${jmxHost}:${port} com.company.data:type=datasystem,id=0
echo "Executing XML update..."
java -jar ${cmdLineJMXJar} - ${jmxHost}:${port} com.company.data:type=datasystem,id=0 jmxForceRefresh
Simple way to programmatically access JMX console
Take a look at this SO question:
- Calling JMX MBean method from a shell script
Linux Shell Script for calling JBoss 5x JMX's MBeans
Jboss shipped with twiddle script, you can get the list of Mbeans from jmx-console and query/invoke it through twiddle, such as
$JBOSS_HOME/twiddle.sh -s 127.0.0.1 invoke "jboss.system:type=ServerInfo" listMemoryPools "True"
$JBOSS_HOME/twiddle.sh -s 127.0.0.1 get "jboss.system:type=ServerInfo"
and you can also use nagios-jmx-plugin
java -jar check_jmx.jar -U service:jmx:rmi://127.0.0.1/jndi/rmi://127.0.0.1:1090/jmxconnector --username admin --password admin -O "jboss.system:type=ServerInfo" -A FreeMemory
How to query running java application from command line?
Use JMX
Considering your requirements, the easiest solution is most likely to use JMX. It's exactly what it's made for, as it's the Java Management eXtensions API.
You can find a nicely detailed tutorial trail in the Java Tutorial. It's relatively simple. Your Java program will listen for connections from JMX clients, and allow you to query your own Management Beans (MBean).
Administrators would then be able to use a JMX compatible client (for instance jconsole
) or a custom client. See here for a custom JMX client example.
Another good - though somewhat ancient now - tutorial is Getting Started with MBeans.
If what you want is to intercept the return value of a particular function, not to create your own extension points for monitoring and administration, then you're more likely to want to use a debugger.
Also, you may be interested in these SO questions:
- How to have 2 JVMs talk to one another
- Calling JMX MBean method from a shell script
How to pass parameters into JMX MBean function from command line
According to the cmdline-jmxclient documentation:
http://crawler.archive.org/cmdline-jmxclient/ you have to use comma-delimited parameters to pass to your operation.
So in your case if would be:
java -jar cmdline-jmxclient-0.10.3.jar admin:P@sSw0rd10.11.12.13:1111 com.sun.management:type=HotSpotDiagnostic dumpHeap test,true
Take note that there is an present bug in the cmdline jar file that doesn't take into account Java primitives(int, booelean, byte, etc.) and will throw a ClassNotFoundException because it can't find by the primitive name.
If you find yourself coming across this issue you can either apply the patch to the jar code that is documented here: https://webarchive.jira.com/browse/HER-1630. Or simply change the type field in the jmx endpoint code from it's primitive type to it's Wrapper object type (int -> Integer)
Differences in calling JMX MBean remotely or from servlet deployed in the same JVM
I suspect what is happening here is that your servlet thread has a context classloader that is different from that of the MBeans that you are invoking against. Consequently, if the MBean attributes, operation parameters or return values contain types that are not core JVM classes (or classes not shared from the same root classloader), you will get ClassCast, ClassNotFound and ClassDefNotFound Exceptions.
This procedure may work for you. What you need to do is temporarily change the context classloader of the servlet thread to the same classloader as the MBean was loaded from. Once the invocation is complete, you set it back again. Since you know the ObjectName of the target MBean, the MBeanServer will supply you the correct classloader.
Here's a basic example:
public void callMBean() throws MalformedObjectNameException, NullPointerException, InstanceNotFoundException {
final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
try {
ObjectName targetObjectName = new ObjectName(".....");
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ClassLoader tmpClassLoader = server.getClassLoaderFor(targetObjectName);
Thread.currentThread().setContextClassLoader(tmpClassLoader);
// ==========================================
// Invoke operations here
// ==========================================
} finally {
Thread.currentThread().setContextClassLoader(currentClassLoader);
}
}
Can one MBean link to another?
My conclusion is that you can return an ObjectName
but it will not be linked when you access your M[X]Bean from the sun jconsole application. Instead you will just be presented the string representation of the ObjectName.
However, if you implement your own JMX client you can use these returned ObjectName to look up the "linked to" M[X]Bean.
Related Topics
Peer Not Authenticated While Importing Gradle Project in Eclipse
Comparing and Thencomparing Gives Compile Error
How to Parse a JSON String to an Array Using Jackson
Comparing Strings by Their Alphabetical Order
How to Bind an Object List with Thymeleaf
Why Can Final Object Be Modified
Integer Arithmetic in Java with Char and Integer Literal
Preparedstatement with Statement.Return_Generated_Keys
How to Bundle Images in Jar File
How to Properly Use Java Executor
Adding Points to Xyseries Dynamically with Jfreechart
How to Abort a Thread in a Fast and Clean Way in Java
How to Show Jrbeancollectiondatasource Data with Help of Table Component