Daniel,

On 12/13/23 15:42, Daniel Skiles 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.

This is what I was trying to get you to say out loud, just so you know this was a potential issue.

I'm not sure why, but Tomcat's introspecter seems to be only registering one of those two methods. The one-argument method still exists... it simply calls the two-argument variant with the value of replace=value.

It's very surprising to me that this works 50% of the time. The JMX bean has exactly one operation defined: the two-argument version. So I'm not sure how you are ever able to invoke this operation with only a single argument.

-chris

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