Do you have any pointers on how to do that using JMX?  So far as I can tell
from what little documentation I can find on the tomcat site, this is how
it's done.

I'm suspicious that there might be an issue in
Tomcat's MbeansDescriptorsIntrospectionSource.createManagedBean(...)
method.  I'm not familiar with the code, but it appears that there might be
an issue with how that map is constructed.

On Thu, Dec 14, 2023 at 4:25 AM Rémy Maucherat <r...@apache.org> wrote:

> On Wed, Dec 13, 2023 at 9:43 PM Daniel Skiles
> <dski...@docfinity.com.invalid> wrote:
> >
> > 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.
>
> I'm pretty sure you got the explanation right. It is very similar to
> using reflection here. You're doing the lookup based on the method
> name, which matches something. However, if you want to avoid an error,
> you also have to check that the arguments match, otherwise you're
> going to randomly pick one of the two methods and fail half the time.
>
> Rémy
>
> > 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
> > >
> > >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

Reply via email to