or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

conditional-annotations.mdcore-infrastructure.mdendpoint-filtering.mdendpoint-properties.mdindex.mdjmx-endpoints.mdmanagement-endpoints.mdmanagement-server.mdweb-endpoints.md
tile.json

jmx-endpoints.mddocs/

JMX Endpoint Exposure

Configuration for JMX MBean exposure of Spring Boot Actuator endpoints.

Quick Reference

# Enable JMX (enabled by default)
spring.jmx.enabled=true

# JMX domain
management.endpoints.jmx.domain=com.example.myapp

# Exposure (default: all)
management.endpoints.jmx.exposure.include=*
management.endpoints.jmx.exposure.exclude=shutdown

# Static ObjectName properties
management.endpoints.jmx.static-names.application=MyApp
management.endpoints.jmx.static-names.environment=production

ObjectName Format

<domain>:type=Endpoint,name=<EndpointId>[,context=<ContextId>][,<staticNames>]

Example:
com.example.myapp:type=Endpoint,name=Health,application=MyApp,environment=production

API Reference

JmxEndpointAutoConfiguration

@AutoConfiguration
@ConditionalOnBooleanProperty("spring.jmx.enabled")
@EnableConfigurationProperties({JmxEndpointProperties.class, JmxProperties.class})
public final class JmxEndpointAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(JmxEndpointsSupplier.class)
    JmxEndpointDiscoverer jmxAnnotationEndpointDiscoverer(
        ParameterValueMapper parameterValueMapper,
        ObjectProvider<OperationInvokerAdvisor> invokerAdvisors,
        ObjectProvider<EndpointFilter<ExposableJmxEndpoint>> endpointFilters,
        ObjectProvider<OperationFilter<JmxOperation>> operationFilters
    );

    @Bean
    @ConditionalOnMissingBean(value = EndpointObjectNameFactory.class)
    DefaultEndpointObjectNameFactory endpointObjectNameFactory(MBeanServer mBeanServer);

    @Bean
    IncludeExcludeEndpointFilter<ExposableJmxEndpoint> jmxIncludeExcludePropertyEndpointFilter();

    /**
     * Creates a lazy initialization exclude filter for JMX endpoint exporter
     * Ensures JmxEndpointExporter is initialized eagerly to register MBeans early
     * @return Lazy initialization exclude filter for JmxEndpointExporter bean
     * @since 2.5.0
     */
    @Bean
    LazyInitializationExcludeFilter eagerlyInitializeJmxEndpointExporter();

    /**
     * Creates operation filter based on endpoint access properties for JMX
     * Filters JMX operations based on access levels (UNRESTRICTED, READ_ONLY, NONE)
     * @param endpointAccessResolver Access resolver from properties
     * @return Operation filter that enforces access restrictions for JMX operations
     * @since 3.4.0
     */
    @Bean
    OperationFilter<JmxOperation> jmxAccessPropertiesOperationFilter(EndpointAccessResolver endpointAccessResolver);
}

// Jackson 3 support
@Configuration
@ConditionalOnClass(JsonMapper.class)
static class JmxJacksonEndpointConfiguration {
    @Bean
    @ConditionalOnSingleCandidate(MBeanServer.class)
    JmxEndpointExporter jmxMBeanExporter(
        MBeanServer mBeanServer,
        EndpointObjectNameFactory endpointObjectNameFactory,
        ObjectProvider<JsonMapper> jsonMapper,
        JmxEndpointsSupplier jmxEndpointsSupplier
    );
}

// Jackson 2 support (DEPRECATED - removed in 4.2.0)
@Configuration
@ConditionalOnClass(ObjectMapper.class)
@ConditionalOnMissingClass("tools.jackson.databind.json.JsonMapper")
@Deprecated(since = "4.0.0", forRemoval = true)
static class JmxJackson2EndpointConfiguration {
    // Use JmxJacksonEndpointConfiguration instead
}

JmxEndpointProperties

@ConfigurationProperties("management.endpoints.jmx")
public class JmxEndpointProperties {

    private String domain;                           // JMX domain name
    private Properties staticNames = new Properties();  // Additional ObjectName properties
    private Exposure exposure = new Exposure();      // Include/exclude

    public static class Exposure {
        private Set<String> include = new LinkedHashSet<>(Set.of("*"));  // Default: all
        private Set<String> exclude = new LinkedHashSet<>();             // Default: none
    }
}

DefaultEndpointObjectNameFactory

⚠️ INTERNAL IMPLEMENTATION - NOT FOR PUBLIC USE

This class is package-private and is an internal implementation detail. It is not part of the public API and should not be extended or used directly by application code. For custom ObjectName generation, implement the EndpointObjectNameFactory interface instead.

/**
 * Default implementation of EndpointObjectNameFactory
 * Creates ObjectNames for JMX endpoint MBeans using Spring Boot conventions
 * Package-private internal implementation - NOT FOR PUBLIC USE
 *
 * @since 2.0.0
 */
class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {

    /**
     * Creates factory with JMX configuration
     * @param properties JMX endpoint properties (domain, static names)
     * @param jmxProperties JMX properties (default domain)
     * @param mBeanServer MBean server instance
     * @param contextId Application context ID (for multi-context scenarios)
     */
    public DefaultEndpointObjectNameFactory(
        JmxEndpointProperties properties,
        JmxProperties jmxProperties,
        MBeanServer mBeanServer,
        String contextId
    );

    /**
     * Gets the JMX ObjectName for an endpoint
     * Format: <domain>:type=Endpoint,name=<EndpointId>[,context=<ContextId>][,<staticNames>]
     *
     * @param endpoint The JMX endpoint
     * @return The ObjectName for this endpoint
     * @throws MalformedObjectNameException if the ObjectName is invalid
     */
    @Override
    public ObjectName getObjectName(ExposableJmxEndpoint endpoint) throws MalformedObjectNameException;
}

/**
 * Factory interface for creating JMX ObjectNames
 */
public interface EndpointObjectNameFactory {
    /**
     * Gets the JMX ObjectName for an endpoint
     * @param endpoint The JMX endpoint
     * @return The ObjectName
     * @throws MalformedObjectNameException if the name is invalid
     */
    ObjectName getObjectName(ExposableJmxEndpoint endpoint) throws MalformedObjectNameException;
}

Configuration Examples

Custom JMX Domain

management.endpoints.jmx.domain=com.example.monitoring

# Results in:
# com.example.monitoring:type=Endpoint,name=Health
# com.example.monitoring:type=Endpoint,name=Info

Static ObjectName Properties

management.endpoints.jmx.static-names.application=MyApp
management.endpoints.jmx.static-names.environment=production
management.endpoints.jmx.static-names.region=us-east-1

# Results in:
# org.springframework.boot:type=Endpoint,name=Health,application=MyApp,environment=production,region=us-east-1

Selective Exposure

# Expose specific endpoints
management.endpoints.jmx.exposure.include=health,metrics,threaddump

# Exclude sensitive endpoints
management.endpoints.jmx.exposure.exclude=shutdown

Different Exposure for Web vs JMX

# Limited web exposure
management.endpoints.web.exposure.include=health,info

# Full JMX exposure (for internal monitoring)
management.endpoints.jmx.exposure.include=*

Customization

Custom ObjectName Factory

@Bean
public EndpointObjectNameFactory customObjectNameFactory() {
    return endpoint -> {
        try {
            String id = endpoint.getEndpointId().toString();
            return new ObjectName("com.example:type=ActuatorEndpoint,name=" + id);
        } catch (MalformedObjectNameException e) {
            throw new IllegalStateException("Invalid ObjectName", e);
        }
    };
}

Custom JMX Endpoint Filter

@Bean
public EndpointFilter<ExposableJmxEndpoint> securityJmxEndpointFilter() {
    return endpoint -> {
        String id = endpoint.getEndpointId().toString();
        return !id.equals("shutdown");  // Never expose shutdown via JMX
    };
}

JMX Monitoring

Using JConsole

jconsole <pid>

Navigate to: MBeansorg.springframework.bootEndpoint<endpoint-name>

Using jmxterm

java -jar jmxterm.jar
open <pid>
domain org.springframework.boot
bean org.springframework.boot:type=Endpoint,name=Health
run health

Programmatic Access

@Component
public class JmxEndpointMonitor {

    private final MBeanServer mBeanServer;

    public JmxEndpointMonitor(MBeanServer mBeanServer) {
        this.mBeanServer = mBeanServer;
    }

    public Object invokeHealthEndpoint() throws Exception {
        ObjectName objectName = new ObjectName(
            "org.springframework.boot:type=Endpoint,name=Health"
        );
        return mBeanServer.invoke(
            objectName,
            "health",
            new Object[0],
            new String[0]
        );
    }

    public Set<ObjectName> getAllEndpointMBeans() throws Exception {
        ObjectName pattern = new ObjectName("org.springframework.boot:type=Endpoint,*");
        return mBeanServer.queryNames(pattern, null);
    }
}

Common Issues

Issue: Endpoints Not Visible in JConsole

Causes:

  1. JMX disabled: spring.jmx.enabled=false
  2. Not exposed: Check management.endpoints.jmx.exposure.include

Solution:

spring.jmx.enabled=true
management.endpoints.jmx.exposure.include=*

Issue: Duplicate MBean Registration

Symptom: InstanceAlreadyExistsException

Cause: Multiple application contexts or naming conflict

Solution: Use unique JMX domain or context-aware ObjectName factory

Issue: Jackson 2 Deprecation Warning

Warning: Jackson2EndpointAutoConfiguration deprecated

Solution: Migrate to Jackson 3:

<dependency>
  <groupId>tools.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>

Web vs JMX Comparison

AspectWeb (HTTP)JMX (MBeans)
Default Exposurehealth* (all)
FormatJSONJava objects
AccessHTTP clientsJMX clients
SecuritySpring SecurityJMX authentication
Typical UseExternal monitoringInternal monitoring

Security Considerations

Network Isolation

# Main app: accessible from anywhere
server.address=0.0.0.0

# JMX: internal network only
management.endpoints.jmx.exposure.include=*
# Configure JMX port and SSL at JVM level

JMX Authentication

Configure at JVM level:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.password.file=/path/to/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=/path/to/jmxremote.access
-Dcom.sun.management.jmxremote.ssl=true

Related Documentation

  • Web Endpoints - HTTP exposure
  • Endpoint Filtering - Include/exclude filtering
  • Management Endpoints - Individual endpoints