diff --git a/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/RmiConnector.java b/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/RmiConnector.java
index 1a418b93b6..bf17de99ec 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/RmiConnector.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/protocols/jmx/RmiConnector.java
@@ -65,9 +65,6 @@ public class RmiConnector
{
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
- static final String JMX_REMOTE_RMI_SERVER_CREDENTIAL_TYPES =
- "jmx.remote.rmi.server.credential.types";
-
/**
* JDK 10+ JMX environment property scoping a JEP 290 deserialization
* filter to the credentials object passed during {@code newClient()}.
@@ -75,15 +72,16 @@ public class RmiConnector
* {@code jmx.remote.rmi.server.serial.filter.pattern}) avoids breaking
* legitimate JMX traffic such as MBean invocations and notifications,
* which may legitimately carry non-String types.
+ *
+ * Note: this property is mutually exclusive with
+ * {@code jmx.remote.rmi.server.credential.types}; specifying both makes
+ * {@code RMIJRMPServerImpl} throw an {@link IllegalArgumentException} and
+ * prevents the connector from starting. The filter pattern is preferred
+ * because it additionally constrains array length and nesting depth.
*/
static final String JMX_REMOTE_RMI_SERVER_CREDENTIALS_FILTER_PATTERN =
"jmx.remote.rmi.server.credentials.filter.pattern";
- private static final String[] JMX_CREDENTIAL_TYPES =
- {
- String.class.getName(),
- String[].class.getName()
- };
private static final String JMX_CREDENTIAL_SERIAL_FILTER =
"maxdepth=3;maxarray=2;java.lang.String;!*";
@@ -392,11 +390,13 @@ private void startConnectorNoClientCertificate() throws Exception
static void configureJmxDeserializationProtection(Map env)
{
- env.put(JMX_REMOTE_RMI_SERVER_CREDENTIAL_TYPES,
- JMX_CREDENTIAL_TYPES.clone());
// Scope the JEP 290 deserialization filter to the credentials object
// only, so legitimate JMX RMI traffic (MBean operations, notifications,
// etc.) is not affected by the restrictive allowlist.
+ //
+ // Do NOT also set "jmx.remote.rmi.server.credential.types": the JDK
+ // rejects an environment that defines both properties, which would
+ // prevent the RMI connector from starting.
env.put(JMX_REMOTE_RMI_SERVER_CREDENTIALS_FILTER_PATTERN,
JMX_CREDENTIAL_SERIAL_FILTER);
}
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/protocols/jmx/RmiAuthenticatorTest.java b/opendj-server-legacy/src/test/java/org/opends/server/protocols/jmx/RmiAuthenticatorTest.java
index 6c7b5eb3ec..7dce751fce 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/protocols/jmx/RmiAuthenticatorTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/protocols/jmx/RmiAuthenticatorTest.java
@@ -67,29 +67,15 @@ public void configuresCredentialDeserializationProtection()
Map env = new HashMap<>();
RmiConnector.configureJmxDeserializationProtection(env);
- assertEquals(env.get(RmiConnector.JMX_REMOTE_RMI_SERVER_CREDENTIAL_TYPES),
- new String[] { String.class.getName(), String[].class.getName() });
assertEquals(env.get(RmiConnector.JMX_REMOTE_RMI_SERVER_CREDENTIALS_FILTER_PATTERN),
"maxdepth=3;maxarray=2;java.lang.String;!*");
// The connector-wide filter must NOT be set, so legitimate JMX traffic
// (MBean operations, notifications) is not affected by the allowlist.
assertNull(env.get("jmx.remote.rmi.server.serial.filter.pattern"));
- }
-
- /** Verifies that each environment receives its own credential type array. */
- @Test
- public void credentialTypesAreDefensivelyCopied()
- {
- Map env = new HashMap<>();
- RmiConnector.configureJmxDeserializationProtection(env);
- String[] credentialTypes =
- (String[]) env.get(RmiConnector.JMX_REMOTE_RMI_SERVER_CREDENTIAL_TYPES);
- credentialTypes[0] = Date.class.getName();
-
- Map env2 = new HashMap<>();
- RmiConnector.configureJmxDeserializationProtection(env2);
- assertEquals(((String[]) env2.get(RmiConnector.JMX_REMOTE_RMI_SERVER_CREDENTIAL_TYPES))[0],
- String.class.getName());
+ // "jmx.remote.rmi.server.credential.types" is mutually exclusive with the
+ // credentials filter pattern: setting both prevents the connector from
+ // starting, so only the filter pattern must be configured.
+ assertNull(env.get("jmx.remote.rmi.server.credential.types"));
}
/** Verifies the configured filter allows only the expected credential payload. */