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