Home » Java » Enterprise Java » JMX and Spring – Part 1

About Marco Tedone

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.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*


eight × = 72

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Want to take your Java Skills to the next level?
Grab our programming books for FREE!
  • Save time by leveraging our field-tested solutions to common problems.
  • The books cover a wide range of topics, from JPA and JUnit, to JMeter and Android.
  • Each book comes as a standalone guide (with source code provided), so that you use it as reference.
Last Step ...

Where should we send the free eBooks?

Good Work!
To download the books, please verify your email address by following the instructions found on the email we just sent you.