-
-
Notifications
You must be signed in to change notification settings - Fork 9.2k
Deprecating Extension.optional
#11201
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
| * @author Basil Crow | ||
| */ | ||
| @Restricted(NoExternalUse.class) | ||
| @Extension(optional = true) |
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.
Unclear why this was “optional”. Of course this would only make sense on servers with systemd. But it would get loaded as an extension in all cases.
| * @since 1.254 | ||
| */ | ||
| public abstract class Lifecycle implements ExtensionPoint { | ||
| public abstract class Lifecycle { |
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.
And Lifecycle does not even use the extension loader to begin with! Traditionally ExtensionPoint was just used as a very hand-wavy indicator for “things you might want to pay attention to in Javadoc as a plugin author”, rather than specifically meaning “a type which can be subtyped and marked with @Extension to register”. (A broad category of such mistakes is placing ExtensionPoint on a Describable. It is the Descriptor which is the extension point.)
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.
Traditionally
ExtensionPointwas just used as a very hand-wavy indicator for “things you might want to pay attention to in Javadoc as a plugin author”, rather than specifically meaning “a type which can be subtyped and marked with@Extensionto register”.
Isn't that an indicator this should stay?
See also class Javadoc for PluginServletFilter in which this quirk is made explicit.
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.
jenkins/core/src/main/java/hudson/util/PluginServletFilter.java
Lines 57 to 58 in c9eaa5d
| * While this class by itself is not an extension point, I'm marking this class | |
| * as an extension point so that this class will be more discoverable. |
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.
The point stands, it's not just tradition, but also documented as such.
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.
Then we can correct the documentation: #11210
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.
If the idea is that ExtensionPoint is only for things intended to be @Extension'ed, then
jenkins/core/src/main/java/hudson/ExtensionPoint.java
Lines 35 to 41 in c97fecc
| * Marker interface that designates extensible components | |
| * in Jenkins that can be implemented by plugins. | |
| * | |
| * <p> | |
| * See respective interfaces/classes for more about how to register custom | |
| * implementations to Jenkins. See {@link Extension} for how to have | |
| * Jenkins auto-discover your implementations. |
PluginServletFilter), only adding a mention of @Extension.
| * @author Kohsuke Kawaguchi | ||
| */ | ||
| @Extension(optional = true) @Symbol("hsErrPid") | ||
| // TODO why would an extension using a built-in extension point need to be marked optional? |
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.
Who knows.
timja
left a comment
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.
/label ready-for-merge
This PR is now ready for merge, after ~24 hours, we will merge it if there's no negative feedback.
Thanks!
A1exKH
left a comment
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.
LGTM.
Plugin developers often grab for this flag because it is easy to find, but it is almost always the wrong choice. It means the extension loader will still try to load the extension; it will just be less noisy (still printing a warning to the log, one line rather than a stack trace!) if it fails. And it is actually tricky to get it to fail. You have to arrange for the initialization of the extension class (and perhaps also the constructor, I do not recall) to fail. So if your plugin has an
optionaldep on a pluginxxx-apiand you writethen that is fine, because types from
xxx-apiare required in the signature ofMyImpl, so theNoClassDefFoundErrorwill be caught by the extension loader and this extension will be skipped. But people often try to do something like the following:This will be quietly registered even when
xxx-apiis disabled—and then throwNoClassDefFoundErrors every time it is used! That is because the HotSpot linker is lazy: even though some method bodies refer to an inaccessible type, they are not linked until the first time the method is run.You can use
optional = truecorrectly if you think carefully about what you are doing, and write tests withRealJenkinsRule.omitPluginsto prove that it behaves as expected. But you might as well just use@OptionalExtensionwhich is much easier to reason about (and avoids the one-line warning to boot).Testing done
None.
Proposed changelog entries
Extension.optionalattribute.Proposed changelog category
/label developer
Proposed upgrade guidelines
N/A
Maintainer checklist
upgrade-guide-neededlabel is set and there is a Proposed upgrade guidelines section in the pull request title (see example).lts-candidateto be considered (see query).