Christ,
Thanks for the explanation.

The XML-based registration - is that something I would do as a user, or
something that would be changed on the Tomcat side as part of its release
bundle?

On Thu, Dec 14, 2023 at 10:17 AM Christopher Schultz <
ch...@christopherschultz.net> wrote:

> Daniel,
>
> On 12/14/23 09:43, Daniel Skiles wrote:
> > 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.
>
> +1
>
> The operations map is keyed on method-name which means that overloads
> are not supported.
>
> I suppose it's possible that the introspecter doesn't always get the
> methods back from the reflection process in exactly the same order, and
> the last one always wins. This would explain why it sometimes works and
> sometimes does not work.
>
> The best solution would be to explicitly-define this operation in the
> MBeans XML-based registration. Then no introspection is necessary and we
> always get the right method.
>
> -chris
>
> > 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
> >>
> >>
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

Reply via email to