JMX Publisher

Tool to get properties and methods published via JMX easily.

License

License

GroupId

GroupId

com.avast
ArtifactId

ArtifactId

jmx-publisher
Last Version

Last Version

1.4.2
Release Date

Release Date

Type

Type

jar
Description

Description

JMX Publisher
Tool to get properties and methods published via JMX easily.
Project URL

Project URL

https://github.com/avast/jmx-publisher/wiki
Project Organization

Project Organization

AVAST Software
Source Code Management

Source Code Management

https://github.com/avast/jmx-publisher

Download jmx-publisher

How to add to project

<!-- https://jarcasting.com/artifacts/com.avast/jmx-publisher/ -->
<dependency>
    <groupId>com.avast</groupId>
    <artifactId>jmx-publisher</artifactId>
    <version>1.4.2</version>
</dependency>
// https://jarcasting.com/artifacts/com.avast/jmx-publisher/
implementation 'com.avast:jmx-publisher:1.4.2'
// https://jarcasting.com/artifacts/com.avast/jmx-publisher/
implementation ("com.avast:jmx-publisher:1.4.2")
'com.avast:jmx-publisher:jar:1.4.2'
<dependency org="com.avast" name="jmx-publisher" rev="1.4.2">
  <artifact name="jmx-publisher" type="jar" />
</dependency>
@Grapes(
@Grab(group='com.avast', module='jmx-publisher', version='1.4.2')
)
libraryDependencies += "com.avast" % "jmx-publisher" % "1.4.2"
[com.avast/jmx-publisher "1.4.2"]

Dependencies

compile (2)

Group / Artifact Type Version
org.slf4j : slf4j-api jar 1.7.7
com.google.code.findbugs : jsr305 jar 2.0.1

test (3)

Group / Artifact Type Version
ch.qos.logback : logback-classic jar 1.1.3
com.avast.client : client-jmx jar 1.0.0
junit : junit jar 4.11

Project Modules

There are no modules declared in this project.

JMX publisher

Tool to get properties and methods published via JMX easily.

It consist of following annotations:

  • @JMXProperty - annotates field OR method that should be visible through JMX. Method should have no parameters, it's result is returned.
  • @JMXPropertyGetter - annotates method that serves as getter for specific field
  • @JMXPropertySetter - annotates method that serves as setter for specific field
  • @JMXOperation - annotates method (must be public) that servers as JMX operation

Usage is fairly simple - user annotates fields or method that he wants to show via JMX as @JMXProperty. As long as these fields are java types (no custom types), everything should work out of the box. There is no need to create getters for fields, methods marked as @JMXPropertyGetter are optional (however, return type must be compatible with property type). By the same logic, you can mark method as a @JMXProperty and its result will be published as it was an ordinary property - no need to create cover property.

Setters and getters can have names - this links them to the field. Field can have names too, if no name is specified, field name is used. If there is no name specified for setter/getter, framework tries to automatically resolve what property do these methods belong to - stripping get/is/set prefix and lowercasing first letter. See example below.

Finally, there is the MyDynamicBean class that processes annotations and exposes JMX properties. Just like this:

ClassWithJMXProperties obj = new ClassWithJMXProperties();
...
...
MyDynamicBean.exposeAndRegisterSilently(obj);//expose JMX

Larger Example:

public class TestMonitorable {

    private static final Logger LOGGER = LoggerFactory.getLogger(TestMonitorable.class);

    @JMXProperty(setable = true)
    private long primitiveCnt = 0L;
    @JMXProperty
    private AtomicInteger atomicCnt = new AtomicInteger(0);
    @JMXProperty
    private AtomicInteger atomicCntSetable = new AtomicInteger(0);
    @JMXProperty
    private Map<String, Long> mapStats = new HashMap<String, Long>();

    public static void main(String[] args) throws Exception {
        TestMonitorable tm = new TestMonitorable();
        tm.testMonitorable();
    }

    @JMXProperty(name="cacheSize")
    public long getCacheSize() {
        return mapStats.size();
    }

    @JMXPropertySetter
    public void setPrimitiveCnt(long num) {
        LOGGER.debug("Set method invoked");
        primitiveCnt = num;
    }

    @JMXPropertyGetter
    public long getPrimitiveCnt() {
        LOGGER.debug("Get method invoked");
        return primitiveCnt;
    }

    @JMXOperation
    public void jmxOperationTest(String param) {
        System.out.println("This is @JMXOperation, called with parameter "+param);
    }

    public void testMonitorable() throws Exception {
        //can be called like that, or simplier: MyDynamicBean.exposeAndRegisterSilently(this);
        MyDynamicBean mdb = new MyDynamicBean(this);
        mdb.register();
        Thread.sleep(Long.MAX_VALUE);
    }
  • As setable can be used properties of following types: int, long, boolean, Integer, Long, Boolean, String, AtomicInteger, AtomicLong and AtomicBoolean
  • The atomic types looks like its basic class, e.g. AtomicInteger is shown like it was an ordinary Integer (see example usage below).

#JMX client

JMXClientConnection class provides a good way to access the JMX properties (and operations) directly from Java/Scala program.

Small example of usage (snippet from tests):

  JMXClientConnection connection = new JMXClientConnection("localhost:9969");
  ObjectName objectName = connection.getObjectName("com.avast.jmx:type=JmxTestApplication");

  int valueInt = new Random().nextInt();
  connection.setAttribute(objectName, "setableInt", valueInt);
  connection.setAttribute(objectName, "setableInteger", valueInt);

  assertEquals(valueInt, connection.getAttribute(objectName, "setableInt"));
  assertEquals(valueInt, connection.getAttribute(objectName, "setableInteger"));

or (Scala):

  val jmx = new JMXClientConnection(URL_JMX, PORT_JMX)

  val o = jmx.getObjectName("com.avast.sb.plugins:type=WinQualPlugin")

  assert(o != null)

  val oldVal = jmx.getAttribute(o, "dumpPercentage")

  jmx.invoke(o, "setDumpPercentage", Array(1.0.asInstanceOf[AnyRef]), Array(JMXClientConnection.JAVA_DOUBLE_TYPE))

Unfortunately, method invoking requires exact parameter typing (or the method would not be found by reflection).

Atomic properties usage:

  connection.setAttribute(objectName, "setableAtomicInteger", valueInt);
  assertEquals(valueInt, connection.getAttribute(objectName, "setableAtomicInteger"));

Just like and ordinary Integer...

com.avast

Avast

https://avast.github.io

Versions

Version
1.4.2
1.4.1
1.4.0
1.3.0
1.2.0
1.1.1
1.1.0
1.0.2
1.0.1
1.0.0