-
Notifications
You must be signed in to change notification settings - Fork 41.5k
Set classloader for JMX endpoints to application classloader #12209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Build failure seems to be random and not related to this change, can someone re-trigger the build? |
Closing and re-opening to trigger a new build. |
I think that used to work with Travis. Doesn’t appear to have worked with Concourse. |
I’ve manually triggered a new build on Concourse but I’m not sure it’s building the right change. There are some git-related errors in the logs. |
Any news or interest in this? |
@Dav1dde there is. I had a look at your proposal a while back and didn't like it very much but I have nothing else to offer. I'll have to dig a bit more first. |
@snicoll thank you! You're right, it feels hack-ish. Want me to update it so the classloader comes from |
That won't change much I am afraid. Switching the classloader of the current thread without restoring the previous instance once the method has been invoked sounds definitely wrong to me. I would only do this as a last resort option. |
Oh, that's not a problem, actually had a version that restored it. (that's also what we do at work right now). I'll update this tonight and let's see if you like that more. |
Sorry, I meant that this proposal doesn’t look great to me (and at the very least the classloader should be restored). |
Updated and restoring class loader now (no-op if bean class loader is not set, e.g. in tests). I personally don't like the solution either but I can't think of anything better, if you can think of something let me know and I can change the PR accordingly. |
Thanks @Dav1dde, that's a very nice summary of the situation indeed. I'll spend a bit more time on it and report here when I am done. |
throw new ReflectionException(new IllegalArgumentException(message), message); | ||
} | ||
return invoke(operation, params); | ||
ClassLoader previousClassLoader = ClassUtils.overrideThreadContextClassLoader(this.classLoader); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may throw a SecurityException
. I think we should set the TCCL on a best-effort basis so any SecurityException
that's thrown should be caught (and logged) and we should then proceed with the invoke
.
FWIW, other than the |
I'll update it later tonight. |
try { | ||
ObjectName name = this.objectNameFactory.getObjectName(endpoint); | ||
EndpointMBean mbean = new EndpointMBean(this.responseMapper, endpoint); | ||
mbean.setBeanClassLoader(this.classLoader); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered having the class loader as a constructor argument, but for me the class loader is optional for the EndpointMBean
.
} | ||
catch (SecurityException exc) { | ||
// can't set class loader, ignore it and proceed | ||
logger.warn("Unable to override class loader for JMX endpoint."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if a info log would be better here.
Branch updated, I added a few comments where I am not sure if things are okay this way and fit into the spring codebase. |
* pr/12209: Polish "Set classloader for JMX endpoints to application classloader" Set classloader for JMX endpoints to application classloader
@Dav1dde thank you for your first contribution to Spring Boot. This has been merged in |
Related to and fixes: #12088
Sets the Thread's classloader for JMX endpoints, before invoking the endpoint, to the classloader which was initially used to load the context.
Before:
After:
Test-Code (using sample Application from start.spring.io including web and actuator):