druvu-lib-jmxmp
A modular, security-hardened JMXMP connector for Java 21+ — JMX over a plain socket (no RMI), locked to mandatory TLS + SASL, with no Security-Manager dependencies. A maintained, JPMS-modular fork of OpenDMK jmxremote_optional.
Overview
JMXMP is the JSR-160 “optional” connector — JMX over a plain TCP socket instead of RMI. The reference implementation (Sun’s OpenDMK jmx-optional, also distributed as jmxremote_optional) has been unmaintained since 2007 and depends on the Java Security Manager, which was disabled by default in JDK 18 and removed in JDK 24 (JEP 486).
druvu-lib-jmxmp is a faithful fork that:
- Runs on current Java (21–25+). No
SecurityManager, noAccessController/doPrivileged, no deprecation-for-removal warnings. Identity propagates through the JDK’s ownSubject.current()/Subject.callAs. - Fixes a silent authorization bypass. OpenDMK’s file access controller read the caller via
Subject.getSubject(AccessController.getContext())and treated anullsubject as “allow everything” — which is alwaysnullon JDK 24+. This fork readsSubject.current()and fails closed, pinned by a regression test on JDK 21 and 25. - Is JPMS-modular. Three real modules (
client → common,server → common), no split packages. - Keeps the public API frozen.
javax.management.remote.*is byte-for-byte the OpenDMK surface, so existingJMXConnectorFactorycode recompiles unchanged.
Security model
Security is mandatory on the server, secure-by-default on the client:
- The listener is exactly
TLS SASL/PLAINwith a requiredJMXAuthenticator— no plaintext, no escape hatch. - Encrypted by default — with no keystore configured the server generates an ephemeral self-signed certificate at startup (supply your own for full MITM protection).
- TLS 1.3 by default.
- A built-in, default-deny deserialization filter on every wire stream — the well-known gadget sinks never resolve.
- A typed, default-deny authorization SPI with a built-in role /
ObjectName-pattern policy (READ/WRITE/INVOKE/NOTIFY); remote MBean lifecycle is permanently denied.
See SECURITY.md for the threat model and maintainer support scope.
Installation
Requirements: Java 21+
Pick the module(s) for your scenario (groupId com.druvu, version 2.0.0):
Client — connect to a JMXMP server:
<dependency>
<groupId>com.druvu</groupId>
<artifactId>druvu-lib-jmxmp-client</artifactId>
<version>2.0.0</version>
</dependency>
Server — expose an MBean server over JMXMP:
<dependency>
<groupId>com.druvu</groupId>
<artifactId>druvu-lib-jmxmp-server</artifactId>
<version>2.0.0</version>
</dependency>
Each transitively brings druvu-lib-jmxmp-common.
Gradle:
implementation 'com.druvu:druvu-lib-jmxmp-client:2.0.0' // or -server
Compatibility
The public javax.management.remote.* API is unchanged (verified each build). The one behavioral break vs OpenDMK: the server is TLS SASL/PLAIN-only, so it is not a drop-in for a plaintext JMXMP listener — configure a JMXAuthenticator (TLS is automatic) and it starts. A client reaching an existing plaintext endpoint stays supported through a typed, code-only opt-out.
License
Derived from OpenDMK jmx-optional (Sun Microsystems). Dual-licensed: GPL v2 with the Classpath exception, or CDDL v1.0 — your choice.