-
Notifications
You must be signed in to change notification settings - Fork 103
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
[JENKINS-73258] Migrate Stapler from EE 8 to EE 9 #482
Conversation
9818bb9
to
28b6ce2
Compare
4996efc
to
3f566c2
Compare
7dd5d97
to
4721447
Compare
b2a0128
to
7ab2633
Compare
8d92a23
to
c2378c0
Compare
6299e57
to
2d50895
Compare
<dependency> | ||
<groupId>org.eclipse.jetty.toolchain</groupId> | ||
<artifactId>jetty-servlet-api</artifactId> | ||
<version>4.0.6</version> | ||
</dependency> |
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.
A dependency of the compatibility layer. Not part of the servlet container (Jetty) classpath, but part of the web application classpath in order to handle calls made from Jenkins plugins that were compiled against EE 8.
public class ServletRequestWrapper { | ||
public static jakarta.servlet.ServletRequest toJakartaServletRequest(ServletRequest from) { | ||
if (from instanceof JavaxServletRequestWrapper javax) { | ||
return javax.toJakartaServletRequest(); |
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.
Here and elsewhere, prevent infinite recursion by returning the original request.
import java.util.Objects; | ||
import javax.servlet.http.Cookie; | ||
|
||
public class CookieWrapper { |
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.
Does a deep copy rather than wrapping the Cookie
object (which is a POJO rather than an interface), but an audit of usages shows that this should not be a problem for existing callers.
import jakarta.servlet.ServletResponse; | ||
import java.io.IOException; | ||
|
||
public interface CompatibleFilter extends Filter { |
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.
A convenience class that allows existing Filter
subclasses in Stapler and Jenkins core to be used as-is with either EE 8 (i.e., old plugins) or EE 9 (modern Stapler and core). I sprinkled this liberally wherever a class extends Filter
in Stapler or core. Perhaps not all of them are necessary, and this can be simplified in the future when usages of Filter
in plugins have been migrated to EE 9.
* @throws IllegalArgumentException When {@code derived} does not derive from {@code base}, or when {@code base} | ||
* does not contain the specified method. | ||
*/ | ||
public static boolean isOverridden( |
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.
Copypasta of the corresponding utilities from core. Unfortunately I can't easily mark them as @Restricted(DoNotUse.class)
at present because this repository isn't set up for lib-access-modifier
. Perhaps someone else will find the energy to add both lib-access-modifier
and the annotation. Unfortunately I can't make it package-private either, as it needs to be used in a lot of places in Stapler.
* | ||
* @author Kohsuke Kawaguchi | ||
*/ | ||
public class RequestImpl extends HttpServletRequestWrapper implements StaplerRequest { | ||
public class RequestImpl extends HttpServletRequestWrapper implements StaplerRequest2 { |
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 implementation class is changing incompatibly to implement StaplerRequest2
. With the exception of a single proprietary plugin, no plugins care about the implementation class, just the interface.
* @see Stapler#getCurrentRequest2() | ||
* @author Kohsuke Kawaguchi | ||
*/ | ||
public interface StaplerRequest2 extends HttpServletRequest { |
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 Jakarta version of StaplerRequest
(which is now deprecated).
String paramNames = m.getParameters().stream() | ||
.map(VariableElement::getSimpleName) | ||
.collect(Collectors.joining(",")); | ||
String existing = output.get(m.getSimpleName().toString()); | ||
/* | ||
* Allow multiple methods to have the same name but different argument types as long as the arguments | ||
* have the same names. This allows deprecated StaplerRequest/StaplerResponse methods to coexist | ||
* alongside non-deprecated StaplerRequest2/StaplerResponse2 methods. | ||
*/ | ||
if (existing == null || !existing.equals(paramNames)) { | ||
write(paramNames, m); | ||
output.put(m.getSimpleName().toString(), paramNames); | ||
} |
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.
Needed to fix a compilation error in core. Comes with an associated unit test that demonstrates the problem.
context.setVariable("request", StaplerRequest.fromStaplerRequest2(req)); | ||
context.setVariable("response", StaplerResponse.fromStaplerResponse2(rsp)); | ||
context.setVariable("request2", req); | ||
context.setVariable("response2", rsp); |
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 had briefly considered changing request
and response
into Jakarta versions, but this broke plugins with Jelly views that called plugin methods whose parameters were requests or responses.
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.
Thanks!
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
public class AsyncContextWrapper { |
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.
@basil Just curious why don't we have the documentation for any of the class here. At least 1-2 liner description would have given the clarity that the purpose of that class.
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 would not hurt, but the most important aspect of Javadoc in this PR is linking to non-deprecated versions of newly-deprecated functionality, which I have done consistently.
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
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
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.
Looks fine, security-wise
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.
Looks good as far as I can evaluate it 👍
Some *Wrapper
methods seem to not handle documented null
values well, but I'm not sure how relevant that really is.
StaplerResponse*#getCompressed*
methods were accidentally undeprecated.
I don't think any of my comments need to be addressed for the weekly.
core/src/main/java/org/kohsuke/stapler/StaplerResponse2Wrapper.java
Outdated
Show resolved
Hide resolved
core/src/main/java/io/jenkins/servlet/ServletContextWrapper.java
Outdated
Show resolved
Hide resolved
core/src/main/java/io/jenkins/servlet/ServletContextWrapper.java
Outdated
Show resolved
Hide resolved
core/src/main/java/io/jenkins/servlet/ServletContextWrapper.java
Outdated
Show resolved
Hide resolved
core/src/main/java/io/jenkins/servlet/ServletContextWrapper.java
Outdated
Show resolved
Hide resolved
Co-authored-by: Daniel Beck <[email protected]>
Co-authored-by: Daniel Beck <[email protected]>
Context
Goes with three other pull requests:
Problem
Stapler only supports EE 8, precluding an upgrade to Spring Security 6.x in Jenkins core (which requires Spring Framework 6.x, which requires EE 9).
Solution
pom.xml
to align with Jetty 12 (EE 9)At a high level, we add
StaplerRequest2
andStaplerResponse2
classes, the Jakarta equivalents of the old versions (now deprecated). TheRequestImpl
andResponseImpl
implementations are now based on EE 9 rather than EE 8, but support for plugins is maintained by converting to and from the interfaces as needed.Testing done
Full PCT and ATH (Jenkins public version and CloudBees internal version)