-
-
Notifications
You must be signed in to change notification settings - Fork 8.8k
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
Add SetContextClassLoader
utility class
#6575
Conversation
public SetContextClassLoader(Class<?> clazz) { | ||
t = Thread.currentThread(); | ||
orig = t.getContextClassLoader(); | ||
// It is too bad that Reflection.getCallerClass() is a private API. | ||
t.setContextClassLoader(clazz.getClassLoader()); | ||
} |
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.
Once we're on Java 11, we could perhaps remove the clazz
argument and get the calling class via the StackWalker
API.
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.
FWIW I would much prefer the explicit Class
argument as currently written here. It is hardly bothersome to pass, and sometimes you may actually want something other than the calling class: a class from a library, a plugin you depend upon, etc. Magically inferring an argument according to the caller is a poor practice in terms of legibility and predictability; for example, it means that supposedly safe refactorings like pull up method may quietly lead to different behavior.
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.
Well you can have your opinion and I can have mine. I actually think a no-argument version is preferable since you can cut and paste code from one class to another without having to worry about updating the calling class argument to reflect the new home of the code.
I think I am going leave this as draft/on-hold until we require Java 11. I would love to have a clean API from day 1 (with zero arguments), but that only seems possible with Java 11 features like |
public SetContextClassLoader(Class<?> clazz) { | ||
t = Thread.currentThread(); | ||
orig = t.getContextClassLoader(); | ||
// It is too bad that Reflection.getCallerClass() is a private API. | ||
t.setContextClassLoader(clazz.getClassLoader()); | ||
} |
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.
FWIW I would much prefer the explicit Class
argument as currently written here. It is hardly bothersome to pass, and sometimes you may actually want something other than the calling class: a class from a library, a plugin you depend upon, etc. Magically inferring an argument according to the caller is a poor practice in terms of legibility and predictability; for example, it means that supposedly safe refactorings like pull up method may quietly lead to different behavior.
* @since TODO | ||
*/ | ||
public SetContextClassLoader() { | ||
this(StackWalker.getInstance().getCallerClass()); |
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.
cool can hopefully simplify a few APIs with this, e.g. https://github.com/jenkinsci/configuration-as-code-plugin/blob/e345fd8df353db1a9fbd930968b87fce30548438/test-harness/src/main/java/io/jenkins/plugins/casc/misc/Util.java#L172
public SetContextClassLoader() { | ||
this(StackWalker.getInstance().getCallerClass()); |
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.
Still -0 on including the no-arg overload as in #6575 (comment): StackWalker
and similar idioms should be avoided in production code.
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.
(an Object
argument delegating to the Class
overload would be fine, for calls from non-static
contexts)
This PR is now ready for merge. We will merge it after approximately 24 hours if there is no negative feedback. Please see the merge process documentation for more information about the merge process. Thanks! |
BTW there are a few internal places that could use the new utility as a demonstration: |
Two examples of usages of the new utility were provided in the PR description as a demonstration. There are a lot more that could be done. |
Promoting https://github.com/jenkinsci/ldap-plugin/blob/3731881c37d1c66f8f43101b7f8b0cdd5f1eba56/src/main/java/jenkins/security/plugins/ldap/SetContextClassLoader.java into a core utility class.
Example usages
Production code: jenkinsci/xcode-plugin#114
Test code: jenkinsci/jaxb-plugin#34
Proposed changelog entries
Introduced
SetContextClassLoader
utility class to assist in plugin class loading.Proposed upgrade guidelines
N/A
Submitter checklist
Proposed changelog entries
section only if there are breaking changes or other changes which may require extra steps from users during the upgrade@Restricted
or have@since TODO
Javadoc, as appropriate.Desired reviewers
@mention
Maintainer checklist
Before the changes are marked as
ready-for-merge
:Proposed changelog entries
are accurate, human-readable, and in the imperative moodupgrade-guide-needed
label is set and there is aProposed upgrade guidelines
section in the PR title. (example)lts-candidate
to be considered (see query).