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

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.

Related

Valid "protocols" for HornetQ

I have some code like this for connecting to HornetQ.
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
properties.put(Context.PROVIDER_URL, "remote://127.0.0.1:4447");
properties.put(Context.SECURITY_PRINCIPAL, "user");
properties.put(Context.SECURITY_CREDENTIALS, "pwd");
ConnectionFactory connectionFactory = null;
Destination destination = null;
try {
Context context = new InitialContext(properties);
I inherited this, and am trying to get a better understanding of it. I haven't found documentation for the valid values where I have "remote://". I'm not sure if it's accurate to call that a protocol or not, but that's what it looks like. I've seen "jnp://" in other samples.
Is there an official list of valid values, and what they mean?
You may want to refer to specific JNDI Reference for specific versions. JBOSS AS 7.2 is covered here: https://docs.jboss.org/author/display/AS72/JNDI+Reference (note that in JBOSS AS 7.x, jnp is no longer supported, older JBOSS versions do support the jnp:// and access via the standard naming services).
Another link: https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Web_Platform/5/html/Administration_And_Configuration_Guide/Naming_on_JBoss-The_Naming_InitialContext_Factories.html.

How do you use consistent hashing with the java elasticache libs?

Im trying to use elasticache as a memcache service with AWS's elasticache client library for java.
The following code works for connecting to the cluster:
_client = new MemcachedClient(_serverList);
But any attempt I've made to use consistent hashing results in memcache client failing to initialize:
_client = new MemcachedClient(new KetamaConnectionFactory(), _serverList);
or
ConnectionFactoryBuilder connectionFactoryBuilder = new ConnectionFactoryBuilder();
connectionFactoryBuilder.setLocatorType(Locator.CONSISTENT);
connectionFactoryBuilder.setHashAlg(DefaultHashAlgorithm.KETAMA_HASH);
connectionFactoryBuilder.setClientMode(ClientMode.Dynamic);
ConnectionFactory connectionFactory = connectionFactoryBuilder.build();
_client = new MemcachedClient(connectionFactory, _serverList);
Any attempt I've made to use anything but a vanilla MemcacheClient results in errors such as :
2015-04-07 07:00:32.914 WARN net.spy.memcached.ConfigurationPoller: The configuration is null in the server localhost
2015-04-07 07:00:32.914 WARN net.spy.memcached.ConfigurationPoller: Number of consecutive poller errors is 7. Number of minutes since the last successful polling is 0
Also, I've verified with telnet, spymecached libs, and the vanilla MemcacheClient constructor, that the security groups are permissive.
When using the AWS Client Library KetamaConnectionFactory defaults to the "dynamic" client mode which tries to poll the list of available memcached nodes from the configuration endpoint. For this to work your _serverList should only contain the configuration endpoint.
Your error message indicates the host was a "plain" memcached node which doesn't understand the ElastiCache extensions. If this is what you intend to do (specify the nodes yourself rather than use the autodiscovery feature) then you need to use the multiple-arg KetamaConnectionFactory constructor and pass in ClientMode.Static as the first argument.
You will need to use the AddrUtil.getAddresses() method.
_client = new MemcachedClient(new KetamaConnectionFactory(), AddrUtil.getAddresses("configEndpoint:port"));
or
ConnectionFactoryBuilder connectionFactoryBuilder = new ConnectionFactoryBuilder(new KetamaConnectionFactory());
// set any other properties you want on the builder
ConnectionFactory connectionFactory = connectionFactoryBuilder.build();
_client = new MemcachedClient(connectionFactory, AddrUtil.getAddresses("configEndpoint:port"));

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();

Java (and JBoss) JNDI and RMI ports

I have JBoss running on a couple of Linux machines. If I want to send a JMS message from box 1 to a queue on box2, I may do something like this:
Hashtable<String,String> jndiProperties = new Hashtable<String,String>();
jndiProperties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
jndiProperties.put(javax.naming.Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
jndiProperties.put(javax.naming.Context.PROVIDER_URL, "jnp://<ip of box2>:1099"); //
InitialContext context = new InitialContext(m_jndiProperties);
Queue queue = (Queue)context.lookup("queue/myqueue");
and then put a message on the queue. Clearly port 1099 needs to be open on box2, but I am curious what other ports are involved in that communication?
Thank You.
Others I have off top of my head:
Rmi: 1098.
HornetQ acceptors / connectors: 5446 / 5445. Both configurable in JBOSS_HOME/server/default/deploy/hornetq/hornetq-configuration.xml

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