The object and operation I'm trying to address is Catalina -->
ProtocolHandler --> <port> --> <host> --> operations --> addSslHostConfig.

The parameters are an SslHostConfig object and the boolean value "true".

The operation is "addSslHostConfig".

The code I sent in the previous message works 100% of the time in 9.0.82.
In 9.0.83, it works about 50% of the time.  I can always query that the
operation exists, but roughly half the time it will fail with a JMX
exception saying that the operation does not exist.

I am not positive, but I believe the behavior in 9.0.83 might have to do
with the fact that the catalina java code now has a one argument and two
argument variant of the same method.

On Wed, Dec 13, 2023 at 10:27 AM Christopher Schultz <
ch...@christopherschultz.net> wrote:

> Daniel,
>
> On 12/12/23 19:45, Daniel Skiles wrote:
> > 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);
> > }
> > }
> > }
>
> What objctName do you think you are addressing, here? What parameters
> are you passing it and what types? What parameters and types are
> expected by the operation you are trying to invoke?
>
> -chris
>
> > 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
> >>
> >>
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

Reply via email to