Skip to content

Conversation

@mcculls
Copy link
Contributor

@mcculls mcculls commented Oct 7, 2020

This takes a similar approach to how we deal with custom log managers, however unlike the logging case there is no clear activating class with a static initialization block. Instead we wait for the MBeanServerBuilder class to be loaded and use that as an indication that we can go ahead and access JMX.

This is acceptable because MBeanServerBuilder is the base class for all custom JMX builders and is only used in MBeanServerFactory which creates the custom builder instance. Note JMX doesn't let you supply an actual builder instance - it only lets you specify the class name which MBeanServerFactory attempts to load, first by the current thread's context classloader, then falling back to Class.forName.

The place where MBeanServerBuilder is loaded should be where MBeanServerFactory is looking up the custom builder, unless the application is using MBeanServerBuilder itself before starting JMX. But that would be unusual because its only use is to create MBean servers and delegates for JMX. Even in that case though we should be OK because at the time the application loads MBeanServerBuilder the current thread's context classloader should be able to see the custom JMX builder. And since the classload hook thread inherits that context classloader then it too should be able to see that custom JMX builder. Therefore it doesn't matter if the classload hook or the application win the race to start JMX. Either one should be able to see the custom builder class at that point. (We just need to make sure we make a call to JMX before we change the classload hook thread's context classloader when starting JMXFetch.)

The only other classes loaded after MBeanServerBuilder would be the internal JMX classes, whose names could vary between JDKs. Alternatively we could wait for the custom JMX builder class, but there's a chance that the initial value is overridden later on and the initially named class is never loaded.

@mcculls mcculls requested a review from a team October 7, 2020 11:58
@mcculls mcculls marked this pull request as draft October 7, 2020 16:46
@mcculls mcculls marked this pull request as ready for review October 8, 2020 08:34
@mcculls mcculls marked this pull request as draft October 8, 2020 08:40
…on the system classpath (ie. it will be provisioned later)
…read-context-classloader (TCCL)

This handles a situation where the app thread triggering JMX has a special thread-context-classloader
set that can see the custom JMX builder class. The callback thread inherits this TCCL so we just need
to make sure to load core JMX using this before starting JMXFetch (which needs a different TCCL set.)
@mcculls mcculls force-pushed the mcculls/supportCustomManagementBuilders branch from e867580 to f919ffd Compare October 9, 2020 11:11
@mcculls mcculls marked this pull request as ready for review October 9, 2020 11:15
@mcculls mcculls requested a review from a team October 9, 2020 18:32
@mcculls mcculls merged commit ca17f11 into master Oct 12, 2020
@mcculls mcculls deleted the mcculls/supportCustomManagementBuilders branch October 12, 2020 13:27
@github-actions github-actions bot added this to the 0.65.0 milestone Oct 12, 2020
@aldiyen
Copy link

aldiyen commented Oct 15, 2020

Hey thanks, this just saved me a bunch of headache in my company's application built on Wildfly 9.0.2 (don't ask). It took quite a while for me to figure out what was causing my MBeans not to be registered when the JMX fetch functionality was enabled in the tracer, and still ended up having to explicitly set the dd.app.customjmxbuilder even after I upgraded from v0.64 to v0.65, presumably because Wildfly is setting javax.management.builder.initial after Datadog looks for it or something... ugh.

Anyway, it's nice that your code is open source and I had the opportunity to read through enough of it to find this flag, otherwise I would've had to do some horrible hack to solve this problem. Thanks for fixing it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants