I have more than 5 spring web application and all of them are utilizing another common library. This common library has its own MBeans. Because of mandatory unique objectName constraint, my applications could not be deployed on same server.
The way I am using MBeans are like this:
@ManagedResource(objectName = "com.org.city:name=City", description = "City related operations")
I would like to use same MBean class with different objectNames for all applications. What is the correct way to utilize it without duplicating my MBeans.
Thanks
I ran into the same issue, and built off of Cemo's solution. Here is a sample implementation.
<!-- Set up jmx bean auto scanning -->
<!-- Note: we're not using <context:mbean-export /> because we need to provide our own naming strategy -->
<bean id="mbeanExporter" class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter">
<property name="namingStrategy">
<bean class="com.foo.MultiAppMetadataNamingStrategy">
<property name="applicationName" value="${application.name}" />
</bean>
</property>
</bean>
public class MultiAppMetadataNamingStrategy implements ObjectNamingStrategy, InitializingBean {
private String applicationName;
public MultiAppMetadataNamingStrategy() {
}
public MultiAppMetadataNamingStrategy(String applicationName) {
this.applicationName = Preconditions.checkNotNull(applicationName, "applicationName must not be null");
}
public void setApplicationName(String applicationName) {
this.applicationName = Preconditions.checkNotNull(applicationName, "applicationName must not be null");
}
@Override
public void afterPropertiesSet() throws Exception {
if (applicationName == null) {
throw new IllegalArgumentException("Property 'applicationName' is required");
}
}
@Override
public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
Class managedClass = AopUtils.getTargetClass(managedBean);
String domain = ClassUtils.getPackageName(managedClass);
Hashtable<String, String> properties = new Hashtable<>();
properties.put("type", ClassUtils.getShortName(managedClass));
properties.put("name", beanKey);
// ensure the application name is included as a property in the object name
properties.put("app", applicationName);
return ObjectNameManager.getInstance(domain, properties);
}
}
This allows setting up an mbean like:
package com.foo;
@ManagedResource(description = "Bean description")
public class MyBean {
...
}
which will register an mbean with object name com.foo:name=myBean,type=MyBean,app=CustomAppName
I have implemented ObjectNamingStrategy for custom behaviour.
@Override
public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
Class managedClass = AopUtils.getTargetClass(managedBean);
Hashtable<String, String> properties = new Hashtable<String, String>();
properties.put("type",ClassUtils.getPackageName(managedClass).concat(".").concat(ClassUtils.getShortName(managedClass)));
properties.put("name", beanKey);
return ObjectNameManager.getInstance(domain, properties);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With