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.

View on GitHub


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, no AccessController / doPrivileged, no deprecation-for-removal warnings. Identity propagates through the JDK’s own Subject.current() / Subject.callAs.
  • Fixes a silent authorization bypass. OpenDMK’s file access controller read the caller via Subject.getSubject(AccessController.getContext()) and treated a null subject as “allow everything” — which is always null on JDK 24+. This fork reads Subject.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 existing JMXConnectorFactory code recompiles unchanged.

Security model

Security is mandatory on the server, secure-by-default on the client:

  • The listener is exactly TLS SASL/PLAIN with a required JMXAuthenticator — 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.



Back to top

Copyright © 2026 druvu.com. All rights reserved.

This site uses Just the Docs, a documentation theme for Jekyll.