Configuration for JMX MBean exposure of Spring Boot Actuator endpoints.
# 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<domain>:type=Endpoint,name=<EndpointId>[,context=<ContextId>][,<staticNames>]
Example:
com.example.myapp:type=Endpoint,name=Health,application=MyApp,environment=production@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
}@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
}
}⚠️ 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;
}management.endpoints.jmx.domain=com.example.monitoring
# Results in:
# com.example.monitoring:type=Endpoint,name=Health
# com.example.monitoring:type=Endpoint,name=Infomanagement.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# Expose specific endpoints
management.endpoints.jmx.exposure.include=health,metrics,threaddump
# Exclude sensitive endpoints
management.endpoints.jmx.exposure.exclude=shutdown# Limited web exposure
management.endpoints.web.exposure.include=health,info
# Full JMX exposure (for internal monitoring)
management.endpoints.jmx.exposure.include=*@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);
}
};
}@Bean
public EndpointFilter<ExposableJmxEndpoint> securityJmxEndpointFilter() {
return endpoint -> {
String id = endpoint.getEndpointId().toString();
return !id.equals("shutdown"); // Never expose shutdown via JMX
};
}jconsole <pid>Navigate to: MBeans → org.springframework.boot → Endpoint → <endpoint-name>
java -jar jmxterm.jar
open <pid>
domain org.springframework.boot
bean org.springframework.boot:type=Endpoint,name=Health
run health@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);
}
}Causes:
spring.jmx.enabled=falsemanagement.endpoints.jmx.exposure.includeSolution:
spring.jmx.enabled=true
management.endpoints.jmx.exposure.include=*Symptom: InstanceAlreadyExistsException
Cause: Multiple application contexts or naming conflict
Solution: Use unique JMX domain or context-aware ObjectName factory
Warning: Jackson2EndpointAutoConfiguration deprecated
Solution: Migrate to Jackson 3:
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>| Aspect | Web (HTTP) | JMX (MBeans) |
|---|---|---|
| Default Exposure | health | * (all) |
| Format | JSON | Java objects |
| Access | HTTP clients | JMX clients |
| Security | Spring Security | JMX authentication |
| Typical Use | External monitoring | Internal monitoring |
# 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 levelConfigure 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