JMX and Spring – Part 1

This is the first of three articles which will show how to empower your Spring applications with JMX support.

Maven Configuration

This is the Maven pom.xml to setup the code for this example:

 
 
 
 
 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>uk.co.jemos.experiments.jmx</groupId>
  <artifactId>jemos-jmx-experiments</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>jemos-jmx-experiments</name>
  <description>Jemos JMX Experiments</description>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.16</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>3.0.5.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>3.0.5.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jmx</artifactId>
      <version>2.0.8</version>
      <scope>compile</scope>
    </dependency>        
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>3.0.5.RELEASE</version>
        <type>jar</type>
        <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Spring configuration

The Spring configuration is pretty straight-forward:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">


    <context:property-placeholder location="classpath:jemos-jmx.properties" />

    <bean id="rmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
        <property name="port" value="${jemos.jmx.rmi.port}" />
    </bean>

    <bean id="jemosJmxServer" class="org.springframework.jmx.support.ConnectorServerFactoryBean"
        depends-on="rmiRegistry" >
        <property name="objectName" value="connector:name=rmi" />
        <property name="serviceUrl"
            value="service:jmx:rmi://localhost/jndi/rmi://localhost:${jemos.jmx.rmi.port}/jemosJmxConnector" />
        <property name="environment">
            <!-- the following is only valid when the sun jmx implementation is used -->
            <map>
                <entry key="jmx.remote.x.password.file" value="${user.home}/.secure/jmxremote.password" />
                <entry key="jmx.remote.x.access.file" value="${user.home}/.secure/jmxremote.access" />
            </map>
        </property>
    </bean>

</beans>

This configuration, although simple, covers all that’s required for the following:

  • Start up a JMX server from your Spring application context
  • Expose access to the JMX server through a remote RMI URL
  • Protect access to the JMX server though authentication and authorisation

Few things to note about the above configuration:

  • You want to externalise some configuration information, such as the RMI registry port and the host where the application is running. Although I externalised the RMI registry port to a property file in the classpath, I left “localhost” as host name. In a real production environment, especially when you want to scale your application horizontally, e.g. deploy it on different servers, the server part of the remote URL should also be externalised.
  • Because we are exposing a remote RMI URL, in order to expose the JMX server to the RMI registry, we need to start an RMI registry if one is not already started; this happens by declaring the RmiRegistryFactoryBean. The port on which the registry is started must be the same as the exposed URL.
  • The above configuration does not enable annotation-based MBean support; such configuration will be the subject of my next article in which I’ll show how to code a simple MBean to change the logging level of your Log4j-based application. Protecting access to the JMX server through authentication and authorisation

In the above configuration you might have noticed the following part:

<property name="environment">
            <!-- the following is only valid when the sun jmx implementation is used -->
            <map>
                <entry key="jmx.remote.x.password.file" value="${user.home}/.secure/jmxremote.password" />
                <entry key="jmx.remote.x.access.file" value="${user.home}/.secure/jmxremote.access" />
            </map>
        </property>

What the above snippet declares is the location of two files, one used for authorisation, one for authentication. I decided to put such files under ~/.secure but the location is ultimately up to you. The content of such files is simple:

JMX access file

jemosAdmin readwrite

The above file contains the name of a user (jemosAdmin) and its role (readwrite).

JMX password file

In the JMX password file you declare the user and its password:

jemosAdmin secure

Once these information are in place, you can start up the JMX server and then access it through either jconsole or jvisualvm (if you are using JDK6 or later).

Once authenticated, the RMI connector is actually available as a bean, as are all Oracle’s native MBeans.

In my next article I will show how to code a simple Logging MBean service which can be used at runtime to change the logging level of a package (and all its subpackages). This service brings the advantage of increased uptime and helps troubleshooting applications.

Continue to Part 2.

Reference: JMX and Spring – Part 1 from our JCG partner Marco Tedone at the Marco Tedone’s blog blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


× six = 12



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books