I apologize for it being a bit rough - it's what I was using to troubleshoot locally.
import static java.util.Objects.nonNull; import java.lang.management.ManagementFactory; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.function.Predicate; import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanServer; import javax.management.ObjectName; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.tomcat.util.net.SSLHostConfig; import org.apache.tomcat.util.net.SSLHostConfigCertificate; import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type; @javax.annotation.ManagedBean public class MbeanFailure { private static final Logger LOGGER = LogManager.getLogger(); private static final String LOCALHOST = "127.0.0.1"; private static final String SUBTYPE = "subType"; private static final String ADD_SSL_HOST_CONFIG_OP = "addSslHostConfig"; private static final Predicate<ObjectName> NOT_LOCALHOST = Predicate.not(on -> Optional.ofNullable(on).map(ObjectName::getCanonicalName).orElse("").contains(LOCALHOST)); private static final Predicate<ObjectName> NOT_SUBTYPE = Predicate.not(on -> Optional.ofNullable(on).map(ObjectName::getCanonicalName).orElse("").contains(SUBTYPE)); @javax.annotation.PostConstruct public void run() throws Exception { final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); final SSLHostConfig config = new SSLHostConfig(); config.setProtocols("TLSv1.2"); config.setHostName("test.test.com"); config.setCiphers("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"); final SSLHostConfigCertificate cert = new SSLHostConfigCertificate(config, Type.UNDEFINED); config.addCertificate(cert); final Map<MBeanServer, ObjectName> references = getObjectReferences(server, "ProtocolHandler"); references.forEach((s, op) -> invoke(s, op, ADD_SSL_HOST_CONFIG_OP, new Object[] {config}, new String[] {SSLHostConfig.class.getCanonicalName()})); } public Map<MBeanServer, ObjectName> getObjectReferences(final MBeanServer server, final String discriminator) { final Map<MBeanServer, ObjectName> results = new HashMap<>(); final Predicate<ObjectName> extendedFilters = NOT_LOCALHOST.and(NOT_SUBTYPE); final Optional<ObjectName> candidate = server.queryNames(null, null).stream() .filter(on -> nonNull(on.getCanonicalName())) .filter(on -> on.getCanonicalName().contains(discriminator)) .filter(extendedFilters) .findAny(); candidate.ifPresent(on -> results.put(server, on)); return Map.copyOf(results); } public Object invoke(final MBeanServer server, final ObjectName objectName, final String method, final Object[] params, final String[] signature) { try { //This should return addSslHostConfig(SSLHostConfig, boolean) final MBeanInfo info = server.getMBeanInfo(objectName); final MBeanOperationInfo methodInfo = Arrays.stream(info.getOperations()) .filter(i -> i.getName().equals(method)) .findAny() .orElseThrow(() -> new RuntimeException("Could not find method named" + method)); LOGGER.error("Found available operation {}", methodInfo); final Object result = server.invoke(objectName, method, params, signature); return result; } catch (final Exception e) { throw new RuntimeException("Error invoking " + method + " with params " + Arrays.toString(params) + " and signature " + Arrays.toString(signature), e); } } } On Fri, Dec 8, 2023 at 4:55 PM Christopher Schultz < ch...@christopherschultz.net> wrote: > Daniel, > > On 12/7/23 13:25, Daniel Skiles wrote: > > All, > > I've been doing some testing, and I'm pretty sure the addSslHostConfig > > operation on ProtocolHandler is busted in 9.0.83. > > > > In versions prior to 9.0.82, you can call the operation with a single > > argument of type SSLHostConfig. > > > > In 9.0.82, that contract seems to have been broken, and you had to call > > it with two arguments: an SSLHostConfig and a boolean. > > > > In 9.0.83, it seems as though both operations are present, but which one > > is actually accessible at runtime is non-deterministic. > > > > This behavior presents through a direct invoke(...) call and via a JMX > > Proxy object instantiated through JMX.newMBeanProxy. > > > > I have attached a sample file that reproduces the behavior (sometimes, > > as it is nondeterministic). > > > > Is this a bug, or am I simply using the available feature incorrectly? > > > > If it is the former, how do I formally report this? If it is the > > latter, what is the "correct" way to call this operation from JMX? > > I think your attachment was stripped. Can it be posted in-line? > > -chris > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > >