So after more research, I found this documentation:
The list listed here is the only place that configuration and how-to questions belong, ever.
Looking through the mailing list archive, I was able to find one example of programmatic cluster configuration: https://marc.info/?l=tomcat-user&m=160220406421937&w=2
It was able to take me most of the way, I had been setting my cluster on the context via:
@Configuration
public class MyConfig implements WebServerFactoryCustomize<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
factory.addContextCustomizers(context -> {
//cluster setup
SimpleTcpCluster simpleTcpCluster = new SimpleTcpCluster();
// order of your interceptors does matter fyi
// rest of setup details, very similar to mailing list archive
// Make sure the DeltaManager is created for me
context.setDistributable(true);
// The key point:
//context.setCluster(simpleTcpCluster);
// The fix instead of context.setCluster
// context.getParent() is an instance of StandardHost
// And if you are coping from a server.xml, it's also clear
// that the cluster element is set on the host
context.getParent().setCluster(simpleTcpCluster);
// Basically by setting it on the `host`, it allows the startup to
// recognize it early enough to start the cluster up.
});
}
When I set the cluster on the context, none of the cluster elements were ever actually started.
I would also note that when investigating this, I found an article(2013) showing how to load a server.xml when using an embedded tomcat, although I didn't not try it.
Final note: I used the StaticMembershipService vs the multicast stuff, or the StaticMembershipInterceptor.