Invoke Mbean via client program - java

I created an mbean. Below is my configuration. I could see my bean configuration after the server startup on JMX console. I tried to stop/start the mbean from the jmx console and it is working.
But when I am writing the code to invoke the mbean via program running in the same JVM, I could not see my bean
mbean details : xyz.abc.test:service=myTestService,name=myTestServiceName
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
try {
Set<ObjectName> names = new TreeSet<ObjectName>(server.queryNames(null, null));
for (ObjectName name : names) {
System.out.println("\tObjectName = " + name);
}
The above code is not printing my bean to invoke. Even client program is not working.
url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:8080/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

Related

Accessing MBeans in JBoss AS5 from client inside JBoss EAP6.4

I have MBeans in JBoss AS5.1 that were being accessed using RMIAdaptor from client within JBossAS5.1.
we do something like:
InitialContext ic = new InitialContext(props);
org.jboss.jmx.adaptor.rmi.RMIAdaptor rmiAdaptor = (org.jboss.jmx.adaptor.rmi.RMIAdaptor) ic.lookup("jmx/invoker/RMIAdaptor");
ObjectName mBean = new ObjectName(SOME_MBEAN_NAME) ;
rmiAdaptor.invoke(mBean, "performSomeOperation", new Object[]{"xyz"}, new String[] {"java.lang.String"});
We have migrated a portion of client code using RMIAdaptor to JBoss EAP6.4. Now, we are not able to access/invoke MBeans deployed on JBoss AS5.1.
Attempted to user remoting-jmx without success:
service:jmx:remoting-jmx://<host>:<port>
Please reply with your solution or pointers to find the solution.

ERROR when creating a connectioFactory JMS websphere MQ

The native JNI library 'mqjbnd64' not found.
please some one can help me to get mqjbnd64
this is my code
ConnectionFactory connectionFactory=null;
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, "file:/C:/CWMQv75-POT/JMS/JNDI Namespace");
try{
Context ctx = new InitialContext(env);
// MQQueueManager qm = (MQQueueManager)ctx.lookup("QM");
MQConnectionFactory cf = (MQConnectionFactory) ctx.lookup("CF1");
// cf.createConnection().start();
MQQueue q = (MQQueue) ctx.lookup("JMS1");
connectionFactory = (ConnectionFactory)ctx.lookup("CF1");
System.out.println("succes "+q.getBaseQueueManagerName().toString() + " " + q.getBaseQueueName()+" " +" " + cf.getChannel() );
} catch (NamingException e)
{
System.err.println(e.getLocalizedMessage());
e.printStackTrace();
}
Connection connection = connectionFactory.createConnection();
}
The native JNI library 'mqjbnd64' not found
Questions:
1) Are you running your JMS application on the SAME serer as the queue manager or a different server?
2) When you defined your QCF, did you include host, port #, channel name?
3) Do you understand the difference between connecting to a queue manager in bindings mode vs client mode?
You can ONLY connect in bindings mode if your application is running on the same server as the queue manager. When connecting in bindings mode the JMS/Java MQ library uses the native MQ library, hence, it needs the mqjbnd64 shared library or DLL on Windows to perform the MQ API calls.
Most MQ applications do NOT reside on the same server as the queue manager and they will use client mode to connect to the remote queue manager and your QCF would look something like:
DEFINE QCF(MYQCF) QMANAGER(MQWL1) CHANNEL(TESTCHL) HOSTNAME(10.10.10.10) PORT(1414) TRANSPORT(CLIENT) FAILIFQUIESCE(YES)
One other thing I noticed:
env.put(Context.PROVIDER_URL, "file:/C:/CWMQv75-POT/JMS/JNDI Namespace");
that should be:
env.put(Context.PROVIDER_URL, "file://C:/CWMQv75-POT/JMS/JNDI Namespace");
You should have 2 forward slashes "//" after "file:".

Is it possible to enable remote jmx monitoring programmatically?

I need to programmatically start a new java process and dynamically set the JMX port.
So instead of doing this
-Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.port=9995 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
I would like to do the following
System.setProperty("java.rmi.server.hostname", "127.0.0.1" );
System.setProperty("com.sun.management.jmxremote", "true" );
System.setProperty("com.sun.management.jmxremote.authenticate", "false" );
System.setProperty("com.sun.management.jmxremote.ssl", "false" );
System.setProperty("com.sun.management.jmxremote.port", "9995" );
but it doesn't work. Any idea why?
By the time your code is called you've missed your chance to configure the jmxremote connector.
What you need to do is create your own rmi registry and a JMXConnectorServer to listen for rmi calls and pass them to the MBeanServer.
private void createJmxConnectorServer() throws IOException {
LocateRegistry.createRegistry(1234);
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://localhost/jndi/rmi://localhost:1234/jmxrmi");
JMXConnectorServer svr = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
svr.start();
}

How does jconsole discover the JMX enabled processes on local system?

When I run jconsole it shows me a list of Java processes:
I could then connect to one of these and see its MBeans. How does it discover the JMX processes? How can I do this in a program?
This article shows how to do it using Attach API from JDK tools.jar
Replying since I had this question too and got an answer.
There is a JPS program in JDK which shows java processes.
I am not 100% sure (don't want to dive deep into jconsole code) but 99% sure jconsole uses the same mechanism as jps:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/sun/tools/jps/Jps.java?av=f
HostIdentifier hostId = arguments.hostId();
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(hostId);
// get the set active JVMs on the specified host.
Set<Integer> jvms = monitoredHost.activeVms();
These class are part of tools.jar, you need to include it in the project's classpath.
If we go deeper (I do not expose all the intermediate steps) - finally we'll know that active VMs list is populated from hsperfdata files in temporary directories:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java
Here is a link to know more:
java hsperfdata directory
At last, here is a code snippet allowing you to get the java processes ids:
sun.jvmstat.monitor.MonitoredHost host = sun.jvmstat.monitor.MonitoredHost.getMonitoredHost(new sun.jvmstat.monitor.HostIdentifier((String) null));
System.out.println(host.activeVms());
P.S.
Then you can use Attach API (as kostya mentioned) to discover the rest of needed things.
After you register the MBean in your application, like this:
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
//register the MBean
ObjectMbean mBean = new ObjectMbean();
ObjectName name = new ObjectName("com.gd.eventfiltering.jmx:type=SystemConfig");
mbs.registerMBean(mBean, name);
Then you can call your MBean like this:
JMXServiceURL url = new JMXServiceURL(JMX_PATH);
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName(JMX_OBJECT);
IObjectMbean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName,IObjectMbean.class, false);
//call the method
List<EventType> filters = mbeanProxy.methodFromYourMBean();
jmxc.close();

How do I programmatically dump JMX data?

I want to be able to log all JMX data accessible via jconsole. Is there a way to do this programmatically? I'm building a form of logging of the system, and I want to create intervaled data viewable with some tool similar to jconsole.
How would I go about doing this?
java.lang.management.ManagementFactory gives you access to JMX data.
i.g.
List<MemoryPoolMXBean> memPoolBeans = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean mpb : memPoolBeans) {
System.out.println("Memory Pool: " + mpb.getName());
}
Some samples are available at SO query: [java]+managementfactory
A good read: https://www.ibm.com/developerworks/library/j-jtp09196/index.html
For full implementation connecting to a remote VM:
Map<String,String[]> env = new HashMap<String, String[]>();
env.put( JMXConnector.CREDENTIALS, new String[]{"user","pass"} );
JMXServiceURL address = new JMXServiceURL("service:rmi:///jndi/rmi://host:port/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(address,env);
MBeanServerConnection mbs = connector.getMBeanServerConnection();
//get all mbeans
Set<ObjectInstance> beans = mbs.queryMBeans(null,null);
for( ObjectInstance instance : beans )
{
MBeanInfo info = mbs.getMBeanInfo( instance.getObjectName() );
}
From the info, you can query object names and attributes as desired.
I used this command line JMX client as a starting point when I wanted to do the same thing.

Categories