diff --git a/.github/renovate.json b/.github/renovate.json index aab994ad8187..1f023c99f4f5 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -91,17 +91,6 @@ "org.jfree:jfreechart" ] }, - { - "description": "Starting with 6.x, Spring requires Java 17 at a minimum.", - "matchManagers": [ - "maven" - ], - "allowedVersions": "<6.0.0", - "matchPackageNames": [ - "org.springframework:spring-framework-bom", - "org.springframework.security:spring-security-bom" - ] - }, { "description": "Starting with 7.x, Guice switches from javax.* to jakarta.* bindings. See https://github.com/google/guice/wiki/Guice700", "matchManagers": [ diff --git a/.idea/encodings.xml b/.idea/encodings.xml index ca018ebc3ab9..68f564fff79d 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -29,12 +29,9 @@ <file url="file://$PROJECT_DIR$/war/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/war/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/war/src/test/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/websocket/jetty10/src/filter/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/websocket/jetty10/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/websocket/jetty10/src/main/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/websocket/jetty12-ee8/src/filter/resources" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/websocket/jetty12-ee8/src/main/java" charset="UTF-8" /> - <file url="file://$PROJECT_DIR$/websocket/jetty12-ee8/src/main/resources" charset="UTF-8" /> + <file url="file://$PROJECT_DIR$/websocket/jetty12-ee9/src/filter/resources" charset="UTF-8" /> + <file url="file://$PROJECT_DIR$/websocket/jetty12-ee9/src/main/java" charset="UTF-8" /> + <file url="file://$PROJECT_DIR$/websocket/jetty12-ee9/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/websocket/spi/src/filter/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/websocket/spi/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/websocket/spi/src/main/resources" charset="UTF-8" /> diff --git a/bom/pom.xml b/bom/pom.xml index adf65f6cf439..cd55b58d52c9 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -39,7 +39,7 @@ THE SOFTWARE. <properties> <commons-fileupload2.version>2.0.0-M2</commons-fileupload2.version> - <stapler.version>1896.v8170998149d0</stapler.version> + <stapler.version>1903.v994a_db_314d58</stapler.version> <groovy.version>2.4.21</groovy.version> </properties> @@ -62,15 +62,15 @@ THE SOFTWARE. <dependency> <groupId>org.springframework</groupId> <artifactId>spring-framework-bom</artifactId> - <version>5.3.39</version> + <version>6.1.12</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> - <!-- https://docs.spring.io/spring-security/site/docs/5.5.4/reference/html5/#getting-maven-no-boot --> + <!-- https://docs.spring.io/spring-security/reference/6.3/getting-spring-security.html#getting-maven-no-boot --> <groupId>org.springframework.security</groupId> <artifactId>spring-security-bom</artifactId> - <version>5.8.14</version> + <version>6.3.3</version> <type>pom</type> <scope>import</scope> </dependency> @@ -154,12 +154,12 @@ THE SOFTWARE. <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> - <version>4.0.4</version> + <version>5.0.0</version> </dependency> <dependency> <groupId>jakarta.servlet.jsp.jstl</groupId> <artifactId>jakarta.servlet.jsp.jstl-api</artifactId> - <version>1.2.7</version> + <version>2.0.0</version> </dependency> <dependency> <groupId>jaxen</groupId> @@ -295,7 +295,7 @@ THE SOFTWARE. <dependency> <groupId>org.jvnet.hudson</groupId> <artifactId>commons-jelly-tags-define</artifactId> - <version>1.1-jenkins-20240510</version> + <version>1.1-jenkins-20240903</version> </dependency> <dependency> <groupId>org.jvnet.localizer</groupId> diff --git a/core/pom.xml b/core/pom.xml index 8e30ae211ed7..9bff5e5ad0b2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -217,6 +217,20 @@ THE SOFTWARE. <!-- needed by Jelly --> <groupId>jakarta.servlet.jsp.jstl</groupId> <artifactId>jakarta.servlet.jsp.jstl-api</artifactId> + <exclusions> + <exclusion> + <groupId>jakarta.el</groupId> + <artifactId>jakarta.el-api</artifactId> + </exclusion> + <exclusion> + <groupId>jakarta.servlet</groupId> + <artifactId>jakarta.servlet-api</artifactId> + </exclusion> + <exclusion> + <groupId>jakarta.xml.bind</groupId> + <artifactId>jakarta.xml.bind-api</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>jaxen</groupId> @@ -288,7 +302,7 @@ THE SOFTWARE. </dependency> <dependency> <groupId>org.apache.commons</groupId> - <artifactId>commons-fileupload2-javax</artifactId> + <artifactId>commons-fileupload2-jakarta-servlet5</artifactId> </dependency> <dependency> <groupId>org.codehaus.groovy</groupId> @@ -427,6 +441,10 @@ THE SOFTWARE. <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <exclusions> + <exclusion> + <groupId>io.micrometer</groupId> + <artifactId>micrometer-observation</artifactId> + </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring-jcl</artifactId> diff --git a/core/src/main/java/hudson/DescriptorExtensionList.java b/core/src/main/java/hudson/DescriptorExtensionList.java index c92b6ae206c0..c658c83fe1fc 100644 --- a/core/src/main/java/hudson/DescriptorExtensionList.java +++ b/core/src/main/java/hudson/DescriptorExtensionList.java @@ -145,7 +145,7 @@ public T newInstanceFromRadioList(JSONObject config) throws FormException { if (config.isNullObject()) return null; // none was selected int idx = config.getInt("value"); - return get(idx).newInstance(Stapler.getCurrentRequest(), config); + return get(idx).newInstance(Stapler.getCurrentRequest2(), config); } /** diff --git a/core/src/main/java/hudson/ExpressionFactory2.java b/core/src/main/java/hudson/ExpressionFactory2.java index 7fcec22e7604..1bc99160439b 100644 --- a/core/src/main/java/hudson/ExpressionFactory2.java +++ b/core/src/main/java/hudson/ExpressionFactory2.java @@ -12,7 +12,7 @@ import org.apache.commons.jelly.expression.ExpressionSupport; import org.apache.commons.jexl.JexlContext; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.access.AccessDeniedException; /** @@ -78,7 +78,7 @@ public Object evaluate(JellyContext context) { // let the security exception pass through throw e; } catch (Exception e) { - StaplerRequest currentRequest = Stapler.getCurrentRequest(); + StaplerRequest2 currentRequest = Stapler.getCurrentRequest2(); LOGGER.log(Level.WARNING, "Caught exception evaluating: " + expression + " in " + (currentRequest != null ? currentRequest.getOriginalRequestURI() : "?") + ". Reason: " + e, e); return null; } finally { diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index 06773dd9a9ee..f5288b26d9d1 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -3510,7 +3510,7 @@ public FormValidation validateRelativePath(String value, boolean errorIfNotExist } private static void checkPermissionForValidate() { - AccessControlled subject = Stapler.getCurrentRequest().findAncestorObject(AbstractProject.class); + AccessControlled subject = Stapler.getCurrentRequest2().findAncestorObject(AbstractProject.class); if (subject == null) Jenkins.get().checkPermission(Jenkins.MANAGE); else diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index cd25f9bc9871..d2b62e99a2f2 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -95,6 +95,14 @@ import hudson.views.MyViewsTabBar; import hudson.views.ViewsTabBar; import hudson.widgets.RenderOnDemandClosure; +import io.jenkins.servlet.ServletExceptionWrapper; +import io.jenkins.servlet.http.CookieWrapper; +import io.jenkins.servlet.http.HttpServletRequestWrapper; +import io.jenkins.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.PrintStream; @@ -148,10 +156,6 @@ import java.util.logging.SimpleFormatter; import java.util.regex.Pattern; import java.util.stream.Collectors; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.console.ConsoleUrlProvider; import jenkins.model.GlobalConfiguration; import jenkins.model.GlobalConfigurationCategory; @@ -176,7 +180,9 @@ import org.kohsuke.stapler.RawHtmlArgument; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.access.AccessDeniedException; /** @@ -276,8 +282,8 @@ public static boolean isExtensionsAvailable() { } public static void initPageVariables(JellyContext context) { - StaplerRequest currentRequest = Stapler.getCurrentRequest(); - currentRequest.getWebApp().getDispatchValidator().allowDispatch(currentRequest, Stapler.getCurrentResponse()); + StaplerRequest2 currentRequest = Stapler.getCurrentRequest2(); + currentRequest.getWebApp().getDispatchValidator().allowDispatch(currentRequest, Stapler.getCurrentResponse2()); String rootURL = currentRequest.getContextPath(); Functions h = new Functions(); @@ -372,7 +378,10 @@ public static String addSuffix(int n, String singular, String plural) { return buf.toString(); } - public static RunUrl decompose(StaplerRequest req) { + /** + * @since TODO + */ + public static RunUrl decompose(StaplerRequest2 req) { List<Ancestor> ancestors = req.getAncestors(); // find the first and last Run instances @@ -405,12 +414,20 @@ public static RunUrl decompose(StaplerRequest req) { return new RunUrl((Run) f.getObject(), head, base, rest); } + /** + * @deprecated use {@link #decompose(StaplerRequest2)} + */ + @Deprecated + public static RunUrl decompose(StaplerRequest req) { + return decompose(StaplerRequest.toStaplerRequest2(req)); + } + /** * If we know the user's screen resolution, return it. Otherwise null. * @since 1.213 */ public static Area getScreenResolution() { - Cookie res = Functions.getCookie(Stapler.getCurrentRequest(), "screenResolution"); + Cookie res = Functions.getCookie(Stapler.getCurrentRequest2(), "screenResolution"); if (res != null) return Area.parse(res.getValue()); return null; @@ -592,6 +609,9 @@ public static <T> Iterable<T> reverse(Collection<T> collection) { return list; } + /** + * @since TODO + */ public static Cookie getCookie(HttpServletRequest req, String name) { Cookie[] cookies = req.getCookies(); if (cookies != null) { @@ -604,12 +624,31 @@ public static Cookie getCookie(HttpServletRequest req, String name) { return null; } + /** + * @deprecated use {@link #getCookie(HttpServletRequest, String)} + */ + @Deprecated + public static javax.servlet.http.Cookie getCookie(javax.servlet.http.HttpServletRequest req, String name) { + return CookieWrapper.fromJakartaServletHttpCookie(getCookie(HttpServletRequestWrapper.toJakartaHttpServletRequest(req), name)); + } + + /** + * @since TODO + */ public static String getCookie(HttpServletRequest req, String name, String defaultValue) { Cookie c = getCookie(req, name); if (c == null || c.getValue() == null) return defaultValue; return c.getValue(); } + /** + * @deprecated use {@link #getCookie(HttpServletRequest, String, String)} + */ + @Deprecated + public static String getCookie(javax.servlet.http.HttpServletRequest req, String name, String defaultValue) { + return getCookie(HttpServletRequestWrapper.toJakartaHttpServletRequest(req), name, defaultValue); + } + private static final Pattern ICON_SIZE = Pattern.compile("\\d+x\\d+"); @Restricted(NoExternalUse.class) @@ -713,8 +752,10 @@ public static long getHourLocalTimezone() { * Finds the given object in the ancestor list and returns its URL. * This is used to determine the "current" URL assigned to the given object, * so that one can compute relative URLs from it. + * + * @since TODO */ - public static String getNearestAncestorUrl(StaplerRequest req, Object it) { + public static String getNearestAncestorUrl(StaplerRequest2 req, Object it) { List list = req.getAncestors(); for (int i = list.size() - 1; i >= 0; i--) { Ancestor anc = (Ancestor) list.get(i); @@ -724,11 +765,19 @@ public static String getNearestAncestorUrl(StaplerRequest req, Object it) { return null; } + /** + * @deprecated use {@link #getNearestAncestorUrl(StaplerRequest2, Object)} + */ + @Deprecated + public static String getNearestAncestorUrl(StaplerRequest req, Object it) { + return getNearestAncestorUrl(StaplerRequest.toStaplerRequest2(req), it); + } + /** * Finds the inner-most {@link SearchableModelObject} in scope. */ public static String getSearchURL() { - List list = Stapler.getCurrentRequest().getAncestors(); + List list = Stapler.getCurrentRequest2().getAncestors(); for (int i = list.size() - 1; i >= 0; i--) { Ancestor anc = (Ancestor) list.get(i); if (anc.getObject() instanceof SearchableModelObject) @@ -888,7 +937,7 @@ public static void checkPermission(Object object, Permission permission) throws if (object instanceof AccessControlled) checkPermission((AccessControlled) object, permission); else { - List<Ancestor> ancs = Stapler.getCurrentRequest().getAncestors(); + List<Ancestor> ancs = Stapler.getCurrentRequest2().getAncestors(); for (Ancestor anc : Iterators.reverse(ancs)) { Object o = anc.getObject(); if (o instanceof AccessControlled) { @@ -920,7 +969,7 @@ public static boolean hasPermission(Object object, Permission permission) throws if (object instanceof AccessControlled) return ((AccessControlled) object).hasPermission(permission); else { - List<Ancestor> ancs = Stapler.getCurrentRequest().getAncestors(); + List<Ancestor> ancs = Stapler.getCurrentRequest2().getAncestors(); for (Ancestor anc : Iterators.reverse(ancs)) { Object o = anc.getObject(); if (o instanceof AccessControlled) { @@ -931,10 +980,13 @@ public static boolean hasPermission(Object object, Permission permission) throws } } - public static void adminCheck(StaplerRequest req, StaplerResponse rsp, Object required, Permission permission) throws IOException, ServletException { + /** + * @since TODO + */ + public static void adminCheck(StaplerRequest2 req, StaplerResponse2 rsp, Object required, Permission permission) throws IOException, ServletException { // this is legacy --- all views should be eventually converted to // the permission based model. - if (required != null && !Hudson.adminCheck(req, rsp)) { + if (required != null && !Hudson.adminCheck(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp))) { // check failed. commit the FORBIDDEN response, then abort. rsp.setStatus(HttpServletResponse.SC_FORBIDDEN); rsp.getOutputStream().close(); @@ -946,10 +998,24 @@ public static void adminCheck(StaplerRequest req, StaplerResponse rsp, Object re checkPermission(permission); } + /** + * @deprecated use {@link #adminCheck(StaplerRequest2, StaplerResponse2, Object, Permission)} + */ + @Deprecated + public static void adminCheck(StaplerRequest req, StaplerResponse rsp, Object required, Permission permission) throws IOException, javax.servlet.ServletException { + try { + adminCheck(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), required, permission); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Infers the hudson installation URL from the given request. + * + * @since TODO */ - public static String inferHudsonURL(StaplerRequest req) { + public static String inferHudsonURL(StaplerRequest2 req) { String rootUrl = Jenkins.get().getRootUrl(); if (rootUrl != null) // prefer the one explicitly configured, to work with load-balancer, frontend, etc. @@ -963,6 +1029,14 @@ public static String inferHudsonURL(StaplerRequest req) { return buf.toString(); } + /** + * @deprecated use {@link #inferHudsonURL(StaplerRequest2)} + */ + @Deprecated + public static String inferHudsonURL(StaplerRequest req) { + return inferHudsonURL(StaplerRequest.toStaplerRequest2(req)); + } + /** * Returns the link to be displayed in the footer of the UI. */ @@ -1226,7 +1300,7 @@ public static boolean hasAnyPermission(Object object, Permission[] permissions) if (object instanceof AccessControlled) return hasAnyPermission((AccessControlled) object, permissions); else { - AccessControlled ac = Stapler.getCurrentRequest().findAncestorObject(AccessControlled.class); + AccessControlled ac = Stapler.getCurrentRequest2().findAncestorObject(AccessControlled.class); if (ac != null) { return hasAnyPermission(ac, permissions); } @@ -1264,7 +1338,7 @@ public static void checkAnyPermission(Object object, Permission[] permissions) t if (object instanceof AccessControlled) checkAnyPermission((AccessControlled) object, permissions); else { - List<Ancestor> ancs = Stapler.getCurrentRequest().getAncestors(); + List<Ancestor> ancs = Stapler.getCurrentRequest2().getAncestors(); for (Ancestor anc : Iterators.reverse(ancs)) { Object o = anc.getObject(); if (o instanceof AccessControlled) { @@ -1335,7 +1409,7 @@ public static String getRelativeLinkTo(Item p) { Map<Object, String> ancestors = new HashMap<>(); View view = null; - StaplerRequest request = Stapler.getCurrentRequest(); + StaplerRequest2 request = Stapler.getCurrentRequest2(); for (Ancestor a : request.getAncestors()) { ancestors.put(a.getObject(), a.getRelativePath()); if (a.getObject() instanceof View) @@ -1681,7 +1755,7 @@ public static String getViewResource(Object it, String path) { if (it instanceof Descriptor) clazz = ((Descriptor) it).clazz; - String buf = Stapler.getCurrentRequest().getContextPath() + Jenkins.VIEW_RESOURCE_PATH + '/' + + String buf = Stapler.getCurrentRequest2().getContextPath() + Jenkins.VIEW_RESOURCE_PATH + '/' + clazz.getName().replace('.', '/').replace('$', '/') + '/' + path; return buf; @@ -1689,7 +1763,7 @@ public static String getViewResource(Object it, String path) { public static boolean hasView(Object it, String path) throws IOException { if (it == null) return false; - return Stapler.getCurrentRequest().getView(it, path) != null; + return Stapler.getCurrentRequest2().getView(it, path) != null; } /** @@ -1900,10 +1974,10 @@ public static String joinPath(String... components) { return null; } if (urlName.startsWith("/")) - return joinPath(Stapler.getCurrentRequest().getContextPath(), urlName); + return joinPath(Stapler.getCurrentRequest2().getContextPath(), urlName); else // relative URL name - return joinPath(Stapler.getCurrentRequest().getContextPath() + '/' + itUrl, urlName); + return joinPath(Stapler.getCurrentRequest2().getContextPath() + '/' + itUrl, urlName); } /** @@ -1966,7 +2040,7 @@ public String getServerName() { } catch (MalformedURLException e) { // fall back to HTTP request } - return Stapler.getCurrentRequest().getServerName(); + return Stapler.getCurrentRequest2().getServerName(); } /** @@ -2004,7 +2078,7 @@ public void calcCheckUrl(Map attributes, String userDefined, Object descriptor, * Used in {@code task.jelly} to decide if the page should be highlighted. */ public boolean hyperlinkMatchesCurrentPage(String href) { - String url = Stapler.getCurrentRequest().getRequestURL().toString(); + String url = Stapler.getCurrentRequest2().getRequestURL().toString(); if (href == null || href.length() <= 1) return ".".equals(href) && url.endsWith("/"); url = URLDecoder.decode(url, StandardCharsets.UTF_8); href = URLDecoder.decode(href, StandardCharsets.UTF_8); @@ -2063,12 +2137,23 @@ public static List<Descriptor<CrumbIssuer>> getCrumbIssuerDescriptors() { return CrumbIssuer.all(); } - public static String getCrumb(StaplerRequest req) { + /** + * @since TODO + */ + public static String getCrumb(StaplerRequest2 req) { Jenkins h = Jenkins.getInstanceOrNull(); CrumbIssuer issuer = h != null ? h.getCrumbIssuer() : null; return issuer != null ? issuer.getCrumb(req) : ""; } + /** + * @deprecated use {@link #getCrumb(StaplerRequest2)} + */ + @Deprecated + public static String getCrumb(StaplerRequest req) { + return getCrumb(req != null ? StaplerRequest.toStaplerRequest2(req) : null); + } + public static String getCrumbRequestField() { Jenkins h = Jenkins.getInstanceOrNull(); CrumbIssuer issuer = h != null ? h.getCrumbIssuer() : null; @@ -2081,7 +2166,7 @@ public static Date getCurrentTime() { public static Locale getCurrentLocale() { Locale locale = null; - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req != null) locale = req.getLocale(); if (locale == null) @@ -2094,7 +2179,7 @@ public static Locale getCurrentLocale() { * from {@link ConsoleAnnotatorFactory}s and {@link ConsoleAnnotationDescriptor}s. */ public static String generateConsoleAnnotationScriptAndStylesheet() { - String cp = Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH; + String cp = Stapler.getCurrentRequest2().getContextPath() + Jenkins.RESOURCE_PATH; StringBuilder buf = new StringBuilder(); for (ConsoleAnnotatorFactory f : ConsoleAnnotatorFactory.all()) { String path = cp + "/extensionList/" + ConsoleAnnotatorFactory.class.getName() + "/" + f.getClass().getName(); @@ -2147,7 +2232,7 @@ public String getPasswordValue(Object o) { } /* Mask from Extended Read */ - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (o instanceof Secret || Secret.BLANK_NONSECRET_PASSWORD_FIELDS_WITHOUT_ITEM_CONFIGURE) { if (req != null) { Item item = req.findAncestorObject(Item.class); @@ -2243,15 +2328,17 @@ public static boolean isWipeOutPermissionEnabled() { @Deprecated public static String createRenderOnDemandProxy(JellyContext context, String attributesToCapture) { - return Stapler.getCurrentRequest().createJavaScriptProxy(new RenderOnDemandClosure(context, attributesToCapture)); + return Stapler.getCurrentRequest2().createJavaScriptProxy(new RenderOnDemandClosure(context, attributesToCapture)); } /** * Called from renderOnDemand.jelly to generate the parameters for the proxy object generation. + * + * @since TODO */ @Restricted(NoExternalUse.class) - public static StaplerRequest.RenderOnDemandParameters createRenderOnDemandProxyParameters(JellyContext context, String attributesToCapture) { - return Stapler.getCurrentRequest().createJavaScriptProxyParameters(new RenderOnDemandClosure(context, attributesToCapture)); + public static StaplerRequest2.RenderOnDemandParameters createRenderOnDemandProxyParameters(JellyContext context, String attributesToCapture) { + return Stapler.getCurrentRequest2().createJavaScriptProxyParameters(new RenderOnDemandClosure(context, attributesToCapture)); } public static String getCurrentDescriptorByNameUrl() { @@ -2260,18 +2347,18 @@ public static String getCurrentDescriptorByNameUrl() { public static String setCurrentDescriptorByNameUrl(String value) { String o = getCurrentDescriptorByNameUrl(); - Stapler.getCurrentRequest().setAttribute("currentDescriptorByNameUrl", value); + Stapler.getCurrentRequest2().setAttribute("currentDescriptorByNameUrl", value); return o; } public static void restoreCurrentDescriptorByNameUrl(String old) { - Stapler.getCurrentRequest().setAttribute("currentDescriptorByNameUrl", old); + Stapler.getCurrentRequest2().setAttribute("currentDescriptorByNameUrl", old); } public static List<String> getRequestHeaders(String name) { List<String> r = new ArrayList<>(); - Enumeration e = Stapler.getCurrentRequest().getHeaders(name); + Enumeration e = Stapler.getCurrentRequest2().getHeaders(name); while (e.hasMoreElements()) { r.add(e.nextElement().toString()); } @@ -2366,6 +2453,7 @@ public static String breakableString(final String plain) { * Advertises the minimum set of HTTP headers that assist programmatic * discovery of Jenkins. */ + @SuppressFBWarnings(value = "UC_USELESS_VOID_METHOD", justification = "TODO needs triage") public static void advertiseHeaders(HttpServletResponse rsp) { Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { @@ -2375,6 +2463,14 @@ public static void advertiseHeaders(HttpServletResponse rsp) { } } + /** + * @deprecated use {@link #advertiseHeaders(HttpServletResponse)} + */ + @Deprecated + public static void advertiseHeaders(javax.servlet.http.HttpServletResponse rsp) { + advertiseHeaders(HttpServletResponseWrapper.toJakartaHttpServletResponse(rsp)); + } + @Restricted(NoExternalUse.class) // for actions.jelly and ContextMenu.add public static boolean isContextMenuVisible(Action a) { if (a instanceof ModelObjectWithContextMenu.ContextMenuVisibility) { @@ -2449,7 +2545,7 @@ public static String tryGetIconPath(String iconGuess, JellyContext context) { return iconGuess; } - StaplerRequest currentRequest = Stapler.getCurrentRequest(); + StaplerRequest2 currentRequest = Stapler.getCurrentRequest2(); String rootURL = currentRequest.getContextPath(); Icon iconMetadata = tryGetIcon(iconGuess); diff --git a/core/src/main/java/hudson/LocalPluginManager.java b/core/src/main/java/hudson/LocalPluginManager.java index d1fcfd678e3a..7ee8c68b40d3 100644 --- a/core/src/main/java/hudson/LocalPluginManager.java +++ b/core/src/main/java/hudson/LocalPluginManager.java @@ -26,11 +26,12 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; +import io.jenkins.servlet.ServletContextWrapper; +import jakarta.servlet.ServletContext; import java.io.File; import java.util.Collection; import java.util.Collections; import java.util.logging.Logger; -import javax.servlet.ServletContext; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; @@ -49,12 +50,20 @@ public LocalPluginManager(@CheckForNull ServletContext context, @NonNull File ro super(context, new File(rootDir, "plugins")); } + /** + * @deprecated use {@link #LocalPluginManager(ServletContext, File)} + */ + @Deprecated + public LocalPluginManager(@CheckForNull javax.servlet.ServletContext context, @NonNull File rootDir) { + this(context != null ? ServletContextWrapper.toJakartaServletContext(context) : null, rootDir); + } + /** * Creates a new LocalPluginManager * @param jenkins Jenkins instance that will use the plugin manager. */ public LocalPluginManager(@NonNull Jenkins jenkins) { - this(jenkins.servletContext, jenkins.getRootDir()); + this(jenkins.getServletContext(), jenkins.getRootDir()); } /** @@ -62,7 +71,7 @@ public LocalPluginManager(@NonNull Jenkins jenkins) { * @param rootDir Jenkins home directory. */ public LocalPluginManager(@NonNull File rootDir) { - this(null, rootDir); + this((ServletContext) null, rootDir); } @Override diff --git a/core/src/main/java/hudson/Plugin.java b/core/src/main/java/hudson/Plugin.java index c87a2cbe9b3c..1427da9fda8a 100644 --- a/core/src/main/java/hudson/Plugin.java +++ b/core/src/main/java/hudson/Plugin.java @@ -33,25 +33,29 @@ import hudson.model.Saveable; import hudson.model.listeners.ItemListener; import hudson.model.listeners.SaveableListener; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Locale; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.GlobalConfiguration; import jenkins.model.Jenkins; import jenkins.model.Loadable; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * Base class of Hudson plugin. @@ -92,11 +96,11 @@ public abstract class Plugin implements Loadable, Saveable, StaplerProxy { /** * You do not need to create custom subtypes: * <ul> - * <li>{@code config.jelly}, {@link #configure(StaplerRequest, JSONObject)}, {@link #load}, and {@link #save} + * <li>{@code config.jelly}, {@link #configure(StaplerRequest2, JSONObject)}, {@link #load}, and {@link #save} * can be replaced by {@link GlobalConfiguration} * <li>{@link #start} and {@link #postInitialize} can be replaced by {@link Initializer} (or {@link ItemListener#onLoaded}) * <li>{@link #stop} can be replaced by {@link Terminator} - * <li>{@link #setServletContext} can be replaced by {@link Jenkins#servletContext} + * <li>{@link #setServletContext} can be replaced by {@link Jenkins#getServletContext} * </ul> * Note that every plugin gets a {@link DummyImpl} by default, * which will still route the URL space, serve {@link #getWrapper}, and so on. @@ -189,10 +193,10 @@ public void stop() throws Exception { /** * @since 1.233 - * @deprecated as of 1.305 override {@link #configure(StaplerRequest,JSONObject)} instead + * @deprecated as of 1.305 override {@link #configure(StaplerRequest2,JSONObject)} instead */ @Deprecated - public void configure(JSONObject formData) throws IOException, ServletException, FormException { + public void configure(JSONObject formData) throws IOException, javax.servlet.ServletException, FormException { } /** @@ -220,16 +224,60 @@ public void configure(JSONObject formData) throws IOException, ServletException, * <p> * If you are using this method, you'll likely be interested in * using {@link #save()} and {@link #load()}. + * @since TODO + */ + public void configure(StaplerRequest2 req, JSONObject formData) throws IOException, ServletException, FormException { + try { + if (Util.isOverridden(Plugin.class, getClass(), "configure", StaplerRequest.class, JSONObject.class)) { + configure(StaplerRequest.fromStaplerRequest2(req), formData); + } else { + configure(formData); + } + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } + + /** + * @deprecated use {@link #configure(StaplerRequest2, JSONObject)} * @since 1.305 */ - public void configure(StaplerRequest req, JSONObject formData) throws IOException, ServletException, FormException { + @Deprecated + public void configure(StaplerRequest req, JSONObject formData) throws IOException, javax.servlet.ServletException, FormException { configure(formData); } /** * This method serves static resources in the plugin under {@code hudson/plugin/SHORTNAME}. + * + * @since TODO + */ + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Plugin.class, getClass(), "doDynamic", StaplerRequest.class, StaplerResponse.class)) { + try { + doDynamic(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doDynamicImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doDynamic(StaplerRequest2, StaplerResponse2)} */ - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + @Deprecated + @StaplerNotDispatchable + public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doDynamicImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doDynamicImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { String path = req.getRestOfPath(); String pathUC = path.toUpperCase(Locale.ENGLISH); diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index 16c22e9ca90c..e1f5d4cc1184 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -66,6 +66,10 @@ import hudson.util.Service; import hudson.util.VersionNumber; import hudson.util.XStream2; +import io.jenkins.servlet.ServletContextWrapper; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FilenameFilter; @@ -118,8 +122,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; import javax.xml.XMLConstants; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; @@ -134,6 +136,7 @@ import jenkins.model.Jenkins; import jenkins.plugins.DetachedPluginsUtil; import jenkins.security.CustomClassFilter; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import jenkins.util.io.OnMaster; import jenkins.util.xml.RestrictiveEntityResolver; @@ -143,8 +146,8 @@ import org.apache.commons.fileupload2.core.DiskFileItemFactory; import org.apache.commons.fileupload2.core.FileItem; import org.apache.commons.fileupload2.core.FileUploadException; -import org.apache.commons.fileupload2.javax.JavaxServletDiskFileUpload; -import org.apache.commons.fileupload2.javax.JavaxServletFileUpload; +import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletDiskFileUpload; +import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletFileUpload; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; @@ -165,7 +168,8 @@ import org.kohsuke.stapler.StaplerOverridable; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -237,11 +241,22 @@ PluginManager doCreate(@NonNull Class<? extends PluginManager> klass, return klass.getConstructor(Jenkins.class).newInstance(jenkins); } }, + SC_FILE2 { + @Override + @NonNull PluginManager doCreate(@NonNull Class<? extends PluginManager> klass, + @NonNull Jenkins jenkins) throws ReflectiveOperationException { + return klass.getConstructor(ServletContext.class, File.class).newInstance(jenkins.getServletContext(), jenkins.getRootDir()); + } + }, + /** + * @deprecated use {@link #SC_FILE2} + */ + @Deprecated SC_FILE { @Override @NonNull PluginManager doCreate(@NonNull Class<? extends PluginManager> klass, @NonNull Jenkins jenkins) throws ReflectiveOperationException { - return klass.getConstructor(ServletContext.class, File.class).newInstance(jenkins.servletContext, jenkins.getRootDir()); + return klass.getConstructor(javax.servlet.ServletContext.class, File.class).newInstance(jenkins.servletContext, jenkins.getRootDir()); } }, FILE { @@ -363,6 +378,9 @@ PluginManager doCreate(@NonNull Class<? extends PluginManager> klass, */ private final PluginStrategy strategy; + /** + * @since TODO + */ protected PluginManager(ServletContext context, File rootDir) { this.context = context; @@ -378,6 +396,14 @@ protected PluginManager(ServletContext context, File rootDir) { strategy = createPluginStrategy(); } + /** + * @deprecated use {@link #PluginManager(ServletContext, File)} + */ + @Deprecated + protected PluginManager(javax.servlet.ServletContext context, File rootDir) { + this(context != null ? ServletContextWrapper.toJakartaServletContext(context) : null, rootDir); + } + public Api getApi() { Jenkins.get().checkPermission(Jenkins.SYSTEM_READ); return new Api(this); @@ -655,7 +681,7 @@ void considerDetachedPlugin(String shortName, String source) { protected @NonNull Set<String> loadPluginsFromWar(@NonNull String fromPath, @CheckForNull FilenameFilter filter) { Set<String> names = new HashSet<>(); - ServletContext context = Jenkins.get().servletContext; + ServletContext context = Jenkins.get().getServletContext(); Set<String> plugins = Util.fixNull(context.getResourcePaths(fromPath)); Set<URL> copiedPlugins = new HashSet<>(); Set<URL> dependencies = new HashSet<>(); @@ -723,7 +749,7 @@ protected static void addDependencies(URL hpiResUrl, String fromPath, Set<URL> d String dependencySpec = manifest.getMainAttributes().getValue("Plugin-Dependencies"); if (dependencySpec != null) { String[] dependencyTokens = dependencySpec.split(","); - ServletContext context = Jenkins.get().servletContext; + ServletContext context = Jenkins.get().getServletContext(); for (String dependencyToken : dependencyTokens) { if (dependencyToken.endsWith(";resolution:=optional")) { @@ -1597,7 +1623,7 @@ public HttpResponse doPlugins() { } @RequirePOST - public HttpResponse doUpdateSources(StaplerRequest req) throws IOException { + public HttpResponse doUpdateSources(StaplerRequest2 req) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); if (req.hasParameter("remove")) { @@ -1632,7 +1658,7 @@ public void doInstallPluginsDone() { * Performs the installation of the plugins. */ @RequirePOST - public void doInstall(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doInstall(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); Set<String> plugins = new LinkedHashSet<>(); @@ -1656,12 +1682,12 @@ public void doInstall(StaplerRequest req, StaplerResponse rsp) throws IOExceptio * @param req The request object. * @return A JSON response that includes a "correlationId" in the "data" element. * That "correlationId" can then be used in calls to - * {@link UpdateCenter#doInstallStatus(org.kohsuke.stapler.StaplerRequest)}. + * {@link UpdateCenter#doInstallStatus(org.kohsuke.stapler.StaplerRequest2)}. * @throws IOException Error reading JSON payload fro request. */ @RequirePOST @Restricted(DoNotUse.class) // WebOnly - public HttpResponse doInstallPlugins(StaplerRequest req) throws IOException { + public HttpResponse doInstallPlugins(StaplerRequest2 req) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); String payload = IOUtils.toString(req.getInputStream(), req.getCharacterEncoding()); JSONObject request = JSONObject.fromObject(payload); @@ -1815,7 +1841,7 @@ public HttpResponse doSiteConfigure(@QueryParameter String site) throws IOExcept } @POST - public HttpResponse doProxyConfigure(StaplerRequest req) throws IOException, ServletException { + public HttpResponse doProxyConfigure(StaplerRequest2 req) throws IOException, ServletException { Jenkins jenkins = Jenkins.get(); jenkins.checkPermission(Jenkins.ADMINISTER); @@ -1880,14 +1906,39 @@ public void cleanup() { * Uploads a plugin. */ @RequirePOST - public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, ServletException { + public HttpResponse doUploadPlugin(StaplerRequest2 req) throws IOException, ServletException { + if (Util.isOverridden(PluginManager.class, getClass(), "doUploadPlugin", StaplerRequest.class)) { + try { + return doUploadPlugin(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + return doUploadPluginImpl(req); + } + } + + /** + * @deprecated use {@link #doUploadPlugin(StaplerRequest2)} + */ + @Deprecated + @StaplerNotDispatchable + public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, javax.servlet.ServletException { + try { + return doUploadPluginImpl(StaplerRequest.toStaplerRequest2(req)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private HttpResponse doUploadPluginImpl(StaplerRequest2 req) throws IOException, ServletException { try { Jenkins.get().checkPermission(Jenkins.ADMINISTER); String fileName = ""; PluginCopier copier; File tmpDir = Files.createTempDirectory("uploadDir").toFile(); - JavaxServletFileUpload<DiskFileItem, DiskFileItemFactory> upload = new JavaxServletDiskFileUpload(DiskFileItemFactory.builder().setFile(tmpDir).get()); + JakartaServletFileUpload<DiskFileItem, DiskFileItemFactory> upload = new JakartaServletDiskFileUpload(DiskFileItemFactory.builder().setFile(tmpDir).get()); List<DiskFileItem> items = upload.parseRequest(req); String string = items.get(1).getString(); if (string != null && !string.isBlank()) { @@ -1965,7 +2016,7 @@ public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, Servl } @Restricted(NoExternalUse.class) - @RequirePOST public FormValidation doCheckPluginUrl(StaplerRequest request, @QueryParameter String value) throws IOException { + @RequirePOST public FormValidation doCheckPluginUrl(StaplerRequest2 request, @QueryParameter String value) throws IOException { if (value != null && !value.isBlank()) { try { URL url = new URL(value); @@ -1984,7 +2035,7 @@ public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, Servl } @Restricted(NoExternalUse.class) - @RequirePOST public FormValidation doCheckUpdateSiteUrl(StaplerRequest request, @QueryParameter String value) throws InterruptedException { + @RequirePOST public FormValidation doCheckUpdateSiteUrl(StaplerRequest2 request, @QueryParameter String value) throws InterruptedException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); return checkUpdateSiteURL(value); } @@ -2217,7 +2268,7 @@ private void logPluginWarnings(Map.Entry<String, VersionNumber> requestedPlugin, } /** - * Like {@link #doInstallNecessaryPlugins(StaplerRequest)} but only checks if everything is installed + * Like {@link #doInstallNecessaryPlugins(StaplerRequest2)} but only checks if everything is installed * or if some plugins need updates or installation. * * This method runs without side-effect. I'm still requiring the ADMINISTER permission since @@ -2227,7 +2278,7 @@ private void logPluginWarnings(Map.Entry<String, VersionNumber> requestedPlugin, * @since 1.483 */ @RequirePOST - public JSONArray doPrevalidateConfig(StaplerRequest req) throws IOException { + public JSONArray doPrevalidateConfig(StaplerRequest2 req) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); JSONArray response = new JSONArray(); @@ -2252,7 +2303,7 @@ public JSONArray doPrevalidateConfig(StaplerRequest req) throws IOException { * @since 1.483 */ @RequirePOST - public HttpResponse doInstallNecessaryPlugins(StaplerRequest req) throws IOException { + public HttpResponse doInstallNecessaryPlugins(StaplerRequest2 req) throws IOException { prevalidateConfig(req.getInputStream()); return HttpResponses.redirectViaContextPath("pluginManager/updates/"); } diff --git a/core/src/main/java/hudson/PluginWrapper.java b/core/src/main/java/hudson/PluginWrapper.java index 47cfcb02d955..c8cd9f5240a0 100644 --- a/core/src/main/java/hudson/PluginWrapper.java +++ b/core/src/main/java/hudson/PluginWrapper.java @@ -80,8 +80,8 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -1212,7 +1212,7 @@ public PluginWrapper getPlugin(String shortName) { /** * Depending on whether the user said "dismiss" or "correct", send him to the right place. */ - public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doAct(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.hasParameter("correct")) { rsp.sendRedirect(req.getContextPath() + "/pluginManager"); diff --git a/core/src/main/java/hudson/ProxyConfigurationManager.java b/core/src/main/java/hudson/ProxyConfigurationManager.java index 52f15f84c87e..d3ae0d79ee0e 100644 --- a/core/src/main/java/hudson/ProxyConfigurationManager.java +++ b/core/src/main/java/hudson/ProxyConfigurationManager.java @@ -32,7 +32,7 @@ import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; @Extension @Restricted(NoExternalUse.class) public class ProxyConfigurationManager extends GlobalConfiguration { @@ -48,7 +48,7 @@ public Descriptor<ProxyConfiguration> getProxyDescriptor() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { ProxyConfiguration pc = req.bindJSON(ProxyConfiguration.class, json); try { saveProxyConfiguration(pc); diff --git a/core/src/main/java/hudson/ResponseHeaderFilter.java b/core/src/main/java/hudson/ResponseHeaderFilter.java index 90fb0be87d37..416e5c4c6919 100644 --- a/core/src/main/java/hudson/ResponseHeaderFilter.java +++ b/core/src/main/java/hudson/ResponseHeaderFilter.java @@ -24,15 +24,15 @@ package hudson; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; +import org.kohsuke.stapler.CompatibleFilter; /** * This filter allows you to modify headers set by the container or other servlets @@ -77,7 +77,7 @@ * * @author Mike Wille */ -public class ResponseHeaderFilter implements Filter { +public class ResponseHeaderFilter implements CompatibleFilter { private FilterConfig config; @Override diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java index abe9f97d6551..5ca66e9c4424 100644 --- a/core/src/main/java/hudson/Util.java +++ b/core/src/main/java/hudson/Util.java @@ -125,6 +125,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Various utility methods that don't have more proper home. @@ -1850,9 +1851,11 @@ public static long daysElapsedSince(@NonNull Date date) { /** * Find the specific ancestor, or throw an exception. * Useful for an ancestor we know is inside the URL to ease readability + * + * @since TODO */ @Restricted(NoExternalUse.class) - public static @NonNull <T> T getNearestAncestorOfTypeOrThrow(@NonNull StaplerRequest request, @NonNull Class<T> clazz) { + public static @NonNull <T> T getNearestAncestorOfTypeOrThrow(@NonNull StaplerRequest2 request, @NonNull Class<T> clazz) { T t = request.findAncestorObject(clazz); if (t == null) { throw new IllegalArgumentException("No ancestor of type " + clazz.getName() + " in the request"); @@ -1860,6 +1863,15 @@ public static long daysElapsedSince(@NonNull Date date) { return t; } + /** + * @deprecated use {@link #getNearestAncestorOfTypeOrThrow(StaplerRequest2, Class)} + */ + @Deprecated + @Restricted(NoExternalUse.class) + public static @NonNull <T> T getNearestAncestorOfTypeOrThrow(@NonNull StaplerRequest request, @NonNull Class<T> clazz) { + return getNearestAncestorOfTypeOrThrow(StaplerRequest.toStaplerRequest2(request), clazz); + } + @Restricted(NoExternalUse.class) public static void printRedirect(String contextPath, String redirectUrl, String message, PrintWriter out) { out.printf( diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index 9f328328c710..986452797f90 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -45,6 +45,12 @@ import hudson.util.NoHomeDir; import hudson.util.NoTempDir; import hudson.util.RingBufferLogHandler; +import io.jenkins.servlet.ServletContextEventWrapper; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.SessionTrackingMode; import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -65,11 +71,6 @@ import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletResponse; -import javax.servlet.SessionTrackingMode; import jenkins.model.Jenkins; import jenkins.util.JenkinsJVM; import jenkins.util.SystemProperties; @@ -320,10 +321,21 @@ private void recordBootAttempt(File home) { } } + /** + * @since TODO + */ public static void installExpressionFactory(ServletContextEvent event) { JellyFacet.setExpressionFactory(event, new ExpressionFactory2()); } + /** + * @deprecated use {@link #installExpressionFactory(ServletContextEvent)} + */ + @Deprecated + public static void installExpressionFactory(javax.servlet.ServletContextEvent event) { + installExpressionFactory(ServletContextEventWrapper.toJakartaServletContextEvent(event)); + } + /** * Installs log handler to monitor all Hudson logs. */ diff --git a/core/src/main/java/hudson/cli/CLIAction.java b/core/src/main/java/hudson/cli/CLIAction.java index 9e29b141560c..a2fc5f590197 100644 --- a/core/src/main/java/hudson/cli/CLIAction.java +++ b/core/src/main/java/hudson/cli/CLIAction.java @@ -26,6 +26,8 @@ import hudson.Extension; import hudson.model.UnprotectedRootAction; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; @@ -45,8 +47,6 @@ import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.util.FullDuplexHttpService; import jenkins.util.SystemProperties; @@ -59,8 +59,8 @@ import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.core.Authentication; /** @@ -97,7 +97,7 @@ public String getUrlName() { return "cli"; } - public void doCommand(StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + public void doCommand(StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { final Jenkins jenkins = Jenkins.get(); jenkins.checkPermission(Jenkins.READ); @@ -121,7 +121,7 @@ public boolean isWebSocketSupported() { /** * WebSocket endpoint. */ - public HttpResponse doWs(StaplerRequest req) { + public HttpResponse doWs(StaplerRequest2 req) { if (!WebSockets.isSupported()) { return HttpResponses.notFound(); } @@ -216,7 +216,7 @@ protected void closed(int statusCode, String reason) { @Override public Object getTarget() { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req.getRestOfPath().isEmpty() && "POST".equals(req.getMethod())) { // CLI connection request if ("false".equals(req.getParameter("remoting"))) { @@ -349,7 +349,7 @@ private class PlainCliEndpointResponse extends FullDuplexHttpService.Response { } @Override - protected FullDuplexHttpService createService(StaplerRequest req, UUID uuid) throws IOException { + protected FullDuplexHttpService createService(StaplerRequest2 req, UUID uuid) throws IOException { return new FullDuplexHttpService(uuid) { @Override protected void run(InputStream upload, OutputStream download) throws IOException, InterruptedException { diff --git a/core/src/main/java/hudson/cli/CliCrumbExclusion.java b/core/src/main/java/hudson/cli/CliCrumbExclusion.java index 4e3064f43178..08c204eb55b1 100644 --- a/core/src/main/java/hudson/cli/CliCrumbExclusion.java +++ b/core/src/main/java/hudson/cli/CliCrumbExclusion.java @@ -26,11 +26,11 @@ import hudson.Extension; import hudson.security.csrf.CrumbExclusion; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; diff --git a/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java b/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java index 6b29dcf52904..aab260747f65 100644 --- a/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java +++ b/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java @@ -50,7 +50,7 @@ protected int run() throws Exception { // Or perhaps simpler to inline the thread body of doReload? j.doReload(); Object app; - while ((app = WebApp.get(j.servletContext).getApp()) instanceof HudsonIsLoading) { + while ((app = WebApp.get(j.getServletContext()).getApp()) instanceof HudsonIsLoading) { Thread.sleep(100); } if (app instanceof Jenkins) { diff --git a/core/src/main/java/hudson/cli/UpdateNodeCommand.java b/core/src/main/java/hudson/cli/UpdateNodeCommand.java index c9210f89cc68..5909a2f0fcf2 100644 --- a/core/src/main/java/hudson/cli/UpdateNodeCommand.java +++ b/core/src/main/java/hudson/cli/UpdateNodeCommand.java @@ -26,8 +26,8 @@ import hudson.Extension; import hudson.model.Node; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import org.kohsuke.args4j.Argument; /** diff --git a/core/src/main/java/hudson/console/AnnotatedLargeText.java b/core/src/main/java/hudson/console/AnnotatedLargeText.java index 4e0d3b9908af..1798512f3e03 100644 --- a/core/src/main/java/hudson/console/AnnotatedLargeText.java +++ b/core/src/main/java/hudson/console/AnnotatedLargeText.java @@ -30,6 +30,7 @@ import edu.umd.cs.findbugs.annotations.CheckReturnValue; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Util; import hudson.remoting.ObjectInputStreamEx; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -50,10 +51,13 @@ import javax.crypto.CipherOutputStream; import jenkins.model.Jenkins; import jenkins.security.CryptoConfidentialKey; +import jenkins.security.stapler.StaplerNotDispatchable; import org.jenkinsci.remoting.util.AnonymousClassWarnings; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.framework.io.ByteBuffer; import org.kohsuke.stapler.framework.io.LargeText; @@ -90,14 +94,44 @@ public AnnotatedLargeText(ByteBuffer memory, Charset charset, boolean completed, this.context = context; } + /** + * @since TODO + */ + public void doProgressiveHtml(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { + if (Util.isOverridden(AnnotatedLargeText.class, getClass(), "doProgressiveHtml", StaplerRequest.class, StaplerResponse.class)) { + doProgressiveHtml(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + doProgressiveHtmlImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doProgressiveHtml(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable public void doProgressiveHtml(StaplerRequest req, StaplerResponse rsp) throws IOException { + doProgressiveHtmlImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doProgressiveHtmlImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { req.setAttribute("html", true); doProgressText(req, rsp); } /** * Aliasing what I think was a wrong name in {@link LargeText} + * + * @since TODO */ + public void doProgressiveText(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { + doProgressText(req, rsp); + } + + /** + * @deprecated use {@link #doProgressiveText(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated public void doProgressiveText(StaplerRequest req, StaplerResponse rsp) throws IOException { doProgressText(req, rsp); } @@ -107,16 +141,35 @@ public void doProgressiveText(StaplerRequest req, StaplerResponse rsp) throws IO * and use this request attribute to differentiate. */ private boolean isHtml() { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); return req != null && req.getAttribute("html") != null; } + /** + * @since TODO + */ @Override + protected void setContentType(StaplerResponse2 rsp) { + if (Util.isOverridden(AnnotatedLargeText.class, getClass(), "setContentType", StaplerResponse.class)) { + setContentType(StaplerResponse.fromStaplerResponse2(rsp)); + } else { + setContentTypeImpl(rsp); + } + } + + /** + * @deprecated use {@link #setContentType(StaplerResponse2)} + */ + @Deprecated protected void setContentType(StaplerResponse rsp) { + setContentTypeImpl(StaplerResponse.toStaplerResponse2(rsp)); + } + + private void setContentTypeImpl(StaplerResponse2 rsp) { rsp.setContentType(isHtml() ? "text/html;charset=UTF-8" : "text/plain;charset=UTF-8"); } - private ConsoleAnnotator<T> createAnnotator(StaplerRequest req) throws IOException { + private ConsoleAnnotator<T> createAnnotator(StaplerRequest2 req) throws IOException { try { String base64 = req != null ? req.getHeader("X-ConsoleAnnotator") : null; if (base64 != null) { @@ -176,7 +229,7 @@ public long writeRawLogTo(long start, OutputStream out) throws IOException { @CheckReturnValue public long writeHtmlTo(long start, Writer w) throws IOException { ConsoleAnnotationOutputStream<T> caw = new ConsoleAnnotationOutputStream<>( - w, createAnnotator(Stapler.getCurrentRequest()), context, charset); + w, createAnnotator(Stapler.getCurrentRequest2()), context, charset); long r = super.writeLogTo(start, caw); ByteArrayOutputStream baos = new ByteArrayOutputStream(); @@ -185,7 +238,7 @@ public long writeHtmlTo(long start, Writer w) throws IOException { oos.writeLong(System.currentTimeMillis()); // send timestamp to prevent a replay attack oos.writeObject(caw.getConsoleAnnotator()); oos.close(); - StaplerResponse rsp = Stapler.getCurrentResponse(); + StaplerResponse2 rsp = Stapler.getCurrentResponse2(); if (rsp != null) rsp.setHeader("X-ConsoleAnnotator", Base64.getEncoder().encodeToString(baos.toByteArray())); return r; diff --git a/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java b/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java index bb68ccc66194..e63e2dab5cae 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java @@ -28,13 +28,13 @@ import hudson.DescriptorExtensionList; import hudson.ExtensionPoint; import hudson.model.Descriptor; +import jakarta.servlet.ServletException; import java.io.IOException; import java.net.URL; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import jenkins.model.Jenkins; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; /** @@ -81,12 +81,12 @@ private URL hasResource(String name) { } @WebMethod(name = "script.js") - public void doScriptJs(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doScriptJs(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { rsp.serveFile(req, hasResource("/script.js"), TimeUnit.DAYS.toMillis(1)); } @WebMethod(name = "style.css") - public void doStyleCss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doStyleCss(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { rsp.serveFile(req, hasResource("/style.css"), TimeUnit.DAYS.toMillis(1)); } diff --git a/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java b/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java index b2f6948fd155..3e56f80ed5d0 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java @@ -28,15 +28,15 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.Run; +import jakarta.servlet.ServletException; import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.net.URL; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import org.jvnet.tiger_types.Types; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; /** @@ -113,12 +113,12 @@ private URL getResource(String fileName) { * Serves the JavaScript file associated with this console annotator factory. */ @WebMethod(name = "script.js") - public void doScriptJs(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doScriptJs(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { rsp.serveFile(req, getResource("/script.js"), TimeUnit.DAYS.toMillis(1)); } @WebMethod(name = "style.css") - public void doStyleCss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doStyleCss(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { rsp.serveFile(req, getResource("/style.css"), TimeUnit.DAYS.toMillis(1)); } diff --git a/core/src/main/java/hudson/console/HyperlinkNote.java b/core/src/main/java/hudson/console/HyperlinkNote.java index 1e582dab2b4a..8aa011660592 100644 --- a/core/src/main/java/hudson/console/HyperlinkNote.java +++ b/core/src/main/java/hudson/console/HyperlinkNote.java @@ -37,7 +37,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Turns a text into a hyperlink by specifying the URL separately. @@ -62,7 +62,7 @@ public HyperlinkNote(String url, int length) { public ConsoleAnnotator annotate(Object context, MarkupText text, int charPos) { String url = this.url; if (url.startsWith("/")) { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req != null) { // if we are serving HTTP request, we want to use app relative URL url = req.getContextPath() + url; diff --git a/core/src/main/java/hudson/diagnosis/OldDataMonitor.java b/core/src/main/java/hudson/diagnosis/OldDataMonitor.java index e2bfa4678fc9..425c52150949 100644 --- a/core/src/main/java/hudson/diagnosis/OldDataMonitor.java +++ b/core/src/main/java/hudson/diagnosis/OldDataMonitor.java @@ -65,8 +65,8 @@ import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -310,7 +310,7 @@ public Iterator<VersionNumber> getVersionList() { * Depending on whether the user said "yes" or "no", send him to the right place. */ @RequirePOST - public HttpResponse doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + public HttpResponse doAct(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.hasParameter("no")) { disable(true); return HttpResponses.redirectViaContextPath("/manage"); @@ -324,7 +324,7 @@ public HttpResponse doAct(StaplerRequest req, StaplerResponse rsp) throws IOExce * Remove those items from the data map. */ @RequirePOST - public HttpResponse doUpgrade(StaplerRequest req, StaplerResponse rsp) { + public HttpResponse doUpgrade(StaplerRequest2 req, StaplerResponse2 rsp) { final String thruVerParam = req.getParameter("thruVer"); final VersionNumber thruVer = thruVerParam.equals("all") ? null : new VersionNumber(thruVerParam); @@ -341,7 +341,7 @@ public HttpResponse doUpgrade(StaplerRequest req, StaplerResponse rsp) { * Remove those items from the data map. */ @RequirePOST - public HttpResponse doDiscard(StaplerRequest req, StaplerResponse rsp) { + public HttpResponse doDiscard(StaplerRequest2 req, StaplerResponse2 rsp) { saveAndRemoveEntries(entry -> entry.getValue().max == null); return HttpResponses.forwardToPreviousPage(); @@ -377,7 +377,7 @@ private void saveAndRemoveEntries(Predicate<Map.Entry<SaveableReference, Version data.keySet().removeAll(removed); } - public HttpResponse doIndex(StaplerResponse rsp) throws IOException { + public HttpResponse doIndex(StaplerResponse2 rsp) throws IOException { return new HttpRedirect("manage"); } diff --git a/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java b/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java index af7b2579db74..374df6da783e 100644 --- a/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java +++ b/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java @@ -41,7 +41,7 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -68,7 +68,7 @@ public boolean isActivated() { @Restricted(DoNotUse.class) // WebOnly @RestrictedSince("2.235") - public HttpResponse doTest(StaplerRequest request, @QueryParameter boolean testWithContext) { + public HttpResponse doTest(StaplerRequest2 request, @QueryParameter boolean testWithContext) { String referer = request.getReferer(); Jenkins j = Jenkins.get(); String redirect; diff --git a/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java b/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java index 6412ac63bcb2..1ea6c6336a02 100644 --- a/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java +++ b/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java @@ -30,8 +30,8 @@ import java.io.IOException; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -64,7 +64,7 @@ public boolean isActivated() { * Depending on whether the user said "yes" or "no", send him to the right place. */ @RequirePOST - public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doAct(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); if (req.hasParameter("no")) { disable(true); diff --git a/core/src/main/java/hudson/init/impl/GroovyInitScript.java b/core/src/main/java/hudson/init/impl/GroovyInitScript.java index 17f6a4702c94..ffe8c77513c8 100644 --- a/core/src/main/java/hudson/init/impl/GroovyInitScript.java +++ b/core/src/main/java/hudson/init/impl/GroovyInitScript.java @@ -39,6 +39,6 @@ public class GroovyInitScript { @Initializer(after = JOB_CONFIG_ADAPTED) public static void init(Jenkins j) { - new GroovyHookScript("init", j.servletContext, j.getRootDir(), j.getPluginManager().uberClassLoader).run(); + new GroovyHookScript("init", j.getServletContext(), j.getRootDir(), j.getPluginManager().uberClassLoader).run(); } } diff --git a/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java b/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java index c305e9a6febc..4a8d6ce51900 100644 --- a/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java +++ b/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java @@ -2,22 +2,22 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.init.Initializer; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.EOFException; import java.io.IOException; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.kohsuke.MetaInfServices; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.UncaughtExceptionFilter; import org.kohsuke.stapler.WebApp; @@ -30,7 +30,7 @@ public class InstallUncaughtExceptionHandler { @Initializer public static void init(final Jenkins j) throws IOException { - UncaughtExceptionFilter.setUncaughtExceptionHandler(j.servletContext, (e, context, req, rsp) -> handleException(j, e, req, rsp, 500)); + UncaughtExceptionFilter.setUncaughtExceptionHandler(j.getServletContext(), (e, context, req, rsp) -> handleException(j, e, req, rsp, 500)); try { Thread.setDefaultUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler()); LOGGER.log(Level.FINE, "Successfully installed a global UncaughtExceptionHandler."); @@ -53,10 +53,10 @@ private static void handleException(Jenkins j, Throwable e, HttpServletRequest r String id = UUID.randomUUID().toString(); LOGGER.log(isEOFException(e) ? Level.FINE : Level.WARNING, "Caught unhandled exception with ID " + id, e); req.setAttribute("jenkins.exception.id", id); - req.setAttribute("javax.servlet.error.exception", e); + req.setAttribute("jakarta.servlet.error.exception", e); rsp.setStatus(code); try { - WebApp.get(j.servletContext).getSomeStapler().invoke(req, rsp, j, "/oops"); + WebApp.get(j.getServletContext()).getSomeStapler().invoke(req, rsp, j, "/oops"); } catch (ServletException | IOException x) { if (!Stapler.isSocketException(x)) { throw x; @@ -75,7 +75,7 @@ public HttpResponses.HttpResponseException handleError(int code, Throwable cause } return new HttpResponses.HttpResponseException(cause) { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { handleException(Jenkins.get(), cause, req, rsp, code); } }; diff --git a/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java b/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java index 875a3e4ef7e0..c54a90d1c576 100644 --- a/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java +++ b/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java @@ -35,6 +35,7 @@ import hudson.model.TaskListener; import hudson.util.StreamTaskListener; import hudson.util.jna.DotNet; +import jakarta.servlet.ServletException; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -43,7 +44,6 @@ import java.nio.file.Files; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.apache.commons.io.FileUtils; @@ -52,8 +52,8 @@ import org.apache.tools.ant.taskdefs.Move; import org.apache.tools.ant.types.FileSet; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -116,7 +116,7 @@ public boolean isInstalled() { * Performs installation. */ @RequirePOST - public void doDoInstall(StaplerRequest req, StaplerResponse rsp, @QueryParameter("dir") String _dir) throws IOException, ServletException { + public void doDoInstall(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter("dir") String _dir) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); if (installationDir != null) { @@ -168,7 +168,7 @@ public void doDoInstall(StaplerRequest req, StaplerResponse rsp, @QueryParameter /** * Copies a single resource into the target folder, by the given name, and handle errors gracefully. */ - private void copy(StaplerRequest req, StaplerResponse rsp, File dir, URL src, String name) throws ServletException, IOException { + private void copy(StaplerRequest2 req, StaplerResponse2 rsp, File dir, URL src, String name) throws ServletException, IOException { try { FileUtils.copyURLToFile(src, new File(dir, name)); } catch (IOException e) { @@ -179,7 +179,7 @@ private void copy(StaplerRequest req, StaplerResponse rsp, File dir, URL src, St } @RequirePOST - public void doRestart(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRestart(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); if (installationDir == null) { @@ -250,11 +250,11 @@ private DefaultLogger createLogger() { /** * Displays the error in a page. */ - protected final void sendError(Exception e, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + protected final void sendError(Exception e, StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { sendError(e.getMessage(), req, rsp); } - protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + protected final void sendError(String message, StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { req.setAttribute("message", message); req.setAttribute("pre", true); rsp.forward(Jenkins.get(), "error", req); diff --git a/core/src/main/java/hudson/logging/LogRecorder.java b/core/src/main/java/hudson/logging/LogRecorder.java index 86aea6575048..ad4c40028547 100644 --- a/core/src/main/java/hudson/logging/LogRecorder.java +++ b/core/src/main/java/hudson/logging/LogRecorder.java @@ -48,6 +48,7 @@ import hudson.util.HttpResponses; import hudson.util.RingBufferLogHandler; import hudson.util.XStream2; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.Serializable; @@ -71,7 +72,6 @@ import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.Loadable; import jenkins.security.MasterToSlaveCallable; @@ -82,8 +82,8 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -439,7 +439,7 @@ public LogRecorderManager getParent() { * Accepts submission from the configuration page. */ @POST - public synchronized void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); JSONObject src = req.getSubmittedForm(); @@ -536,7 +536,7 @@ public int hashCode() { * Deletes this recorder, then go back to the parent. */ @RequirePOST - public synchronized void doDoDelete(StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doDoDelete(StaplerResponse2 rsp) throws IOException, ServletException { delete(); rsp.sendRedirect2(".."); } @@ -562,7 +562,7 @@ public void delete() throws IOException { /** * RSS feed for log entries. */ - public void doRss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRss(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { LogRecorderManager.doRss(req, rsp, getLogRecords()); } diff --git a/core/src/main/java/hudson/logging/LogRecorderManager.java b/core/src/main/java/hudson/logging/LogRecorderManager.java index 70856024df12..2c589adaa612 100644 --- a/core/src/main/java/hudson/logging/LogRecorderManager.java +++ b/core/src/main/java/hudson/logging/LogRecorderManager.java @@ -38,6 +38,7 @@ import hudson.model.RSS; import hudson.util.CopyOnWriteMap; import hudson.util.FormValidation; +import jakarta.servlet.ServletException; import java.io.File; import java.io.FileFilter; import java.io.IOException; @@ -53,7 +54,6 @@ import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.JenkinsLocationConfiguration; import jenkins.model.ModelObjectWithChildren; @@ -68,8 +68,8 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -188,7 +188,7 @@ public FormValidation doCheckNewName(@QueryParameter String name) { } @Override - public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { ContextMenu menu = new ContextMenu(); menu.add("all", "All Jenkins Logs"); for (LogRecorder lr : recorders) { @@ -225,14 +225,14 @@ public HttpResponse doConfigLogger(@QueryParameter String name, @QueryParameter /** * RSS feed for log entries. */ - public void doRss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRss(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { doRss(req, rsp, Jenkins.logRecords); } /** * Renders the given log recorders as RSS. */ - /*package*/ static void doRss(StaplerRequest req, StaplerResponse rsp, List<LogRecord> logs) throws IOException, ServletException { + /*package*/ static void doRss(StaplerRequest2 req, StaplerResponse2 rsp, List<LogRecord> logs) throws IOException, ServletException { // filter log records based on the log level String entryType = "all"; String level = req.getParameter("level"); diff --git a/core/src/main/java/hudson/markup/MarkupFormatter.java b/core/src/main/java/hudson/markup/MarkupFormatter.java index e588e0cfcc8e..a3bf53a739a1 100644 --- a/core/src/main/java/hudson/markup/MarkupFormatter.java +++ b/core/src/main/java/hudson/markup/MarkupFormatter.java @@ -28,6 +28,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionPoint; import hudson.model.AbstractDescribableImpl; +import jakarta.servlet.ServletException; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; @@ -44,7 +45,8 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.verb.GET; import org.kohsuke.stapler.verb.POST; @@ -138,7 +140,7 @@ public HttpResponse doPreviewDescription(@QueryParameter String text) throws IOE @GET @WebMethod(name = "previewDescription") @Restricted(NoExternalUse.class) - public HttpResponse previewsNowNeedPostForSecurity2153(@QueryParameter String text, StaplerRequest req) throws IOException { + public HttpResponse previewsNowNeedPostForSecurity2153(@QueryParameter String text, StaplerRequest2 req) throws IOException { LOGGER.log(Level.FINE, "Received a GET request at " + req.getRequestURL()); if (PREVIEWS_ALLOW_GET) { return doPreviewDescription(text); @@ -155,15 +157,18 @@ public HttpResponse previewsNowNeedPostForSecurity2153(@QueryParameter String te */ private static HttpResponse html(int status, @NonNull String html, @NonNull Map<String, String> headers) { // TODO Move to Stapler's HttpResponses, (also add a corresponding 'text' method) - return (req, rsp, node) -> { - rsp.setContentType("text/html;charset=UTF-8"); - rsp.setStatus(status); - for (Map.Entry<String, String> header : headers.entrySet()) { - rsp.setHeader(header.getKey(), header.getValue()); + return new HttpResponse() { + @Override + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { + rsp.setContentType("text/html;charset=UTF-8"); + rsp.setStatus(status); + for (Map.Entry<String, String> header : headers.entrySet()) { + rsp.setHeader(header.getKey(), header.getValue()); + } + PrintWriter pw = rsp.getWriter(); + pw.print(html); + pw.flush(); } - PrintWriter pw = rsp.getWriter(); - pw.print(html); - pw.flush(); }; } } diff --git a/core/src/main/java/hudson/model/AbstractBuild.java b/core/src/main/java/hudson/model/AbstractBuild.java index 85d62df78896..d993d722eacb 100644 --- a/core/src/main/java/hudson/model/AbstractBuild.java +++ b/core/src/main/java/hudson/model/AbstractBuild.java @@ -62,6 +62,8 @@ import hudson.util.HttpResponses; import hudson.util.Iterators; import hudson.util.VariableResolver; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.InterruptedIOException; @@ -81,7 +83,6 @@ import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.lazy.BuildReference; import jenkins.model.lazy.LazyBuildMixIn; @@ -275,7 +276,7 @@ public Queue.Executable getParentExecutable() { */ @Deprecated(since = "2.364") public String getUpUrl() { - return Functions.getNearestAncestorUrl(Stapler.getCurrentRequest(), getParent()) + '/'; + return Functions.getNearestAncestorUrl(Stapler.getCurrentRequest2(), getParent()) + '/'; } /** @@ -1391,8 +1392,12 @@ public List<AbstractBuild> getBuilds() { */ @Deprecated @RequirePOST // #doStop() should be preferred, but better to be safe - public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - doStop().generateResponse(req, rsp, this); + public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doStop().generateResponse(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), this); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } /** diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java index adebec8f289f..af64ff19df34 100644 --- a/core/src/main/java/hudson/model/AbstractItem.java +++ b/core/src/main/java/hudson/model/AbstractItem.java @@ -25,7 +25,7 @@ package hudson.model; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.NonNull; @@ -47,6 +47,8 @@ import hudson.util.FormValidation; import hudson.util.IOUtils; import hudson.util.Secret; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -59,7 +61,6 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.servlet.ServletException; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.sax.SAXSource; @@ -70,6 +71,7 @@ import jenkins.model.Loadable; import jenkins.model.queue.ItemDeletion; import jenkins.security.NotReallyRoleSensitiveCallable; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import jenkins.util.xml.XMLUtils; import org.apache.tools.ant.Project; @@ -87,7 +89,9 @@ import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -530,7 +534,7 @@ public void onCopiedFrom(Item src) { @Override public final String getUrl() { // try to stick to the current view if possible - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); String shortUrl = getShortUrl(); String uri = req == null ? null : req.getRequestURI(); if (req != null) { @@ -644,9 +648,36 @@ private Object readResolve() { /** * Accepts the new description. + * + * @since TODO */ @RequirePOST - public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(AbstractItem.class, getClass(), "doSubmitDescription", StaplerRequest.class, StaplerResponse.class)) { + try { + doSubmitDescription(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doSubmitDescriptionImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doSubmitDescription(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doSubmitDescriptionImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doSubmitDescriptionImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { checkPermission(CONFIGURE); setDescription(req.getParameter("description")); @@ -658,9 +689,32 @@ public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse * Note on the funny name: for reasons of historical compatibility, this URL is {@code /doDelete} * since it predates {@code <l:confirmationLink>}. {@code /delete} goes to a Jelly page * which should now be unused by core but is left in case plugins are still using it. + * + * @since TODO */ @RequirePOST - public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public void doDoDelete(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { + if (Util.isOverridden(AbstractItem.class, getClass(), "doDoDelete", StaplerRequest.class, StaplerResponse.class)) { + try { + doDoDelete(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doDoDeleteImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doDoDelete(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException, InterruptedException { + doDoDeleteImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doDoDeleteImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, InterruptedException { delete(); if (req == null || rsp == null) { // CLI return; @@ -681,8 +735,28 @@ public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOExcepti rsp.sendRedirect2(req.getContextPath() + '/' + url); } + /** + * @since TODO + */ @Override - public void delete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void delete(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + deleteImpl(rsp); + } + + /** + * @deprecated use {@link #delete(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @Override + public void delete(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + deleteImpl(StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void deleteImpl(StaplerResponse2 rsp) throws IOException, ServletException { try { delete(); rsp.setStatus(204); @@ -755,10 +829,31 @@ protected void performDelete() throws IOException, InterruptedException { /** * Accepts {@code config.xml} submission, as well as serve it. + * + * @since TODO */ @WebMethod(name = "config.xml") + public void doConfigDotXml(StaplerRequest2 req, StaplerResponse2 rsp) + throws IOException { + if (Util.isOverridden(AbstractItem.class, getClass(), "doConfigDotXml", StaplerRequest.class, StaplerResponse.class)) { + doConfigDotXml(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + doConfigDotXmlImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doConfigDotXml(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp) throws IOException { + doConfigDotXmlImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doConfigDotXmlImpl(StaplerRequest2 req, StaplerResponse2 rsp) + throws IOException { if (req.getMethod().equals("GET")) { // read rsp.setContentType("application/xml"); diff --git a/core/src/main/java/hudson/model/AbstractModelObject.java b/core/src/main/java/hudson/model/AbstractModelObject.java index f6c7104f8e42..87b42527a86e 100644 --- a/core/src/main/java/hudson/model/AbstractModelObject.java +++ b/core/src/main/java/hudson/model/AbstractModelObject.java @@ -29,11 +29,14 @@ import hudson.search.SearchIndex; import hudson.search.SearchIndexBuilder; import hudson.search.SearchableModelObject; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -45,33 +48,69 @@ public abstract class AbstractModelObject implements SearchableModelObject { /** * Displays the error in a page. */ - protected final void sendError(Exception e, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + protected final void sendError(Exception e, StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { req.setAttribute("exception", e); sendError(e.getMessage(), req, rsp); } + /** + * @deprecated use {@link #sendError(Exception, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + protected final void sendError(Exception e, StaplerRequest req, StaplerResponse rsp) throws javax.servlet.ServletException, IOException { + try { + sendError(e, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException ex) { + throw ServletExceptionWrapper.fromJakartaServletException(ex); + } + } + protected final void sendError(Exception e) throws ServletException, IOException { - sendError(e, Stapler.getCurrentRequest(), Stapler.getCurrentResponse()); + sendError(e, Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2()); } - protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + protected final void sendError(String message, StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { req.setAttribute("message", message); rsp.forward(this, "error", req); } + /** + * @deprecated use {@link #sendError(String, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp) throws javax.servlet.ServletException, IOException { + try { + sendError(message, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * @param pre * If true, the message is put in a PRE tag. */ - protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp, boolean pre) throws ServletException, IOException { + protected final void sendError(String message, StaplerRequest2 req, StaplerResponse2 rsp, boolean pre) throws ServletException, IOException { req.setAttribute("message", message); if (pre) req.setAttribute("pre", true); rsp.forward(this, "error", req); } + /** + * @deprecated use {@link #sendError(String, StaplerRequest2, StaplerResponse2, boolean)} + */ + @Deprecated + protected final void sendError(String message, StaplerRequest req, StaplerResponse rsp, boolean pre) throws javax.servlet.ServletException, IOException { + try { + sendError(message, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), pre); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + protected final void sendError(String message) throws ServletException, IOException { - sendError(message, Stapler.getCurrentRequest(), Stapler.getCurrentResponse()); + sendError(message, Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2()); } /** @@ -82,7 +121,7 @@ protected final void sendError(String message) throws ServletException, IOExcept */ @Deprecated protected final void requirePOST() throws ServletException { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req == null) return; // invoked outside the context of servlet String method = req.getMethod(); if (!method.equalsIgnoreCase("POST")) diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index 917ff1f7b81f..a380943687f7 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -77,6 +77,8 @@ import hudson.util.AlternativeUiTextProvider.Message; import hudson.util.DescribableList; import hudson.util.FormValidation; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -96,7 +98,6 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.BlockedBecauseOfBuildInProgress; import jenkins.model.Jenkins; import jenkins.model.ParameterizedJobMixIn; @@ -120,7 +121,9 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -769,7 +772,7 @@ public List<ProminentProjectAction> getProminentActions() { @Override @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { super.doConfigSubmit(req, rsp); updateTransientActions(); @@ -1726,10 +1729,14 @@ protected SearchIndexBuilder makeSearchIndex() { // // - /** @deprecated use {@link #doBuild(StaplerRequest, StaplerResponse, TimeDuration)} */ + /** @deprecated use {@link #doBuild(StaplerRequest2, StaplerResponse2, TimeDuration)} */ @Deprecated - public void doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - doBuild(req, rsp, TimeDuration.fromString(req.getParameter("delay"))); + public void doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doBuild(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), TimeDuration.fromString(req.getParameter("delay"))); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } /** @@ -1739,7 +1746,7 @@ public void doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, * Inject {@link TimeDuration}. */ @Deprecated - public int getDelay(StaplerRequest req) throws ServletException { + public int getDelay(StaplerRequest req) throws javax.servlet.ServletException { String delay = req.getParameter("delay"); if (delay == null) return getQuietPeriod(); @@ -1749,26 +1756,59 @@ public int getDelay(StaplerRequest req) throws ServletException { if (delay.endsWith("secs")) delay = delay.substring(0, delay.length() - 4); return Integer.parseInt(delay); } catch (NumberFormatException e) { - throw new ServletException("Invalid delay parameter value: " + delay, e); + throw new javax.servlet.ServletException("Invalid delay parameter value: " + delay, e); } } - /** @deprecated use {@link #doBuildWithParameters(StaplerRequest, StaplerResponse, TimeDuration)} */ + /** @deprecated use {@link #doBuildWithParameters(StaplerRequest2, StaplerResponse2, TimeDuration)} */ @Deprecated - public void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - doBuildWithParameters(req, rsp, TimeDuration.fromString(req.getParameter("delay"))); + public void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doBuildWithParameters(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), TimeDuration.fromString(req.getParameter("delay"))); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } @Override // in case schedulePolling was overridden - public void doPolling(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doPolling(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { BuildAuthorizationToken.checkPermission((Job) this, authToken, req, rsp); schedulePolling(); rsp.sendRedirect("."); } + /** + * @since TODO + */ + @Override + protected void submit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { + if (Util.isOverridden(AbstractProject.class, getClass(), "submit", StaplerRequest.class, StaplerResponse.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + super.submit(req, rsp); + submitImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated @Override - protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException, FormException { super.submit(req, rsp); + try { + submitImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void submitImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { JSONObject json = req.getSubmittedForm(); makeDisabled(!json.optBoolean("enable")); @@ -1835,14 +1875,18 @@ protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOExceptio /** * @deprecated - * As of 1.261. Use {@link #buildDescribable(StaplerRequest, List)} instead. + * As of 1.261. Use {@link #buildDescribable(StaplerRequest2, List)} instead. */ @Deprecated - protected final <T extends Describable<T>> List<T> buildDescribable(StaplerRequest req, List<? extends Descriptor<T>> descriptors, String prefix) throws FormException, ServletException { - return buildDescribable(req, descriptors); + protected final <T extends Describable<T>> List<T> buildDescribable(StaplerRequest req, List<? extends Descriptor<T>> descriptors, String prefix) throws FormException, javax.servlet.ServletException { + try { + return buildDescribable(StaplerRequest.toStaplerRequest2(req), descriptors); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } - protected final <T extends Describable<T>> List<T> buildDescribable(StaplerRequest req, List<? extends Descriptor<T>> descriptors) + protected final <T extends Describable<T>> List<T> buildDescribable(StaplerRequest2 req, List<? extends Descriptor<T>> descriptors) throws FormException, ServletException { JSONObject data = req.getSubmittedForm(); @@ -1860,7 +1904,7 @@ protected final <T extends Describable<T>> List<T> buildDescribable(StaplerReque /** * Serves the workspace files. */ - public DirectoryBrowserSupport doWs(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public DirectoryBrowserSupport doWs(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { checkPermission(Item.WORKSPACE); FilePath ws = getSomeWorkspace(); if (ws == null || !ws.exists()) { @@ -1887,7 +1931,7 @@ public DirectoryBrowserSupport doWs(StaplerRequest req, StaplerResponse rsp) thr * Wipes out the workspace. */ @RequirePOST - public HttpResponse doDoWipeOutWorkspace() throws IOException, ServletException, InterruptedException { + public HttpResponse doDoWipeOutWorkspace() throws IOException, InterruptedException { checkPermission(Functions.isWipeOutPermissionEnabled() ? WIPEOUT : BUILD); R b = getSomeBuildWithWorkspace(); FilePath ws = b != null ? b.getWorkspace() : null; diff --git a/core/src/main/java/hudson/model/Actionable.java b/core/src/main/java/hudson/model/Actionable.java index 7e3e695d9c4f..d8088319021b 100644 --- a/core/src/main/java/hudson/model/Actionable.java +++ b/core/src/main/java/hudson/model/Actionable.java @@ -37,8 +37,11 @@ import java.util.logging.Logger; import jenkins.model.ModelObjectWithContextMenu; import jenkins.model.TransientActionFactory; +import jenkins.security.stapler.StaplerNotDispatchable; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -338,7 +341,26 @@ public <T extends Action> T getAction(Class<T> type) { return null; } + /** + * @since TODO + */ + public Object getDynamic(String token, StaplerRequest2 req, StaplerResponse2 rsp) { + if (Util.isOverridden(Actionable.class, getClass(), "getDynamic", String.class, StaplerRequest.class, StaplerResponse.class)) { + return getDynamic(token, StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + return getDynamicImpl(token, req, rsp); + } + } + + /** + * @deprecated use {@link #getDynamic(String, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) { + return getDynamicImpl(token, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private Object getDynamicImpl(String token, StaplerRequest2 req, StaplerResponse2 rsp) { for (Action a : getAllActions()) { if (a == null) continue; // be defensive @@ -351,7 +373,29 @@ public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) return null; } - @Override public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + /** + * @since TODO + */ + @Override + public ContextMenu doContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { + if (Util.isOverridden(Actionable.class, getClass(), "doContextMenu", StaplerRequest.class, StaplerResponse.class)) { + return doContextMenu(StaplerRequest.fromStaplerRequest2(request), StaplerResponse.fromStaplerResponse2(response)); + } else { + return doContextMenuImpl(request, response); + } + } + + /** + * @deprecated use {@link #doContextMenu(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + @Override + public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + return doContextMenuImpl(StaplerRequest.toStaplerRequest2(request), StaplerResponse.toStaplerResponse2(response)); + } + + private ContextMenu doContextMenuImpl(StaplerRequest2 request, StaplerResponse2 response) throws Exception { return new ContextMenu().from(this, request, response); } diff --git a/core/src/main/java/hudson/model/AdministrativeMonitor.java b/core/src/main/java/hudson/model/AdministrativeMonitor.java index bdbfb48027d3..59518ba79e57 100644 --- a/core/src/main/java/hudson/model/AdministrativeMonitor.java +++ b/core/src/main/java/hudson/model/AdministrativeMonitor.java @@ -37,8 +37,8 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -175,7 +175,7 @@ public boolean isSecurity() { * URL binding to disable this monitor. */ @RequirePOST - public void doDisable(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doDisable(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); disable(true); rsp.sendRedirect2(req.getContextPath() + "/manage"); @@ -188,7 +188,7 @@ public void doDisable(StaplerRequest req, StaplerResponse rsp) throws IOExceptio * Changing this permission check to return {@link Jenkins#SYSTEM_READ} will make the active * administrative monitor appear on {@code manage.jelly} and on the globally visible * {@link jenkins.management.AdministrativeMonitorsDecorator} to users without Administer permission. - * {@link #doDisable(StaplerRequest, StaplerResponse)} will still always require Administer permission. + * {@link #doDisable(StaplerRequest2, StaplerResponse2)} will still always require Administer permission. * </p> * <p> * This method only allows for a single permission to be returned. If more complex permission checks are required, diff --git a/core/src/main/java/hudson/model/AllView.java b/core/src/main/java/hudson/model/AllView.java index ca1ef0d5cc0d..3972625ea7ab 100644 --- a/core/src/main/java/hudson/model/AllView.java +++ b/core/src/main/java/hudson/model/AllView.java @@ -26,7 +26,10 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; +import hudson.Util; import hudson.model.Descriptor.FormException; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.Collection; import java.util.List; @@ -34,12 +37,12 @@ import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.util.SystemProperties; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -91,7 +94,7 @@ public String getDisplayName() { @RequirePOST @Override - public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) + public Item doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { ItemGroup<? extends TopLevelItem> ig = getOwner().getItemGroup(); if (ig instanceof ModifiableItemGroup) @@ -110,7 +113,24 @@ public String getPostConstructLandingPage() { } @Override - protected void submit(StaplerRequest req) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest2 req) throws IOException, ServletException, FormException { + if (Util.isOverridden(AllView.class, getClass(), "submit", StaplerRequest.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + // noop + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2)} + */ + @Deprecated + @Override + protected void submit(StaplerRequest req) throws IOException, javax.servlet.ServletException, FormException { // noop } diff --git a/core/src/main/java/hudson/model/Api.java b/core/src/main/java/hudson/model/Api.java index 23e72072112f..4b16e1b0b540 100644 --- a/core/src/main/java/hudson/model/Api.java +++ b/core/src/main/java/hudson/model/Api.java @@ -25,6 +25,10 @@ package hudson.model; import hudson.ExtensionList; +import hudson.Util; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.io.StringReader; @@ -34,11 +38,10 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import javax.xml.transform.stream.StreamResult; import jenkins.model.Jenkins; import jenkins.security.SecureRequester; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.xml.FilteredFunctionContext; import org.dom4j.CharacterData; import org.dom4j.Document; @@ -52,7 +55,9 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.Flavor; import org.kohsuke.stapler.export.Model; @@ -96,7 +101,7 @@ public String getSearchUrl() { /** * Exposes the bean as XML. */ - public void doXml(StaplerRequest req, StaplerResponse rsp, + public void doXml(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String xpath, @QueryParameter String wrapper, @QueryParameter String tree, @@ -212,7 +217,7 @@ private boolean isSimpleOutput(Object result) { /** * Generate schema. */ - public void doSchema(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doSchema(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { setHeaders(rsp); rsp.setContentType("application/xml"); StreamResult r = new StreamResult(rsp.getOutputStream()); @@ -223,7 +228,32 @@ public void doSchema(StaplerRequest req, StaplerResponse rsp) throws IOException /** * Exposes the bean as JSON. */ - public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doJson(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Api.class, getClass(), "doJson", StaplerRequest.class, StaplerResponse.class)) { + try { + doJson(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doJsonImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doJson(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doJsonImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doJsonImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { if (req.getParameter("jsonp") == null || permit(req)) { setHeaders(rsp); rsp.serveExposedBean(req, bean, req.getParameter("jsonp") == null ? Flavor.JSON : Flavor.JSONP); @@ -235,12 +265,37 @@ public void doJson(StaplerRequest req, StaplerResponse rsp) throws IOException, /** * Exposes the bean as Python literal. */ - public void doPython(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doPython(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Api.class, getClass(), "doPython", StaplerRequest.class, StaplerResponse.class)) { + try { + doPython(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doPythonImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doPython(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doPython(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doPythonImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doPythonImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { setHeaders(rsp); rsp.serveExposedBean(req, bean, Flavor.PYTHON); } - private boolean permit(StaplerRequest req) { + private boolean permit(StaplerRequest2 req) { for (SecureRequester r : ExtensionList.lookup(SecureRequester.class)) { if (r.permit(req, bean)) { return true; @@ -250,7 +305,7 @@ private boolean permit(StaplerRequest req) { } @Restricted(NoExternalUse.class) - protected void setHeaders(StaplerResponse rsp) { + protected void setHeaders(StaplerResponse2 rsp) { rsp.setHeader("X-Jenkins", Jenkins.VERSION); rsp.setHeader("X-Jenkins-Session", Jenkins.SESSION_HASH); // to be really defensive against dumb browsers not taking into consideration the content-type being set diff --git a/core/src/main/java/hudson/model/AutoCompletionCandidates.java b/core/src/main/java/hudson/model/AutoCompletionCandidates.java index d2f5f17c255f..366f626e3144 100644 --- a/core/src/main/java/hudson/model/AutoCompletionCandidates.java +++ b/core/src/main/java/hudson/model/AutoCompletionCandidates.java @@ -28,16 +28,16 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.search.Search; import hudson.search.UserSearchProperty; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Locale; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Flavor; /** @@ -69,7 +69,7 @@ public List<String> getValues() { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object o) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object o) throws IOException, ServletException { Search.Result r = new Search.Result(); for (String value : values) { r.suggestions.add(new hudson.search.Search.Item(value)); diff --git a/core/src/main/java/hudson/model/BallColor.java b/core/src/main/java/hudson/model/BallColor.java index 5913f59466f9..3e8dc2f28802 100644 --- a/core/src/main/java/hudson/model/BallColor.java +++ b/core/src/main/java/hudson/model/BallColor.java @@ -113,7 +113,7 @@ public String getImage() { @Override public String getImageOf(String size) { - return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH + "/images/" + size + '/' + image; + return Stapler.getCurrentRequest2().getContextPath() + Jenkins.RESOURCE_PATH + "/images/" + size + '/' + image; } /** diff --git a/core/src/main/java/hudson/model/BooleanParameterDefinition.java b/core/src/main/java/hudson/model/BooleanParameterDefinition.java index 6e9db32216fd..6bf1a50096e3 100644 --- a/core/src/main/java/hudson/model/BooleanParameterDefinition.java +++ b/core/src/main/java/hudson/model/BooleanParameterDefinition.java @@ -33,7 +33,7 @@ import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link ParameterDefinition} that is either 'true' or 'false'. @@ -79,7 +79,7 @@ public void setDefaultValue(boolean defaultValue) { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { BooleanParameterValue value = req.bindJSON(BooleanParameterValue.class, jo); value.setDescription(getDescription()); return value; diff --git a/core/src/main/java/hudson/model/BuildAuthorizationToken.java b/core/src/main/java/hudson/model/BuildAuthorizationToken.java index a09ed113e1cf..3611824fb54d 100644 --- a/core/src/main/java/hudson/model/BuildAuthorizationToken.java +++ b/core/src/main/java/hudson/model/BuildAuthorizationToken.java @@ -27,11 +27,13 @@ import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; import hudson.Util; import hudson.security.ACL; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.access.AccessDeniedException; /** @@ -51,7 +53,10 @@ public BuildAuthorizationToken(String token) { this.token = token; } - public static BuildAuthorizationToken create(StaplerRequest req) { + /** + * @since TODO + */ + public static BuildAuthorizationToken create(StaplerRequest2 req) { if (req.getParameter("pseudoRemoteTrigger") != null) { String token = Util.fixEmpty(req.getParameter("authToken")); if (token != null) @@ -61,11 +66,22 @@ public static BuildAuthorizationToken create(StaplerRequest req) { return null; } + /** + * @deprecated use {@link #create(StaplerRequest2)} + */ + @Deprecated + public static BuildAuthorizationToken create(StaplerRequest req) { + return create(StaplerRequest.toStaplerRequest2(req)); + } + @Deprecated public static void checkPermission(AbstractProject<?, ?> project, BuildAuthorizationToken token, StaplerRequest req, StaplerResponse rsp) throws IOException { - checkPermission((Job<?, ?>) project, token, req, rsp); + checkPermission((Job<?, ?>) project, token, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); } - public static void checkPermission(Job<?, ?> project, BuildAuthorizationToken token, StaplerRequest req, StaplerResponse rsp) throws IOException { + /** + * @since TODO + */ + public static void checkPermission(Job<?, ?> project, BuildAuthorizationToken token, StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (token != null && token.token != null) { //check the provided token String providedToken = req.getParameter("token"); @@ -86,6 +102,14 @@ public static void checkPermission(Job<?, ?> project, BuildAuthorizationToken to throw HttpResponses.forwardToView(project, "requirePOST.jelly"); } + /** + * @deprecated use {@link #checkPermission(Job, BuildAuthorizationToken, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + public static void checkPermission(Job<?, ?> project, BuildAuthorizationToken token, StaplerRequest req, StaplerResponse rsp) throws IOException { + checkPermission(project, token, StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + public String getToken() { return token; } diff --git a/core/src/main/java/hudson/model/BuildTimelineWidget.java b/core/src/main/java/hudson/model/BuildTimelineWidget.java index 9691969162d4..4f5ccbf1c67a 100644 --- a/core/src/main/java/hudson/model/BuildTimelineWidget.java +++ b/core/src/main/java/hudson/model/BuildTimelineWidget.java @@ -25,12 +25,15 @@ package hudson.model; import hudson.util.RunList; +import jakarta.servlet.ServletException; +import java.io.IOException; import java.util.ArrayList; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * UI widget for showing the SIMILE timeline control. @@ -60,12 +63,15 @@ public BuildTimelineWidget(RunList<?> builds) { return builds.getLastBuild(); } - public HttpResponse doData(StaplerRequest req, @QueryParameter long min, @QueryParameter long max) { - return (req1, rsp, node) -> { - JSONObject o = new JSONObject(); - o.put("events", JSONArray.fromObject(new ArrayList<>())); - rsp.setContentType("text/javascript;charset=UTF-8"); - o.write(rsp.getWriter()); + public HttpResponse doData(StaplerRequest2 req, @QueryParameter long min, @QueryParameter long max) { + return new HttpResponse() { + @Override + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { + JSONObject o = new JSONObject(); + o.put("events", JSONArray.fromObject(new ArrayList<>())); + rsp.setContentType("text/javascript;charset=UTF-8"); + o.write(rsp.getWriter()); + } }; } diff --git a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java index 7b12a9b2cee3..98bdcf2e8072 100644 --- a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java +++ b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java @@ -20,7 +20,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; /** @@ -152,7 +152,7 @@ public boolean isValid(ParameterValue value) { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { StringParameterValue value = req.bindJSON(StringParameterValue.class, jo); value.setDescription(getDescription()); checkValue(value, value.getValue()); @@ -218,7 +218,7 @@ public String getHelpFile() { /* * We need this for JENKINS-26143 -- reflective creation cannot handle setChoices(Object). See that method for context. */ - public ParameterDefinition newInstance(@Nullable StaplerRequest req, @NonNull JSONObject formData) throws FormException { + public ParameterDefinition newInstance(@Nullable StaplerRequest2 req, @NonNull JSONObject formData) throws FormException { String name = formData.getString("name"); String desc = formData.getString("description"); String choiceText = formData.getString("choices"); diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java index 14a311381a37..a4878a2c8f91 100644 --- a/core/src/main/java/hudson/model/Computer.java +++ b/core/src/main/java/hudson/model/Computer.java @@ -26,7 +26,7 @@ package hudson.model; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; @@ -73,6 +73,7 @@ import hudson.util.RemotingDiagnostics; import hudson.util.RemotingDiagnostics.HeapDump; import hudson.util.RunList; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -105,7 +106,6 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.security.ImpersonatingExecutorService; import jenkins.security.MasterToSlaveCallable; @@ -129,8 +129,8 @@ import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -227,7 +227,7 @@ * @since 1.607 */ public void recordTermination() { - StaplerRequest request = Stapler.getCurrentRequest(); + StaplerRequest2 request = Stapler.getCurrentRequest2(); if (request != null) { terminatedBy.add(new TerminationRequest( String.format("Termination requested at %s by %s [id=%d] from HTTP request for %s", @@ -416,7 +416,7 @@ public String getOfflineCauseReason() { /** * If {@link #getChannel()}==null, attempts to relaunch the agent. */ - public abstract void doLaunchSlaveAgent(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException; + public abstract void doLaunchSlaveAgent(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException; /** * @deprecated since 2009-01-06. Use {@link #connect(boolean)} @@ -427,7 +427,7 @@ public final void launch() { } /** - * Do the same as {@link #doLaunchSlaveAgent(StaplerRequest, StaplerResponse)} + * Do the same as {@link #doLaunchSlaveAgent(StaplerRequest2, StaplerResponse2)} * but outside the context of serving a request. * * <p> @@ -1391,12 +1391,12 @@ public String call() throws IOException { // // @Restricted(DoNotUse.class) - public void doRssAll(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssAll(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds()); } @Restricted(DoNotUse.class) - public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssFailed(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly()); } @@ -1407,7 +1407,7 @@ public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOExcept * @since 2.215 */ @Restricted(DoNotUse.class) - public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssLatest(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { final List<Run> lastBuilds = new ArrayList<>(); for (AbstractProject<?, ?> p : Jenkins.get().allItems(AbstractProject.class)) { if (p.getLastBuild() != null) { @@ -1452,7 +1452,7 @@ public Api getApi() { /** * Dumps the contents of the export table. */ - public void doDumpExportTable(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public void doDumpExportTable(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { // this is a debug probe and may expose sensitive information checkPermission(Jenkins.ADMINISTER); @@ -1488,18 +1488,18 @@ public String call() throws IOException { * For system diagnostics. * Run arbitrary Groovy script. */ - public void doScript(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doScript(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { _doScript(req, rsp, "_script.jelly"); } /** * Run arbitrary Groovy script and return result as plain text. */ - public void doScriptText(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doScriptText(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { _doScript(req, rsp, "_scriptText.jelly"); } - protected void _doScript(StaplerRequest req, StaplerResponse rsp, String view) throws IOException, ServletException { + protected void _doScript(StaplerRequest2 req, StaplerResponse2 rsp, String view) throws IOException, ServletException { Jenkins._doScript(req, rsp, req.getView(this, view), getChannel(), getACL()); } @@ -1507,7 +1507,7 @@ protected void _doScript(StaplerRequest req, StaplerResponse rsp, String view) t * Accepts the update to the node configuration. */ @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { checkPermission(CONFIGURE); String proposedName = Util.fixEmptyAndTrim(req.getSubmittedForm().getString("name")); @@ -1547,7 +1547,7 @@ public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOExc * Accepts {@code config.xml} submission, as well as serve it. */ @WebMethod(name = "config.xml") - public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp) + public void doConfigDotXml(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { if (req.getMethod().equals("GET")) { @@ -1626,7 +1626,7 @@ public void waitUntilOffline() throws InterruptedException { /** * Handles incremental log. */ - public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doProgressiveLog(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { getLogText().doProgressText(req, rsp); } diff --git a/core/src/main/java/hudson/model/ComputerSet.java b/core/src/main/java/hudson/model/ComputerSet.java index 5cb798978dea..f25d25a19a50 100644 --- a/core/src/main/java/hudson/model/ComputerSet.java +++ b/core/src/main/java/hudson/model/ComputerSet.java @@ -41,6 +41,7 @@ import hudson.util.DescribableList; import hudson.util.FormApply; import hudson.util.FormValidation; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -52,7 +53,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.ModelObjectWithChildren; import jenkins.model.ModelObjectWithContextMenu.ContextMenu; @@ -61,8 +61,8 @@ import net.sf.json.JSONObject; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -112,7 +112,7 @@ public Computer[] get_all() { } @Override - public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { ContextMenu m = new ContextMenu(); for (Computer c : get_all()) { m.add(c); @@ -206,12 +206,12 @@ public String getSearchUrl() { return "/computers/"; } - public Computer getDynamic(String token, StaplerRequest req, StaplerResponse rsp) { + public Computer getDynamic(String token, StaplerRequest2 req, StaplerResponse2 rsp) { return Jenkins.get().getComputer(token); } @RequirePOST - public void do_launchAll(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void do_launchAll(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); for (Computer c : get_all()) { @@ -227,7 +227,7 @@ public void do_launchAll(StaplerRequest req, StaplerResponse rsp) throws IOExcep * TODO: ajax on the client side to wait until the update completion might be nice. */ @RequirePOST - public void doUpdateNow(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doUpdateNow(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.MANAGE); for (NodeMonitor nodeMonitor : NodeMonitor.getAll()) { @@ -244,7 +244,7 @@ public void doUpdateNow(StaplerRequest req, StaplerResponse rsp) throws IOExcept * First check point in creating a new agent. */ @RequirePOST - public synchronized void doCreateItem(StaplerRequest req, StaplerResponse rsp, + public synchronized void doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String name, @QueryParameter String mode, @QueryParameter String from) throws IOException, ServletException { final Jenkins app = Jenkins.get(); @@ -290,7 +290,7 @@ public synchronized void doCreateItem(StaplerRequest req, StaplerResponse rsp, * Really creates a new agent. */ @POST - public synchronized void doDoCreateItem(StaplerRequest req, StaplerResponse rsp, + public synchronized void doDoCreateItem(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String name, @QueryParameter String type) throws IOException, ServletException, FormException { final Jenkins app = Jenkins.get(); @@ -348,7 +348,7 @@ public FormValidation doCheckName(@QueryParameter String value) throws IOExcepti * Accepts submission from the configuration page. */ @POST - public synchronized HttpResponse doConfigSubmit(StaplerRequest req) throws IOException, ServletException, FormException { + public synchronized HttpResponse doConfigSubmit(StaplerRequest2 req) throws IOException, ServletException, FormException { BulkChange bc = new BulkChange(MONITORS_OWNER); try { Jenkins.get().checkPermission(Jenkins.MANAGE); diff --git a/core/src/main/java/hudson/model/Descriptor.java b/core/src/main/java/hudson/model/Descriptor.java index b5eb07784d27..e2067bfc6944 100644 --- a/core/src/main/java/hudson/model/Descriptor.java +++ b/core/src/main/java/hudson/model/Descriptor.java @@ -25,7 +25,7 @@ package hudson.model; import static hudson.util.QuotedStringTokenizer.quote; -import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; +import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; @@ -45,6 +45,9 @@ import hudson.util.ReflectionUtils; import hudson.util.ReflectionUtils.Parameter; import hudson.views.ListViewColumn; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletException; import java.beans.Introspector; import java.io.File; import java.io.IOException; @@ -71,13 +74,12 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; import jenkins.model.GlobalConfiguration; import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; import jenkins.model.Loadable; import jenkins.security.RedactSecretJsonInErrorMessageSanitizer; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.io.OnMaster; import net.sf.json.JSONArray; import net.sf.json.JSONObject; @@ -92,7 +94,9 @@ import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebApp; import org.kohsuke.stapler.jelly.JellyCompatibleFacet; import org.kohsuke.stapler.lang.Klass; @@ -382,7 +386,7 @@ public final String getDescriptorFullUrl() { * @since 1.402 */ public static String getCurrentDescriptorByNameUrl() { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); // this override allows RenderOnDemandClosure to preserve the proper value Object url = req.getAttribute("currentDescriptorByNameUrl"); @@ -576,16 +580,33 @@ public T newInstance(StaplerRequest req) throws FormException { * * @throws FormException * Signals a problem in the submitted form. + * @since TODO + */ + public T newInstance(@Nullable StaplerRequest2 req, @NonNull JSONObject formData) throws FormException { + if (Util.isOverridden(Descriptor.class, getClass(), "newInstance", StaplerRequest.class, JSONObject.class)) { + return newInstance(req != null ? StaplerRequest.fromStaplerRequest2(req) : null, formData); + } else { + return newInstanceImpl(req, formData); + } + } + + /** + * @deprecated use {@link #newInstance(StaplerRequest2, JSONObject)} * @since 1.145 */ + @Deprecated public T newInstance(@Nullable StaplerRequest req, @NonNull JSONObject formData) throws FormException { + return newInstanceImpl(req != null ? StaplerRequest.toStaplerRequest2(req) : null, formData); + } + + private T newInstanceImpl(@Nullable StaplerRequest2 req, @NonNull JSONObject formData) throws FormException { try { Method m = getClass().getMethod("newInstance", StaplerRequest.class); if (!Modifier.isAbstract(m.getDeclaringClass().getModifiers())) { // this class overrides newInstance(StaplerRequest). // maintain the backward compatible behavior - return verifyNewInstance(newInstance(req)); + return verifyNewInstance(newInstance(StaplerRequest.fromStaplerRequest2(req))); } else { if (req == null) { // yes, req is supposed to be always non-null, but see the note above @@ -602,16 +623,25 @@ public T newInstance(@Nullable StaplerRequest req, @NonNull JSONObject formData) } /** - * Replacement for {@link StaplerRequest#bindJSON(Class, JSONObject)} which honors {@link #newInstance(StaplerRequest, JSONObject)}. - * This is automatically used inside {@link #newInstance(StaplerRequest, JSONObject)} so a direct call would only be necessary - * in case the top level binding might use a {@link Descriptor} which overrides {@link #newInstance(StaplerRequest, JSONObject)}. + * Replacement for {@link StaplerRequest2#bindJSON(Class, JSONObject)} which honors {@link #newInstance(StaplerRequest2, JSONObject)}. + * This is automatically used inside {@link #newInstance(StaplerRequest2, JSONObject)} so a direct call would only be necessary + * in case the top level binding might use a {@link Descriptor} which overrides {@link #newInstance(StaplerRequest2, JSONObject)}. + * @since TODO + */ + public static <T> T bindJSON(StaplerRequest2 req, Class<T> type, JSONObject src) { + return bindJSON(req, type, src, false); + } + + /** + * @deprecated use {@link #bindJSON(StaplerRequest2, Class, JSONObject)} * @since 2.342 */ + @Deprecated public static <T> T bindJSON(StaplerRequest req, Class<T> type, JSONObject src) { - return bindJSON(req, type, src, false); + return bindJSON(StaplerRequest.toStaplerRequest2(req), type, src); } - private static <T> T bindJSON(StaplerRequest req, Class<T> type, JSONObject src, boolean fromNewInstance) { + private static <T> T bindJSON(StaplerRequest2 req, Class<T> type, JSONObject src, boolean fromNewInstance) { BindInterceptor oldInterceptor = req.getBindInterceptor(); try { NewInstanceBindInterceptor interceptor; @@ -631,9 +661,9 @@ private static <T> T bindJSON(StaplerRequest req, Class<T> type, JSONObject src, } /** - * Ensures that calls to {@link StaplerRequest#bindJSON(Class, JSONObject)} from {@link #newInstance(StaplerRequest, JSONObject)} recurse properly. + * Ensures that calls to {@link StaplerRequest2#bindJSON(Class, JSONObject)} from {@link #newInstance(StaplerRequest2, JSONObject)} recurse properly. * {@code doConfigSubmit}-like methods will wind up calling {@code newInstance} directly - * or via {@link #newInstancesFromHeteroList(StaplerRequest, Object, Collection)}, + * or via {@link #newInstancesFromHeteroList(StaplerRequest2, Object, Collection)}, * which consult any custom {@code newInstance} overrides for top-level {@link Describable} objects. * But for nested describable objects Stapler would know nothing about {@code newInstance} without this trick. */ @@ -671,7 +701,7 @@ public Object instantiate(Class actualType, JSONObject json) { try { final Descriptor descriptor = Jenkins.get().getDescriptor(actualType); if (descriptor != null) { - return descriptor.newInstance(Stapler.getCurrentRequest(), json); + return descriptor.newInstance(Stapler.getCurrentRequest2(), json); } else { LOGGER.log(Level.WARNING, "Descriptor not found. Falling back to default instantiation " + actualType.getName() + " " + json); @@ -694,7 +724,7 @@ public Object onConvert(Type targetType, Class targetTypeErasure, Object jsonSou if (isApplicable(targetTypeErasure, json)) { LOGGER.log(Level.FINE, "switching to newInstance {0} {1}", new Object[] {targetTypeErasure.getName(), json}); try { - return Jenkins.get().getDescriptor(targetTypeErasure).newInstance(Stapler.getCurrentRequest(), json); + return Jenkins.get().getDescriptor(targetTypeErasure).newInstance(Stapler.getCurrentRequest2(), json); } catch (Exception x) { LOGGER.log(Level.WARNING, "falling back to default instantiation " + targetTypeErasure.getName() + " " + json, x); } @@ -776,13 +806,13 @@ public String getHelpFile(Klass<?> clazz, String fieldName) { } try { - if (Stapler.getCurrentRequest().getView(c, "help" + suffix) != null) + if (Stapler.getCurrentRequest2().getView(c, "help" + suffix) != null) return page; } catch (IOException e) { throw new Error(e); } - if (getStaticHelpUrl(Stapler.getCurrentRequest(), c, suffix) != null) return page; + if (getStaticHelpUrl(Stapler.getCurrentRequest2(), c, suffix) != null) return page; } return null; } @@ -812,7 +842,7 @@ public final boolean isSubTypeOf(Class type) { /** * @deprecated - * As of 1.239, use {@link #configure(StaplerRequest, JSONObject)}. + * As of 1.239, use {@link #configure(StaplerRequest2, JSONObject)}. */ @Deprecated public boolean configure(StaplerRequest req) throws FormException { @@ -829,7 +859,21 @@ public boolean configure(StaplerRequest req) throws FormException { * See <a href="https://www.jenkins.io/doc/developer/forms/structured-form-submission/">the developer documentation</a>. * @return false * to keep the client in the same config page. + * @since TODO */ + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { + if (Util.isOverridden(Descriptor.class, getClass(), "configure", StaplerRequest.class, JSONObject.class)) { + return configure(StaplerRequest.fromStaplerRequest2(req), json); + } else { + // compatibility + return configure(StaplerRequest.fromStaplerRequest2(req)); + } + } + + /** + * @deprecated use {@link #configure(StaplerRequest2, JSONObject)} + */ + @Deprecated public boolean configure(StaplerRequest req, JSONObject json) throws FormException { // compatibility return configure(req); @@ -895,7 +939,7 @@ protected final String getViewPage(Class<?> clazz, String pageName) { protected List<String> getPossibleViewNames(String baseName) { List<String> names = new ArrayList<>(); - for (Facet f : WebApp.get(Jenkins.get().servletContext).facets) { + for (Facet f : WebApp.get(Jenkins.get().getServletContext()).facets) { if (f instanceof JellyCompatibleFacet jcf) { for (String ext : jcf.getScriptExtensions()) names.add(baseName + ext); @@ -957,7 +1001,32 @@ protected PluginWrapper getPlugin() { /** * Serves {@code help.html} from the resource of {@link #clazz}. */ - public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doHelp(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Descriptor.class, getClass(), "doHelp", StaplerRequest.class, StaplerResponse.class)) { + try { + doHelp(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doHelpImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doHelp(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doHelpImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doHelpImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { String path = req.getRestOfPath(); if (path.contains("..")) throw new ServletException("Illegal path: " + path); @@ -972,13 +1041,13 @@ public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, } for (Klass<?> c = getKlass(); c != null; c = c.getSuperClass()) { - RequestDispatcher rd = Stapler.getCurrentRequest().getView(c, "help" + path); + RequestDispatcher rd = Stapler.getCurrentRequest2().getView(c, "help" + path); if (rd != null) { // template based help page rd.forward(req, rsp); return; } - URL url = getStaticHelpUrl(Stapler.getCurrentRequest(), c, path); + URL url = getStaticHelpUrl(Stapler.getCurrentRequest2(), c, path); if (url != null) { // TODO: generalize macro expansion and perhaps even support JEXL rsp.setContentType("text/html;charset=UTF-8"); @@ -992,8 +1061,11 @@ public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, rsp.sendError(SC_NOT_FOUND); } + /** + * @since TODO + */ @Restricted(NoExternalUse.class) - public static URL getStaticHelpUrl(StaplerRequest req, Klass<?> c, String suffix) { + public static URL getStaticHelpUrl(StaplerRequest2 req, Klass<?> c, String suffix) { String base = "help" + suffix; URL url; @@ -1017,6 +1089,15 @@ public static URL getStaticHelpUrl(StaplerRequest req, Klass<?> c, String suffix return c.getResource(base + ".html"); } + /** + * @deprecated use {@link #getStaticHelpUrl(StaplerRequest2, Klass, String)} + */ + @Deprecated + @Restricted(NoExternalUse.class) + public static URL getStaticHelpUrl(StaplerRequest req, Klass<?> c, String suffix) { + return getStaticHelpUrl(StaplerRequest.toStaplerRequest2(req), c, suffix); + } + // // static methods @@ -1061,16 +1142,30 @@ Map<Descriptor<T>, T> toMap(Iterable<T> describables) { * List of descriptors to create instances from. * @return * Can be empty but never null. + * @since TODO */ public static <T extends Describable<T>> - List<T> newInstancesFromHeteroList(StaplerRequest req, JSONObject formData, String key, + List<T> newInstancesFromHeteroList(StaplerRequest2 req, JSONObject formData, String key, Collection<? extends Descriptor<T>> descriptors) throws FormException { return newInstancesFromHeteroList(req, formData.get(key), descriptors); } + /** + * @deprecated use {@link #newInstancesFromHeteroList(StaplerRequest2, JSONObject, String, Collection)} + */ + @Deprecated + public static <T extends Describable<T>> + List<T> newInstancesFromHeteroList(StaplerRequest req, JSONObject formData, String key, + Collection<? extends Descriptor<T>> descriptors) throws FormException { + return newInstancesFromHeteroList(StaplerRequest.toStaplerRequest2(req), formData, key, descriptors); + } + + /** + * @since TODO + */ public static <T extends Describable<T>> - List<T> newInstancesFromHeteroList(StaplerRequest req, Object formData, + List<T> newInstancesFromHeteroList(StaplerRequest2 req, Object formData, Collection<? extends Descriptor<T>> descriptors) throws FormException { List<T> items = new ArrayList<>(); @@ -1086,7 +1181,7 @@ List<T> newInstancesFromHeteroList(StaplerRequest req, Object formData, if (kind != null) { // Only applies when Descriptor.getId is overridden. // Note that kind is only supported here, - // *not* inside the StaplerRequest.bindJSON which is normally called by newInstance + // *not* inside the StaplerRequest2.bindJSON which is normally called by newInstance // (since Descriptor.newInstance is not itself available to Stapler). // If you merely override getId for some reason, but use @DataBoundConstructor on your Describable, // there is no problem; but you can only rely on newInstance being called at top level. @@ -1114,6 +1209,16 @@ List<T> newInstancesFromHeteroList(StaplerRequest req, Object formData, return items; } + /** + * @deprecated use {@link #newInstancesFromHeteroList(StaplerRequest2, JSONObject, String, Collection)} + */ + @Deprecated + public static <T extends Describable<T>> + List<T> newInstancesFromHeteroList(StaplerRequest req, Object formData, + Collection<? extends Descriptor<T>> descriptors) throws FormException { + return newInstancesFromHeteroList(StaplerRequest.toStaplerRequest2(req), formData, descriptors); + } + /** * Finds a descriptor from a collection by its ID. * @param id should match {@link #getId} @@ -1199,7 +1304,7 @@ public String getFormField() { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { if (FormApply.isApply(req)) { FormApply.applyResponse("notificationBar.show(" + quote(getMessage()) + ",notificationBar.ERROR)") .generateResponse(req, rsp, node); diff --git a/core/src/main/java/hudson/model/DirectlyModifiableView.java b/core/src/main/java/hudson/model/DirectlyModifiableView.java index 61362272c248..138f33a6a32c 100644 --- a/core/src/main/java/hudson/model/DirectlyModifiableView.java +++ b/core/src/main/java/hudson/model/DirectlyModifiableView.java @@ -26,8 +26,8 @@ import edu.umd.cs.findbugs.annotations.NonNull; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.interceptor.RequirePOST; diff --git a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java index 9d455f4c1bd3..72da0c7514c1 100644 --- a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java +++ b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java @@ -27,6 +27,9 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.FilePath; import hudson.Util; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -55,8 +58,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; import jenkins.security.ResourceDomainConfiguration; @@ -70,7 +71,9 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * Has convenience methods to serve file system. @@ -157,7 +160,7 @@ public DirectoryBrowserSupport(ModelObject owner, VirtualFile base, String title } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { if (!ResourceDomainConfiguration.isResourceRequest(req) && ResourceDomainConfiguration.isResourceDomainConfigured()) { resourceToken = ResourceDomainRootAction.get().getToken(this, req); } @@ -191,11 +194,15 @@ public void setIndexFileName(String fileName) { * from the {@code doXYZ} method and let Stapler generate a response for you. */ @Deprecated - public void serveFile(StaplerRequest req, StaplerResponse rsp, FilePath root, String icon, boolean serveDirIndex) throws IOException, ServletException, InterruptedException { - serveFile(req, rsp, root.toVirtualFile(), icon, serveDirIndex); + public void serveFile(StaplerRequest req, StaplerResponse rsp, FilePath root, String icon, boolean serveDirIndex) throws IOException, javax.servlet.ServletException, InterruptedException { + try { + serveFile(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), root.toVirtualFile(), icon, serveDirIndex); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } - private void serveFile(StaplerRequest req, StaplerResponse rsp, VirtualFile root, String icon, boolean serveDirIndex) throws IOException, ServletException, InterruptedException { + private void serveFile(StaplerRequest2 req, StaplerResponse2 rsp, VirtualFile root, String icon, boolean serveDirIndex) throws IOException, ServletException, InterruptedException { // handle form submission String pattern = req.getParameter("pattern"); if (pattern == null) @@ -492,7 +499,7 @@ private boolean isDescendant(VirtualFile root, String relativePath) { } } - private String getPath(StaplerRequest req) { + private String getPath(StaplerRequest2 req) { String path = req.getRestOfPath(); if (path.isEmpty()) path = "/"; @@ -521,7 +528,7 @@ private static String createBackRef(int times) { return "../".repeat(times); } - private static void zip(StaplerResponse rsp, VirtualFile root, VirtualFile dir, String glob) throws IOException, InterruptedException { + private static void zip(StaplerResponse2 rsp, VirtualFile root, VirtualFile dir, String glob) throws IOException, InterruptedException { OutputStream outputStream = rsp.getOutputStream(); try (ZipOutputStream zos = new ZipOutputStream(outputStream)) { zos.setEncoding(Charset.defaultCharset().displayName()); // TODO JENKINS-20663 make this overridable via query parameter diff --git a/core/src/main/java/hudson/model/Executor.java b/core/src/main/java/hudson/model/Executor.java index 020399bdd5b8..94aa1c770d21 100644 --- a/core/src/main/java/hudson/model/Executor.java +++ b/core/src/main/java/hudson/model/Executor.java @@ -59,7 +59,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.servlet.ServletException; import jenkins.model.CauseOfInterruption; import jenkins.model.CauseOfInterruption.UserInterruption; import jenkins.model.InterruptedBuildAction; @@ -852,7 +851,7 @@ public void start() { */ @RequirePOST @Deprecated - public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doStop(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { doStop().generateResponse(req, rsp, this); } diff --git a/core/src/main/java/hudson/model/Failure.java b/core/src/main/java/hudson/model/Failure.java index 71318dd0464b..0546f0a7e090 100644 --- a/core/src/main/java/hudson/model/Failure.java +++ b/core/src/main/java/hudson/model/Failure.java @@ -25,12 +25,12 @@ package hudson.model; import edu.umd.cs.findbugs.annotations.CheckForNull; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Represents an error induced by user, encountered during HTTP request processing. @@ -55,7 +55,7 @@ public Failure(String message, boolean pre) { this.pre = pre; } - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node, @CheckForNull Throwable throwable) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node, @CheckForNull Throwable throwable) throws IOException, ServletException { if (throwable != null) { req.setAttribute("exception", throwable); } @@ -63,7 +63,7 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { req.setAttribute("message", getMessage()); if (pre) req.setAttribute("pre", true); diff --git a/core/src/main/java/hudson/model/FileParameterDefinition.java b/core/src/main/java/hudson/model/FileParameterDefinition.java index 25cb08336da3..b8332f5911c5 100644 --- a/core/src/main/java/hudson/model/FileParameterDefinition.java +++ b/core/src/main/java/hudson/model/FileParameterDefinition.java @@ -29,17 +29,17 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.cli.CLICommand; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.Objects; -import javax.servlet.ServletException; import net.sf.json.JSONObject; import org.apache.commons.fileupload2.core.FileItem; import org.apache.commons.io.FileUtils; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link ParameterDefinition} for doing file upload. @@ -65,7 +65,7 @@ public FileParameterDefinition(@NonNull String name, @CheckForNull String descri } @Override - public FileParameterValue createValue(StaplerRequest req, JSONObject jo) { + public FileParameterValue createValue(StaplerRequest2 req, JSONObject jo) { FileParameterValue p = req.bindJSON(FileParameterValue.class, jo); p.setLocation(getName()); p.setDescription(getDescription()); @@ -87,7 +87,7 @@ public String getHelpFile() { } @Override - public ParameterValue createValue(StaplerRequest req) { + public ParameterValue createValue(StaplerRequest2 req) { FileItem src; try { src = req.getFileItem2(getName()); diff --git a/core/src/main/java/hudson/model/FileParameterValue.java b/core/src/main/java/hudson/model/FileParameterValue.java index 343e30bb64f4..abeb1f41816a 100644 --- a/core/src/main/java/hudson/model/FileParameterValue.java +++ b/core/src/main/java/hudson/model/FileParameterValue.java @@ -50,8 +50,8 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link ParameterValue} for {@link FileParameterDefinition}. @@ -235,9 +235,9 @@ public String toString() { } /** - * Serve this file parameter in response to a {@link StaplerRequest}. + * Serve this file parameter in response to a {@link StaplerRequest2}. */ - public DirectoryBrowserSupport doDynamic(StaplerRequest request, StaplerResponse response) { + public DirectoryBrowserSupport doDynamic(StaplerRequest2 request, StaplerResponse2 response) { AbstractBuild build = (AbstractBuild) request.findAncestor(AbstractBuild.class).getObject(); File fileParameter = getFileParameterFolderUnderBuild(build); return new DirectoryBrowserSupport(build, new FilePath(fileParameter), Messages.FileParameterValue_IndexTitle(), "folder.png", false); diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java index 784fa47da20e..7d45fd63d749 100644 --- a/core/src/main/java/hudson/model/Hudson.java +++ b/core/src/main/java/hudson/model/Hudson.java @@ -38,14 +38,16 @@ import hudson.slaves.ComputerListener; import hudson.util.CopyOnWriteList; import hudson.util.FormValidation; +import io.jenkins.servlet.ServletContextWrapper; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.text.NumberFormat; import java.text.ParseException; import java.util.List; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.jvnet.hudson.reactor.ReactorException; import org.kohsuke.stapler.QueryParameter; @@ -78,14 +80,36 @@ public static Hudson getInstance() { return (Hudson) Jenkins.get(); } + /** + * @since TODO + */ public Hudson(File root, ServletContext context) throws IOException, InterruptedException, ReactorException { this(root, context, null); } + /** + * @deprecated use {@link #Hudson(File, ServletContext)} + */ + @Deprecated + public Hudson(File root, javax.servlet.ServletContext context) throws IOException, InterruptedException, ReactorException { + this(root, ServletContextWrapper.toJakartaServletContext(context)); + } + + /** + * @since TODO + */ public Hudson(File root, ServletContext context, PluginManager pluginManager) throws IOException, InterruptedException, ReactorException { super(root, context, pluginManager); } + /** + * @deprecated use {@link #Hudson(File, ServletContext, PluginManager)} + */ + @Deprecated + public Hudson(File root, javax.servlet.ServletContext context, PluginManager pluginManager) throws IOException, InterruptedException, ReactorException { + this(root, ServletContextWrapper.toJakartaServletContext(context), pluginManager); + } + /** * Gets all the installed {@link ItemListener}s. * @@ -173,8 +197,12 @@ public TopLevelItem getJobCaseInsensitive(String name) { */ @Deprecated @RequirePOST - public synchronized void doQuietDown(StaplerResponse rsp) throws IOException, ServletException { - doQuietDown().generateResponse(null, rsp, this); + public synchronized void doQuietDown(StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doQuietDown().generateResponse(null, StaplerResponse.toStaplerResponse2(rsp), this); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } /** @@ -184,7 +212,7 @@ public synchronized void doQuietDown(StaplerResponse rsp) throws IOException, Se * As on 1.267, moved to "/log/rss..." */ @Deprecated - public void doLogRss(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doLogRss(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { String qs = req.getQueryString(); rsp.sendRedirect2("./log/rss" + (qs == null ? "" : '?' + qs)); } @@ -194,7 +222,7 @@ public void doLogRss(StaplerRequest req, StaplerResponse rsp) throws IOException * Define your own check method, instead of relying on this generic one. */ @Deprecated - public void doFieldCheck(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doFieldCheck(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { doFieldCheck( fixEmpty(req.getParameter("value")), fixEmpty(req.getParameter("type")), diff --git a/core/src/main/java/hudson/model/Item.java b/core/src/main/java/hudson/model/Item.java index a57011579b15..838f4e6f75a7 100644 --- a/core/src/main/java/hudson/model/Item.java +++ b/core/src/main/java/hudson/model/Item.java @@ -41,7 +41,7 @@ import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import jenkins.util.io.OnMaster; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Basic configuration unit in Hudson. @@ -183,7 +183,7 @@ default String getRelativeNameFrom(@NonNull Item item) { /** * Returns the absolute URL of this item. This relies on the current - * {@link StaplerRequest} to figure out what the host name is, + * {@link StaplerRequest2} to figure out what the host name is, * so can be used only during processing client requests. * * @return diff --git a/core/src/main/java/hudson/model/ItemGroupMixIn.java b/core/src/main/java/hudson/model/ItemGroupMixIn.java index faa214dee621..62a46f395247 100644 --- a/core/src/main/java/hudson/model/ItemGroupMixIn.java +++ b/core/src/main/java/hudson/model/ItemGroupMixIn.java @@ -32,6 +32,9 @@ import hudson.util.CopyOnWriteMap; import hudson.util.Function1; import hudson.util.Secret; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -42,8 +45,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; @@ -51,7 +52,9 @@ import jenkins.security.NotReallyRoleSensitiveCallable; import jenkins.util.xml.XMLUtils; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.access.AccessDeniedException; import org.xml.sax.SAXException; @@ -140,8 +143,10 @@ public static <K, V extends Item> Map<K, V> loadChildren(ItemGroup parent, File /** * Creates a {@link TopLevelItem} for example from the submission of the {@code /lib/hudson/newFromList/form} tag * or throws an exception if it fails. + * + * @since TODO */ - public synchronized TopLevelItem createTopLevelItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized TopLevelItem createTopLevelItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { acl.checkPermission(Item.CREATE); TopLevelItem result; @@ -206,10 +211,22 @@ public synchronized TopLevelItem createTopLevelItem(StaplerRequest req, StaplerR return result; } + /** + * @deprecated use {@link #createTopLevelItem(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + public synchronized TopLevelItem createTopLevelItem(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + return createTopLevelItem(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Computes the redirection target URL for the newly created {@link TopLevelItem}. */ - protected String redirectAfterCreateItem(StaplerRequest req, TopLevelItem result) throws IOException { + protected String redirectAfterCreateItem(StaplerRequest2 req, TopLevelItem result) throws IOException { return req.getContextPath() + '/' + result.getUrl() + "configure"; } diff --git a/core/src/main/java/hudson/model/Job.java b/core/src/main/java/hudson/model/Job.java index 4bd28ff2e325..10637d666d68 100644 --- a/core/src/main/java/hudson/model/Job.java +++ b/core/src/main/java/hudson/model/Job.java @@ -24,8 +24,8 @@ package hudson.model; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; -import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; +import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static jakarta.servlet.http.HttpServletResponse.SC_NO_CONTENT; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.CheckForNull; @@ -69,6 +69,8 @@ import hudson.widgets.HistoryWidget; import hudson.widgets.HistoryWidget.Adapter; import hudson.widgets.Widget; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.awt.Color; import java.awt.Paint; import java.io.File; @@ -85,7 +87,6 @@ import java.util.SortedMap; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.BuildDiscarder; import jenkins.model.BuildDiscarderProperty; import jenkins.model.DirectlyModifiableTopLevelItemGroup; @@ -98,6 +99,7 @@ import jenkins.model.lazy.LazyBuildMixIn; import jenkins.scm.RunWithSCM; import jenkins.security.HexStringConfidentialKey; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.triggers.SCMTriggerItem; import jenkins.widgets.HasWidgets; import net.sf.json.JSONException; @@ -122,7 +124,9 @@ import org.kohsuke.args4j.CmdLineException; import org.kohsuke.stapler.StaplerOverridable; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -854,9 +858,43 @@ public RunT getNearestOldBuild(int n) { return m.get(m.firstKey()); } + /** + * @since TODO + */ + @Override + public Object getDynamic(String token, StaplerRequest2 req, + StaplerResponse2 rsp) { + if (Util.isOverridden(Job.class, getClass(), "getDynamic", String.class, StaplerRequest.class, StaplerResponse.class)) { + return getDynamic(token, StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } + try { + // try to interpret the token as build number + return getBuildByNumber(Integer.parseInt(token)); + } catch (NumberFormatException e) { + // try to map that to widgets + for (Widget w : getWidgets()) { + if (w.getUrlName().equals(token)) + return w; + } + + // is this a permalink? + for (Permalink p : getPermalinks()) { + if (p.getId().equals(token)) + return p.resolve(this); + } + + return super.getDynamic(token, req, rsp); + } + } + + /** + * @deprecated use {@link #getDynamic(String, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated @Override public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) { + // Intentionally not factoring this out into a common implementation method because it contains a call to super. try { // try to interpret the token as build number return getBuildByNumber(Integer.parseInt(token)); @@ -1092,7 +1130,7 @@ public PermalinkList getPermalinks() { * * @since 2.60 */ - public void doRssChangelog(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssChangelog(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { class FeedItem { ChangeLogSet.Entry e; int idx; @@ -1168,8 +1206,29 @@ public String getEntryAuthor(FeedItem entry) { } + /** + * @since TODO + */ + @Override + public ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { + if (Util.isOverridden(Job.class, getClass(), "doChildrenContextMenu", StaplerRequest.class, StaplerResponse.class)) { + return doChildrenContextMenu(StaplerRequest.fromStaplerRequest2(request), StaplerResponse.fromStaplerResponse2(response)); + } else { + return doChildrenContextMenuImpl(request, response); + } + } - @Override public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + /** + * @deprecated use {@link #doChildrenContextMenu(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + @Override + public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + return doChildrenContextMenuImpl(StaplerRequest.toStaplerRequest2(request), StaplerResponse.toStaplerResponse2(response)); + } + + private ContextMenu doChildrenContextMenuImpl(StaplerRequest2 request, StaplerResponse2 response) { // not sure what would be really useful here. This needs more thoughts. // for the time being, I'm starting with permalinks ContextMenu menu = new ContextMenu(); @@ -1327,8 +1386,8 @@ private HealthReport getBuildStabilityHealthReport() { * Accepts submission from the configuration page. */ @POST - public synchronized void doConfigSubmit(StaplerRequest req, - StaplerResponse rsp) throws IOException, ServletException, FormException { + public synchronized void doConfigSubmit(StaplerRequest2 req, + StaplerResponse2 rsp) throws IOException, ServletException, FormException { checkPermission(CONFIGURE); description = req.getParameter("description"); @@ -1373,15 +1432,32 @@ public synchronized void doConfigSubmit(StaplerRequest req, /** * Derived class can override this to perform additional config submission * work. + * + * @since TODO */ - protected void submit(StaplerRequest req, StaplerResponse rsp) + protected void submit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { + if (Util.isOverridden(Job.class, getClass(), "submit", StaplerRequest.class, StaplerResponse.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + protected void submit(StaplerRequest req, StaplerResponse rsp) + throws IOException, javax.servlet.ServletException, FormException { } /** * Accepts and serves the job description */ - public void doDescription(StaplerRequest req, StaplerResponse rsp) + public void doDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.getMethod().equals("GET")) { //read @@ -1407,7 +1483,7 @@ public void doDescription(StaplerRequest req, StaplerResponse rsp) /** * Returns the image that shows the current buildCommand status. */ - public void doBuildStatus(StaplerRequest req, StaplerResponse rsp) + public void doBuildStatus(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { rsp.sendRedirect2(req.getContextPath() + "/images/48x48/" + getBuildStatusUrl()); } @@ -1577,7 +1653,7 @@ private Calendar getLastBuildTime() { @RequirePOST public/* not synchronized. see renameTo() */void doDoRename( StaplerRequest req, StaplerResponse rsp) throws IOException, - ServletException { + javax.servlet.ServletException { String newName = req.getParameter("newName"); doConfirmRename(newName).generateResponse(req, rsp, null); } @@ -1589,12 +1665,12 @@ protected void checkRename(String newName) throws Failure { } } - public void doRssAll(StaplerRequest req, StaplerResponse rsp) + public void doRssAll(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds().newBuilds()); } - public void doRssFailed(StaplerRequest req, StaplerResponse rsp) + public void doRssFailed(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly().newBuilds()); } diff --git a/core/src/main/java/hudson/model/JobProperty.java b/core/src/main/java/hudson/model/JobProperty.java index 14ff87591fe9..70ef159547c0 100644 --- a/core/src/main/java/hudson/model/JobProperty.java +++ b/core/src/main/java/hudson/model/JobProperty.java @@ -27,6 +27,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionPoint; import hudson.Launcher; +import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.model.queue.SubTask; import hudson.tasks.BuildStep; @@ -41,6 +42,7 @@ import jenkins.model.OptionalJobProperty; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.ExportedBean; /** @@ -183,8 +185,28 @@ public Collection<?> getJobOverrides() { return Collections.emptyList(); } + /** + * @since TODO + */ + @Override + public JobProperty<?> reconfigure(StaplerRequest2 req, JSONObject form) throws FormException { + if (Util.isOverridden(JobProperty.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + /** + * @deprecated use {@link #reconfigure(StaplerRequest2, JSONObject)} + */ + @Deprecated @Override public JobProperty<?> reconfigure(StaplerRequest req, JSONObject form) throws FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private JobProperty<?> reconfigureImpl(StaplerRequest2 req, JSONObject form) throws FormException { return form == null ? null : getDescriptor().newInstance(req, form); } diff --git a/core/src/main/java/hudson/model/JobPropertyDescriptor.java b/core/src/main/java/hudson/model/JobPropertyDescriptor.java index 1f1c3aa7e6f0..eb9b990b7056 100644 --- a/core/src/main/java/hudson/model/JobPropertyDescriptor.java +++ b/core/src/main/java/hudson/model/JobPropertyDescriptor.java @@ -24,6 +24,7 @@ package hudson.model; +import hudson.Util; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; @@ -34,6 +35,7 @@ import net.sf.json.JSONObject; import org.jvnet.tiger_types.Types; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link Descriptor} for {@link JobProperty}. @@ -61,6 +63,23 @@ protected JobPropertyDescriptor() { * null to avoid setting an instance of {@link JobProperty} to the target project (or just use {@link OptionalJobProperty}) */ @Override + public JobProperty<?> newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { + if (Util.isOverridden(JobPropertyDescriptor.class, getClass(), "newInstance", StaplerRequest.class, JSONObject.class)) { + return newInstance(req != null ? StaplerRequest.fromStaplerRequest2(req) : null, formData); + } else { + // JobPropertyDescriptors are bit different in that we allow them even without any user-visible configuration parameter, + // so replace the lack of form data by an empty one. + if (formData.isNullObject()) formData = new JSONObject(); + + return super.newInstance(req, formData); + } + } + + /** + * @deprecated use {@link #newInstance(StaplerRequest2, JSONObject)} + */ + @Deprecated + @Override public JobProperty<?> newInstance(StaplerRequest req, JSONObject formData) throws FormException { // JobPropertyDescriptors are bit different in that we allow them even without any user-visible configuration parameter, // so replace the lack of form data by an empty one. diff --git a/core/src/main/java/hudson/model/Label.java b/core/src/main/java/hudson/model/Label.java index 88661c6df690..53c51db9cc4b 100644 --- a/core/src/main/java/hudson/model/Label.java +++ b/core/src/main/java/hudson/model/Label.java @@ -71,8 +71,8 @@ import org.antlr.v4.runtime.CommonTokenStream; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -548,7 +548,7 @@ public String toString() { } @Override - public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { ContextMenu menu = new ContextMenu(); for (Node node : getNodes()) { menu.add(node); diff --git a/core/src/main/java/hudson/model/ListView.java b/core/src/main/java/hudson/model/ListView.java index d8f6a8d48bcb..a2e25f1f1d1b 100644 --- a/core/src/main/java/hudson/model/ListView.java +++ b/core/src/main/java/hudson/model/ListView.java @@ -41,6 +41,8 @@ import hudson.views.ListViewColumn; import hudson.views.StatusFilter; import hudson.views.ViewJobFilter; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -55,7 +57,6 @@ import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import net.jcip.annotations.GuardedBy; import net.sf.json.JSONObject; @@ -67,7 +68,8 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; import org.springframework.security.access.AccessDeniedException; @@ -97,7 +99,7 @@ public class ListView extends View implements DirectlyModifiableView { /** * Whether to recurse in ItemGroups */ - private boolean recurse; + private volatile boolean recurse; /** * Compiled include pattern from the includeRegex string. @@ -357,7 +359,7 @@ public boolean isAddToCurrentView() { } } - private boolean needToAddToCurrentView(StaplerRequest req) throws ServletException { + private boolean needToAddToCurrentView(StaplerRequest2 req) throws ServletException { String json = req.getParameter("json"); if (json != null && !json.isEmpty()) { // Submitted via UI @@ -371,7 +373,7 @@ private boolean needToAddToCurrentView(StaplerRequest req) throws ServletExcepti @Override @POST - public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public Item doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { ItemGroup<? extends TopLevelItem> ig = getOwner().getItemGroup(); if (ig instanceof ModifiableItemGroup) { TopLevelItem item = ((ModifiableItemGroup<? extends TopLevelItem>) ig).doCreateItem(req, rsp); @@ -439,7 +441,32 @@ public HttpResponse doRemoveJobFromView(@QueryParameter String name) throws IOEx * Load view-specific properties here. */ @Override - protected void submit(StaplerRequest req) throws ServletException, FormException, IOException { + protected void submit(StaplerRequest2 req) throws ServletException, FormException, IOException { + if (Util.isOverridden(View.class, getClass(), "submit", StaplerRequest.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + submitImpl(req); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2)} + */ + @Deprecated + @Override + protected void submit(StaplerRequest req) throws javax.servlet.ServletException, FormException, IOException { + try { + submitImpl(StaplerRequest.toStaplerRequest2(req)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void submitImpl(StaplerRequest2 req) throws ServletException, FormException, IOException { JSONObject json = req.getSubmittedForm(); synchronized (this) { recurse = json.optBoolean("recurse", true); diff --git a/core/src/main/java/hudson/model/ManageJenkinsAction.java b/core/src/main/java/hudson/model/ManageJenkinsAction.java index c6c37a57662a..776b37c4f265 100644 --- a/core/src/main/java/hudson/model/ManageJenkinsAction.java +++ b/core/src/main/java/hudson/model/ManageJenkinsAction.java @@ -36,8 +36,8 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerFallback; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Adds the "Manage Jenkins" link to the top page. @@ -70,7 +70,7 @@ public Object getStaplerFallback() { } @Override - public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws JellyException, IOException { + public ContextMenu doContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws JellyException, IOException { return new ContextMenu().from(this, request, response, "index"); } @@ -80,7 +80,7 @@ public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse respons */ @Restricted(NoExternalUse.class) public void addContextMenuItem(ContextMenu menu, String url, String icon, String iconXml, String text, boolean post, boolean requiresConfirmation, Badge badge, String message) { - if (Stapler.getCurrentRequest().findAncestorObject(this.getClass()) != null || !Util.isSafeToRedirectTo(url)) { + if (Stapler.getCurrentRequest2().findAncestorObject(this.getClass()) != null || !Util.isSafeToRedirectTo(url)) { // Default behavior if the URL is absolute or scheme-relative, or the current object is an ancestor (i.e. would resolve correctly) menu.add(url, icon, iconXml, text, post, requiresConfirmation, badge, message); return; diff --git a/core/src/main/java/hudson/model/ModifiableItemGroup.java b/core/src/main/java/hudson/model/ModifiableItemGroup.java index 726a0455dc74..35e41305afb5 100644 --- a/core/src/main/java/hudson/model/ModifiableItemGroup.java +++ b/core/src/main/java/hudson/model/ModifiableItemGroup.java @@ -24,10 +24,15 @@ package hudson.model; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; +import jenkins.security.stapler.StaplerNotDispatchable; +import org.kohsuke.stapler.ReflectionUtils; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link ItemGroup} that is a general purpose container, which allows users and the rest of the program @@ -45,5 +50,45 @@ public interface ModifiableItemGroup<T extends Item> extends ItemGroup<T> { * The request format follows that of {@code <n:form xmlns:n="/lib/form">}. * */ - T doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException; + @StaplerNotDispatchable + default T doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (ReflectionUtils.isOverridden( + ModifiableItemGroup.class, + getClass(), + "doCreateItem", + StaplerRequest.class, + StaplerResponse.class)) { + try { + return doCreateItem(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + ModifiableItemGroup.class.getSimpleName() + ".doCreateItem methods"); + } + } + + /** + * @deprecated use {@link #doCreateItem(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + default T doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + if (ReflectionUtils.isOverridden( + ModifiableItemGroup.class, + getClass(), + "doCreateItem", + StaplerRequest2.class, + StaplerResponse2.class)) { + try { + return doCreateItem(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + ModifiableItemGroup.class.getSimpleName() + ".doCreateItem methods"); + } + } } diff --git a/core/src/main/java/hudson/model/MultiStageTimeSeries.java b/core/src/main/java/hudson/model/MultiStageTimeSeries.java index ea9d25a043c0..84963cde928f 100644 --- a/core/src/main/java/hudson/model/MultiStageTimeSeries.java +++ b/core/src/main/java/hudson/model/MultiStageTimeSeries.java @@ -26,6 +26,7 @@ import hudson.util.ChartUtil; import hudson.util.NoOverlapCategoryAxis; +import jakarta.servlet.ServletException; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; @@ -39,7 +40,6 @@ import java.util.List; import java.util.Locale; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; @@ -53,7 +53,9 @@ import org.jvnet.localizer.Localizable; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -298,8 +300,8 @@ protected void configurePlot(CategoryPlot plot) { * Renders this object as an image. */ @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { - ChartUtil.generateGraph(req, rsp, createChart(), 500, 400); + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { + ChartUtil.generateGraph(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp), createChart(), 500, 400); } } diff --git a/core/src/main/java/hudson/model/MyView.java b/core/src/main/java/hudson/model/MyView.java index bc98d9a55f7f..93c9967e0e86 100644 --- a/core/src/main/java/hudson/model/MyView.java +++ b/core/src/main/java/hudson/model/MyView.java @@ -26,18 +26,21 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; +import hudson.Util; import hudson.model.Descriptor.FormException; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -64,7 +67,7 @@ public boolean contains(TopLevelItem item) { @RequirePOST @Override - public TopLevelItem doCreateItem(StaplerRequest req, StaplerResponse rsp) + public TopLevelItem doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { ItemGroup<? extends TopLevelItem> ig = getOwner().getItemGroup(); if (ig instanceof ModifiableItemGroup) { @@ -85,7 +88,24 @@ public String getPostConstructLandingPage() { } @Override - protected void submit(StaplerRequest req) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest2 req) throws IOException, ServletException, FormException { + if (Util.isOverridden(MyView.class, getClass(), "submit", StaplerRequest.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + // noop + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2)} + */ + @Deprecated + @Override + protected void submit(StaplerRequest req) throws IOException, javax.servlet.ServletException, FormException { // noop } diff --git a/core/src/main/java/hudson/model/MyViewsProperty.java b/core/src/main/java/hudson/model/MyViewsProperty.java index 49fdfac48d2d..32ef03f73ecd 100644 --- a/core/src/main/java/hudson/model/MyViewsProperty.java +++ b/core/src/main/java/hudson/model/MyViewsProperty.java @@ -35,13 +35,13 @@ import hudson.util.FormValidation; import hudson.views.MyViewsTabBar; import hudson.views.ViewsTabBar; +import jakarta.servlet.ServletException; import java.io.IOException; import java.text.ParseException; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import net.sf.json.JSONObject; @@ -54,8 +54,8 @@ import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerFallback; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; /** @@ -196,7 +196,7 @@ public HttpResponse doIndex() { } @POST - public synchronized void doCreateView(StaplerRequest req, StaplerResponse rsp) + public synchronized void doCreateView(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, ParseException, FormException { checkPermission(View.CREATE); addView(View.create(req, rsp, this)); @@ -276,7 +276,7 @@ public UserProperty newInstance(User user) { } @Override - public UserProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { + public UserProperty reconfigure(StaplerRequest2 req, JSONObject form) throws FormException { req.bindJSON(this, form); return this; } diff --git a/core/src/main/java/hudson/model/Node.java b/core/src/main/java/hudson/model/Node.java index 8ba16e77d4d3..55cacd269133 100644 --- a/core/src/main/java/hudson/model/Node.java +++ b/core/src/main/java/hudson/model/Node.java @@ -79,6 +79,7 @@ import org.kohsuke.stapler.BindInterceptor; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.springframework.security.core.Authentication; @@ -560,8 +561,25 @@ public ACL getACL() { return Jenkins.get().getAuthorizationStrategy().getACL(this); } + @Override + public Node reconfigure(@NonNull final StaplerRequest2 req, JSONObject form) throws FormException { + if (Util.isOverridden(Node.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + /** + * @deprecated use {@link #reconfigure(StaplerRequest2, JSONObject)} + */ + @Deprecated @Override public Node reconfigure(@NonNull final StaplerRequest req, JSONObject form) throws FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private Node reconfigureImpl(@NonNull final StaplerRequest2 req, JSONObject form) throws FormException { if (form == null) return null; final JSONObject jsonForProperties = form.optJSONObject("nodeProperties"); diff --git a/core/src/main/java/hudson/model/PaneStatusProperties.java b/core/src/main/java/hudson/model/PaneStatusProperties.java index 4807020ca714..12cb0003d671 100644 --- a/core/src/main/java/hudson/model/PaneStatusProperties.java +++ b/core/src/main/java/hudson/model/PaneStatusProperties.java @@ -6,8 +6,8 @@ import hudson.Extension; import hudson.model.userproperty.UserPropertyCategory; import hudson.util.PersistedList; +import jakarta.servlet.http.HttpSession; import java.io.IOException; -import javax.servlet.http.HttpSession; import org.jenkinsci.Symbol; import org.kohsuke.stapler.Stapler; @@ -70,13 +70,13 @@ private static class PaneStatusPropertiesSessionFallback extends PaneStatusPrope @Override public boolean isCollapsed(String paneId) { - final HttpSession session = Stapler.getCurrentRequest().getSession(); + final HttpSession session = Stapler.getCurrentRequest2().getSession(); return session.getAttribute(format(attribute, paneId)) != null; } @Override public boolean toggleCollapsed(String paneId) { - final HttpSession session = Stapler.getCurrentRequest().getSession(); + final HttpSession session = Stapler.getCurrentRequest2().getSession(); final String property = format(attribute, paneId); final Object collapsed = session.getAttribute(property); if (collapsed == null) { diff --git a/core/src/main/java/hudson/model/ParameterDefinition.java b/core/src/main/java/hudson/model/ParameterDefinition.java index 262b632ab5a2..29653c0250f4 100644 --- a/core/src/main/java/hudson/model/ParameterDefinition.java +++ b/core/src/main/java/hudson/model/ParameterDefinition.java @@ -41,6 +41,7 @@ import net.sf.json.JSONObject; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -59,7 +60,7 @@ * <p> * Three classes are used to model build parameters. First is the * {@link ParameterDescriptor}, which tells Hudson what kind of implementations are - * available. From {@link ParameterDescriptor#newInstance(StaplerRequest, JSONObject)}, + * available. From {@link ParameterDescriptor#newInstance(StaplerRequest2, JSONObject)}, * Hudson creates {@link ParameterDefinition}s based on the job configuration. * For example, if the user defines two string parameters "database-type" and * "appserver-type", we'll get two {@link StringParameterDefinition} instances @@ -69,7 +70,7 @@ * When a job is configured with {@link ParameterDefinition} (or more precisely, * {@link ParametersDefinitionProperty}, which in turns retains {@link ParameterDefinition}s), * user would have to enter the values for the defined build parameters. - * The {@link #createValue(StaplerRequest, JSONObject)} method is used to convert this + * The {@link #createValue(StaplerRequest2, JSONObject)} method is used to convert this * form submission into {@link ParameterValue} objects, which are then accessible * during a build. * @@ -85,12 +86,12 @@ * <h3>config.jelly</h3> * {@link ParameterDefinition} class uses {@code config.jelly} to contribute a form * fragment in the job configuration screen. Values entered there are fed back to - * {@link ParameterDescriptor#newInstance(StaplerRequest, JSONObject)} to create {@link ParameterDefinition}s. + * {@link ParameterDescriptor#newInstance(StaplerRequest2, JSONObject)} to create {@link ParameterDefinition}s. * * <h3>index.jelly</h3> * The {@code index.jelly} view contributes a form fragment in the page where the user * enters actual values of parameters for a build. The result of this form submission - * is then fed to {@link ParameterDefinition#createValue(StaplerRequest, JSONObject)} to + * is then fed to {@link ParameterDefinition#createValue(StaplerRequest2, JSONObject)} to * create {@link ParameterValue}s. * * @see StringParameterDefinition @@ -183,14 +184,37 @@ public ParameterDescriptor getDescriptor() { * and submits it to the server. */ @CheckForNull - public abstract ParameterValue createValue(StaplerRequest req, JSONObject jo); + public /* abstract */ ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { + return Util.ifOverridden( + () -> createValue(StaplerRequest.fromStaplerRequest2(req), jo), + ParameterDefinition.class, + getClass(), + "createValue", + StaplerRequest.class, + JSONObject.class); + } + + /** + * @deprecated use {@link #createValue(StaplerRequest2, JSONObject)} + */ + @CheckForNull + @Deprecated + public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + return Util.ifOverridden( + () -> createValue(StaplerRequest.toStaplerRequest2(req), jo), + ParameterDefinition.class, + getClass(), + "createValue", + StaplerRequest2.class, + JSONObject.class); + } /** * Create a parameter value from a GET with query string. * If no value is available in the request, it returns a default value if possible, or null. * * <p> - * Unlike {@link #createValue(StaplerRequest, JSONObject)}, this method is intended to support + * Unlike {@link #createValue(StaplerRequest2, JSONObject)}, this method is intended to support * the programmatic POST-ing of the build URL. This form is less expressive (as it doesn't support * the tree form), but it's more scriptable. * @@ -202,8 +226,28 @@ public ParameterDescriptor getDescriptor() { * If the parameter is deemed required but was missing in the submission. */ @CheckForNull - public abstract ParameterValue createValue(StaplerRequest req); + public /* abstract */ ParameterValue createValue(StaplerRequest2 req) { + return Util.ifOverridden( + () -> createValue(StaplerRequest.fromStaplerRequest2(req)), + ParameterDefinition.class, + getClass(), + "createValue", + StaplerRequest.class); + } + /** + * @deprecated use {@link #createValue(StaplerRequest2)} + */ + @CheckForNull + @Deprecated + public ParameterValue createValue(StaplerRequest req) { + return Util.ifOverridden( + () -> createValue(StaplerRequest.toStaplerRequest2(req)), + ParameterDefinition.class, + getClass(), + "createValue", + StaplerRequest2.class); + } /** * Create a parameter value from the string given in the CLI. diff --git a/core/src/main/java/hudson/model/ParameterValue.java b/core/src/main/java/hudson/model/ParameterValue.java index 5da680b3bb76..2fd481446f4b 100644 --- a/core/src/main/java/hudson/model/ParameterValue.java +++ b/core/src/main/java/hudson/model/ParameterValue.java @@ -43,14 +43,14 @@ import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; /** * A value for a parameter in a build. * - * Created by {@link ParameterDefinition#createValue(StaplerRequest, JSONObject)} for + * Created by {@link ParameterDefinition#createValue(StaplerRequest2, JSONObject)} for * a particular build (although this 'owner' build object is passed in for every method * call as a parameter so that the parameter won't have to persist it.) * @@ -240,7 +240,7 @@ public VariableResolver<String> createVariableResolver(AbstractBuild<?, ?> build * @deprecated since 2008-09-20. * parameter definition may change any time. So if you find yourself * in need of accessing the information from {@link ParameterDefinition}, - * instead copy them in {@link ParameterDefinition#createValue(StaplerRequest, JSONObject)} + * instead copy them in {@link ParameterDefinition#createValue(StaplerRequest2, JSONObject)} * into {@link ParameterValue}. */ @Deprecated diff --git a/core/src/main/java/hudson/model/ParametersDefinitionProperty.java b/core/src/main/java/hudson/model/ParametersDefinitionProperty.java index 66a70047e89d..a9019e5a8f1f 100644 --- a/core/src/main/java/hudson/model/ParametersDefinitionProperty.java +++ b/core/src/main/java/hudson/model/ParametersDefinitionProperty.java @@ -25,8 +25,8 @@ package hudson.model; -import static javax.servlet.http.HttpServletResponse.SC_CREATED; -import static javax.servlet.http.HttpServletResponse.SC_SEE_OTHER; +import static jakarta.servlet.http.HttpServletResponse.SC_CREATED; +import static jakarta.servlet.http.HttpServletResponse.SC_SEE_OTHER; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; @@ -35,6 +35,8 @@ import hudson.model.Queue.WaitingItem; import hudson.model.queue.ScheduleResult; import hudson.util.AlternativeUiTextProvider; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.AbstractList; import java.util.ArrayList; @@ -43,7 +45,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.OptionalJobProperty; import jenkins.model.ParameterizedJobMixIn; @@ -56,7 +57,9 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -133,19 +136,23 @@ public Collection<Action> getJobActions(AbstractProject<?, ?> job) { return (AbstractProject<?, ?>) owner; } - /** @deprecated use {@link #_doBuild(StaplerRequest, StaplerResponse, TimeDuration)} */ + /** @deprecated use {@link #_doBuild(StaplerRequest2, StaplerResponse2, TimeDuration)} */ @Deprecated - public void _doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - _doBuild(req, rsp, TimeDuration.fromString(req.getParameter("delay"))); + public void _doBuild(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + _doBuild(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), TimeDuration.fromString(req.getParameter("delay"))); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } /** * Interprets the form submission and schedules a build for a parameterized job. * * <p> - * This method is supposed to be invoked from {@link ParameterizedJobMixIn#doBuild(StaplerRequest, StaplerResponse, TimeDuration)}. + * This method is supposed to be invoked from {@link ParameterizedJobMixIn#doBuild(StaplerRequest2, StaplerResponse2, TimeDuration)}. */ - public void _doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { + public void _doBuild(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { if (delay == null) delay = new TimeDuration(TimeUnit.MILLISECONDS.convert(getJob().getQuietPeriod(), TimeUnit.SECONDS)); @@ -185,13 +192,17 @@ public void _doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter Ti rsp.sendRedirect("."); } - /** @deprecated use {@link #buildWithParameters(StaplerRequest, StaplerResponse, TimeDuration)} */ + /** @deprecated use {@link #buildWithParameters(StaplerRequest2, StaplerResponse2, TimeDuration)} */ @Deprecated - public void buildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - buildWithParameters(req, rsp, TimeDuration.fromString(req.getParameter("delay"))); + public void buildWithParameters(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + buildWithParameters(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), TimeDuration.fromString(req.getParameter("delay"))); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } - public void buildWithParameters(StaplerRequest req, StaplerResponse rsp, @CheckForNull TimeDuration delay) throws IOException, ServletException { + public void buildWithParameters(StaplerRequest2 req, StaplerResponse2 rsp, @CheckForNull TimeDuration delay) throws IOException, ServletException { List<ParameterValue> values = new ArrayList<>(); for (ParameterDefinition d : parameterDefinitions) { ParameterValue value = d.createValue(req); @@ -232,7 +243,7 @@ public ParameterDefinition getParameterDefinition(String name) { @Symbol("parameters") public static class DescriptorImpl extends OptionalJobPropertyDescriptor { @Override - public ParametersDefinitionProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public ParametersDefinitionProperty newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { ParametersDefinitionProperty prop = (ParametersDefinitionProperty) super.newInstance(req, formData); if (prop != null && prop.parameterDefinitions.isEmpty()) { return null; diff --git a/core/src/main/java/hudson/model/PasswordParameterDefinition.java b/core/src/main/java/hudson/model/PasswordParameterDefinition.java index 8074740088f0..901f1ee66712 100644 --- a/core/src/main/java/hudson/model/PasswordParameterDefinition.java +++ b/core/src/main/java/hudson/model/PasswordParameterDefinition.java @@ -36,7 +36,7 @@ import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Parameter whose value is a {@link Secret} and is hidden from the UI. @@ -80,7 +80,7 @@ public ParameterValue createValue(String value) { } @Override - public PasswordParameterValue createValue(StaplerRequest req, JSONObject jo) { + public PasswordParameterValue createValue(StaplerRequest2 req, JSONObject jo) { PasswordParameterValue value = req.bindJSON(PasswordParameterValue.class, jo); if (value.getValue().getPlainText().equals(DEFAULT_VALUE)) { value = new PasswordParameterValue(getName(), getDefaultValue()); diff --git a/core/src/main/java/hudson/model/Project.java b/core/src/main/java/hudson/model/Project.java index 7dc8b692d940..eb31add23938 100644 --- a/core/src/main/java/hudson/model/Project.java +++ b/core/src/main/java/hudson/model/Project.java @@ -40,6 +40,8 @@ import hudson.triggers.SCMTrigger; import hudson.triggers.Trigger; import hudson.util.DescribableList; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.Collection; import java.util.HashSet; @@ -49,11 +51,12 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.triggers.SCMTriggerItem; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * Buildable software project. @@ -223,10 +226,39 @@ public MavenInstallation inferMavenInstallation() { // actions // // + + /** + * @since TODO + */ + @Override + protected void submit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { + if (Util.isOverridden(Project.class, getClass(), "submit", StaplerRequest.class, StaplerResponse.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + super.submit(req, rsp); + submitImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated @Override - protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException, FormException { super.submit(req, rsp); + try { + submitImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw new javax.servlet.ServletException(e); + } + } + private void submitImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { JSONObject json = req.getSubmittedForm(); getBuildWrappersList().rebuild(req, json, BuildWrappers.getFor(this)); diff --git a/core/src/main/java/hudson/model/ProxyView.java b/core/src/main/java/hudson/model/ProxyView.java index b3d19282752c..41aa51df389e 100644 --- a/core/src/main/java/hudson/model/ProxyView.java +++ b/core/src/main/java/hudson/model/ProxyView.java @@ -29,9 +29,10 @@ import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.util.FormValidation; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.Collection; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; @@ -39,7 +40,8 @@ import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerFallback; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -98,7 +100,32 @@ public TopLevelItem getItem(String name) { } @Override - protected void submit(StaplerRequest req) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest2 req) throws IOException, ServletException, FormException { + if (Util.isOverridden(ProxyView.class, getClass(), "submit", StaplerRequest.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + submitImpl(req); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2)} + */ + @Deprecated + @Override + protected void submit(StaplerRequest req) throws IOException, javax.servlet.ServletException, FormException { + try { + submitImpl(StaplerRequest.toStaplerRequest2(req)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void submitImpl(StaplerRequest2 req) throws ServletException, FormException { String proxiedViewName = req.getSubmittedForm().getString("proxiedViewName"); if (Jenkins.get().getView(proxiedViewName) == null) { throw new FormException("Not an existing global view", "proxiedViewName"); @@ -108,7 +135,7 @@ protected void submit(StaplerRequest req) throws IOException, ServletException, @RequirePOST @Override - public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public Item doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { return getProxiedView().doCreateItem(req, rsp); } @@ -139,7 +166,7 @@ public String getDisplayName() { @Override public boolean isInstantiable() { // doesn't make sense to add a ProxyView to the global views - return !(Stapler.getCurrentRequest().findAncestorObject(ViewGroup.class) instanceof Jenkins); + return !(Stapler.getCurrentRequest2().findAncestorObject(ViewGroup.class) instanceof Jenkins); } } diff --git a/core/src/main/java/hudson/model/Queue.java b/core/src/main/java/hudson/model/Queue.java index 0d299fb9426d..a8d4ca08ea0d 100644 --- a/core/src/main/java/hudson/model/Queue.java +++ b/core/src/main/java/hudson/model/Queue.java @@ -76,6 +76,8 @@ import hudson.util.ConsistentHash; import hudson.util.Futures; import hudson.util.XStream2; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; @@ -107,8 +109,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.model.queue.AsynchronousExecution; import jenkins.model.queue.CompositeCauseOfBlockage; @@ -130,7 +130,7 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -2415,7 +2415,7 @@ public Api getApi() throws AccessDeniedException { } } - public HttpResponse doIndex(StaplerRequest req) { + public HttpResponse doIndex(StaplerRequest2 req) { return HttpResponses.text("Queue item exists. For details check, for example, " + req.getRequestURI() + "api/json?tree=cancelled,executable[url]"); } diff --git a/core/src/main/java/hudson/model/RSS.java b/core/src/main/java/hudson/model/RSS.java index 19727656e729..bb41c8af10a2 100644 --- a/core/src/main/java/hudson/model/RSS.java +++ b/core/src/main/java/hudson/model/RSS.java @@ -26,13 +26,17 @@ import hudson.FeedAdapter; import hudson.util.RunList; +import io.jenkins.servlet.ServletExceptionWrapper; +import io.jenkins.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Collection; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * RSS related code. @@ -52,8 +56,9 @@ public final class RSS { * Entries to be listed in the RSS feed. * @param adapter * Controls how to render entries to RSS. + * @since TODO */ - public static <E> void forwardToRss(String title, String url, Collection<? extends E> entries, FeedAdapter<E> adapter, StaplerRequest req, HttpServletResponse rsp) throws IOException, ServletException { + public static <E> void forwardToRss(String title, String url, Collection<? extends E> entries, FeedAdapter<E> adapter, StaplerRequest2 req, HttpServletResponse rsp) throws IOException, ServletException { req.setAttribute("adapter", adapter); req.setAttribute("title", title); req.setAttribute("url", url); @@ -72,6 +77,18 @@ public static <E> void forwardToRss(String title, String url, Collection<? exten req.getView(Jenkins.get(), "/hudson/" + flavor + ".jelly").forward(req, rsp); } + /** + * @deprecated use {@link #forwardToRss(String, String, Collection, FeedAdapter, StaplerRequest2, HttpServletResponse)} + */ + @Deprecated + public static <E> void forwardToRss(String title, String url, Collection<? extends E> entries, FeedAdapter<E> adapter, StaplerRequest req, javax.servlet.http.HttpServletResponse rsp) throws IOException, javax.servlet.ServletException { + try { + forwardToRss(title, url, entries, adapter, StaplerRequest.toStaplerRequest2(req), HttpServletResponseWrapper.toJakartaHttpServletResponse(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Sends the RSS feed to the client using a default feed adapter. * @@ -81,12 +98,25 @@ public static <E> void forwardToRss(String title, String url, Collection<? exten * URL of the model object that owns this feed. Relative to the context root. * @param runList * Entries to be listed in the RSS feed. - * @since 2.215 + * @since TODO */ - public static void rss(StaplerRequest req, StaplerResponse rsp, String title, String url, RunList runList) throws IOException, ServletException { + public static void rss(StaplerRequest2 req, StaplerResponse2 rsp, String title, String url, RunList runList) throws IOException, ServletException { rss(req, rsp, title, url, runList, null); } + /** + * @deprecated use {@link #rss(StaplerRequest2, StaplerResponse2, String, String, RunList)} + * @since 2.215 + */ + @Deprecated + public static void rss(StaplerRequest req, StaplerResponse rsp, String title, String url, RunList runList) throws IOException, javax.servlet.ServletException { + try { + rss(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), title, url, runList, null); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Sends the RSS feed to the client using a specific feed adapter. * @@ -98,10 +128,23 @@ public static void rss(StaplerRequest req, StaplerResponse rsp, String title, St * Entries to be listed in the RSS feed. * @param feedAdapter * Controls how to render entries to RSS. - * @since 2.215 + * @since TODO */ - public static void rss(StaplerRequest req, StaplerResponse rsp, String title, String url, RunList runList, FeedAdapter<Run> feedAdapter) throws IOException, ServletException { + public static void rss(StaplerRequest2 req, StaplerResponse2 rsp, String title, String url, RunList runList, FeedAdapter<Run> feedAdapter) throws IOException, ServletException { final FeedAdapter<Run> feedAdapter_ = feedAdapter == null ? Run.FEED_ADAPTER : feedAdapter; forwardToRss(title, url, runList, feedAdapter_, req, rsp); } + + /** + * @deprecated use {@link #rss(StaplerRequest2, StaplerResponse2, String, String, RunList, FeedAdapter)} + * @since 2.215 + */ + @Deprecated + public static void rss(StaplerRequest req, StaplerResponse rsp, String title, String url, RunList runList, FeedAdapter<Run> feedAdapter) throws IOException, javax.servlet.ServletException { + try { + rss(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), title, url, runList, feedAdapter); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } } diff --git a/core/src/main/java/hudson/model/ReconfigurableDescribable.java b/core/src/main/java/hudson/model/ReconfigurableDescribable.java index 1747fdb452c1..c044391b77ad 100644 --- a/core/src/main/java/hudson/model/ReconfigurableDescribable.java +++ b/core/src/main/java/hudson/model/ReconfigurableDescribable.java @@ -26,10 +26,13 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.slaves.NodeProperty; +import jenkins.security.stapler.StaplerNotDispatchable; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Marks modern {@link Describable}s that allow the current instances to pass information down to the next @@ -44,7 +47,7 @@ * <strong>Invisible Property:</strong> * This mechanism can be used to create an entirely invisible {@link Describable}, which is handy * for {@link NodeProperty}, {@link JobProperty}, etc. To do so, define an empty config.jelly to prevent it from - * showing up in the config UI, then implement {@link #reconfigure(StaplerRequest, JSONObject)} + * showing up in the config UI, then implement {@link #reconfigure(StaplerRequest2, JSONObject)} * and simply return {@code this}. * * <p> @@ -78,5 +81,29 @@ public interface ReconfigurableDescribable<T extends ReconfigurableDescribable<T * @return * The new instance. To not to create an instance of a describable, return null. */ - @CheckForNull T reconfigure(@NonNull StaplerRequest req, @CheckForNull JSONObject form) throws FormException; + @CheckForNull + @StaplerNotDispatchable + default T reconfigure(@NonNull StaplerRequest2 req, @CheckForNull JSONObject form) throws FormException { + if (Util.isOverridden(ReconfigurableDescribable.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + ReconfigurableDescribable.class.getSimpleName() + ".reconfigure methods"); + } + } + + /** + * @deprecated use {@link #reconfigure(StaplerRequest2, JSONObject)} + */ + @CheckForNull + @Deprecated + @StaplerNotDispatchable + default T reconfigure(@NonNull StaplerRequest req, @CheckForNull JSONObject form) throws FormException { + if (Util.isOverridden(ReconfigurableDescribable.class, getClass(), "reconfigure", StaplerRequest2.class, JSONObject.class)) { + return reconfigure(StaplerRequest.toStaplerRequest2(req), form); + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + ReconfigurableDescribable.class.getSimpleName() + ".reconfigure methods"); + } + } } diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index 33658252b922..c6eedc42785f 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -68,6 +68,9 @@ import hudson.util.LogTaskListener; import hudson.util.ProcessTree; import hudson.util.XStream2; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; @@ -106,8 +109,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.GZIPInputStream; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.ArtifactManager; import jenkins.model.ArtifactManagerConfiguration; import jenkins.model.ArtifactManagerFactory; @@ -119,6 +120,7 @@ import jenkins.model.lazy.BuildReference; import jenkins.model.lazy.LazyBuildMixIn; import jenkins.security.MasterToSlaveCallable; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import jenkins.util.VirtualFile; import jenkins.util.io.OnMaster; @@ -132,7 +134,9 @@ import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -1043,7 +1047,7 @@ protected void dropLinks() { // RUN may be accessed using permalinks, as "/lastSuccessful" or other, so try to retrieve this base URL // looking for "this" in the current request ancestors // @see also {@link AbstractItem#getUrl} - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req != null) { String seed = Functions.getNearestAncestorUrl(req, this); if (seed != null) { @@ -2157,7 +2161,7 @@ private String convertBytesToString(List<Byte> bytes) { return new String(byteArray, getCharset()); } - public void doBuildStatus(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doBuildStatus(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { rsp.sendRedirect2(req.getContextPath() + "/images/48x48/" + getBuildStatusUrl()); } @@ -2260,7 +2264,7 @@ public abstract static class StatusSummarizer implements ExtensionPoint { /** * Returns the build number in the body. */ - public void doBuildNumber(StaplerResponse rsp) throws IOException { + public void doBuildNumber(StaplerResponse2 rsp) throws IOException { rsp.setContentType("text/plain"); rsp.setCharacterEncoding("US-ASCII"); rsp.setStatus(HttpServletResponse.SC_OK); @@ -2270,7 +2274,7 @@ public void doBuildNumber(StaplerResponse rsp) throws IOException { /** * Returns the build time stamp in the body. */ - public void doBuildTimestamp(StaplerRequest req, StaplerResponse rsp, @QueryParameter String format) throws IOException { + public void doBuildTimestamp(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String format) throws IOException { rsp.setContentType("text/plain"); rsp.setCharacterEncoding("US-ASCII"); rsp.setStatus(HttpServletResponse.SC_OK); @@ -2282,8 +2286,27 @@ public void doBuildTimestamp(StaplerRequest req, StaplerResponse rsp, @QueryPara /** * Sends out the raw console output. + * + * @since TODO */ + public void doConsoleText(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { + if (Util.isOverridden(Run.class, getClass(), "doConsoleText", StaplerRequest.class, StaplerResponse.class)) { + doConsoleText(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + doConsoleTextImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doConsoleText(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable public void doConsoleText(StaplerRequest req, StaplerResponse rsp) throws IOException { + doConsoleTextImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doConsoleTextImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { rsp.setContentType("text/plain;charset=UTF-8"); try (InputStream input = getLogInputStream(); OutputStream os = rsp.getOutputStream(); @@ -2299,7 +2322,7 @@ public void doConsoleText(StaplerRequest req, StaplerResponse rsp) throws IOExce */ @Deprecated public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOException { - getLogText().doProgressText(req, rsp); + getLogText().doProgressText(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); } /** @@ -2320,7 +2343,7 @@ public boolean canToggleLogKeep() { } @RequirePOST - public void doToggleLogKeep(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doToggleLogKeep(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { keepLog(!keepLog); rsp.forwardToPreviousPage(req); } @@ -2341,9 +2364,37 @@ public void keepLog(boolean newValue) throws IOException { /** * Deletes the build when the button is pressed. + * + * @since TODO */ @RequirePOST - public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doDoDelete(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Run.class, getClass(), "doDoDelete", StaplerRequest.class, StaplerResponse.class)) { + try { + doDoDelete(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + return; + } else { + doDoDeleteImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doDoDelete(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doDoDeleteImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doDoDeleteImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { checkPermission(DELETE); // We should not simply delete the build if it has been explicitly @@ -2376,7 +2427,7 @@ public void setDescription(String description) throws IOException { * Accepts the new description. */ @RequirePOST - public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { setDescription(req.getParameter("description")); rsp.sendRedirect("."); // go to the top page } @@ -2507,7 +2558,7 @@ public long getEstimatedDuration() { } @POST - public @NonNull HttpResponse doConfigSubmit(StaplerRequest req) throws IOException, ServletException, FormException { + public @NonNull HttpResponse doConfigSubmit(StaplerRequest2 req) throws IOException, ServletException, FormException { checkPermission(UPDATE); try (BulkChange bc = new BulkChange(this)) { JSONObject json = req.getSubmittedForm(); @@ -2625,9 +2676,27 @@ public String getEntryAuthor(Run entry) { } } + @Override + public Object getDynamic(String token, StaplerRequest2 req, StaplerResponse2 rsp) { + if (Util.isOverridden(Run.class, getClass(), "getDynamic", String.class, StaplerRequest.class, StaplerResponse.class)) { + return getDynamic(token, StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + Object returnedResult = super.getDynamic(token, req, rsp); + return getDynamicImpl(token, returnedResult); + } + } + + /** + * @deprecated use {@link #getDynamic(String, StaplerRequest2, StaplerResponse2)} + */ + @Deprecated @Override public Object getDynamic(String token, StaplerRequest req, StaplerResponse rsp) { Object returnedResult = super.getDynamic(token, req, rsp); + return getDynamicImpl(token, returnedResult); + } + + private Object getDynamicImpl(String token, Object returnedResult) { if (returnedResult == null) { //check transient actions too for (Action action : getTransientActions()) { @@ -2669,7 +2738,7 @@ public Object getTarget() { public static class RedirectUp { - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { // Compromise to handle both browsers (auto-redirect) and programmatic access // (want accurate 404 response).. send 404 with javascript to redirect browsers. rsp.setStatus(HttpServletResponse.SC_NOT_FOUND); diff --git a/core/src/main/java/hudson/model/RunParameterDefinition.java b/core/src/main/java/hudson/model/RunParameterDefinition.java index 9aec159686b9..487d895839dd 100644 --- a/core/src/main/java/hudson/model/RunParameterDefinition.java +++ b/core/src/main/java/hudson/model/RunParameterDefinition.java @@ -38,7 +38,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; public class RunParameterDefinition extends SimpleParameterDefinition { @@ -155,7 +155,7 @@ public String getHelpFile() { } @Override - public ParameterDefinition newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public ParameterDefinition newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { return req.bindJSON(RunParameterDefinition.class, formData); } @@ -202,7 +202,7 @@ public ParameterValue getDefaultParameterValue() { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { RunParameterValue value = req.bindJSON(RunParameterValue.class, jo); value.setDescription(getDescription()); return value; diff --git a/core/src/main/java/hudson/model/SimpleParameterDefinition.java b/core/src/main/java/hudson/model/SimpleParameterDefinition.java index 0be175bb4a86..f52f9a338922 100644 --- a/core/src/main/java/hudson/model/SimpleParameterDefinition.java +++ b/core/src/main/java/hudson/model/SimpleParameterDefinition.java @@ -5,7 +5,7 @@ import hudson.cli.CLICommand; import java.io.IOException; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Convenient base class for {@link ParameterDefinition} whose value can be represented in a context-independent single string token. @@ -31,7 +31,7 @@ protected SimpleParameterDefinition(@NonNull String name, @CheckForNull String d public abstract ParameterValue createValue(String value); @Override - public final ParameterValue createValue(StaplerRequest req) { + public final ParameterValue createValue(StaplerRequest2 req) { String[] value = req.getParameterValues(getName()); if (value == null) { return getDefaultParameterValue(); diff --git a/core/src/main/java/hudson/model/Slave.java b/core/src/main/java/hudson/model/Slave.java index 4ad75e039386..588dbf70b40d 100644 --- a/core/src/main/java/hudson/model/Slave.java +++ b/core/src/main/java/hudson/model/Slave.java @@ -51,6 +51,7 @@ import hudson.util.ClockDifference; import hudson.util.DescribableList; import hudson.util.FormValidation; +import jakarta.servlet.ServletException; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -69,7 +70,6 @@ import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; import jenkins.slaves.WorkspaceLocator; @@ -80,8 +80,8 @@ import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Information about a Hudson agent node. @@ -418,7 +418,7 @@ public JnlpJar(String fileName) { this.fileName = fileName; } - public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doIndex(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { URLConnection con = connect(); // since we end up redirecting users to jnlpJars/foo.jar/, set the content disposition // so that browsers can download them in the right file name. @@ -430,7 +430,7 @@ public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { doIndex(req, rsp); } @@ -465,7 +465,7 @@ public URL getURL() throws IOException { } } - URL res = Jenkins.get().servletContext.getResource("/WEB-INF/" + name); + URL res = Jenkins.get().getServletContext().getResource("/WEB-INF/" + name); if (res == null) { throw new FileNotFoundException(name); // giving up } else { @@ -622,7 +622,7 @@ public FormValidation doCheckNumExecutors(@QueryParameter String value) { /** * Performs syntactical check on the remote FS for agents. */ - public FormValidation doCheckRemoteFS(@QueryParameter String value) throws IOException, ServletException { + public FormValidation doCheckRemoteFS(@QueryParameter String value) throws IOException { if (Util.fixEmptyAndTrim(value) == null) return FormValidation.error(Messages.Slave_Remote_Director_Mandatory()); diff --git a/core/src/main/java/hudson/model/StockStatusIcon.java b/core/src/main/java/hudson/model/StockStatusIcon.java index 00ce50b0453b..4fb1a9bfa007 100644 --- a/core/src/main/java/hudson/model/StockStatusIcon.java +++ b/core/src/main/java/hudson/model/StockStatusIcon.java @@ -29,9 +29,9 @@ public StockStatusIcon(String image, Localizable description) { @Override public String getImageOf(String size) { if (image.endsWith(".svg")) { - return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH + "/images/svgs/" + image; + return Stapler.getCurrentRequest2().getContextPath() + Jenkins.RESOURCE_PATH + "/images/svgs/" + image; } else { - return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH + + return Stapler.getCurrentRequest2().getContextPath() + Jenkins.RESOURCE_PATH + "/images/" + size + "/" + image; } } diff --git a/core/src/main/java/hudson/model/StringParameterDefinition.java b/core/src/main/java/hudson/model/StringParameterDefinition.java index 8a5dfa9f1b04..160e1b1a9c0c 100644 --- a/core/src/main/java/hudson/model/StringParameterDefinition.java +++ b/core/src/main/java/hudson/model/StringParameterDefinition.java @@ -36,7 +36,7 @@ import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Parameter whose value is a string value. @@ -147,7 +147,7 @@ public String getHelpFile() { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { StringParameterValue value = req.bindJSON(StringParameterValue.class, jo); if (isTrim()) { value.doTrim(); diff --git a/core/src/main/java/hudson/model/TaskAction.java b/core/src/main/java/hudson/model/TaskAction.java index 60ca66ac0536..e0597218f5d5 100644 --- a/core/src/main/java/hudson/model/TaskAction.java +++ b/core/src/main/java/hudson/model/TaskAction.java @@ -27,12 +27,12 @@ import hudson.console.AnnotatedLargeText; import hudson.security.ACL; import hudson.security.Permission; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.ref.WeakReference; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.framework.io.LargeText; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -113,7 +113,7 @@ public TaskThread getWorkerThread() { /** * Handles incremental log output. */ - public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doProgressiveLog(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { AnnotatedLargeText text = obtainLog(); if (text != null) { text.doProgressText(req, rsp); @@ -125,7 +125,7 @@ public void doProgressiveLog(StaplerRequest req, StaplerResponse rsp) throws IOE /** * Handles incremental log output. */ - public void doProgressiveHtml(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doProgressiveHtml(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { AnnotatedLargeText text = obtainLog(); if (text != null) { text.doProgressiveHtml(req, rsp); @@ -138,7 +138,7 @@ public void doProgressiveHtml(StaplerRequest req, StaplerResponse rsp) throws IO * Clears the error status. */ @RequirePOST - public synchronized void doClearError(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doClearError(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { getACL().checkPermission(getPermission()); if (workerThread != null && !workerThread.isRunning()) diff --git a/core/src/main/java/hudson/model/TextParameterDefinition.java b/core/src/main/java/hudson/model/TextParameterDefinition.java index a22b1903e59b..96d973dc765a 100644 --- a/core/src/main/java/hudson/model/TextParameterDefinition.java +++ b/core/src/main/java/hudson/model/TextParameterDefinition.java @@ -32,7 +32,7 @@ import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link StringParameterDefinition} that uses textarea, instead of text box. @@ -68,7 +68,7 @@ public StringParameterValue getDefaultParameterValue() { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { TextParameterValue value = req.bindJSON(TextParameterValue.class, jo); value.setDescription(getDescription()); return value; diff --git a/core/src/main/java/hudson/model/TopLevelItemDescriptor.java b/core/src/main/java/hudson/model/TopLevelItemDescriptor.java index d84e4a684f22..817c1194a3d5 100644 --- a/core/src/main/java/hudson/model/TopLevelItemDescriptor.java +++ b/core/src/main/java/hudson/model/TopLevelItemDescriptor.java @@ -164,7 +164,7 @@ public String getDescription() { DefaultScriptInvoker dsi = new DefaultScriptInvoker(); StringWriter sw = new StringWriter(); XMLOutput xml = dsi.createXMLOutput(sw, true); - dsi.invokeScript(Stapler.getCurrentRequest(), Stapler.getCurrentResponse(), s, this, xml); + dsi.invokeScript(Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2(), s, this, xml); return sw.toString(); } catch (Exception e) { LOGGER.log(Level.WARNING, null, e); diff --git a/core/src/main/java/hudson/model/UpdateCenter.java b/core/src/main/java/hudson/model/UpdateCenter.java index 4df95b7b3f45..437444feb434 100644 --- a/core/src/main/java/hudson/model/UpdateCenter.java +++ b/core/src/main/java/hudson/model/UpdateCenter.java @@ -58,6 +58,7 @@ import hudson.util.PersistedList; import hudson.util.VersionNumber; import hudson.util.XStream2; +import jakarta.servlet.ServletException; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; @@ -107,7 +108,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.SSLHandshakeException; -import javax.servlet.ServletException; import jenkins.MissingDependencyException; import jenkins.RestartRequiredException; import jenkins.install.InstallUtil; @@ -115,6 +115,7 @@ import jenkins.model.Jenkins; import jenkins.model.Loadable; import jenkins.security.stapler.StaplerDispatchable; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import jenkins.util.Timer; import jenkins.util.io.OnMaster; @@ -129,7 +130,8 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -439,7 +441,25 @@ public Badge getBadge() { * @return The current connection status. */ @Restricted(DoNotUse.class) + public HttpResponse doConnectionStatus(StaplerRequest2 request) { + if (Util.isOverridden(UpdateCenter.class, getClass(), "doConnectionStatus", StaplerRequest.class)) { + return doConnectionStatus(StaplerRequest.fromStaplerRequest2(request)); + } else { + return doConnectionStatusImpl(request); + } + } + + /** + * @deprecated use {@link #doConnectionStatus(StaplerRequest2)} + */ + @Deprecated + @StaplerNotDispatchable + @Restricted(DoNotUse.class) public HttpResponse doConnectionStatus(StaplerRequest request) { + return doConnectionStatusImpl(StaplerRequest.toStaplerRequest2(request)); + } + + private HttpResponse doConnectionStatusImpl(StaplerRequest2 request) { Jenkins.get().checkPermission(Jenkins.SYSTEM_READ); try { String siteId = request.getParameter("siteId"); @@ -536,12 +556,12 @@ public synchronized void persistInstallStatus() { * <p> * Supports a "correlationId" request parameter if you only want to get the * install status of a set of plugins requested for install through - * {@link PluginManager#doInstallPlugins(org.kohsuke.stapler.StaplerRequest)}. + * {@link PluginManager#doInstallPlugins(org.kohsuke.stapler.StaplerRequest2)}. * * @return The current installation status of a plugin set. */ @Restricted(DoNotUse.class) - public HttpResponse doInstallStatus(StaplerRequest request) { + public HttpResponse doInstallStatus(StaplerRequest2 request) { try { String correlationId = request.getParameter("correlationId"); Map<String, Object> response = new HashMap<>(); @@ -754,7 +774,7 @@ private boolean checkMinVersion(@CheckForNull Plugin p, @CheckForNull VersionNum * Schedules a Jenkins upgrade. */ @RequirePOST - public void doUpgrade(StaplerResponse rsp) throws IOException, ServletException { + public void doUpgrade(StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); HudsonUpgradeJob job = new HudsonUpgradeJob(getCoreSource(), Jenkins.getAuthentication2()); if (!Lifecycle.get().canRewriteHudsonWar()) { @@ -786,7 +806,7 @@ public HttpResponse doInvalidateData() { * Schedules a Jenkins restart. */ @RequirePOST - public void doSafeRestart(StaplerRequest request, StaplerResponse response) throws IOException, ServletException { + public void doSafeRestart(StaplerRequest2 request, StaplerResponse2 response) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); synchronized (jobs) { if (!isRestartScheduled()) { @@ -801,7 +821,7 @@ public void doSafeRestart(StaplerRequest request, StaplerResponse response) thro * Cancel all scheduled jenkins restarts */ @RequirePOST - public void doCancelRestart(StaplerResponse response) throws IOException, ServletException { + public void doCancelRestart(StaplerResponse2 response) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); synchronized (jobs) { for (UpdateCenterJob job : jobs) { @@ -860,7 +880,7 @@ public boolean isDowngradable() { * Performs hudson downgrade. */ @RequirePOST - public void doDowngrade(StaplerResponse rsp) throws IOException, ServletException { + public void doDowngrade(StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); if (!isDowngradable()) { sendError("Jenkins downgrade is not possible, probably backup does not exist"); @@ -877,7 +897,7 @@ public void doDowngrade(StaplerResponse rsp) throws IOException, ServletExceptio * Performs hudson downgrade. */ @RequirePOST - public void doRestart(StaplerResponse rsp) throws IOException, ServletException { + public void doRestart(StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); HudsonDowngradeJob job = new HudsonDowngradeJob(getCoreSource(), Jenkins.getAuthentication2()); LOGGER.info("Scheduling the core downgrade"); @@ -2392,7 +2412,7 @@ private File getCached(DownloadJob job) { * Could make PluginManager#getDetachedLocation public and consume it here, but this method is * best-effort anyway. */ - src = Jenkins.get().servletContext.getResource(String.format("/WEB-INF/detached-plugins/%s.hpi", plugin.name)); + src = Jenkins.get().getServletContext().getResource(String.format("/WEB-INF/detached-plugins/%s.hpi", plugin.name)); } catch (MalformedURLException e) { return null; } diff --git a/core/src/main/java/hudson/model/UsageStatistics.java b/core/src/main/java/hudson/model/UsageStatistics.java index 341f135c52f1..04d1be58209a 100644 --- a/core/src/main/java/hudson/model/UsageStatistics.java +++ b/core/src/main/java/hudson/model/UsageStatistics.java @@ -67,7 +67,7 @@ import jenkins.security.FIPS140; import jenkins.util.SystemProperties; import net.sf.json.JSONObject; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @author Kohsuke Kawaguchi @@ -138,7 +138,7 @@ public String getStatData() throws IOException { JSONObject o = new JSONObject(); o.put("stat", 1); o.put("install", j.getLegacyInstanceId()); - o.put("servletContainer", j.servletContext.getServerInfo()); + o.put("servletContainer", j.getServletContext().getServerInfo()); o.put("version", Jenkins.VERSION); List<JSONObject> nodes = new ArrayList<>(); @@ -212,7 +212,7 @@ public Permission getRequiredGlobalConfigPagePermission() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { try { // for backward compatibility reasons, this configuration is stored in Jenkins if (DISABLED) { diff --git a/core/src/main/java/hudson/model/User.java b/core/src/main/java/hudson/model/User.java index 792622eb3c54..685a80e540a9 100644 --- a/core/src/main/java/hudson/model/User.java +++ b/core/src/main/java/hudson/model/User.java @@ -47,6 +47,8 @@ import hudson.util.FormValidation; import hudson.util.RunList; import hudson.util.XStream2; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -64,8 +66,6 @@ import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.model.IdStrategy; import jenkins.model.Jenkins; import jenkins.model.Loadable; @@ -79,8 +79,8 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -485,7 +485,7 @@ private LegitimateButUnknownUserDetails(String username) throws IllegalArgumentE * Accepts the new description. */ @RequirePOST - public void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doSubmitDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { checkPermission(Jenkins.ADMINISTER); description = req.getParameter("description"); @@ -882,7 +882,7 @@ public Api getApi() { * Deletes this user from Hudson. */ @RequirePOST - public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doDoDelete(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { checkPermission(Jenkins.ADMINISTER); if (idStrategy().equals(id, Jenkins.getAuthentication2().getName())) { rsp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Cannot delete self"); @@ -894,15 +894,15 @@ public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOExcepti rsp.sendRedirect2("../.."); } - public void doRssAll(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssAll(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds().newBuilds()); } - public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssFailed(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().regressionOnly()); } - public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssLatest(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { final List<Run> lastBuilds = new ArrayList<>(); for (Job<?, ?> p : Jenkins.get().allItems(Job.class)) { for (Run<?, ?> b = p.getLastBuild(); b != null; b = b.getPreviousBuild()) { @@ -1010,7 +1010,7 @@ public List<Action> getTransientActions() { } @Override - public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ContextMenu doContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { return new ContextMenu().from(this, request, response); } diff --git a/core/src/main/java/hudson/model/UserProperty.java b/core/src/main/java/hudson/model/UserProperty.java index a6ebeb738b23..9813cfaba62b 100644 --- a/core/src/main/java/hudson/model/UserProperty.java +++ b/core/src/main/java/hudson/model/UserProperty.java @@ -27,6 +27,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.DescriptorExtensionList; import hudson.ExtensionPoint; +import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.model.userproperty.UserPropertyCategory; import java.util.ArrayList; @@ -34,6 +35,7 @@ import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.ExportedBean; /** @@ -101,8 +103,22 @@ public static List<UserPropertyDescriptor> allByCategoryClass(@NonNull Class<? e return onlyForTheCategory; } + @Override + public UserProperty reconfigure(StaplerRequest2 req, JSONObject form) throws FormException { + if (Util.isOverridden(UserProperty.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + @Deprecated @Override public UserProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private UserProperty reconfigureImpl(StaplerRequest2 req, JSONObject form) throws FormException { return form == null ? null : getDescriptor().newInstance(req, form); } } diff --git a/core/src/main/java/hudson/model/View.java b/core/src/main/java/hudson/model/View.java index 7b1bd98eb9ee..e807fa23de30 100644 --- a/core/src/main/java/hudson/model/View.java +++ b/core/src/main/java/hudson/model/View.java @@ -25,7 +25,7 @@ package hudson.model; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST; import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.io.StreamException; @@ -57,6 +57,9 @@ import hudson.util.RunList; import hudson.util.XStream2; import hudson.views.ListViewColumn; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -80,8 +83,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.sax.SAXSource; @@ -93,6 +94,7 @@ import jenkins.model.item_category.Categories; import jenkins.model.item_category.Category; import jenkins.model.item_category.ItemCategory; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.xml.XMLUtils; import jenkins.widgets.HasWidgets; import net.sf.json.JSONObject; @@ -108,7 +110,9 @@ import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -673,7 +677,28 @@ public SearchIndexBuilder makeSearchIndex() { * Accepts the new description. */ @RequirePOST - public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(View.class, getClass(), "doSubmitDescription", StaplerRequest.class, StaplerResponse.class)) { + try { + doSubmitDescription(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doSubmitDescriptionImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doSubmitDescription(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + doSubmitDescriptionImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doSubmitDescriptionImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { checkPermission(CONFIGURE); description = req.getParameter("description"); @@ -684,10 +709,10 @@ public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse /** * Accepts submission from the configuration page. * - * Subtypes should override the {@link #submit(StaplerRequest)} method. + * Subtypes should override the {@link #submit(StaplerRequest2)} method. */ @POST - public final synchronized void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public final synchronized void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { checkPermission(CONFIGURE); submit(req); @@ -710,13 +735,42 @@ public final synchronized void doConfigSubmit(StaplerRequest req, StaplerRespons * * Load view-specific properties here. */ - protected abstract void submit(StaplerRequest req) throws IOException, ServletException, FormException; + protected /* abstract */ void submit(StaplerRequest2 req) throws IOException, ServletException, FormException { + if (Util.isOverridden(View.class, getClass(), "submit", StaplerRequest.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + View.class.getSimpleName() + ".submit methods"); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2)} + */ + @Deprecated + protected void submit(StaplerRequest req) throws IOException, javax.servlet.ServletException, FormException { + if (Util.isOverridden(View.class, getClass(), "submit", StaplerRequest2.class)) { + try { + submit(StaplerRequest.toStaplerRequest2(req)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + View.class.getSimpleName() + ".submit methods"); + } + } + /** * Deletes this view. */ @RequirePOST - public synchronized void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doDoDelete(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { checkPermission(DELETE); owner.deleteView(this); @@ -729,13 +783,44 @@ public synchronized void doDoDelete(StaplerRequest req, StaplerResponse rsp) thr * Creates a new {@link Item} in this collection. * * <p> - * This method should call {@link ModifiableItemGroup#doCreateItem(StaplerRequest, StaplerResponse)} + * This method should call {@link ModifiableItemGroup#doCreateItem(StaplerRequest2, StaplerResponse2)} * and then add the newly created item to this view. * * @return * null if fails. + * @since TODO */ - public abstract Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException; + @RequirePOST + public /* abstract */ Item doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(View.class, getClass(), "doCreateItem", StaplerRequest.class, StaplerResponse.class)) { + try { + return doCreateItem(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + View.class.getSimpleName() + ".doCreateItem methods"); + } + } + + /** + * @deprecated use {@link #doCreateItem(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + if (Util.isOverridden(View.class, getClass(), "doCreateItem", StaplerRequest2.class, StaplerResponse2.class)) { + try { + return doCreateItem(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + View.class.getSimpleName() + ".doCreateItem methods"); + } + } /** * Makes sure that the given name is good as a job name. @@ -774,7 +859,7 @@ public FormValidation doCheckJobName(@QueryParameter String value) { * @return A {@link Categories} entity that is shown as JSON file. */ @Restricted(DoNotUse.class) - public Categories doItemCategories(StaplerRequest req, StaplerResponse rsp, @QueryParameter String iconStyle) throws IOException, ServletException { + public Categories doItemCategories(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String iconStyle) throws IOException, ServletException { getOwner().checkPermission(Item.CREATE); rsp.addHeader("Cache-Control", "no-cache, no-store, must-revalidate"); @@ -833,11 +918,11 @@ public Categories doItemCategories(StaplerRequest req, StaplerResponse rsp, @Que return categories; } - public void doRssAll(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssAll(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (all builds)", getUrl(), getBuilds().newBuilds()); } - public void doRssFailed(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssFailed(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { RSS.rss(req, rsp, "Jenkins:" + getDisplayName() + " (failed builds)", getUrl(), getBuilds().failureOnly().newBuilds()); } @@ -851,7 +936,7 @@ public BuildTimelineWidget getTimeline() { return new BuildTimelineWidget(getBuilds()); } - public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doRssLatest(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { List<Run> lastBuilds = new ArrayList<>(); for (TopLevelItem item : getItems()) { if (item instanceof Job job) { @@ -866,13 +951,13 @@ public void doRssLatest(StaplerRequest req, StaplerResponse rsp) throws IOExcept * Accepts {@code config.xml} submission, as well as serve it. */ @WebMethod(name = "config.xml") - public HttpResponse doConfigDotXml(StaplerRequest req) throws IOException { + public HttpResponse doConfigDotXml(StaplerRequest2 req) throws IOException { if (req.getMethod().equals("GET")) { // read checkPermission(READ); return new HttpResponse() { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { rsp.setContentType("application/xml"); View.this.writeXml(rsp.getOutputStream()); } @@ -940,7 +1025,7 @@ public void updateByXml(Source source) throws IOException { } @Override - public ModelObjectWithContextMenu.ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ModelObjectWithContextMenu.ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { ModelObjectWithContextMenu.ContextMenu m = new ModelObjectWithContextMenu.ContextMenu(); for (TopLevelItem i : getItems()) m.add(Functions.getRelativeLinkTo(i), Functions.getRelativeDisplayNameFrom(i, getOwner().getItemGroup())); @@ -964,15 +1049,15 @@ public static DescriptorExtensionList<View, ViewDescriptor> all() { /** * Returns the {@link ViewDescriptor} instances that can be instantiated for the {@link ViewGroup} in the current - * {@link StaplerRequest}. + * {@link StaplerRequest2}. * <p> - * <strong>NOTE: Historically this method is only ever called from a {@link StaplerRequest}</strong> - * @return the list of instantiable {@link ViewDescriptor} instances for the current {@link StaplerRequest} + * <strong>NOTE: Historically this method is only ever called from a {@link StaplerRequest2}</strong> + * @return the list of instantiable {@link ViewDescriptor} instances for the current {@link StaplerRequest2} */ @NonNull public static List<ViewDescriptor> allInstantiable() { List<ViewDescriptor> r = new ArrayList<>(); - StaplerRequest request = Stapler.getCurrentRequest(); + StaplerRequest2 request = Stapler.getCurrentRequest2(); if (request == null) { throw new IllegalStateException("This method can only be invoked from a stapler request"); } @@ -1018,7 +1103,10 @@ public static Permission getItemCreatePermission() { return Item.CREATE; } - public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup owner) + /** + * @since TODO + */ + public static View create(StaplerRequest2 req, StaplerResponse2 rsp, ViewGroup owner) throws FormException, IOException, ServletException { String mode = req.getParameter("mode"); @@ -1070,7 +1158,20 @@ public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup own return v; } - private static View copy(StaplerRequest req, ViewGroup owner, String name) throws IOException { + /** + * @deprecated use {@link #create(StaplerRequest2, StaplerResponse2, ViewGroup)} + */ + @Deprecated + public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup owner) + throws FormException, IOException, javax.servlet.ServletException { + try { + return create(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), owner); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private static View copy(StaplerRequest2 req, ViewGroup owner, String name) throws IOException { View v; String from = req.getParameter("from"); View src = owner.getView(from); diff --git a/core/src/main/java/hudson/model/ViewDescriptor.java b/core/src/main/java/hudson/model/ViewDescriptor.java index f38e5d846d9a..e140ac474054 100644 --- a/core/src/main/java/hudson/model/ViewDescriptor.java +++ b/core/src/main/java/hudson/model/ViewDescriptor.java @@ -40,7 +40,7 @@ import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link Descriptor} for {@link View}. @@ -108,7 +108,7 @@ public AutoCompletionCandidates doAutoCompleteCopyNewItemFrom(@QueryParameter fi * Possible {@link ListViewColumnDescriptor}s that can be used with this view. */ public List<Descriptor<ListViewColumn>> getColumnsDescriptors() { - StaplerRequest request = Stapler.getCurrentRequest(); + StaplerRequest2 request = Stapler.getCurrentRequest2(); if (request != null) { View view = request.findAncestorObject(clazz); return view == null ? DescriptorVisibilityFilter.applyType(clazz, ListViewColumn.all()) @@ -121,7 +121,7 @@ public List<Descriptor<ListViewColumn>> getColumnsDescriptors() { * Possible {@link ViewJobFilter} types that can be used with this view. */ public List<Descriptor<ViewJobFilter>> getJobFiltersDescriptors() { - StaplerRequest request = Stapler.getCurrentRequest(); + StaplerRequest2 request = Stapler.getCurrentRequest2(); if (request != null) { View view = request.findAncestorObject(clazz); return view == null ? DescriptorVisibilityFilter.applyType(clazz, ViewJobFilter.all()) diff --git a/core/src/main/java/hudson/model/ViewJob.java b/core/src/main/java/hudson/model/ViewJob.java index 0da32700c1bd..055b98cafdb5 100644 --- a/core/src/main/java/hudson/model/ViewJob.java +++ b/core/src/main/java/hudson/model/ViewJob.java @@ -25,7 +25,10 @@ package hudson.model; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Util; import hudson.model.Descriptor.FormException; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.util.LinkedHashSet; @@ -34,11 +37,12 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link Job} that monitors activities that happen outside Hudson, @@ -165,8 +169,30 @@ private void _reload() { protected abstract void reload(); @Override - protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + protected void submit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { + if (Util.isOverridden(ViewJob.class, getClass(), "submit", StaplerRequest.class, StaplerResponse.class)) { + try { + submit(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + super.submit(req, rsp); + submitImpl(); + } + } + + /** + * @deprecated use {@link #submit(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @Override + protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException, FormException { super.submit(req, rsp); + submitImpl(); + } + + private void submitImpl() { // make sure to reload to reflect this config change. nextUpdate = 0; } diff --git a/core/src/main/java/hudson/model/ViewProperty.java b/core/src/main/java/hudson/model/ViewProperty.java index 31ad3078d449..15f0e62164c4 100644 --- a/core/src/main/java/hudson/model/ViewProperty.java +++ b/core/src/main/java/hudson/model/ViewProperty.java @@ -26,9 +26,11 @@ import hudson.DescriptorExtensionList; import hudson.ExtensionPoint; +import hudson.Util; import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Extensible property of {@link View}. @@ -68,8 +70,22 @@ public static DescriptorExtensionList<ViewProperty, ViewPropertyDescriptor> all( return Jenkins.get().getDescriptorList(ViewProperty.class); } + @Override + public ViewProperty reconfigure(StaplerRequest2 req, JSONObject form) throws Descriptor.FormException { + if (Util.isOverridden(ViewProperty.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + @Deprecated @Override public ViewProperty reconfigure(StaplerRequest req, JSONObject form) throws Descriptor.FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private ViewProperty reconfigureImpl(StaplerRequest2 req, JSONObject form) throws Descriptor.FormException { return form == null ? null : getDescriptor().newInstance(req, form); } } diff --git a/core/src/main/java/hudson/model/labels/LabelAtom.java b/core/src/main/java/hudson/model/labels/LabelAtom.java index 84ee083c488d..f5e597b71b30 100644 --- a/core/src/main/java/hudson/model/labels/LabelAtom.java +++ b/core/src/main/java/hudson/model/labels/LabelAtom.java @@ -46,6 +46,7 @@ import hudson.util.QuotedStringTokenizer; import hudson.util.VariableResolver; import hudson.util.XStream2; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -56,13 +57,12 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -221,7 +221,7 @@ public List<LabelAtomPropertyDescriptor> getApplicablePropertyDescriptors() { * Accepts the update to the node configuration. */ @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { final Jenkins app = Jenkins.get(); app.checkPermission(Jenkins.ADMINISTER); @@ -249,7 +249,7 @@ private boolean isInvalidName() { */ @RequirePOST @Restricted(DoNotUse.class) - public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); setDescription(req.getParameter("description")); diff --git a/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAccountAction.java b/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAccountAction.java index 822cdc6f4c99..c0424e828419 100644 --- a/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAccountAction.java +++ b/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAccountAction.java @@ -32,20 +32,20 @@ import hudson.model.User; import hudson.model.UserProperty; import hudson.model.UserPropertyDescriptor; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.security.UserDetailsCache; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; @Restricted(NoExternalUse.class) @@ -91,7 +91,7 @@ private static List<UserPropertyDescriptor> allByTwoCategoryClasses( } @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, Descriptor.FormException { User targetUser = this.getTargetUser(); targetUser.checkPermission(Jenkins.ADMINISTER); diff --git a/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAction.java b/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAction.java index caec7c1bdf88..6eadb9f89ece 100644 --- a/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAction.java +++ b/core/src/main/java/hudson/model/userproperty/UserPropertyCategoryAction.java @@ -6,14 +6,14 @@ import hudson.model.UserProperty; import hudson.model.UserPropertyDescriptor; import hudson.util.FormApply; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import net.sf.json.JSONObject; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; public abstract class UserPropertyCategoryAction { @@ -31,7 +31,7 @@ public UserPropertyCategoryAction(User targetUser) { public @NonNull abstract List<UserPropertyDescriptor> getMyCategoryDescriptors(); @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, Descriptor.FormException { this.targetUser.checkPermission(Jenkins.ADMINISTER); JSONObject json = req.getSubmittedForm(); diff --git a/core/src/main/java/hudson/scm/AbstractScmTagAction.java b/core/src/main/java/hudson/scm/AbstractScmTagAction.java index b861a90b15fe..3bf14e753242 100644 --- a/core/src/main/java/hudson/scm/AbstractScmTagAction.java +++ b/core/src/main/java/hudson/scm/AbstractScmTagAction.java @@ -24,17 +24,22 @@ package hudson.scm; +import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.BuildBadgeAction; import hudson.model.Run; import hudson.model.TaskAction; import hudson.security.ACL; import hudson.security.Permission; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import jenkins.model.RunAction2; +import jenkins.security.stapler.StaplerNotDispatchable; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * Common part of {@code CVSSCM.TagAction} and {@code SubversionTagAction}. @@ -108,7 +113,32 @@ protected ACL getACL() { return run.getACL(); } - public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doIndex(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(AbstractScmTagAction.class, getClass(), "doIndex", StaplerRequest.class, StaplerResponse.class)) { + try { + doIndex(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doIndexImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doIndex(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doIndexImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doIndexImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { req.getView(this, chooseAction()).forward(req, rsp); } diff --git a/core/src/main/java/hudson/scm/RepositoryBrowsers.java b/core/src/main/java/hudson/scm/RepositoryBrowsers.java index 0a1e28d1a152..3562f1c13964 100644 --- a/core/src/main/java/hudson/scm/RepositoryBrowsers.java +++ b/core/src/main/java/hudson/scm/RepositoryBrowsers.java @@ -32,6 +32,7 @@ import java.util.List; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * List of all installed {@link RepositoryBrowsers}. @@ -63,7 +64,7 @@ public static List<Descriptor<RepositoryBrowser<?>>> filter(Class<? extends Repo * Creates an instance of {@link RepositoryBrowser} from a form submission. * * @deprecated since 2008-06-19. - * Use {@link #createInstance(Class, StaplerRequest, JSONObject, String)}. + * Use {@link #createInstance(Class, StaplerRequest2, JSONObject, String)}. */ @Deprecated public static <T extends RepositoryBrowser> @@ -82,13 +83,23 @@ T createInstance(Class<T> type, StaplerRequest req, String fieldName) throws For /** * Creates an instance of {@link RepositoryBrowser} from a form submission. * - * @since 1.227 + * @since TODO */ public static <T extends RepositoryBrowser> - T createInstance(Class<T> type, StaplerRequest req, JSONObject parent, String fieldName) throws FormException { + T createInstance(Class<T> type, StaplerRequest2 req, JSONObject parent, String fieldName) throws FormException { JSONObject o = (JSONObject) parent.get(fieldName); if (o == null) return null; return req.bindJSON(type, o); } + + /** + * @deprecated use {@link #createInstance(Class, StaplerRequest2, JSONObject, String)} + * @since 1.227 + */ + @Deprecated + public static <T extends RepositoryBrowser> + T createInstance(Class<T> type, StaplerRequest req, JSONObject parent, String fieldName) throws FormException { + return createInstance(type, StaplerRequest.toStaplerRequest2(req), parent, fieldName); + } } diff --git a/core/src/main/java/hudson/scm/SCMS.java b/core/src/main/java/hudson/scm/SCMS.java index a8fd4ddc4dc1..de92d453d248 100644 --- a/core/src/main/java/hudson/scm/SCMS.java +++ b/core/src/main/java/hudson/scm/SCMS.java @@ -28,9 +28,11 @@ import hudson.model.AbstractProject; import hudson.model.Descriptor.FormException; import hudson.util.DescriptorList; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.util.List; -import javax.servlet.ServletException; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * List of all installed SCMs. @@ -53,7 +55,7 @@ public class SCMS { * The project for which this SCM is configured to. */ @SuppressWarnings("deprecation") - public static SCM parseSCM(StaplerRequest req, AbstractProject target) throws FormException, ServletException { + public static SCM parseSCM(StaplerRequest2 req, AbstractProject target) throws FormException, ServletException { SCM scm = SCM.all().newInstanceFromRadioList(req.getSubmittedForm().getJSONObject("scm")); if (scm == null) { scm = new NullSCM(); // JENKINS-36043 workaround for AbstractMultiBranchProject.submit @@ -62,12 +64,24 @@ public static SCM parseSCM(StaplerRequest req, AbstractProject target) throws Fo return scm; } + /** + * @deprecated use {@link #parseSCM(StaplerRequest2, AbstractProject)} + */ + @Deprecated + public static SCM parseSCM(StaplerRequest req, AbstractProject target) throws FormException, javax.servlet.ServletException { + try { + return parseSCM(StaplerRequest.toStaplerRequest2(req), target); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * @deprecated as of 1.294 - * Use {@link #parseSCM(StaplerRequest, AbstractProject)} and pass in the caller's project type. + * Use {@link #parseSCM(StaplerRequest2, AbstractProject)} and pass in the caller's project type. */ @Deprecated - public static SCM parseSCM(StaplerRequest req) throws FormException, ServletException { + public static SCM parseSCM(StaplerRequest req) throws FormException, javax.servlet.ServletException { return parseSCM(req, null); } diff --git a/core/src/main/java/hudson/search/Search.java b/core/src/main/java/hudson/search/Search.java index a3a674ae1106..7773d9e9d696 100644 --- a/core/src/main/java/hudson/search/Search.java +++ b/core/src/main/java/hudson/search/Search.java @@ -25,12 +25,14 @@ package hudson.search; -import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; +import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Util; import hudson.util.EditDistance; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.AbstractList; import java.util.ArrayList; @@ -40,8 +42,8 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.MemoryReductionUtil; import jenkins.util.SystemProperties; import org.kohsuke.accmod.Restricted; @@ -50,7 +52,9 @@ import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.DataWriter; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -73,7 +77,32 @@ public class Search implements StaplerProxy { */ private static /* nonfinal for Jenkins script console */ int MAX_SEARCH_SIZE = Integer.getInteger(Search.class.getName() + ".MAX_SEARCH_SIZE", 500); - public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doIndex(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(Search.class, getClass(), "doIndex", StaplerRequest.class, StaplerResponse.class)) { + try { + doIndex(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doIndexImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doIndex(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doIndexImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void doIndexImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { List<Ancestor> l = req.getAncestors(); for (int i = l.size() - 1; i >= 0; i--) { Ancestor a = l.get(i); @@ -110,7 +139,7 @@ public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, * * See http://developer.mozilla.org/en/docs/Supporting_search_suggestions_in_search_plugins */ - public void doSuggestOpenSearch(StaplerRequest req, StaplerResponse rsp, @QueryParameter String q) throws IOException, ServletException { + public void doSuggestOpenSearch(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String q) throws IOException, ServletException { rsp.setContentType(Flavor.JSON.contentType); DataWriter w = Flavor.JSON.createDataWriter(null, rsp); w.startArray(); @@ -126,7 +155,7 @@ public void doSuggestOpenSearch(StaplerRequest req, StaplerResponse rsp, @QueryP /** * Used by search box auto-completion. Returns JSON array. */ - public void doSuggest(StaplerRequest req, StaplerResponse rsp, @QueryParameter String query) throws IOException, ServletException { + public void doSuggest(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String query) throws IOException, ServletException { Result r = new Result(); for (SuggestedItem item : getSuggestions(req, query)) r.suggestions.add(new Item(item.getPath())); @@ -141,7 +170,23 @@ public void doSuggest(StaplerRequest req, StaplerResponse rsp, @QueryParameter S * can be empty but never null. The size of the list is always smaller than * a certain threshold to avoid showing too many options. */ + public SearchResult getSuggestions(StaplerRequest2 req, String query) { + if (Util.isOverridden(Search.class, getClass(), "getSuggestions", StaplerRequest.class, String.class)) { + return getSuggestions(StaplerRequest.fromStaplerRequest2(req), query); + } else { + return getSuggestionsImpl(req, query); + } + } + + /** + * @deprecated use {@link #getSuggestions(StaplerRequest2, String)} + */ + @Deprecated public SearchResult getSuggestions(StaplerRequest req, String query) { + return getSuggestionsImpl(StaplerRequest.toStaplerRequest2(req), query); + } + + private SearchResult getSuggestionsImpl(StaplerRequest2 req, String query) { Set<String> paths = new HashSet<>(); // paths already added, to control duplicates SearchResultImpl r = new SearchResultImpl(); int max = Math.min( @@ -164,7 +209,7 @@ public int getMaxSearchSize() { return MAX_SEARCH_SIZE; } - private @CheckForNull SearchableModelObject findClosestSearchableModelObject(StaplerRequest req) { + private @CheckForNull SearchableModelObject findClosestSearchableModelObject(StaplerRequest2 req) { List<Ancestor> l = req.getAncestors(); for (int i = l.size() - 1; i >= 0; i--) { Ancestor a = l.get(i); @@ -178,7 +223,7 @@ public int getMaxSearchSize() { /** * Creates merged search index for suggestion. */ - private SearchIndex makeSuggestIndex(StaplerRequest req) { + private SearchIndex makeSuggestIndex(StaplerRequest2 req) { SearchIndexBuilder builder = new SearchIndexBuilder(); for (Ancestor a : req.getAncestors()) { if (a.getObject() instanceof SearchableModelObject) { diff --git a/core/src/main/java/hudson/search/UserSearchProperty.java b/core/src/main/java/hudson/search/UserSearchProperty.java index a3515dd08874..7f36476b112b 100644 --- a/core/src/main/java/hudson/search/UserSearchProperty.java +++ b/core/src/main/java/hudson/search/UserSearchProperty.java @@ -8,7 +8,7 @@ import hudson.model.userproperty.UserPropertyCategory; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; public class UserSearchProperty extends hudson.model.UserProperty { @@ -51,7 +51,7 @@ public UserProperty newInstance(User user) { } @Override - public UserProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public UserProperty newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { return new UserSearchProperty(formData.optBoolean("insensitiveSearch")); } diff --git a/core/src/main/java/hudson/security/AccessDeniedException2.java b/core/src/main/java/hudson/security/AccessDeniedException2.java index 00daee721251..e745669bad67 100644 --- a/core/src/main/java/hudson/security/AccessDeniedException2.java +++ b/core/src/main/java/hudson/security/AccessDeniedException2.java @@ -1,5 +1,6 @@ package hudson.security; +import io.jenkins.servlet.http.HttpServletResponseWrapper; import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse; import jenkins.util.SystemProperties; @@ -42,7 +43,7 @@ public AccessDeniedException2(Throwable t, Authentication authentication, Permis * Reports the details of the access failure in HTTP headers to assist diagnosis. */ public void reportAsHeaders(HttpServletResponse rsp) { - toSpring().reportAsHeaders(rsp); + toSpring().reportAsHeaders(HttpServletResponseWrapper.toJakartaHttpServletResponse(rsp)); } /** diff --git a/core/src/main/java/hudson/security/AccessDeniedException3.java b/core/src/main/java/hudson/security/AccessDeniedException3.java index 82f5d50428ce..90fc521dfd7b 100644 --- a/core/src/main/java/hudson/security/AccessDeniedException3.java +++ b/core/src/main/java/hudson/security/AccessDeniedException3.java @@ -1,7 +1,8 @@ package hudson.security; +import io.jenkins.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.http.HttpServletResponse; import java.io.PrintWriter; -import javax.servlet.http.HttpServletResponse; import jenkins.util.SystemProperties; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; @@ -43,6 +44,18 @@ public AccessDeniedException3(Throwable t, Authentication authentication, Permis * Reports the details of the access failure in HTTP headers to assist diagnosis. */ public void reportAsHeaders(HttpServletResponse rsp) { + reportAsHeadersImpl(rsp); + } + + /** + * @deprecated use {@link #reportAsHeaders(HttpServletResponse)} + */ + @Deprecated + public void reportAsHeaders(javax.servlet.http.HttpServletResponse rsp) { + reportAsHeadersImpl(HttpServletResponseWrapper.toJakartaHttpServletResponse(rsp)); + } + + private void reportAsHeadersImpl(HttpServletResponse rsp) { rsp.addHeader("X-You-Are-Authenticated-As", authentication.getName()); if (REPORT_GROUP_HEADERS) { for (GrantedAuthority auth : authentication.getAuthorities()) { diff --git a/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java b/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java index 68843cfddd16..b1f1e35e1fc8 100644 --- a/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java +++ b/core/src/main/java/hudson/security/AccessDeniedHandlerImpl.java @@ -24,10 +24,10 @@ package hudson.security; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -53,7 +53,7 @@ public void handle(HttpServletRequest req, HttpServletResponse rsp, AccessDenied ((AccessDeniedException3) cause).reportAsHeaders(rsp); } - WebApp.get(Jenkins.get().servletContext).getSomeStapler() + WebApp.get(Jenkins.get().getServletContext()).getSomeStapler() .invoke(req, rsp, Jenkins.get(), "/accessDenied"); } } diff --git a/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java b/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java index 2714ec8eba63..0c9559bf140f 100644 --- a/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java +++ b/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java @@ -26,14 +26,14 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.User; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import jenkins.security.SecurityListener; import jenkins.security.seed.UserSeedProperty; import jenkins.util.SystemProperties; diff --git a/core/src/main/java/hudson/security/AuthorizationStrategy.java b/core/src/main/java/hudson/security/AuthorizationStrategy.java index f77385829730..db3001fc40f2 100644 --- a/core/src/main/java/hudson/security/AuthorizationStrategy.java +++ b/core/src/main/java/hudson/security/AuthorizationStrategy.java @@ -47,7 +47,7 @@ import jenkins.security.stapler.StaplerAccessibleType; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Controls authorization throughout Hudson. @@ -241,7 +241,7 @@ public String getDisplayName() { } @Override - public @NonNull AuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public @NonNull AuthorizationStrategy newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { return UNSECURED; } } diff --git a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java index b2a06024278b..8586fb0317a0 100644 --- a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java +++ b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java @@ -27,24 +27,24 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.User; import hudson.util.Scrambler; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.security.BasicApiTokenHelper; import jenkins.security.SecurityListener; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.CompatibleFilter; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; @@ -68,7 +68,7 @@ * This causes the container to perform authentication, but there's no way * to find out whether the user has been successfully authenticated or not. * So to find this out, we then redirect the user to - * {@link jenkins.model.Jenkins#doSecured(StaplerRequest, StaplerResponse) /secured/... page}. + * {@link jenkins.model.Jenkins#doSecured(StaplerRequest2, StaplerResponse2) /secured/... page}. * * <p> * The handler of the above URL checks if the user is authenticated, @@ -91,7 +91,7 @@ * * @author Kohsuke Kawaguchi */ -public class BasicAuthenticationFilter implements Filter { +public class BasicAuthenticationFilter implements CompatibleFilter { private ServletContext servletContext; @Override diff --git a/core/src/main/java/hudson/security/ChainedServletFilter.java b/core/src/main/java/hudson/security/ChainedServletFilter.java index 74e1e463f565..98bc725c2b1a 100644 --- a/core/src/main/java/hudson/security/ChainedServletFilter.java +++ b/core/src/main/java/hudson/security/ChainedServletFilter.java @@ -24,27 +24,28 @@ package hudson.security; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import org.kohsuke.stapler.CompatibleFilter; /** * Servlet {@link Filter} that chains multiple {@link Filter}s. * * @author Kohsuke Kawaguchi */ -public class ChainedServletFilter implements Filter { +public class ChainedServletFilter implements CompatibleFilter { // array is assumed to be immutable once set protected volatile Filter[] filters; diff --git a/core/src/main/java/hudson/security/ContainerAuthentication.java b/core/src/main/java/hudson/security/ContainerAuthentication.java index be7bdc01ab62..571b5cc782e8 100644 --- a/core/src/main/java/hudson/security/ContainerAuthentication.java +++ b/core/src/main/java/hudson/security/ContainerAuthentication.java @@ -24,12 +24,12 @@ package hudson.security; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.security.Principal; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; diff --git a/core/src/main/java/hudson/security/FederatedLoginService.java b/core/src/main/java/hudson/security/FederatedLoginService.java index 2d176290d8be..38d91f7da901 100644 --- a/core/src/main/java/hudson/security/FederatedLoginService.java +++ b/core/src/main/java/hudson/security/FederatedLoginService.java @@ -30,13 +30,13 @@ import hudson.ExtensionPoint; import hudson.model.User; import hudson.model.UserProperty; +import jakarta.servlet.ServletException; import java.io.IOException; import java.io.Serializable; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; @@ -245,7 +245,7 @@ public UnclaimedIdentityException(FederatedIdentity identity) { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { SecurityRealm sr = Jenkins.get().getSecurityRealm(); if (sr.allowsSignup()) { try { diff --git a/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java b/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java index 4c9dc1add7e7..a8657df65685 100644 --- a/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java +++ b/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java @@ -35,13 +35,13 @@ import hudson.model.Descriptor.FormException; import hudson.model.ManagementLink; import hudson.util.FormApply; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.Set; import java.util.TreeSet; import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; import jenkins.util.ServerTcpPort; @@ -51,8 +51,8 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; /** @@ -108,7 +108,7 @@ public Category getCategory() { } @POST - public synchronized void doConfigure(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public synchronized void doConfigure(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { // for compatibility reasons, the actual value is stored in Jenkins JSONObject json = req.getSubmittedForm(); BulkChange bc = new BulkChange(Jenkins.get()); @@ -125,7 +125,7 @@ public synchronized void doConfigure(StaplerRequest req, StaplerResponse rsp) th } } - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { // for compatibility reasons, the actual value is stored in Jenkins Jenkins j = Jenkins.get(); j.checkPermission(Jenkins.ADMINISTER); @@ -171,7 +171,7 @@ public boolean configure(StaplerRequest req, JSONObject json) throws FormExcepti return result; } - private boolean configureDescriptor(StaplerRequest req, JSONObject json, Descriptor<?> d) throws FormException { + private boolean configureDescriptor(StaplerRequest2 req, JSONObject json, Descriptor<?> d) throws FormException { // collapse the structure to remain backward compatible with the JSON structure before 1. String name = d.getJsonSafeClassName(); JSONObject js = json.has(name) ? json.getJSONObject(name) : new JSONObject(); // if it doesn't have the property, the method returns invalid null object. diff --git a/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java b/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java index 786df5d72879..c2c0d8a6abe1 100644 --- a/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java +++ b/core/src/main/java/hudson/security/HttpSessionContextIntegrationFilter2.java @@ -25,13 +25,13 @@ package hudson.security; import hudson.model.User; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; import jenkins.security.seed.UserSeedProperty; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; diff --git a/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java b/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java index e99dfdc14f74..950cf3614c82 100644 --- a/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java +++ b/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java @@ -24,19 +24,19 @@ package hudson.security; -import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; +import static jakarta.servlet.http.HttpServletResponse.SC_FORBIDDEN; import hudson.Functions; import hudson.Util; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.text.MessageFormat; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.springframework.security.authentication.InsufficientAuthenticationException; diff --git a/core/src/main/java/hudson/security/HudsonFilter.java b/core/src/main/java/hudson/security/HudsonFilter.java index 333180b32ead..4438874b6030 100644 --- a/core/src/main/java/hudson/security/HudsonFilter.java +++ b/core/src/main/java/hudson/security/HudsonFilter.java @@ -26,17 +26,18 @@ import static java.util.logging.Level.SEVERE; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; +import org.kohsuke.stapler.CompatibleFilter; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.RememberMeServices; @@ -52,7 +53,7 @@ * @author Kohsuke Kawaguchi * @since 1.160 */ -public class HudsonFilter implements Filter { +public class HudsonFilter implements CompatibleFilter { /** * The SecurityRealm specific filter. */ diff --git a/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java b/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java index bd122244c7e2..1a6ebe66f749 100644 --- a/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java +++ b/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java @@ -24,7 +24,7 @@ package hudson.security; -import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; +import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; import com.thoughtworks.xstream.converters.UnmarshallingContext; import edu.umd.cs.findbugs.annotations.NonNull; @@ -47,6 +47,15 @@ import hudson.util.Protector; import hudson.util.Scrambler; import hudson.util.XStream2; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.lang.reflect.Constructor; import java.nio.charset.StandardCharsets; @@ -67,15 +76,6 @@ import java.util.regex.Pattern; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import jenkins.model.Jenkins; import jenkins.security.FIPS140; import jenkins.security.SecurityListener; @@ -85,14 +85,15 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.CompatibleFilter; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.ForwardToView; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; import org.mindrot.jbcrypt.BCrypt; import org.springframework.security.authentication.BadCredentialsException; @@ -236,10 +237,10 @@ protected UserDetails authenticate2(String username, String password) throws Aut @Override public HttpResponse commenceSignup(final FederatedIdentity identity) { // store the identity in the session so that we can use this later - Stapler.getCurrentRequest().getSession().setAttribute(FEDERATED_IDENTITY_SESSION_KEY, identity); + Stapler.getCurrentRequest2().getSession().setAttribute(FEDERATED_IDENTITY_SESSION_KEY, identity); return new ForwardToView(this, "signupWithFederatedIdentity.jelly") { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { SignupInfo si = new SignupInfo(identity); si.errorMessage = Messages.HudsonPrivateSecurityRealm_WouldYouLikeToSignUp(identity.getPronoun(), identity.getIdentifier()); req.setAttribute("data", si); @@ -253,7 +254,7 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod * with {@link #commenceSignup}. */ @RequirePOST - public User doCreateAccountWithFederatedIdentity(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public User doCreateAccountWithFederatedIdentity(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { User u = _doCreateAccount(req, rsp, "signupWithFederatedIdentity.jelly"); if (u != null) ((FederatedIdentity) req.getSession().getAttribute(FEDERATED_IDENTITY_SESSION_KEY)).addTo(u); @@ -266,11 +267,11 @@ public User doCreateAccountWithFederatedIdentity(StaplerRequest req, StaplerResp * Creates an user account. Used for self-registration. */ @RequirePOST - public User doCreateAccount(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public User doCreateAccount(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { return _doCreateAccount(req, rsp, "signup.jelly"); } - private User _doCreateAccount(StaplerRequest req, StaplerResponse rsp, String formView) throws ServletException, IOException { + private User _doCreateAccount(StaplerRequest2 req, StaplerResponse2 rsp, String formView) throws ServletException, IOException { if (!allowsSignup()) throw HttpResponses.errorWithoutStack(SC_UNAUTHORIZED, "User sign up is prohibited"); @@ -287,7 +288,7 @@ private User _doCreateAccount(StaplerRequest req, StaplerResponse rsp, String fo /** * Lets the current user silently login as the given user and report back accordingly. */ - private void loginAndTakeBack(StaplerRequest req, StaplerResponse rsp, User u) throws ServletException, IOException { + private void loginAndTakeBack(StaplerRequest2 req, StaplerResponse2 rsp, User u) throws ServletException, IOException { HttpSession session = req.getSession(false); if (session != null) { // avoid session fixation @@ -309,11 +310,11 @@ private void loginAndTakeBack(StaplerRequest req, StaplerResponse rsp, User u) t /** * Creates a user account. Used by admins. * - * This version behaves differently from {@link #doCreateAccount(StaplerRequest, StaplerResponse)} in that + * This version behaves differently from {@link #doCreateAccount(StaplerRequest2, StaplerResponse2)} in that * this is someone creating another user. */ @RequirePOST - public void doCreateAccountByAdmin(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doCreateAccountByAdmin(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { createAccountByAdmin(req, rsp, "addUser.jelly", "."); // send the user back to the listing page on success } @@ -321,7 +322,7 @@ public void doCreateAccountByAdmin(StaplerRequest req, StaplerResponse rsp) thro * Creates a user account. Requires {@link Jenkins#ADMINISTER} */ @Restricted(NoExternalUse.class) - public User createAccountByAdmin(StaplerRequest req, StaplerResponse rsp, String addUserView, String successView) throws IOException, ServletException { + public User createAccountByAdmin(StaplerRequest2 req, StaplerResponse2 rsp, String addUserView, String successView) throws IOException, ServletException { checkPermission(Jenkins.ADMINISTER); User u = createAccount(req, rsp, false, addUserView); if (u != null && successView != null) { @@ -340,7 +341,7 @@ public User createAccountByAdmin(StaplerRequest req, StaplerResponse rsp, String * @throws AccountCreationFailedException if account creation failed due to invalid form input */ @Restricted(NoExternalUse.class) - public User createAccountFromSetupWizard(StaplerRequest req) throws IOException, AccountCreationFailedException { + public User createAccountFromSetupWizard(StaplerRequest2 req) throws IOException, AccountCreationFailedException { checkPermission(Jenkins.ADMINISTER); SignupInfo si = validateAccountCreationForm(req, false); if (!si.errors.isEmpty()) { @@ -366,7 +367,7 @@ private String getErrorMessages(SignupInfo si) { * This can be run by anyone, but only to create the very first user account. */ @RequirePOST - public void doCreateFirstAccount(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doCreateFirstAccount(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { if (hasSomeUser()) { rsp.sendError(SC_UNAUTHORIZED, "First user was already created"); return; @@ -400,7 +401,7 @@ private void tryToMakeAdmin(User u) { * null if failed. The browser is already redirected to retry by the time this method returns. * a valid {@link User} object if the user creation was successful. */ - private User createAccount(StaplerRequest req, StaplerResponse rsp, boolean validateCaptcha, String formView) throws ServletException, IOException { + private User createAccount(StaplerRequest2 req, StaplerResponse2 rsp, boolean validateCaptcha, String formView) throws ServletException, IOException { SignupInfo si = validateAccountCreationForm(req, validateCaptcha); if (!si.errors.isEmpty()) { @@ -416,11 +417,11 @@ private User createAccount(StaplerRequest req, StaplerResponse rsp, boolean vali * @param req the request to process * @param validateCaptcha whether to attempt to validate a captcha in the request * - * @return a {@link SignupInfo#SignupInfo(StaplerRequest) SignupInfo from given request}, with {@link + * @return a {@link SignupInfo#SignupInfo(StaplerRequest2) SignupInfo from given request}, with {@link * SignupInfo#errors} containing errors (keyed by field name), if any of the supported fields are invalid */ @SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "written to by Stapler") - private SignupInfo validateAccountCreationForm(StaplerRequest req, boolean validateCaptcha) { + private SignupInfo validateAccountCreationForm(StaplerRequest2 req, boolean validateCaptcha) { // form field validation // this pattern needs to be generalized and moved to stapler SignupInfo si = new SignupInfo(req); @@ -632,7 +633,7 @@ public static final class SignupInfo { public SignupInfo() { } - public SignupInfo(StaplerRequest req) { + public SignupInfo(StaplerRequest2 req) { req.bindParameters(this); } @@ -707,7 +708,7 @@ public boolean isPasswordCorrect(String candidate) { public String getProtectedPassword() { // put session Id in it to prevent a replay attack. - return Protector.protect(Stapler.getCurrentRequest().getSession().getId() + ':' + getPassword()); + return Protector.protect(Stapler.getCurrentRequest2().getSession().getId() + ':' + getPassword()); } public String getUsername() { @@ -825,7 +826,7 @@ public String getDisplayName() { } @Override - public Details newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public Details newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { if (req == null) { // Should never happen, see newInstance() Javadoc throw new FormException("Stapler request is missing in the call", "staplerRequest"); @@ -858,7 +859,7 @@ public Details newInstance(StaplerRequest req, JSONObject formData) throws FormE } if (data != null) { - String prefix = Stapler.getCurrentRequest().getSession().getId() + ':'; + String prefix = Stapler.getCurrentRequest2().getSession().getId() + ':'; if (data.startsWith(prefix)) { return Details.fromHashedPassword(data.substring(prefix.length())); } @@ -1153,7 +1154,7 @@ public FormValidation doCheckAllowsSignup(@QueryParameter boolean value) { } } - private static final Filter CREATE_FIRST_USER_FILTER = new Filter() { + private static final Filter CREATE_FIRST_USER_FILTER = new CompatibleFilter() { @Override public void init(FilterConfig config) throws ServletException { } diff --git a/core/src/main/java/hudson/security/LegacySecurityRealm.java b/core/src/main/java/hudson/security/LegacySecurityRealm.java index 1e869475caf2..94c895782f74 100644 --- a/core/src/main/java/hudson/security/LegacySecurityRealm.java +++ b/core/src/main/java/hudson/security/LegacySecurityRealm.java @@ -28,10 +28,10 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.model.Descriptor; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; import java.util.ArrayList; import java.util.List; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; diff --git a/core/src/main/java/hudson/security/NoopFilter.java b/core/src/main/java/hudson/security/NoopFilter.java index 3000bb2e81c0..2b2db184fc5f 100644 --- a/core/src/main/java/hudson/security/NoopFilter.java +++ b/core/src/main/java/hudson/security/NoopFilter.java @@ -24,20 +24,21 @@ package hudson.security; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; +import org.kohsuke.stapler.CompatibleFilter; /** * {@link Filter} that does nothing. * * @author Kohsuke Kawaguchi */ -public class NoopFilter implements Filter { +public class NoopFilter implements CompatibleFilter { @Override public void init(FilterConfig filterConfig) throws ServletException { } diff --git a/core/src/main/java/hudson/security/RememberMeServicesProxy.java b/core/src/main/java/hudson/security/RememberMeServicesProxy.java index 2220e313b0cc..1020002794ed 100644 --- a/core/src/main/java/hudson/security/RememberMeServicesProxy.java +++ b/core/src/main/java/hudson/security/RememberMeServicesProxy.java @@ -24,8 +24,8 @@ package hudson.security; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.security.ConfidentialStore; import org.kohsuke.accmod.Restricted; diff --git a/core/src/main/java/hudson/security/SecurityRealm.java b/core/src/main/java/hudson/security/SecurityRealm.java index b969a57eb781..d10e7994ae22 100644 --- a/core/src/main/java/hudson/security/SecurityRealm.java +++ b/core/src/main/java/hudson/security/SecurityRealm.java @@ -36,6 +36,14 @@ import hudson.security.captcha.CaptchaSupport; import hudson.util.DescriptorList; import hudson.util.PluginServletFilter; +import io.jenkins.servlet.FilterConfigWrapper; +import io.jenkins.servlet.FilterWrapper; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpSession; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -44,16 +52,12 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpSession; import jenkins.model.IdStrategy; import jenkins.model.Jenkins; import jenkins.security.AcegiSecurityExceptionFilter; import jenkins.security.AuthenticationSuccessHandler; import jenkins.security.BasicHeaderProcessor; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; @@ -62,7 +66,9 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -264,7 +270,7 @@ public boolean canLogOut() { * of Hudson, but you can return arbitrary URL. * * @param req - * {@link StaplerRequest} that represents the current request. Primarily so that + * {@link StaplerRequest2} that represents the current request. Primarily so that * you can get the context path. By the time this method is called, the session * is already invalidated. Never null. * @param auth @@ -272,14 +278,31 @@ public boolean canLogOut() { * This parameter allows you to redirect people to different pages depending on who they are. * @return * never null. + * @since TODO + * @see #doLogout(StaplerRequest2, StaplerResponse2) + */ + protected String getPostLogOutUrl2(StaplerRequest2 req, Authentication auth) { + if (Util.isOverridden(SecurityRealm.class, getClass(), "getPostLogOutUrl2", StaplerRequest.class, Authentication.class)) { + return getPostLogOutUrl2(StaplerRequest.fromStaplerRequest2(req), auth); + } else { + return getPostLogOutUrl2Impl(req, auth); + } + } + + /** + * @deprecated use {@link #getPostLogOutUrl2(StaplerRequest2, Authentication)} * @since 2.266 - * @see #doLogout(StaplerRequest, StaplerResponse) */ + @Deprecated protected String getPostLogOutUrl2(StaplerRequest req, Authentication auth) { + return getPostLogOutUrl2Impl(StaplerRequest.toStaplerRequest2(req), auth); + } + + private String getPostLogOutUrl2Impl(StaplerRequest2 req, Authentication auth) { if (Util.isOverridden(SecurityRealm.class, getClass(), "getPostLogOutUrl", StaplerRequest.class, org.acegisecurity.Authentication.class) && !insideGetPostLogOutUrl.get()) { insideGetPostLogOutUrl.set(true); try { - return getPostLogOutUrl(req, org.acegisecurity.Authentication.fromSpring(auth)); + return getPostLogOutUrl(StaplerRequest.fromStaplerRequest2(req), org.acegisecurity.Authentication.fromSpring(auth)); } finally { insideGetPostLogOutUrl.set(false); } @@ -295,7 +318,7 @@ protected String getPostLogOutUrl2(StaplerRequest req, Authentication auth) { */ @Deprecated protected String getPostLogOutUrl(StaplerRequest req, org.acegisecurity.Authentication auth) { - return getPostLogOutUrl2(req, auth.toSpring()); + return getPostLogOutUrl2(StaplerRequest.toStaplerRequest2(req), auth.toSpring()); } public CaptchaSupport getCaptchaSupport() { @@ -315,11 +338,37 @@ public List<Descriptor<CaptchaSupport>> getCaptchaSupportDescriptors() { * * <p> * The default implementation erases the session and do a few other clean up, then - * redirect the user to the URL specified by {@link #getPostLogOutUrl2(StaplerRequest, Authentication)}. + * redirect the user to the URL specified by {@link #getPostLogOutUrl2(StaplerRequest2, Authentication)}. * + * @since TODO + */ + public void doLogout(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(SecurityRealm.class, getClass(), "doLogout", StaplerRequest.class, StaplerResponse.class)) { + try { + doLogout(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + doLogoutImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doLogout(StaplerRequest2, StaplerResponse2)} * @since 1.314 */ - public void doLogout(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + @Deprecated + @StaplerNotDispatchable + public void doLogout(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doLogoutImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + void doLogoutImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { HttpSession session = req.getSession(false); if (session != null) session.invalidate(); @@ -333,7 +382,7 @@ public void doLogout(StaplerRequest req, StaplerResponse rsp) throws IOException rsp.sendRedirect2(getPostLogOutUrl2(req, auth)); } - private void resetRememberMeCookie(StaplerRequest req, StaplerResponse rsp, String contextPath) { + private void resetRememberMeCookie(StaplerRequest2 req, StaplerResponse2 rsp, String contextPath) { Cookie cookie = new Cookie(AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY, ""); cookie.setMaxAge(0); cookie.setSecure(req.isSecure()); @@ -342,7 +391,7 @@ private void resetRememberMeCookie(StaplerRequest req, StaplerResponse rsp, Stri rsp.addCookie(cookie); } - private void clearStaleSessionCookies(StaplerRequest req, StaplerResponse rsp, String contextPath) { + private void clearStaleSessionCookies(StaplerRequest2 req, StaplerResponse2 rsp, String contextPath) { /* While "executableWar.jetty.sessionIdCookieName" and * "executableWar.jetty.disableCustomSessionIdCookieName" * <https://github.com/jenkinsci/extras-executable-war/blob/6558df699d1366b18d045d2ffda3e970df377873/src/main/java/Main.java#L79-L97> @@ -516,7 +565,7 @@ public HttpResponse commenceSignup(FederatedIdentity identity) { /** * Generates a captcha image. */ - public final void doCaptcha(StaplerRequest req, StaplerResponse rsp) throws IOException { + public final void doCaptcha(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (captchaSupport != null) { String id = req.getSession().getId(); rsp.setContentType("image/png"); @@ -533,7 +582,7 @@ public final void doCaptcha(StaplerRequest req, StaplerResponse rsp) throws IOEx */ protected final boolean validateCaptcha(String text) { if (captchaSupport != null) { - String id = Stapler.getCurrentRequest().getSession().getId(); + String id = Stapler.getCurrentRequest2().getSession().getId(); return captchaSupport.validateCaptcha(id, text); } @@ -570,10 +619,29 @@ public synchronized SecurityComponents getSecurityComponents() { * For other plugins that want to contribute {@link Filter}, see * {@link PluginServletFilter}. * - * @since 1.271 + * @since TODO */ public Filter createFilter(FilterConfig filterConfig) { - LOGGER.entering(SecurityRealm.class.getName(), "createFilter"); + if (Util.isOverridden(SecurityRealm.class, getClass(), "createFilter", javax.servlet.FilterConfig.class)) { + return FilterWrapper.toJakartaFilter(createFilter( + filterConfig != null ? FilterConfigWrapper.fromJakartaFilterConfig(filterConfig) : null)); + } else { + return createFilterImpl(filterConfig); + } + } + + /** + * @deprecated use {@link #createFilter(FilterConfig)} + * @since 1.271 + */ + @Deprecated + public javax.servlet.Filter createFilter(javax.servlet.FilterConfig filterConfig) { + return FilterWrapper.fromJakartaFilter(createFilterImpl( + filterConfig != null ? FilterConfigWrapper.toJakartaFilterConfig(filterConfig) : null)); + } + + private Filter createFilterImpl(FilterConfig filterConfig) { + LOGGER.entering(SecurityRealm.class.getName(), "createFilterImpl"); SecurityComponents sc = getSecurityComponents(); List<Filter> filters = new ArrayList<>(); @@ -639,7 +707,7 @@ protected final List<Filter> commonFilters() { @Restricted(DoNotUse.class) public static String getFrom() { String from = null; - final StaplerRequest request = Stapler.getCurrentRequest(); + final StaplerRequest2 request = Stapler.getCurrentRequest2(); // Try to obtain a return point from the query parameter if (request != null) { @@ -734,7 +802,7 @@ public String getDisplayName() { } @Override - public SecurityRealm newInstance(StaplerRequest req, JSONObject formData) throws Descriptor.FormException { + public SecurityRealm newInstance(StaplerRequest2 req, JSONObject formData) throws Descriptor.FormException { return NO_AUTHENTICATION; } } diff --git a/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java b/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java index 0e8e19d90a06..9b6974a3f2e4 100644 --- a/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java +++ b/core/src/main/java/hudson/security/TokenBasedRememberMeServices2.java @@ -27,6 +27,8 @@ import com.google.common.annotations.VisibleForTesting; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.User; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.security.MessageDigest; import java.util.Arrays; import java.util.Date; @@ -34,8 +36,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.security.HMACConfidentialKey; import jenkins.security.ImpersonatingUserDetailsService2; diff --git a/core/src/main/java/hudson/security/UnwrapSecurityExceptionFilter.java b/core/src/main/java/hudson/security/UnwrapSecurityExceptionFilter.java index 2abfea11eb71..683725b2fe0d 100644 --- a/core/src/main/java/hudson/security/UnwrapSecurityExceptionFilter.java +++ b/core/src/main/java/hudson/security/UnwrapSecurityExceptionFilter.java @@ -24,14 +24,14 @@ package hudson.security; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import org.apache.commons.jelly.JellyTagException; +import org.kohsuke.stapler.CompatibleFilter; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.access.ExceptionTranslationFilter; @@ -43,7 +43,7 @@ * * @author Kohsuke Kawaguchi */ -public class UnwrapSecurityExceptionFilter implements Filter { +public class UnwrapSecurityExceptionFilter implements CompatibleFilter { @Override public void init(FilterConfig filterConfig) throws ServletException { } diff --git a/core/src/main/java/hudson/security/csrf/CrumbExclusion.java b/core/src/main/java/hudson/security/csrf/CrumbExclusion.java index 4f4135bd9a88..e7d8d67a219f 100644 --- a/core/src/main/java/hudson/security/csrf/CrumbExclusion.java +++ b/core/src/main/java/hudson/security/csrf/CrumbExclusion.java @@ -8,11 +8,16 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; +import hudson.Util; +import io.jenkins.servlet.FilterChainWrapper; +import io.jenkins.servlet.ServletExceptionWrapper; +import io.jenkins.servlet.http.HttpServletRequestWrapper; +import io.jenkins.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; /** * Allows plugins to define exceptions to the CSRF protection filter. @@ -32,7 +37,57 @@ public abstract class CrumbExclusion implements ExtensionPoint { * true to indicate that the callee had processed this request * (for example by reporting an error, or by executing the rest of the chain.) */ - public abstract boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException; + public /* abstract */ boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + if (Util.isOverridden( + CrumbExclusion.class, + getClass(), + "process", + javax.servlet.http.HttpServletRequest.class, + javax.servlet.http.HttpServletResponse.class, + javax.servlet.FilterChain.class)) { + try { + return process( + HttpServletRequestWrapper.fromJakartaHttpServletRequest(request), + HttpServletResponseWrapper.fromJakartaHttpServletResponse(response), + FilterChainWrapper.fromJakartaFilterChain(chain)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + CrumbExclusion.class.getSimpleName() + ".process methods"); + } + } + + /** + * @deprecated use {@link #process(HttpServletRequest, HttpServletResponse, FilterChain)} + */ + @Deprecated + public boolean process( + javax.servlet.http.HttpServletRequest request, + javax.servlet.http.HttpServletResponse response, + javax.servlet.FilterChain chain) + throws IOException, javax.servlet.ServletException { + if (Util.isOverridden( + CrumbExclusion.class, + getClass(), + "process", + HttpServletRequest.class, + HttpServletResponse.class, + FilterChain.class)) { + try { + return process( + HttpServletRequestWrapper.toJakartaHttpServletRequest(request), + HttpServletResponseWrapper.toJakartaHttpServletResponse(response), + FilterChainWrapper.toJakartaFilterChain(chain)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + CrumbExclusion.class.getSimpleName() + ".process methods"); + } + } public static ExtensionList<CrumbExclusion> all() { return ExtensionList.lookup(CrumbExclusion.class); diff --git a/core/src/main/java/hudson/security/csrf/CrumbFilter.java b/core/src/main/java/hudson/security/csrf/CrumbFilter.java index 8b4b558938e7..6835a4365a3c 100644 --- a/core/src/main/java/hudson/security/csrf/CrumbFilter.java +++ b/core/src/main/java/hudson/security/csrf/CrumbFilter.java @@ -7,6 +7,14 @@ package hudson.security.csrf; import hudson.util.MultipartFormDataParser; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -14,20 +22,12 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.kohsuke.MetaInfServices; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.CompatibleFilter; import org.kohsuke.stapler.ForwardToView; import org.kohsuke.stapler.interceptor.RequirePOST; import org.springframework.security.authentication.AnonymousAuthenticationToken; @@ -38,7 +38,7 @@ * * @author dty */ -public class CrumbFilter implements Filter { +public class CrumbFilter implements CompatibleFilter { /** * Because servlet containers generally don't specify the ordering of the initialization * (and different implementations indeed do this differently --- See JENKINS-3878), diff --git a/core/src/main/java/hudson/security/csrf/CrumbIssuer.java b/core/src/main/java/hudson/security/csrf/CrumbIssuer.java index cd0c51b03fb0..491ec735b591 100644 --- a/core/src/main/java/hudson/security/csrf/CrumbIssuer.java +++ b/core/src/main/java/hudson/security/csrf/CrumbIssuer.java @@ -6,26 +6,31 @@ package hudson.security.csrf; +import edu.umd.cs.findbugs.annotations.NonNull; import hudson.DescriptorExtensionList; import hudson.ExtensionPoint; +import hudson.Util; import hudson.init.Initializer; import hudson.model.Api; import hudson.model.Describable; import hudson.model.Descriptor; import hudson.util.MultipartFormDataParser; +import io.jenkins.servlet.ServletRequestWrapper; +import io.jenkins.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; import jenkins.model.Jenkins; import jenkins.security.stapler.StaplerAccessibleType; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebApp; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -64,7 +69,7 @@ public String getCrumbRequestField() { */ @Exported public String getCrumb() { - return getCrumb(Stapler.getCurrentRequest()); + return getCrumb(Stapler.getCurrentRequest2()); } /** @@ -89,6 +94,14 @@ public String getCrumb(ServletRequest request) { return crumb; } + /** + * @deprecated use {@link #getCrumb(ServletRequest)} + */ + @Deprecated + public String getCrumb(javax.servlet.ServletRequest request) { + return getCrumb(request != null ? wrap(request) : null); + } + /** * Create a crumb value based on user specific information in the request. * The crumb should be generated by building a cryptographic hash of: @@ -98,7 +111,30 @@ public String getCrumb(ServletRequest request) { * <li>an implementation specific guarded secret. * </ul> */ - protected abstract String issueCrumb(ServletRequest request, String salt); + protected /* abstract */ String issueCrumb(ServletRequest request, String salt) { + return Util.ifOverridden( + () -> issueCrumb( + request != null ? wrap(request) : null, salt), + CrumbIssuer.class, + getClass(), + "issueCrumb", + javax.servlet.ServletRequest.class, + String.class); + } + + /** + * @deprecated use {@link #issueCrumb(ServletRequest, String)} + */ + @Deprecated + protected String issueCrumb(javax.servlet.ServletRequest request, String salt) { + return Util.ifOverridden( + () -> issueCrumb(request != null ? wrap(request) : null, salt), + CrumbIssuer.class, + getClass(), + "issueCrumb", + ServletRequest.class, + String.class); + } /** * Get a crumb from a request parameter and validate it against other data @@ -126,12 +162,63 @@ public boolean validateCrumb(ServletRequest request, MultipartFormDataParser par return validateCrumb(request, crumbSalt, parser.get(crumbField)); } + /** + * @deprecated use {@link #validateCrumb(ServletRequest, MultipartFormDataParser)} + */ + @Deprecated + public boolean validateCrumb(javax.servlet.ServletRequest request, MultipartFormDataParser parser) { + return validateCrumb(request != null ? wrap(request) : null, parser); + } + + private static ServletRequest wrap(@NonNull javax.servlet.ServletRequest request) { + if (request instanceof javax.servlet.http.HttpServletRequest httpRequest) { + return HttpServletRequestWrapper.toJakartaHttpServletRequest(httpRequest); + } else { + return ServletRequestWrapper.toJakartaServletRequest(request); + } + } + /** * Validate a previously created crumb against information in the current request. * * @param crumb The previously generated crumb to validate against information in the current request */ - public abstract boolean validateCrumb(ServletRequest request, String salt, String crumb); + public /* abstract */ boolean validateCrumb(ServletRequest request, String salt, String crumb) { + return Util.ifOverridden( + () -> validateCrumb( + request != null ? wrap(request) : null, + salt, + crumb), + CrumbIssuer.class, + getClass(), + "validateCrumb", + javax.servlet.ServletRequest.class, + String.class, + String.class); + } + + private static javax.servlet.ServletRequest wrap(@NonNull ServletRequest request) { + if (request instanceof HttpServletRequest httpRequest) { + return HttpServletRequestWrapper.fromJakartaHttpServletRequest(httpRequest); + } else { + return ServletRequestWrapper.fromJakartaServletRequest(request); + } + } + + /** + * @deprecated use {@link #validateCrumb(ServletRequest, String, String)} + */ + @Deprecated + public boolean validateCrumb(javax.servlet.ServletRequest request, String salt, String crumb) { + return Util.ifOverridden( + () -> validateCrumb(request != null ? wrap(request) : null, salt, crumb), + CrumbIssuer.class, + getClass(), + "validateCrumb", + ServletRequest.class, + String.class, + String.class); + } /** * Access global configuration for the crumb issuer. @@ -157,15 +244,15 @@ public Api getApi() { */ @Initializer public static void initStaplerCrumbIssuer() { - WebApp.get(Jenkins.get().servletContext).setCrumbIssuer(new org.kohsuke.stapler.CrumbIssuer() { + WebApp.get(Jenkins.get().getServletContext()).setCrumbIssuer(new org.kohsuke.stapler.CrumbIssuer() { @Override - public String issueCrumb(StaplerRequest request) { + public String issueCrumb(StaplerRequest2 request) { CrumbIssuer ci = Jenkins.get().getCrumbIssuer(); return ci != null ? ci.getCrumb(request) : DEFAULT.issueCrumb(request); } @Override - public void validateCrumb(StaplerRequest request, String submittedCrumb) { + public void validateCrumb(StaplerRequest2 request, String submittedCrumb) { CrumbIssuer ci = Jenkins.get().getCrumbIssuer(); if (ci == null) { DEFAULT.validateCrumb(request, submittedCrumb); @@ -184,7 +271,7 @@ public static class RestrictedApi extends Api { super(instance); } - @Override public void doXml(StaplerRequest req, StaplerResponse rsp, @QueryParameter String xpath, @QueryParameter String wrapper, @QueryParameter String tree, @QueryParameter int depth) throws IOException, ServletException { + @Override public void doXml(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String xpath, @QueryParameter String wrapper, @QueryParameter String tree, @QueryParameter int depth) throws IOException, ServletException { setHeaders(rsp); String text; CrumbIssuer ci = (CrumbIssuer) bean; diff --git a/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java b/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java index 89c7da39e7b4..7a3bc0c9b1d2 100644 --- a/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java +++ b/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java @@ -12,13 +12,13 @@ import hudson.Util; import hudson.model.ModelObject; import hudson.model.PersistentDescriptor; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; import jenkins.model.Jenkins; import jenkins.security.HexStringConfidentialKey; import jenkins.util.SystemProperties; @@ -27,7 +27,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.core.Authentication; /** @@ -69,6 +69,7 @@ private synchronized void initializeMessageDigest() { } @Override + @SuppressFBWarnings(value = "NM_WRONG_PACKAGE", justification = "false positive") protected synchronized String issueCrumb(ServletRequest request, String salt) { if (request instanceof HttpServletRequest) { if (md != null) { @@ -135,7 +136,7 @@ public String getDisplayName() { } @Override - public DefaultCrumbIssuer newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public DefaultCrumbIssuer newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { if (req == null) { // This state is prohibited according to the Javadoc of the super method. throw new FormException("DefaultCrumbIssuer new instance method is called for null Stapler request. " diff --git a/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java b/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java index 6faa5dfc24e0..61a861fefbe3 100644 --- a/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java +++ b/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java @@ -35,7 +35,7 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Show the crumb configuration to the system config page. @@ -50,7 +50,7 @@ public class GlobalCrumbIssuerConfiguration extends GlobalConfiguration { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { // for compatibility reasons, the actual value is stored in Jenkins Jenkins j = Jenkins.get(); diff --git a/core/src/main/java/hudson/slaves/Cloud.java b/core/src/main/java/hudson/slaves/Cloud.java index 6552685a05d0..3bff60c0d0ad 100644 --- a/core/src/main/java/hudson/slaves/Cloud.java +++ b/core/src/main/java/hudson/slaves/Cloud.java @@ -47,11 +47,11 @@ import hudson.slaves.NodeProvisioner.PlannedNode; import hudson.util.DescriptorList; import hudson.util.FormApply; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.Collection; import java.util.Objects; import java.util.concurrent.Future; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; @@ -60,7 +60,8 @@ import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -319,7 +320,7 @@ public HttpResponse doDoDelete() throws IOException { * Accepts the update to the node configuration. */ @POST - public HttpResponse doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException { + public HttpResponse doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, Descriptor.FormException { checkPermission(Jenkins.ADMINISTER); Jenkins j = Jenkins.get(); @@ -340,7 +341,26 @@ public HttpResponse doConfigSubmit(StaplerRequest req, StaplerResponse rsp) thro } + /** + * @since TODO + */ + public Cloud reconfigure(@NonNull final StaplerRequest2 req, JSONObject form) throws Descriptor.FormException { + if (Util.isOverridden(Cloud.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + /** + * @deprecated use {@link #reconfigure(StaplerRequest2, JSONObject)} + */ + @Deprecated public Cloud reconfigure(@NonNull final StaplerRequest req, JSONObject form) throws Descriptor.FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private Cloud reconfigureImpl(@NonNull final StaplerRequest2 req, JSONObject form) throws Descriptor.FormException { if (form == null) return null; return getDescriptor().newInstance(req, form); } diff --git a/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java b/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java index be50bc982062..dd3ec84b131d 100644 --- a/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java +++ b/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java @@ -98,7 +98,7 @@ public String getDisplayName() { public String getHelpPage() { // yes, I know this is a hack. - ComputerSet object = Stapler.getCurrentRequest().findAncestorObject(ComputerSet.class); + ComputerSet object = Stapler.getCurrentRequest2().findAncestorObject(ComputerSet.class); if (object != null) { // we're on a node configuration page, show show that help page return "/help/system-config/nodeEnvironmentVariables.html"; diff --git a/core/src/main/java/hudson/slaves/NodeDescriptor.java b/core/src/main/java/hudson/slaves/NodeDescriptor.java index 8db1eb48139f..848cabbdf747 100644 --- a/core/src/main/java/hudson/slaves/NodeDescriptor.java +++ b/core/src/main/java/hudson/slaves/NodeDescriptor.java @@ -34,14 +34,14 @@ import hudson.model.Slave; import hudson.util.DescriptorList; import hudson.util.FormValidation; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link Descriptor} for {@link Slave}. @@ -83,7 +83,7 @@ public final String newInstanceDetailPage() { * @param name * Name of the new node. */ - public void handleNewNodePage(ComputerSet computerSet, String name, StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void handleNewNodePage(ComputerSet computerSet, String name, StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { computerSet.checkName(name); req.setAttribute("descriptor", this); req.getView(computerSet, "_new.jelly").forward(req, rsp); diff --git a/core/src/main/java/hudson/slaves/NodeProperty.java b/core/src/main/java/hudson/slaves/NodeProperty.java index 8605edcf4515..bcb2a2422025 100644 --- a/core/src/main/java/hudson/slaves/NodeProperty.java +++ b/core/src/main/java/hudson/slaves/NodeProperty.java @@ -30,6 +30,7 @@ import hudson.ExtensionPoint; import hudson.FilePath; import hudson.Launcher; +import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.BuildListener; import hudson.model.Descriptor.FormException; @@ -48,6 +49,7 @@ import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Extensible property of {@link Node}. @@ -171,8 +173,25 @@ public void buildEnvVars(@NonNull EnvVars env, @NonNull TaskListener listener) t // default is no-op } + @Override + public NodeProperty<?> reconfigure(StaplerRequest2 req, JSONObject form) throws FormException { + if (Util.isOverridden(NodeProperty.class, getClass(), "reconfigure", StaplerRequest.class, JSONObject.class)) { + return reconfigure(StaplerRequest.fromStaplerRequest2(req), form); + } else { + return reconfigureImpl(req, form); + } + } + + /** + * @deprecated use {@link #reconfigure(StaplerRequest2, JSONObject)} + */ + @Deprecated @Override public NodeProperty<?> reconfigure(StaplerRequest req, JSONObject form) throws FormException { + return reconfigureImpl(StaplerRequest.toStaplerRequest2(req), form); + } + + private NodeProperty<?> reconfigureImpl(StaplerRequest2 req, JSONObject form) throws FormException { return form == null ? null : getDescriptor().newInstance(req, form); } diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java index dbb579b9b3ae..4165f53a7245 100644 --- a/core/src/main/java/hudson/slaves/SlaveComputer.java +++ b/core/src/main/java/hudson/slaves/SlaveComputer.java @@ -97,8 +97,8 @@ import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -788,7 +788,7 @@ public List<LogRecord> getLogRecords() throws IOException, InterruptedException */ @RequirePOST @Restricted(NoExternalUse.class) - public synchronized void doSubmitDescription(StaplerResponse rsp, @QueryParameter String description) throws IOException { + public synchronized void doSubmitDescription(StaplerResponse2 rsp, @QueryParameter String description) throws IOException { checkPermission(CONFIGURE); final Slave node = this.getNode(); @@ -828,7 +828,7 @@ public void run() { @RequirePOST @Override - public void doLaunchSlaveAgent(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doLaunchSlaveAgent(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { checkPermission(CONNECT); if (channel != null) { @@ -871,12 +871,12 @@ public Slave.JnlpJar getJnlpJars(String fileName) { } @WebMethod(name = "slave-agent.jnlp") // backward compatibility - public HttpResponse doSlaveAgentJnlp(StaplerRequest req, StaplerResponse res) { + public HttpResponse doSlaveAgentJnlp(StaplerRequest2 req, StaplerResponse2 res) { return doJenkinsAgentJnlp(req, res); } @WebMethod(name = "jenkins-agent.jnlp") - public HttpResponse doJenkinsAgentJnlp(StaplerRequest req, StaplerResponse res) { + public HttpResponse doJenkinsAgentJnlp(StaplerRequest2 req, StaplerResponse2 res) { LOGGER.log( Level.WARNING, "Agent \"" + getName() @@ -888,12 +888,12 @@ public HttpResponse doJenkinsAgentJnlp(StaplerRequest req, StaplerResponse res) class LowPermissionResponse { @WebMethod(name = "jenkins-agent.jnlp") - public HttpResponse doJenkinsAgentJnlp(StaplerRequest req, StaplerResponse res) { + public HttpResponse doJenkinsAgentJnlp(StaplerRequest2 req, StaplerResponse2 res) { return SlaveComputer.this.doJenkinsAgentJnlp(req, res); } @WebMethod(name = "slave-agent.jnlp") // backward compatibility - public HttpResponse doSlaveAgentJnlp(StaplerRequest req, StaplerResponse res) { + public HttpResponse doSlaveAgentJnlp(StaplerRequest2 req, StaplerResponse2 res) { return SlaveComputer.this.doJenkinsAgentJnlp(req, res); } } diff --git a/core/src/main/java/hudson/tasks/ArtifactArchiver.java b/core/src/main/java/hudson/tasks/ArtifactArchiver.java index 4300cd1538ab..0ee50010e6a2 100644 --- a/core/src/main/java/hudson/tasks/ArtifactArchiver.java +++ b/core/src/main/java/hudson/tasks/ArtifactArchiver.java @@ -63,7 +63,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Copies the artifacts into an archive directory. @@ -367,7 +367,7 @@ public FormValidation doCheckArtifacts(@AncestorInPath AbstractProject project, } @Override - public ArtifactArchiver newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public ArtifactArchiver newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { return req.bindJSON(ArtifactArchiver.class, formData); } diff --git a/core/src/main/java/hudson/tasks/BuildTrigger.java b/core/src/main/java/hudson/tasks/BuildTrigger.java index 5a58fc7e6716..af71ff83b147 100644 --- a/core/src/main/java/hudson/tasks/BuildTrigger.java +++ b/core/src/main/java/hudson/tasks/BuildTrigger.java @@ -73,7 +73,7 @@ import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.core.Authentication; /** @@ -385,7 +385,7 @@ public String getHelpFile() { } @Override - public BuildTrigger newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public BuildTrigger newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { String childProjectsString = formData.getString("childProjects").trim(); if (childProjectsString.endsWith(",")) { childProjectsString = childProjectsString.substring(0, childProjectsString.length() - 1).trim(); diff --git a/core/src/main/java/hudson/tasks/Fingerprinter.java b/core/src/main/java/hudson/tasks/Fingerprinter.java index 4d843b27b003..2d41e338f212 100644 --- a/core/src/main/java/hudson/tasks/Fingerprinter.java +++ b/core/src/main/java/hudson/tasks/Fingerprinter.java @@ -76,7 +76,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.access.AccessDeniedException; /** @@ -351,7 +351,7 @@ public FormValidation doCheckTargets(@AncestorInPath AbstractProject<?, ?> proje } @Override - public Publisher newInstance(StaplerRequest req, JSONObject formData) { + public Publisher newInstance(StaplerRequest2 req, JSONObject formData) { return req.bindJSON(Fingerprinter.class, formData); } diff --git a/core/src/main/java/hudson/tasks/Maven.java b/core/src/main/java/hudson/tasks/Maven.java index 3c22790d383c..2e9e27326b8e 100644 --- a/core/src/main/java/hudson/tasks/Maven.java +++ b/core/src/main/java/hudson/tasks/Maven.java @@ -80,7 +80,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Build by using Maven. @@ -479,7 +479,7 @@ public void setInstallations(MavenInstallation... installations) { } @Override - public Builder newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public Builder newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { if (req == null) { // This state is prohibited according to the Javadoc of the super method. throw new FormException("Maven Build Step new instance method is called for null Stapler request. " diff --git a/core/src/main/java/hudson/tasks/Shell.java b/core/src/main/java/hudson/tasks/Shell.java index e34c90b89d5c..9cd070136b55 100644 --- a/core/src/main/java/hudson/tasks/Shell.java +++ b/core/src/main/java/hudson/tasks/Shell.java @@ -53,7 +53,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Executes a series of commands by using a shell. @@ -234,7 +234,7 @@ public FormValidation doCheckUnstableReturn(@QueryParameter String value) { } @Override - public boolean configure(StaplerRequest req, JSONObject data) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject data) throws FormException { req.bindJSON(this, data); return super.configure(req, data); } diff --git a/core/src/main/java/hudson/tools/ToolDescriptor.java b/core/src/main/java/hudson/tools/ToolDescriptor.java index cc9a2399196d..e20eb353af63 100644 --- a/core/src/main/java/hudson/tools/ToolDescriptor.java +++ b/core/src/main/java/hudson/tools/ToolDescriptor.java @@ -26,6 +26,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Util; import hudson.model.Descriptor; import hudson.util.DescribableList; import hudson.util.FormValidation; @@ -43,6 +44,7 @@ import org.jvnet.tiger_types.Types; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link Descriptor} for {@link ToolInstallation}. @@ -144,8 +146,25 @@ public DescribableList<ToolProperty<?>, ToolPropertyDescriptor> getDefaultProper } @Override - @SuppressWarnings("unchecked") // cast to T[] + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { + if (Util.isOverridden(ToolDescriptor.class, getClass(), "configure", StaplerRequest.class, JSONObject.class)) { + return configure(StaplerRequest.fromStaplerRequest2(req), json); + } else { + return configureImpl(req, json); + } + } + + /** + * @deprecated use {@link #configure(StaplerRequest2, JSONObject)} + */ + @Deprecated + @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + return configureImpl(StaplerRequest.toStaplerRequest2(req), json); + } + + @SuppressWarnings("unchecked") // cast to T[] + private boolean configureImpl(StaplerRequest2 req, JSONObject json) { setInstallations(req.bindJSONToList(clazz, json.get("tool")).toArray((T[]) Array.newInstance(clazz, 0))); return true; } diff --git a/core/src/main/java/hudson/triggers/SCMTrigger.java b/core/src/main/java/hudson/triggers/SCMTrigger.java index 43fdc6bb1062..f8277a345198 100644 --- a/core/src/main/java/hudson/triggers/SCMTrigger.java +++ b/core/src/main/java/hudson/triggers/SCMTrigger.java @@ -89,8 +89,8 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link Trigger} that checks for SCM updates periodically. @@ -356,7 +356,7 @@ public boolean isPollingThreadCountOptionVisible() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { String t = json.optString("pollingThreadCount", null); if (doCheckPollingThreadCount(t).kind != FormValidation.Kind.OK) { setPollingThreadCount(THREADS_DEFAULT); @@ -466,7 +466,7 @@ public String getUrlName() { /** * Sends out the raw polling log output. */ - public void doPollingLog(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doPollingLog(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { rsp.setContentType("text/plain;charset=UTF-8"); try (OutputStream os = rsp.getOutputStream(); // Prevent jelly from flushing stream so Content-Length header can be added afterwards diff --git a/core/src/main/java/hudson/util/BootFailure.java b/core/src/main/java/hudson/util/BootFailure.java index f23cf7fa66b7..321d8239664c 100644 --- a/core/src/main/java/hudson/util/BootFailure.java +++ b/core/src/main/java/hudson/util/BootFailure.java @@ -2,6 +2,7 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.WebAppMain; +import jakarta.servlet.ServletContext; import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -14,7 +15,6 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletContext; import jenkins.model.Jenkins; import jenkins.util.groovy.GroovyHookScript; import org.kohsuke.stapler.WebApp; diff --git a/core/src/main/java/hudson/util/CharacterEncodingFilter.java b/core/src/main/java/hudson/util/CharacterEncodingFilter.java index cb93c31e7d4a..2e42c0d8098c 100644 --- a/core/src/main/java/hudson/util/CharacterEncodingFilter.java +++ b/core/src/main/java/hudson/util/CharacterEncodingFilter.java @@ -24,17 +24,17 @@ package hudson.util; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; import jenkins.util.SystemProperties; +import org.kohsuke.stapler.CompatibleFilter; /** * Filter that sets the character encoding to be used in parsing the request @@ -42,7 +42,7 @@ * * @author Seiji Sogabe */ -public class CharacterEncodingFilter implements Filter { +public class CharacterEncodingFilter implements CompatibleFilter { /** * The default character encoding. diff --git a/core/src/main/java/hudson/util/ComboBoxModel.java b/core/src/main/java/hudson/util/ComboBoxModel.java index e245c890db2e..63cac72f4d0d 100644 --- a/core/src/main/java/hudson/util/ComboBoxModel.java +++ b/core/src/main/java/hudson/util/ComboBoxModel.java @@ -26,15 +26,15 @@ import static java.util.Arrays.asList; +import jakarta.servlet.ServletException; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; -import javax.servlet.ServletException; import net.sf.json.JSONArray; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Flavor; /** @@ -59,7 +59,7 @@ public ComboBoxModel(String... values) { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { rsp.setContentType(Flavor.JSON.contentType); PrintWriter w = rsp.getWriter(); JSONArray.fromObject(this).write(w); diff --git a/core/src/main/java/hudson/util/DescribableList.java b/core/src/main/java/hudson/util/DescribableList.java index 9c62af2f191a..dbb499b4df66 100644 --- a/core/src/main/java/hudson/util/DescribableList.java +++ b/core/src/main/java/hudson/util/DescribableList.java @@ -50,6 +50,7 @@ import jenkins.model.DependencyDeclarer; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Persisted list of {@link Describable}s with some operations specific @@ -167,7 +168,7 @@ public Map<D, T> toMap() { * @param json * Structured form data that includes the data for nested descriptor list. */ - public void rebuild(StaplerRequest req, JSONObject json, List<? extends Descriptor<T>> descriptors) throws FormException, IOException { + public void rebuild(StaplerRequest2 req, JSONObject json, List<? extends Descriptor<T>> descriptors) throws FormException, IOException { List<T> newList = new ArrayList<>(); for (Descriptor<T> d : descriptors) { @@ -193,9 +194,17 @@ public void rebuild(StaplerRequest req, JSONObject json, List<? extends Descript replaceBy(newList); } + /** + * @deprecated use {@link #rebuild(StaplerRequest2, JSONObject, List)} + */ + @Deprecated + public void rebuild(StaplerRequest req, JSONObject json, List<? extends Descriptor<T>> descriptors) throws FormException, IOException { + rebuild(StaplerRequest.toStaplerRequest2(req), json, descriptors); + } + /** * @deprecated as of 1.271 - * Use {@link #rebuild(StaplerRequest, JSONObject, List)} instead. + * Use {@link #rebuild(StaplerRequest2, JSONObject, List)} instead. */ @Deprecated public void rebuild(StaplerRequest req, JSONObject json, List<? extends Descriptor<T>> descriptors, String prefix) throws FormException, IOException { @@ -210,10 +219,18 @@ public void rebuild(StaplerRequest req, JSONObject json, List<? extends Descript * is allowed to create multiple instances of the same descriptor. Order is also * significant. */ - public void rebuildHetero(StaplerRequest req, JSONObject formData, Collection<? extends Descriptor<T>> descriptors, String key) throws FormException, IOException { + public void rebuildHetero(StaplerRequest2 req, JSONObject formData, Collection<? extends Descriptor<T>> descriptors, String key) throws FormException, IOException { replaceBy(Descriptor.newInstancesFromHeteroList(req, formData, key, descriptors)); } + /** + * @deprecated use {@link #rebuildHetero(StaplerRequest2, JSONObject, Collection, String)} + */ + @Deprecated + public void rebuildHetero(StaplerRequest req, JSONObject formData, Collection<? extends Descriptor<T>> descriptors, String key) throws FormException, IOException { + rebuildHetero(StaplerRequest.toStaplerRequest2(req), formData, descriptors, key); + } + /** * Picks up {@link DependencyDeclarer}s and allow it to build dependencies. */ diff --git a/core/src/main/java/hudson/util/DescriptorList.java b/core/src/main/java/hudson/util/DescriptorList.java index 94f105892cd8..c9b515d85c4e 100644 --- a/core/src/main/java/hudson/util/DescriptorList.java +++ b/core/src/main/java/hudson/util/DescriptorList.java @@ -160,7 +160,7 @@ public T newInstanceFromRadioList(JSONObject config) throws FormException { if (config.isNullObject()) return null; // none was selected int idx = config.getInt("value"); - return get(idx).newInstance(Stapler.getCurrentRequest(), config); + return get(idx).newInstance(Stapler.getCurrentRequest2(), config); } /** diff --git a/core/src/main/java/hudson/util/ErrorObject.java b/core/src/main/java/hudson/util/ErrorObject.java index 2f9f39ec8f19..48e1106b35f1 100644 --- a/core/src/main/java/hudson/util/ErrorObject.java +++ b/core/src/main/java/hudson/util/ErrorObject.java @@ -24,13 +24,13 @@ package hudson.util; -import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; +import static jakarta.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; import hudson.Functions; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Basis for error model objects. @@ -52,7 +52,7 @@ public String getStackTraceString() { return Functions.printThrowable(this); } - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { rsp.setStatus(SC_SERVICE_UNAVAILABLE); req.getView(this, "index.jelly").forward(req, rsp); } diff --git a/core/src/main/java/hudson/util/FormApply.java b/core/src/main/java/hudson/util/FormApply.java index 8a1db5bebe4e..dc5e4d64df9b 100644 --- a/core/src/main/java/hudson/util/FormApply.java +++ b/core/src/main/java/hudson/util/FormApply.java @@ -24,11 +24,12 @@ package hudson.util; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import org.kohsuke.stapler.HttpResponses.HttpResponseException; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Server-side code related to the {@code <f:apply>} button. @@ -47,7 +48,7 @@ public class FormApply { public static HttpResponseException success(final String destination) { return new HttpResponseException() { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { if (isApply(req)) { // if the submission is via 'apply', show a response in the notification bar applyResponse("notificationBar.show('" + Messages.HttpResponses_Saved() + "',notificationBar.SUCCESS)") @@ -61,11 +62,21 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod /** * Is this submission from the "apply" button? + * + * @since TODO */ - public static boolean isApply(StaplerRequest req) { + public static boolean isApply(StaplerRequest2 req) { return Boolean.parseBoolean(req.getParameter("core:apply")); } + /** + * @deprecated use {@link #isApply(StaplerRequest2)} + */ + @Deprecated + public static boolean isApply(StaplerRequest req) { + return isApply(StaplerRequest.toStaplerRequest2(req)); + } + /** * Generates the response for the asynchronous background form submission (AKA the Apply button.) * <p> @@ -75,7 +86,7 @@ public static boolean isApply(StaplerRequest req) { public static HttpResponseException applyResponse(final String script) { return new HttpResponseException() { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { rsp.setContentType("text/html;charset=UTF-8"); rsp.getWriter().println("<html><body><script>" + "window.applyCompletionHandler = function (w) {" + diff --git a/core/src/main/java/hudson/util/FormFillFailure.java b/core/src/main/java/hudson/util/FormFillFailure.java index 5ebd0d5a31e6..946d3f8997cf 100644 --- a/core/src/main/java/hudson/util/FormFillFailure.java +++ b/core/src/main/java/hudson/util/FormFillFailure.java @@ -27,14 +27,14 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Functions; import hudson.Util; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Locale; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Represents a failure in a form field doFillXYZ method. @@ -132,7 +132,7 @@ private static FormFillFailure _errorWithMarkup(@NonNull final String message, f return new FormFillFailure(kind, message) { @Override public String renderHtml() { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req == null) { // being called from some other context return message; } @@ -182,7 +182,7 @@ private FormFillFailure(FormValidation.Kind kind, String message) { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { rsp.setContentType("text/html;charset=UTF-8"); rsp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); diff --git a/core/src/main/java/hudson/util/FormValidation.java b/core/src/main/java/hudson/util/FormValidation.java index c1cfda5ef6a9..f61b95883782 100644 --- a/core/src/main/java/hudson/util/FormValidation.java +++ b/core/src/main/java/hudson/util/FormValidation.java @@ -40,6 +40,7 @@ import hudson.model.Descriptor; import hudson.tasks.Builder; import hudson.util.ReflectionUtils.Parameter; +import jakarta.servlet.ServletException; import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -58,21 +59,20 @@ import java.util.List; import java.util.Locale; import java.util.stream.Stream; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Represents the result of the form field validation. * * <p> * Use one of the factory methods to create an instance, then return it from your {@code doCheckXyz} - * method. (Via {@link HttpResponse}, the returned object will render the result into {@link StaplerResponse}.) + * method. (Via {@link HttpResponse}, the returned object will render the result into {@link StaplerResponse2}.) * This way of designing form field validation allows you to reuse {@code doCheckXyz()} methods * programmatically as well (by using {@link #kind}. * @@ -274,7 +274,7 @@ private static FormValidation _errorWithMarkup(final String message, final Kind return new FormValidation(kind, message) { @Override public String renderHtml() { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req == null) { // being called from some other context return message; } @@ -551,7 +551,7 @@ protected boolean findText(BufferedReader in, String literal) throws IOException * @param url * Pass in the URL that was connected. Used for error diagnosis. */ - protected FormValidation handleIOException(String url, IOException e) throws IOException, ServletException { + protected FormValidation handleIOException(String url, IOException e) throws IOException { // any invalid URL comes here if (e.getMessage().equals(url)) // Sun JRE (and probably others too) often return just the URL in the error. @@ -580,7 +580,7 @@ private String getCharset(URLConnection con) { * Implement the actual form validation logic, by using other convenience methods defined in this class. * If you are not using any of those, you don't need to extend from this class. */ - protected abstract FormValidation check() throws IOException, ServletException; + protected abstract FormValidation check() throws IOException; } @@ -600,7 +600,7 @@ private FormValidation(Kind kind, String message) { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { respond(rsp, renderHtml()); } @@ -609,7 +609,7 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod /** * Sends out an arbitrary HTML fragment as the output. */ - protected void respond(StaplerResponse rsp, String html) throws IOException, ServletException { + protected void respond(StaplerResponse2 rsp, String html) throws IOException, ServletException { rsp.setContentType("text/html;charset=UTF-8"); if (APPLY_CONTENT_SECURITY_POLICY_HEADERS) { for (String header : new String[]{"Content-Security-Policy", "X-WebKit-CSP", "X-Content-Security-Policy"}) { diff --git a/core/src/main/java/hudson/util/Graph.java b/core/src/main/java/hudson/util/Graph.java index a543e18cd6d7..6e4ef6c59515 100644 --- a/core/src/main/java/hudson/util/Graph.java +++ b/core/src/main/java/hudson/util/Graph.java @@ -27,6 +27,8 @@ import com.google.common.annotations.VisibleForTesting; import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Util; +import jakarta.servlet.ServletOutputStream; import java.awt.Color; import java.awt.Dimension; import java.awt.HeadlessException; @@ -34,7 +36,7 @@ import java.io.IOException; import java.util.Calendar; import javax.imageio.ImageIO; -import javax.servlet.ServletOutputStream; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import org.jfree.chart.ChartRenderingInfo; import org.jfree.chart.ChartUtilities; @@ -43,7 +45,9 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * A JFreeChart-generated graph that's bound to UI. @@ -91,7 +95,7 @@ protected Graph(Calendar timestamp, int defaultWidth, int defaultHeight) { */ protected abstract JFreeChart createGraph(); - private BufferedImage render(StaplerRequest req, ChartRenderingInfo info) { + private BufferedImage render(StaplerRequest2 req, ChartRenderingInfo info) { String w = req.getParameter("width"); if (w == null) { w = String.valueOf(defaultWidth); @@ -147,8 +151,27 @@ public static Dimension safeDimension(int width, int height, int defaultWidth, i /** * Renders a graph. + * + * @since TODO */ + public void doPng(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { + if (Util.isOverridden(Graph.class, getClass(), "doPng", StaplerRequest.class, StaplerResponse.class)) { + doPng(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + doPngImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doPng(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable public void doPng(StaplerRequest req, StaplerResponse rsp) throws IOException { + doPngImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doPngImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.checkIfModified(timestamp, rsp)) return; try { @@ -201,8 +224,27 @@ public void doPng(StaplerRequest req, StaplerResponse rsp) throws IOException { /** * Renders a clickable map. + * + * @since TODO */ + public void doMap(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { + if (Util.isOverridden(Graph.class, getClass(), "doMap", StaplerRequest.class, StaplerResponse.class)) { + doMap(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } else { + doMapImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #doMap(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable public void doMap(StaplerRequest req, StaplerResponse rsp) throws IOException { + doMapImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } + + private void doMapImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.checkIfModified(timestamp, rsp)) return; ChartRenderingInfo info = new ChartRenderingInfo(); diff --git a/core/src/main/java/hudson/util/HttpResponses.java b/core/src/main/java/hudson/util/HttpResponses.java index 1e24d8216550..a1e91d2374fa 100644 --- a/core/src/main/java/hudson/util/HttpResponses.java +++ b/core/src/main/java/hudson/util/HttpResponses.java @@ -25,16 +25,16 @@ package hudson.util; import edu.umd.cs.findbugs.annotations.NonNull; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Map; -import javax.servlet.ServletException; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Various {@link HttpResponse} implementations. @@ -204,7 +204,7 @@ static class JSONObjectResponse implements HttpResponse { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { byte[] bytes = jsonObject.toString().getBytes(StandardCharsets.UTF_8); rsp.setContentType("application/json; charset=UTF-8"); rsp.setContentLength(bytes.length); diff --git a/core/src/main/java/hudson/util/HudsonIsLoading.java b/core/src/main/java/hudson/util/HudsonIsLoading.java index 6e6964fbed17..1f3782dfe155 100644 --- a/core/src/main/java/hudson/util/HudsonIsLoading.java +++ b/core/src/main/java/hudson/util/HudsonIsLoading.java @@ -24,13 +24,13 @@ package hudson.util; -import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; +import static jakarta.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Model object used to display "Jenkins is loading data". @@ -41,7 +41,7 @@ * @author Kohsuke Kawaguchi */ public class HudsonIsLoading { - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { rsp.setStatus(SC_SERVICE_UNAVAILABLE); req.getView(this, "index.jelly").forward(req, rsp); } diff --git a/core/src/main/java/hudson/util/HudsonIsRestarting.java b/core/src/main/java/hudson/util/HudsonIsRestarting.java index 4e76657a9fa4..ba0a635b3963 100644 --- a/core/src/main/java/hudson/util/HudsonIsRestarting.java +++ b/core/src/main/java/hudson/util/HudsonIsRestarting.java @@ -24,13 +24,13 @@ package hudson.util; -import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; +import static jakarta.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Model object used to display "Hudson is restarting". @@ -55,7 +55,7 @@ public HudsonIsRestarting() { this.safeRestart = false; } - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { rsp.setStatus(SC_SERVICE_UNAVAILABLE); req.getView(this, "index.jelly").forward(req, rsp); } diff --git a/core/src/main/java/hudson/util/ListBoxModel.java b/core/src/main/java/hudson/util/ListBoxModel.java index cf889493acc4..c97ed0f431e7 100644 --- a/core/src/main/java/hudson/util/ListBoxModel.java +++ b/core/src/main/java/hudson/util/ListBoxModel.java @@ -25,15 +25,19 @@ package hudson.util; import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Util; import hudson.model.ModelObject; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import javax.servlet.ServletException; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.export.Flavor; @@ -166,12 +170,39 @@ public ListBoxModel add(@NonNull String nameAndValue) { return this; } - public void writeTo(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + /** + * @since TODO + */ + public void writeTo(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { + if (Util.isOverridden(ListBoxModel.class, getClass(), "writeTo", StaplerRequest.class, StaplerResponse.class)) { + try { + writeTo(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp)); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + writeToImpl(req, rsp); + } + } + + /** + * @deprecated use {@link #writeTo(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + public void writeTo(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + writeToImpl(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + private void writeToImpl(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { rsp.serveExposedBean(req, this, Flavor.JSON); } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { writeTo(req, rsp); } diff --git a/core/src/main/java/hudson/util/MultipartFormDataParser.java b/core/src/main/java/hudson/util/MultipartFormDataParser.java index f173cff9802b..47e880486fba 100644 --- a/core/src/main/java/hudson/util/MultipartFormDataParser.java +++ b/core/src/main/java/hudson/util/MultipartFormDataParser.java @@ -25,14 +25,15 @@ package hudson.util; import edu.umd.cs.findbugs.annotations.CheckForNull; +import io.jenkins.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.file.Files; import java.util.HashMap; import java.util.Map; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload2.core.DiskFileItem; import org.apache.commons.fileupload2.core.DiskFileItemFactory; import org.apache.commons.fileupload2.core.FileItem; @@ -40,8 +41,8 @@ import org.apache.commons.fileupload2.core.FileUploadException; import org.apache.commons.fileupload2.core.FileUploadFileCountLimitException; import org.apache.commons.fileupload2.core.FileUploadSizeException; -import org.apache.commons.fileupload2.javax.JavaxServletDiskFileUpload; -import org.apache.commons.fileupload2.javax.JavaxServletFileUpload; +import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletDiskFileUpload; +import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletFileUpload; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -56,7 +57,7 @@ public class MultipartFormDataParser implements AutoCloseable { /** * Limits the number of form fields that can be processed in one multipart/form-data request. - * Used to set {@link org.apache.commons.fileupload2.javax.JavaxServletFileUpload#setFileCountMax(long)}. + * Used to set {@link org.apache.commons.fileupload2.jakarta.JakartaServletFileUpload#setFileCountMax(long)}. * Despite the name, this applies to all form fields, not just actual file attachments. * Set to {@code -1} to disable limits. */ @@ -64,7 +65,7 @@ public class MultipartFormDataParser implements AutoCloseable { /** * Limits the size (in bytes) of individual fields that can be processed in one multipart/form-data request. - * Used to set {@link org.apache.commons.fileupload2.javax.JavaxServletFileUpload#setFileSizeMax(long)}. + * Used to set {@link org.apache.commons.fileupload2.jakarta.JakartaServletFileUpload#setFileSizeMax(long)}. * Despite the name, this applies to all form fields, not just actual file attachments. * Set to {@code -1} to disable limits. */ @@ -72,7 +73,7 @@ public class MultipartFormDataParser implements AutoCloseable { /** * Limits the total request size (in bytes) that can be processed in one multipart/form-data request. - * Used to set {@link org.apache.commons.fileupload2.javax.JavaxServletFileUpload#setSizeMax(long)}. + * Used to set {@link org.apache.commons.fileupload2.jakarta.JakartaServletFileUpload#setSizeMax(long)}. * Set to {@code -1} to disable limits. */ private static /* nonfinal for Jenkins script console */ long FILEUPLOAD_MAX_SIZE = Long.getLong(MultipartFormDataParser.class.getName() + ".FILEUPLOAD_MAX_SIZE", -1); @@ -86,7 +87,7 @@ public MultipartFormDataParser(HttpServletRequest request, int maxParts, long ma throw new ServletException("Error creating temporary directory", e); } tmpDir.deleteOnExit(); - JavaxServletFileUpload<DiskFileItem, DiskFileItemFactory> upload = new JavaxServletDiskFileUpload(DiskFileItemFactory.builder().setFile(tmpDir).get()); + JakartaServletFileUpload<DiskFileItem, DiskFileItemFactory> upload = new JakartaServletDiskFileUpload(DiskFileItemFactory.builder().setFile(tmpDir).get()); upload.setFileCountMax(maxParts); upload.setFileSizeMax(maxPartSize); upload.setSizeMax(maxSize); @@ -116,6 +117,39 @@ public MultipartFormDataParser(HttpServletRequest request) throws ServletExcepti this(request, FILEUPLOAD_MAX_FILES, FILEUPLOAD_MAX_FILE_SIZE, FILEUPLOAD_MAX_SIZE); } + /** + * @deprecated use {@link #MultipartFormDataParser(HttpServletRequest)} + */ + @Deprecated + public MultipartFormDataParser(javax.servlet.http.HttpServletRequest request) throws javax.servlet.ServletException { + File tmpDir; + try { + tmpDir = Files.createTempDirectory("jenkins-multipart-uploads").toFile(); + } catch (IOException e) { + throw new javax.servlet.ServletException("Error creating temporary directory", e); + } + tmpDir.deleteOnExit(); + JakartaServletFileUpload<DiskFileItem, DiskFileItemFactory> upload = new JakartaServletDiskFileUpload(DiskFileItemFactory.builder().setFile(tmpDir).get()); + upload.setFileCountMax(FILEUPLOAD_MAX_FILES); + upload.setFileSizeMax(FILEUPLOAD_MAX_FILE_SIZE); + upload.setSizeMax(FILEUPLOAD_MAX_SIZE); + try { + for (FileItem fi : upload.parseRequest(HttpServletRequestWrapper.toJakartaHttpServletRequest(request))) + byName.put(fi.getFieldName(), fi); + } catch (FileUploadFileCountLimitException e) { + throw new javax.servlet.ServletException("File upload field count limit exceeded. Consider setting the Java system property " + + MultipartFormDataParser.class.getName() + ".FILEUPLOAD_MAX_FILES to a value greater than " + FILEUPLOAD_MAX_FILES + ", or to -1 to disable this limit.", e); + } catch (FileUploadByteCountLimitException e) { + throw new javax.servlet.ServletException("File upload field size limit exceeded. Consider setting the Java system property " + + MultipartFormDataParser.class.getName() + ".FILEUPLOAD_MAX_FILE_SIZE to a value greater than " + FILEUPLOAD_MAX_FILE_SIZE + ", or to -1 to disable this limit.", e); + } catch (FileUploadSizeException e) { + throw new javax.servlet.ServletException("File upload total size limit exceeded. Consider setting the Java system property " + + MultipartFormDataParser.class.getName() + ".FILEUPLOAD_MAX_SIZE to a value greater than " + FILEUPLOAD_MAX_SIZE + ", or to -1 to disable this limit.", e); + } catch (FileUploadException e) { + throw new javax.servlet.ServletException(e); + } + } + public String get(String key) { FileItem fi = byName.get(key); if (fi == null) return null; diff --git a/core/src/main/java/hudson/util/PluginServletFilter.java b/core/src/main/java/hudson/util/PluginServletFilter.java index 037b7010d51a..bb4ecfc18d9b 100644 --- a/core/src/main/java/hudson/util/PluginServletFilter.java +++ b/core/src/main/java/hudson/util/PluginServletFilter.java @@ -27,6 +27,15 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.ExtensionPoint; import hudson.security.SecurityRealm; +import io.jenkins.servlet.FilterWrapper; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; @@ -35,17 +44,11 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import jenkins.model.Jenkins; import jenkins.util.HttpServletFilter; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.CompatibleFilter; /** * Servlet {@link Filter} that chains multiple {@link Filter}s, provided by plugins @@ -60,7 +63,7 @@ * * @see SecurityRealm */ -public final class PluginServletFilter implements Filter, ExtensionPoint { +public final class PluginServletFilter implements CompatibleFilter, ExtensionPoint { private final List<Filter> list = new CopyOnWriteArrayList<>(); private /*almost final*/ FilterConfig config; @@ -101,13 +104,15 @@ public void init(FilterConfig config) throws ServletException { * Dynamically register a new filter. * May be paired with {@link #removeFilter}. * <p>For most purposes you can instead use {@link HttpServletFilter}. + * + * @since TODO */ public static void addFilter(Filter filter) throws ServletException { Jenkins j = Jenkins.getInstanceOrNull(); PluginServletFilter container = null; if (j != null) { - container = getInstance(j.servletContext); + container = getInstance(j.getServletContext()); } // https://marvelution.atlassian.net/browse/JJI-188 if (j == null || container == null) { @@ -120,17 +125,29 @@ public static void addFilter(Filter filter) throws ServletException { } } + /** + * @deprecated use {@link #addFilter(Filter)} + */ + @Deprecated + public static void addFilter(javax.servlet.Filter filter) throws javax.servlet.ServletException { + try { + addFilter(FilterWrapper.toJakartaFilter(filter)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Checks whether the given filter is already registered in the chain. * @param filter the filter to check. * @return true if the filter is already registered in the chain. - * @since 2.94 + * @since TODO */ public static boolean hasFilter(Filter filter) { Jenkins j = Jenkins.getInstanceOrNull(); PluginServletFilter container = null; if (j != null) { - container = getInstance(j.servletContext); + container = getInstance(j.getServletContext()); } if (j == null || container == null) { return LEGACY.contains(filter); @@ -139,12 +156,36 @@ public static boolean hasFilter(Filter filter) { } } + /** + * @deprecated use {@link #hasFilter(Filter)} + * @since 2.94 + */ + @Deprecated + public static boolean hasFilter(javax.servlet.Filter filter) { + return hasFilter(FilterWrapper.toJakartaFilter(filter)); + } + + /** + * @since TODO + */ public static void removeFilter(Filter filter) throws ServletException { Jenkins j = Jenkins.getInstanceOrNull(); - if (j == null || getInstance(j.servletContext) == null) { + if (j == null || getInstance(j.getServletContext()) == null) { LEGACY.remove(filter); } else { - getInstance(j.servletContext).list.remove(filter); + getInstance(j.getServletContext()).list.remove(filter); + } + } + + /** + * @deprecated use {@link #removeFilter(Filter)} + */ + @Deprecated + public static void removeFilter(javax.servlet.Filter filter) throws javax.servlet.ServletException { + try { + removeFilter(FilterWrapper.toJakartaFilter(filter)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); } } @@ -180,7 +221,7 @@ public static void cleanUp() { if (jenkins == null) { return; } - PluginServletFilter instance = getInstance(jenkins.servletContext); + PluginServletFilter instance = getInstance(jenkins.getServletContext()); if (instance != null) { // While we could rely on the current implementation of list being a CopyOnWriteArrayList // safer to just take an explicit copy of the list and operate on the copy diff --git a/core/src/main/java/hudson/util/QueryParameterMap.java b/core/src/main/java/hudson/util/QueryParameterMap.java index ba3ce8c0d00a..fc846c6fc73b 100644 --- a/core/src/main/java/hudson/util/QueryParameterMap.java +++ b/core/src/main/java/hudson/util/QueryParameterMap.java @@ -24,6 +24,7 @@ package hudson.util; +import jakarta.servlet.http.HttpServletRequest; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -31,7 +32,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; /** * Parses the query string of the URL into a key/value pair. @@ -70,6 +70,14 @@ public QueryParameterMap(HttpServletRequest req) { this(req.getQueryString()); } + /** + * @deprecated use {@link #QueryParameterMap(HttpServletRequest)} + */ + @Deprecated + public QueryParameterMap(javax.servlet.http.HttpServletRequest req) { + this(req.getQueryString()); + } + public String get(String name) { List<String> v = store.get(name); return v != null ? v.get(0) : null; diff --git a/core/src/main/java/hudson/util/RemotingDiagnostics.java b/core/src/main/java/hudson/util/RemotingDiagnostics.java index 06a42beee69d..c18e056e428b 100644 --- a/core/src/main/java/hudson/util/RemotingDiagnostics.java +++ b/core/src/main/java/hudson/util/RemotingDiagnostics.java @@ -59,8 +59,8 @@ import org.codehaus.groovy.control.customizers.ImportCustomizer; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -211,7 +211,7 @@ public HeapDump(AccessControlled owner, VirtualChannel channel) { @WebMethod(name = "heapdump.hprof") @RequirePOST - public void doHeapDump(StaplerRequest req, StaplerResponse rsp) throws IOException, InterruptedException { + public void doHeapDump(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, InterruptedException { owner.checkPermission(Jenkins.ADMINISTER); rsp.setContentType("application/octet-stream"); diff --git a/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java b/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java index b60939aae5ee..81927927c9e6 100644 --- a/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java +++ b/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java @@ -30,7 +30,7 @@ import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Adds the default view configuration to the system config page. @@ -40,7 +40,7 @@ @Extension(ordinal = 300) @Symbol("defaultView") public class GlobalDefaultViewConfiguration extends GlobalConfiguration { @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { // for compatibility reasons, the actual value is stored in Jenkins Jenkins j = Jenkins.get(); if (json.has("primaryView")) { diff --git a/core/src/main/java/hudson/views/ListViewColumn.java b/core/src/main/java/hudson/views/ListViewColumn.java index 91e93e2145da..423094af51b3 100644 --- a/core/src/main/java/hudson/views/ListViewColumn.java +++ b/core/src/main/java/hudson/views/ListViewColumn.java @@ -42,6 +42,7 @@ import java.util.logging.Logger; import jenkins.model.Jenkins; import net.sf.json.JSONObject; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.export.Exported; /** @@ -162,7 +163,7 @@ private static List<ListViewColumn> createDefaultInitialColumnList(List<Descript continue; // skip this } } - ListViewColumn lvc = d.newInstance(null, emptyJSON); + ListViewColumn lvc = d.newInstance((StaplerRequest2) null, emptyJSON); if (!lvc.shownByDefault()) { continue; // skip this } diff --git a/core/src/main/java/hudson/views/MyViewsTabBar.java b/core/src/main/java/hudson/views/MyViewsTabBar.java index bc73ba9abd9d..f6fc15745b9b 100644 --- a/core/src/main/java/hudson/views/MyViewsTabBar.java +++ b/core/src/main/java/hudson/views/MyViewsTabBar.java @@ -41,7 +41,7 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Extension point for adding a MyViewsTabBar header to Projects {@link MyViewsProperty}. @@ -100,7 +100,7 @@ public MyViewsTabBar getMyViewsTabBar() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { // for compatibility reasons, the actual value is stored in Jenkins Jenkins j = Jenkins.get(); diff --git a/core/src/main/java/hudson/views/ViewsTabBar.java b/core/src/main/java/hudson/views/ViewsTabBar.java index 195f72104aba..a7d133e78213 100644 --- a/core/src/main/java/hudson/views/ViewsTabBar.java +++ b/core/src/main/java/hudson/views/ViewsTabBar.java @@ -41,7 +41,7 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Extension point for adding a ViewsTabBar header to Projects {@link ListView}. @@ -100,7 +100,7 @@ public ViewsTabBar getViewsTabBar() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { // for compatibility reasons, the actual value is stored in Jenkins Jenkins j = Jenkins.get(); diff --git a/core/src/main/java/hudson/widgets/HistoryWidget.java b/core/src/main/java/hudson/widgets/HistoryWidget.java index 1c291d1a48ff..44f6de67ee6f 100644 --- a/core/src/main/java/hudson/widgets/HistoryWidget.java +++ b/core/src/main/java/hudson/widgets/HistoryWidget.java @@ -33,13 +33,13 @@ import hudson.model.Queue; import hudson.model.Run; import hudson.util.AlternativeUiTextProvider; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; -import javax.servlet.ServletException; import jenkins.util.SystemProperties; import jenkins.widgets.HistoryPageEntry; import jenkins.widgets.HistoryPageFilter; @@ -49,8 +49,8 @@ import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.Header; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Displays the history of records (normally {@link Run}s) on the side panel. @@ -103,7 +103,7 @@ public class HistoryWidget<O extends ModelObject, T> extends Widget { * The parent model object that owns this widget. */ public HistoryWidget(O owner, Iterable<T> baseList, Adapter<? super T> adapter) { - StaplerRequest currentRequest = Stapler.getCurrentRequest(); + StaplerRequest2 currentRequest = Stapler.getCurrentRequest2(); this.adapter = adapter; this.baseList = baseList; this.baseUrl = Functions.getNearestAncestorUrl(currentRequest, owner); @@ -234,7 +234,7 @@ public void setTrimmed(boolean trimmed) { * The build 'number' to fetch. This is string because various variants * uses non-numbers as the build key. */ - public void doAjax(StaplerRequest req, StaplerResponse rsp, + public void doAjax(StaplerRequest2 req, StaplerResponse2 rsp, @Header("n") String n) throws IOException, ServletException { rsp.setContentType("text/html;charset=UTF-8"); @@ -298,7 +298,7 @@ public interface Adapter<T> { String getNextKey(String key); } - private Long getPagingParam(@CheckForNull StaplerRequest currentRequest, @CheckForNull String name) { + private Long getPagingParam(@CheckForNull StaplerRequest2 currentRequest, @CheckForNull String name) { if (currentRequest == null || name == null) { return null; } diff --git a/core/src/main/java/hudson/widgets/RenderOnDemandClosure.java b/core/src/main/java/hudson/widgets/RenderOnDemandClosure.java index 9092526f109b..bd3a5518a75b 100644 --- a/core/src/main/java/hudson/widgets/RenderOnDemandClosure.java +++ b/core/src/main/java/hudson/widgets/RenderOnDemandClosure.java @@ -27,6 +27,7 @@ import hudson.Util; import hudson.model.Descriptor; import hudson.util.PackedMap; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -35,13 +36,12 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import org.apache.commons.jelly.JellyContext; import org.apache.commons.jelly.JellyTagException; import org.apache.commons.jelly.Script; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.bind.JavaScriptMethod; import org.kohsuke.stapler.framework.adjunct.AdjunctsInPage; import org.kohsuke.stapler.jelly.DefaultScriptInvoker; @@ -95,12 +95,12 @@ public RenderOnDemandClosure(JellyContext context, String attributesToCapture) { public HttpResponse render() { return new HttpResponse() { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { req.getWebApp().getDispatchValidator().allowDispatch(req, rsp); try { new DefaultScriptInvoker() { @Override - protected JellyContext createContext(StaplerRequest req, StaplerResponse rsp, Script script, Object it) { + protected JellyContext createContext(StaplerRequest2 req, StaplerResponse2 rsp, Script script, Object it) { JellyContext context = super.createContext(req, rsp, script, it); for (int i = bodyStack.length - 1; i > 0; i--) { // exclude bodyStack[0] context = new JellyContext(context); @@ -115,7 +115,7 @@ protected JellyContext createContext(StaplerRequest req, StaplerResponse rsp, Sc } @Override - protected void exportVariables(StaplerRequest req, StaplerResponse rsp, Script script, Object it, JellyContext context) { + protected void exportVariables(StaplerRequest2 req, StaplerResponse2 rsp, Script script, Object it, JellyContext context) { super.exportVariables(req, rsp, script, it, context); context.setVariables(variables); req.setAttribute("currentDescriptorByNameUrl", currentDescriptorByNameUrl); diff --git a/core/src/main/java/jenkins/ErrorAttributeFilter.java b/core/src/main/java/jenkins/ErrorAttributeFilter.java index be67bdab7588..f3dfe05f4f89 100644 --- a/core/src/main/java/jenkins/ErrorAttributeFilter.java +++ b/core/src/main/java/jenkins/ErrorAttributeFilter.java @@ -1,24 +1,24 @@ package jenkins; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.CompatibleFilter; import org.springframework.security.core.Authentication; /** * Record the current user authentication for later impersonation if the response is 404 Not Found. * - * @see Jenkins#generateNotFoundResponse(org.kohsuke.stapler.StaplerRequest, org.kohsuke.stapler.StaplerResponse) + * @see Jenkins#generateNotFoundResponse(org.kohsuke.stapler.StaplerRequest2, org.kohsuke.stapler.StaplerResponse2) */ @Restricted(NoExternalUse.class) -public class ErrorAttributeFilter implements Filter { +public class ErrorAttributeFilter implements CompatibleFilter { public static final String USER_ATTRIBUTE = "jenkins.ErrorAttributeFilter.user"; diff --git a/core/src/main/java/jenkins/I18n.java b/core/src/main/java/jenkins/I18n.java index d9b234b0d2c7..23fa2a4417eb 100644 --- a/core/src/main/java/jenkins/I18n.java +++ b/core/src/main/java/jenkins/I18n.java @@ -32,7 +32,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Internationalization REST (ish) API. @@ -74,7 +74,7 @@ public String getUrlName() { * @param request The request. * @return The JSON response. */ - public HttpResponse doResourceBundle(StaplerRequest request) { + public HttpResponse doResourceBundle(StaplerRequest2 request) { String baseName = request.getParameter("baseName"); if (baseName == null) { diff --git a/core/src/main/java/jenkins/JenkinsHttpSessionListener.java b/core/src/main/java/jenkins/JenkinsHttpSessionListener.java index 4d2c7960b25b..9a9c0b9efba3 100644 --- a/core/src/main/java/jenkins/JenkinsHttpSessionListener.java +++ b/core/src/main/java/jenkins/JenkinsHttpSessionListener.java @@ -24,9 +24,9 @@ package jenkins; +import jakarta.servlet.http.HttpSessionEvent; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.http.HttpSessionEvent; import jenkins.util.HttpSessionListener; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -37,7 +37,7 @@ * @author <a href="mailto:tom.fennelly@gmail.com">tom.fennelly@gmail.com</a> */ @Restricted(NoExternalUse.class) -public final class JenkinsHttpSessionListener implements javax.servlet.http.HttpSessionListener { +public final class JenkinsHttpSessionListener implements jakarta.servlet.http.HttpSessionListener { // TODO: Seems like classes like this should live in the /war/src/java // But that applies to a number of other classes too and it has never happened, so will diff --git a/core/src/main/java/jenkins/agents/CloudSet.java b/core/src/main/java/jenkins/agents/CloudSet.java index 163556a001d1..adbbf51de4e4 100644 --- a/core/src/main/java/jenkins/agents/CloudSet.java +++ b/core/src/main/java/jenkins/agents/CloudSet.java @@ -36,6 +36,7 @@ import hudson.model.UpdateCenter; import hudson.slaves.Cloud; import hudson.util.FormValidation; +import jakarta.servlet.ServletException; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -45,7 +46,6 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.model.ModelObjectWithChildren; import jenkins.model.ModelObjectWithContextMenu; @@ -56,7 +56,8 @@ import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; @@ -102,7 +103,7 @@ public String getSearchUrl() { @SuppressWarnings("unused") // stapler @Restricted(DoNotUse.class) // stapler - public String getCloudUrl(StaplerRequest request, Jenkins jenkins, Cloud cloud) { + public String getCloudUrl(StaplerRequest2 request, Jenkins jenkins, Cloud cloud) { String context = Functions.getNearestAncestorUrl(request, jenkins); if (Jenkins.get().getCloud(cloud.name) != cloud) { // this cloud is not the first occurrence with this name return context + "/cloud/cloudByIndex/" + getClouds().indexOf(cloud) + "/"; @@ -111,6 +112,16 @@ public String getCloudUrl(StaplerRequest request, Jenkins jenkins, Cloud cloud) } } + /** + * @deprecated use {@link #getCloudUrl(StaplerRequest2, Jenkins, Cloud)} + */ + @Deprecated + @SuppressWarnings("unused") // stapler + @Restricted(DoNotUse.class) // stapler + public String getCloudUrl(StaplerRequest request, Jenkins jenkins, Cloud cloud) { + return getCloudUrl(StaplerRequest.toStaplerRequest2(request), jenkins, cloud); + } + @SuppressWarnings("unused") // stapler @Restricted(DoNotUse.class) // stapler public Cloud getCloudByIndex(int index) { @@ -128,13 +139,13 @@ public String getCloudUpdateCenterCategoryLabel() { } @Override - public ModelObjectWithContextMenu.ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ModelObjectWithContextMenu.ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { ModelObjectWithContextMenu.ContextMenu m = new ModelObjectWithContextMenu.ContextMenu(); Jenkins.get().clouds.stream().forEach(m::add); return m; } - public Cloud getDynamic(String name, StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public Cloud getDynamic(String name, StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { return Jenkins.get().clouds.getByName(name); } @@ -186,7 +197,7 @@ public FormValidation doCheckName(@QueryParameter String value) { * First check point in creating a new cloud. */ @RequirePOST - public synchronized void doCreate(StaplerRequest req, StaplerResponse rsp, + public synchronized void doCreate(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String name, @QueryParameter String mode, @QueryParameter String from) throws IOException, ServletException, Descriptor.FormException { final Jenkins jenkins = Jenkins.get(); @@ -226,7 +237,7 @@ public synchronized void doCreate(StaplerRequest req, StaplerResponse rsp, } } - private void handleNewCloudPage(Descriptor<Cloud> descriptor, String name, StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException { + private void handleNewCloudPage(Descriptor<Cloud> descriptor, String name, StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, Descriptor.FormException { checkName(name); JSONObject formData = req.getSubmittedForm(); formData.put("name", name); @@ -240,7 +251,7 @@ private void handleNewCloudPage(Descriptor<Cloud> descriptor, String name, Stapl * Really creates a new agent. */ @POST - public synchronized void doDoCreate(StaplerRequest req, StaplerResponse rsp, + public synchronized void doDoCreate(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String cloudDescriptorName) throws IOException, ServletException, Descriptor.FormException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); Descriptor<Cloud> cloudDescriptor = Cloud.all().findByName(cloudDescriptorName); @@ -256,7 +267,7 @@ public synchronized void doDoCreate(StaplerRequest req, StaplerResponse rsp, } @POST - public void doReorder(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doReorder(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); var names = req.getParameterValues("name"); if (names == null) { diff --git a/core/src/main/java/jenkins/agents/WebSocketAgents.java b/core/src/main/java/jenkins/agents/WebSocketAgents.java index d9560f156ebd..1da8d046d56f 100644 --- a/core/src/main/java/jenkins/agents/WebSocketAgents.java +++ b/core/src/main/java/jenkins/agents/WebSocketAgents.java @@ -57,8 +57,8 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; @Extension @Restricted(NoExternalUse.class) @@ -71,7 +71,7 @@ public String getUrlName() { return WebSockets.isSupported() ? "wsagents" : null; } - public HttpResponse doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException { + public HttpResponse doIndex(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { String agent = req.getHeader(JnlpConnectionState.CLIENT_NAME_KEY); String secret = req.getHeader(JnlpConnectionState.SECRET_KEY); String remoteCapabilityStr = req.getHeader(Capability.KEY); diff --git a/core/src/main/java/jenkins/appearance/AppearanceGlobalConfiguration.java b/core/src/main/java/jenkins/appearance/AppearanceGlobalConfiguration.java index 96e61c0c9371..007b9a314dd5 100644 --- a/core/src/main/java/jenkins/appearance/AppearanceGlobalConfiguration.java +++ b/core/src/main/java/jenkins/appearance/AppearanceGlobalConfiguration.java @@ -30,18 +30,18 @@ import hudson.model.Descriptor; import hudson.model.ManagementLink; import hudson.util.FormApply; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.console.ConsoleUrlProviderGlobalConfiguration; import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; @Extension @@ -94,13 +94,13 @@ public Category getCategory() { } @POST - public synchronized void doConfigure(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException { + public synchronized void doConfigure(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, Descriptor.FormException { boolean result = configure(req, req.getSubmittedForm()); LOGGER.log(Level.FINE, "appearance saved: " + result); FormApply.success(req.getContextPath() + "/manage").generateResponse(req, rsp, null); } - private boolean configure(StaplerRequest req, JSONObject json) throws Descriptor.FormException, IOException { + private boolean configure(StaplerRequest2 req, JSONObject json) throws Descriptor.FormException, IOException { Jenkins j = Jenkins.get(); j.checkPermission(Jenkins.MANAGE); @@ -113,7 +113,7 @@ private boolean configure(StaplerRequest req, JSONObject json) throws Descriptor return result; } - private boolean configureDescriptor(StaplerRequest req, JSONObject json, Descriptor<?> d) throws Descriptor.FormException { + private boolean configureDescriptor(StaplerRequest2 req, JSONObject json, Descriptor<?> d) throws Descriptor.FormException { String name = d.getJsonSafeClassName(); JSONObject js = json.has(name) ? json.getJSONObject(name) : new JSONObject(); // if it doesn't have the property, the method returns invalid null object. json.putAll(js); diff --git a/core/src/main/java/jenkins/console/ConsoleUrlProvider.java b/core/src/main/java/jenkins/console/ConsoleUrlProvider.java index 0b9e70c3db53..3310f13fd332 100644 --- a/core/src/main/java/jenkins/console/ConsoleUrlProvider.java +++ b/core/src/main/java/jenkins/console/ConsoleUrlProvider.java @@ -119,9 +119,9 @@ default Descriptor<ConsoleUrlProvider> getDescriptor() { url = run.getUrl() + "console"; } if (url.startsWith("/")) { - return Stapler.getCurrentRequest().getContextPath() + url; + return Stapler.getCurrentRequest2().getContextPath() + url; } else { - return Stapler.getCurrentRequest().getContextPath() + '/' + url; + return Stapler.getCurrentRequest2().getContextPath() + '/' + url; } } diff --git a/core/src/main/java/jenkins/console/ConsoleUrlProviderGlobalConfiguration.java b/core/src/main/java/jenkins/console/ConsoleUrlProviderGlobalConfiguration.java index a63fe679f200..0ce3ca071322 100644 --- a/core/src/main/java/jenkins/console/ConsoleUrlProviderGlobalConfiguration.java +++ b/core/src/main/java/jenkins/console/ConsoleUrlProviderGlobalConfiguration.java @@ -43,7 +43,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Allows administrators to activate and sort {@link ConsoleUrlProvider} extensions to set defaults for all users. @@ -79,7 +79,7 @@ public void setProviders(List<ConsoleUrlProvider> providers) { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { // We have to null out providers before data binding to allow all providers to be deleted in the config UI. // We use a BulkChange to avoid double saves in other cases. try (BulkChange bc = new BulkChange(this)) { diff --git a/core/src/main/java/jenkins/diagnostics/ControllerExecutorsAgents.java b/core/src/main/java/jenkins/diagnostics/ControllerExecutorsAgents.java index 017fda058051..028528cd523a 100644 --- a/core/src/main/java/jenkins/diagnostics/ControllerExecutorsAgents.java +++ b/core/src/main/java/jenkins/diagnostics/ControllerExecutorsAgents.java @@ -32,8 +32,8 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; @Extension @@ -58,7 +58,7 @@ public boolean isActivated() { } @RequirePOST - public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doAct(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.hasParameter("no")) { disable(true); rsp.sendRedirect(req.getContextPath() + "/manage"); diff --git a/core/src/main/java/jenkins/diagnostics/ControllerExecutorsNoAgents.java b/core/src/main/java/jenkins/diagnostics/ControllerExecutorsNoAgents.java index d06c3c7bff69..8a73178f3849 100644 --- a/core/src/main/java/jenkins/diagnostics/ControllerExecutorsNoAgents.java +++ b/core/src/main/java/jenkins/diagnostics/ControllerExecutorsNoAgents.java @@ -32,8 +32,8 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; @Extension @@ -52,7 +52,7 @@ public boolean isSecurity() { } @RequirePOST - public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doAct(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.hasParameter("no")) { disable(true); rsp.sendRedirect(req.getContextPath() + "/manage"); diff --git a/core/src/main/java/jenkins/diagnostics/SecurityIsOffMonitor.java b/core/src/main/java/jenkins/diagnostics/SecurityIsOffMonitor.java index 4ca6972304b3..04c134333063 100644 --- a/core/src/main/java/jenkins/diagnostics/SecurityIsOffMonitor.java +++ b/core/src/main/java/jenkins/diagnostics/SecurityIsOffMonitor.java @@ -5,8 +5,8 @@ import java.io.IOException; import jenkins.model.Jenkins; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -40,7 +40,7 @@ public boolean isSecurity() { * Depending on whether the user said "yes" or "no", send him to the right place. */ @RequirePOST - public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doAct(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.hasParameter("no")) { disable(true); rsp.sendRedirect(req.getContextPath() + "/manage"); diff --git a/core/src/main/java/jenkins/diagnostics/URICheckEncodingMonitor.java b/core/src/main/java/jenkins/diagnostics/URICheckEncodingMonitor.java index 9fdd7bc38436..df7af46879b0 100644 --- a/core/src/main/java/jenkins/diagnostics/URICheckEncodingMonitor.java +++ b/core/src/main/java/jenkins/diagnostics/URICheckEncodingMonitor.java @@ -14,7 +14,7 @@ import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; @Restricted(NoExternalUse.class) @Extension @@ -36,7 +36,7 @@ public String getDisplayName() { return Messages.URICheckEncodingMonitor_DisplayName(); } - public FormValidation doCheckURIEncoding(StaplerRequest request) throws IOException { + public FormValidation doCheckURIEncoding(StaplerRequest2 request) throws IOException { Jenkins.get().checkPermission(Jenkins.ADMINISTER); // expected is non-ASCII String final String expected = "\u57f7\u4e8b"; diff --git a/core/src/main/java/jenkins/fingerprints/GlobalFingerprintConfiguration.java b/core/src/main/java/jenkins/fingerprints/GlobalFingerprintConfiguration.java index 485d0fd2fe55..93f2966c7382 100644 --- a/core/src/main/java/jenkins/fingerprints/GlobalFingerprintConfiguration.java +++ b/core/src/main/java/jenkins/fingerprints/GlobalFingerprintConfiguration.java @@ -32,7 +32,7 @@ import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Allows configuring the settings of fingerprints. @@ -74,7 +74,7 @@ public void setFingerprintCleanupDisabled(boolean fingerprintCleanupDisabled) { } @Override - public boolean configure(StaplerRequest req, JSONObject json) { + public boolean configure(StaplerRequest2 req, JSONObject json) { req.bindJSON(this, json); save(); return true; diff --git a/core/src/main/java/jenkins/install/SetupWizard.java b/core/src/main/java/jenkins/install/SetupWizard.java index 4ecd23ef9e81..2707807906f1 100644 --- a/core/src/main/java/jenkins/install/SetupWizard.java +++ b/core/src/main/java/jenkins/install/SetupWizard.java @@ -23,6 +23,16 @@ import hudson.util.HttpResponses; import hudson.util.PluginServletFilter; import hudson.util.VersionNumber; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; import java.io.File; import java.io.IOException; import java.net.HttpRetryException; @@ -43,16 +53,6 @@ import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import jenkins.model.Jenkins; import jenkins.model.JenkinsLocationConfiguration; import jenkins.security.ApiTokenProperty; @@ -66,10 +66,11 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.CompatibleFilter; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; import org.kohsuke.stapler.verb.POST; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -332,7 +333,7 @@ public boolean isUsingSecurityToken() { */ @POST @Restricted(NoExternalUse.class) - public HttpResponse doCreateAdminUser(StaplerRequest req, StaplerResponse rsp) throws IOException { + public HttpResponse doCreateAdminUser(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { Jenkins j = Jenkins.get(); j.checkPermission(Jenkins.ADMINISTER); @@ -416,7 +417,7 @@ public HttpResponse doCreateAdminUser(StaplerRequest req, StaplerResponse rsp) t @POST @Restricted(NoExternalUse.class) - public HttpResponse doConfigureInstance(StaplerRequest req, @QueryParameter String rootUrl) { + public HttpResponse doConfigureInstance(StaplerRequest2 req, @QueryParameter String rootUrl) { Jenkins.get().checkPermission(Jenkins.ADMINISTER); Map<String, String> errors = new HashMap<>(); @@ -756,7 +757,7 @@ public boolean hasSetupWizardFilter() { /** * This filter will validate that the security token is provided */ - private final Filter FORCE_SETUP_WIZARD_FILTER = new Filter() { + private final Filter FORCE_SETUP_WIZARD_FILTER = new CompatibleFilter() { @Override public void init(FilterConfig cfg) throws ServletException { } diff --git a/core/src/main/java/jenkins/management/AdministrativeMonitorsApi.java b/core/src/main/java/jenkins/management/AdministrativeMonitorsApi.java index ea2b8e2cf771..8f3f83dd89a9 100644 --- a/core/src/main/java/jenkins/management/AdministrativeMonitorsApi.java +++ b/core/src/main/java/jenkins/management/AdministrativeMonitorsApi.java @@ -3,26 +3,26 @@ import hudson.Extension; import hudson.model.PageDecorator; import hudson.model.RootAction; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.GET; @Extension @Restricted(NoExternalUse.class) public class AdministrativeMonitorsApi implements RootAction { @GET - public void doNonSecurityPopupContent(StaplerRequest req, StaplerResponse resp) throws IOException, ServletException { + public void doNonSecurityPopupContent(StaplerRequest2 req, StaplerResponse2 resp) throws IOException, ServletException { AdministrativeMonitorsApiData viewData = new AdministrativeMonitorsApiData(getDecorator().getNonSecurityAdministrativeMonitors()); req.getView(viewData, "monitorsList.jelly").forward(req, resp); } @GET - public void doSecurityPopupContent(StaplerRequest req, StaplerResponse resp) throws IOException, ServletException { + public void doSecurityPopupContent(StaplerRequest2 req, StaplerResponse2 resp) throws IOException, ServletException { AdministrativeMonitorsApiData viewData = new AdministrativeMonitorsApiData(getDecorator().getSecurityAdministrativeMonitors()); req.getView(viewData, "monitorsList.jelly").forward(req, resp); } diff --git a/core/src/main/java/jenkins/management/AdministrativeMonitorsConfiguration.java b/core/src/main/java/jenkins/management/AdministrativeMonitorsConfiguration.java index 78de6ccfc387..cc4ea526566f 100644 --- a/core/src/main/java/jenkins/management/AdministrativeMonitorsConfiguration.java +++ b/core/src/main/java/jenkins/management/AdministrativeMonitorsConfiguration.java @@ -34,13 +34,13 @@ import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; @Extension @Restricted(NoExternalUse.class) public class AdministrativeMonitorsConfiguration extends GlobalConfiguration { @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { JSONArray monitors = json.optJSONArray("administrativeMonitor"); for (AdministrativeMonitor am : AdministrativeMonitor.all()) { try { diff --git a/core/src/main/java/jenkins/management/AdministrativeMonitorsDecorator.java b/core/src/main/java/jenkins/management/AdministrativeMonitorsDecorator.java index 5b94090f4e3b..d531f898c065 100644 --- a/core/src/main/java/jenkins/management/AdministrativeMonitorsDecorator.java +++ b/core/src/main/java/jenkins/management/AdministrativeMonitorsDecorator.java @@ -43,7 +43,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Ancestor; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Show notifications and popups for active administrative monitors on all pages. @@ -143,7 +143,7 @@ public Collection<AdministrativeMonitor> getMonitorsToDisplay() { return null; } - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req == null) { return null; diff --git a/core/src/main/java/jenkins/management/ShutdownLink.java b/core/src/main/java/jenkins/management/ShutdownLink.java index a5ebcba4f8d3..7f8b4cd36495 100644 --- a/core/src/main/java/jenkins/management/ShutdownLink.java +++ b/core/src/main/java/jenkins/management/ShutdownLink.java @@ -28,15 +28,15 @@ import hudson.Extension; import hudson.model.ManagementLink; import hudson.security.Permission; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; @Extension(ordinal = Integer.MIN_VALUE) @@ -66,7 +66,7 @@ public String getUrlName() { } @POST - public synchronized void doPrepare(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { + public synchronized void doPrepare(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, InterruptedException { Jenkins.get().checkPermission(Jenkins.MANAGE); JSONObject submittedForm = req.getSubmittedForm(); @@ -77,7 +77,7 @@ public synchronized void doPrepare(StaplerRequest req, StaplerResponse rsp) thro } @POST - public synchronized void doCancel(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doCancel(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { Jenkins.get().checkPermission(Jenkins.MANAGE); LOGGER.log(Level.FINE, "Shutdown cancel requested by user {0}", Jenkins.getAuthentication().getName()); diff --git a/core/src/main/java/jenkins/model/ArtifactManagerConfiguration.java b/core/src/main/java/jenkins/model/ArtifactManagerConfiguration.java index 9fe7412699f4..d6dfeafd68f4 100644 --- a/core/src/main/java/jenkins/model/ArtifactManagerConfiguration.java +++ b/core/src/main/java/jenkins/model/ArtifactManagerConfiguration.java @@ -31,7 +31,7 @@ import java.io.IOException; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * List of configured {@link ArtifactManagerFactory}s. @@ -55,7 +55,7 @@ public DescribableList<ArtifactManagerFactory, ArtifactManagerFactoryDescriptor> return artifactManagerFactories; } - @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + @Override public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { try { artifactManagerFactories.rebuildHetero(req, json, ArtifactManagerFactoryDescriptor.all(), "artifactManagerFactories"); return true; diff --git a/core/src/main/java/jenkins/model/AssetManager.java b/core/src/main/java/jenkins/model/AssetManager.java index 5da61d203026..65882afc64d5 100644 --- a/core/src/main/java/jenkins/model/AssetManager.java +++ b/core/src/main/java/jenkins/model/AssetManager.java @@ -4,16 +4,16 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.model.UnprotectedRootAction; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URL; import java.util.Enumeration; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import jenkins.ClassLoaderReflectionToolkit; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Serves files located in the {@code /assets} classpath directory via the Jenkins core ClassLoader. @@ -46,7 +46,7 @@ public String getUrlName() { /** * Exposes assets in the core classloader over HTTP. */ - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { String path = req.getRestOfPath(); URL resource = findResource(path); diff --git a/core/src/main/java/jenkins/model/BuiltInNodeMigration.java b/core/src/main/java/jenkins/model/BuiltInNodeMigration.java index 7f08aa7d5b40..c777407f3c65 100644 --- a/core/src/main/java/jenkins/model/BuiltInNodeMigration.java +++ b/core/src/main/java/jenkins/model/BuiltInNodeMigration.java @@ -26,14 +26,14 @@ import hudson.Extension; import hudson.model.AdministrativeMonitor; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -51,7 +51,7 @@ public boolean isActivated() { } @RequirePOST - public void doAct(StaplerRequest req, StaplerResponse rsp, @QueryParameter String yes, @QueryParameter String no) throws IOException, ServletException { + public void doAct(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String yes, @QueryParameter String no) throws IOException, ServletException { if (yes != null) { Jenkins.get().performRenameMigration(); } else if (no != null) { diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java index 023eb52a4ff6..869ec901757b 100644 --- a/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java @@ -33,7 +33,7 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Global configuration UI for background build discarders @@ -65,7 +65,7 @@ public DescribableList<GlobalBuildDiscarderStrategy, GlobalBuildDiscarderStrateg } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { try { configuredBuildDiscarders.rebuildHetero(req, json, GlobalBuildDiscarderStrategyDescriptor.all(), "configuredBuildDiscarders"); return true; diff --git a/core/src/main/java/jenkins/model/GlobalConfiguration.java b/core/src/main/java/jenkins/model/GlobalConfiguration.java index 4a5aa76ba117..af788945b2a2 100644 --- a/core/src/main/java/jenkins/model/GlobalConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalConfiguration.java @@ -3,10 +3,12 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.ExtensionList; import hudson.ExtensionPoint; +import hudson.Util; import hudson.model.Describable; import hudson.model.Descriptor; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Convenient base class for extensions that contributes to the system configuration page but nothing @@ -28,7 +30,7 @@ * * <p> * While an implementation might store its actual configuration data in various ways, - * meaning {@link #configure(StaplerRequest, JSONObject)} must be overridden, + * meaning {@link #configure(StaplerRequest2, JSONObject)} must be overridden, * in the normal case you would simply define persistable fields with getters and setters. * The {@code config} view would use data-bound controls like {@code f:entry}. * Then make sure your constructor calls {@link #load} and your setters call {@link #save}. @@ -58,12 +60,29 @@ public String getGlobalConfigPage() { } /** - * By default, calls {@link StaplerRequest#bindJSON(Object, JSONObject)}, + * By default, calls {@link StaplerRequest2#bindJSON(Object, JSONObject)}, * appropriate when your implementation has getters and setters for all fields. * <p>{@inheritDoc} */ @Override + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { + if (Util.isOverridden(GlobalConfiguration.class, getClass(), "configure", StaplerRequest.class, JSONObject.class)) { + return configure(StaplerRequest.fromStaplerRequest2(req), json); + } else { + return configureImpl(req, json); + } + } + + /** + * @deprecated use {@link #configure(StaplerRequest2, JSONObject)} + */ + @Deprecated + @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + return configureImpl(StaplerRequest.toStaplerRequest2(req), json); + } + + private boolean configureImpl(StaplerRequest2 req, JSONObject json) throws FormException { req.bindJSON(this, json); return true; } diff --git a/core/src/main/java/jenkins/model/GlobalNodePropertiesConfiguration.java b/core/src/main/java/jenkins/model/GlobalNodePropertiesConfiguration.java index b40b261f0f31..2ca6863c014b 100644 --- a/core/src/main/java/jenkins/model/GlobalNodePropertiesConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalNodePropertiesConfiguration.java @@ -6,7 +6,7 @@ import java.io.IOException; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Include {@link NodePropertyDescriptor} configurations. @@ -16,7 +16,7 @@ @Extension(ordinal = 110) @Symbol("nodeProperties") // historically this was placed above GlobalPluginConfiguration public class GlobalNodePropertiesConfiguration extends GlobalConfiguration { @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { try { Jenkins j = Jenkins.get(); JSONObject np = json.getJSONObject("globalNodeProperties"); diff --git a/core/src/main/java/jenkins/model/GlobalPluginConfiguration.java b/core/src/main/java/jenkins/model/GlobalPluginConfiguration.java index e2803a9c1e76..d7b2336f57c0 100644 --- a/core/src/main/java/jenkins/model/GlobalPluginConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalPluginConfiguration.java @@ -4,11 +4,11 @@ import hudson.Plugin; import hudson.PluginWrapper; import hudson.StructuredForm; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Include config.jelly defined for {@link Plugin}s. @@ -21,7 +21,7 @@ @Extension(ordinal = 100) @Symbol("plugin") // historically this was placed above general configuration from arbitrary descriptors public class GlobalPluginConfiguration extends GlobalConfiguration { @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { try { for (JSONObject o : StructuredForm.toList(json, "plugin")) { String pluginName = o.getString("name"); diff --git a/core/src/main/java/jenkins/model/GlobalProjectNamingStrategyConfiguration.java b/core/src/main/java/jenkins/model/GlobalProjectNamingStrategyConfiguration.java index a1ed1ebd763a..35c3cc3193fd 100644 --- a/core/src/main/java/jenkins/model/GlobalProjectNamingStrategyConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalProjectNamingStrategyConfiguration.java @@ -29,7 +29,7 @@ import hudson.security.Permission; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Configures the project naming strategy. @@ -40,7 +40,7 @@ public class GlobalProjectNamingStrategyConfiguration extends GlobalConfiguration { @Override - public boolean configure(StaplerRequest req, JSONObject json) throws hudson.model.Descriptor.FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws hudson.model.Descriptor.FormException { // for compatibility reasons, the actual value is stored in Jenkins Jenkins j = Jenkins.get(); final JSONObject optJSONObject = json.optJSONObject("useProjectNamingStrategy"); diff --git a/core/src/main/java/jenkins/model/GlobalQuietPeriodConfiguration.java b/core/src/main/java/jenkins/model/GlobalQuietPeriodConfiguration.java index e3cbf464acbc..91ccba1c268e 100644 --- a/core/src/main/java/jenkins/model/GlobalQuietPeriodConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalQuietPeriodConfiguration.java @@ -30,7 +30,7 @@ import java.io.IOException; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Configures the system-default quiet period. @@ -44,7 +44,7 @@ public int getQuietPeriod() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { int i = 0; try { i = Integer.parseInt(json.getString("quietPeriod")); diff --git a/core/src/main/java/jenkins/model/GlobalSCMRetryCountConfiguration.java b/core/src/main/java/jenkins/model/GlobalSCMRetryCountConfiguration.java index c2543a24d4b7..e60ac1c9a598 100644 --- a/core/src/main/java/jenkins/model/GlobalSCMRetryCountConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalSCMRetryCountConfiguration.java @@ -31,7 +31,7 @@ import net.sf.json.JSONException; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Configures global SCM retry count default. @@ -45,7 +45,7 @@ public int getScmCheckoutRetryCount() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { try { // for compatibility reasons, this value is stored in Jenkins Jenkins.get().setScmCheckoutRetryCount(json.getInt("scmCheckoutRetryCount")); diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index a648935527ae..6b3500e6b66a 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -35,12 +35,12 @@ import static hudson.init.InitMilestone.JOB_LOADED; import static hudson.init.InitMilestone.PLUGINS_PREPARED; import static hudson.init.InitMilestone.SYSTEM_CONFIG_LOADED; +import static jakarta.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND; import static java.util.logging.Level.FINE; import static java.util.logging.Level.INFO; import static java.util.logging.Level.SEVERE; import static java.util.logging.Level.WARNING; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; -import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; import com.google.common.annotations.VisibleForTesting; import com.google.inject.Inject; @@ -210,6 +210,14 @@ import hudson.views.MyViewsTabBar; import hudson.views.ViewsTabBar; import hudson.widgets.Widget; +import io.jenkins.servlet.RequestDispatcherWrapper; +import io.jenkins.servlet.ServletContextWrapper; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -257,11 +265,6 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import javax.crypto.SecretKey; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; import jenkins.AgentProtocol; import jenkins.ErrorAttributeFilter; import jenkins.ExtensionComponentSet; @@ -283,6 +286,7 @@ import jenkins.security.stapler.StaplerDispatchValidator; import jenkins.security.stapler.StaplerDispatchable; import jenkins.security.stapler.StaplerFilteredActionListener; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.security.stapler.TypedFilter; import jenkins.slaves.WorkspaceLocator; import jenkins.util.JenkinsJVM; @@ -320,7 +324,9 @@ import org.kohsuke.stapler.StaplerFallback; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebApp; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.export.Exported; @@ -744,8 +750,20 @@ private static int getSlaveAgentPortInitialValue(int def) { @Deprecated public final transient NodeProvisioner overallNodeProvisioner = unlabeledNodeProvisioner; + /** + * @deprecated use {@link #getServletContext} + */ + @Deprecated + public final transient javax.servlet.ServletContext servletContext; + + private final transient ServletContext jakartaServletContext; - public final transient ServletContext servletContext; + /** + * @since TODO + */ + public ServletContext getServletContext() { + return this.jakartaServletContext; + } /** * Transient action list. Useful for adding navigation items to the navigation bar @@ -922,7 +940,8 @@ protected Jenkins(File root, ServletContext context, PluginManager pluginManager // As Jenkins is starting, grant this process full control try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { this.root = root; - this.servletContext = context; + this.jakartaServletContext = context; + this.servletContext = ServletContextWrapper.fromJakartServletContext(context); computeVersion(context); if (theInstance != null) throw new IllegalStateException("second instance"); @@ -972,7 +991,7 @@ protected Jenkins(File root, ServletContext context, PluginManager pluginManager if (pluginManager == null) pluginManager = PluginManager.createDefault(this); this.pluginManager = pluginManager; - WebApp webApp = WebApp.get(servletContext); + WebApp webApp = WebApp.get(getServletContext()); // JSON binding needs to be able to see all the classes from all the plugins webApp.setClassLoader(pluginManager.uberClassLoader); webApp.setJsonInErrorMessageSanitizer(RedactSecretJsonInErrorMessageSanitizer.INSTANCE); @@ -990,7 +1009,7 @@ protected Jenkins(File root, ServletContext context, PluginManager pluginManager webApp.setDispatchValidator(new StaplerDispatchValidator()); webApp.setFilteredDispatchTriggerListener(actionListener); - adjuncts = new AdjunctManager(servletContext, pluginManager.uberClassLoader, "adjuncts/" + SESSION_HASH, TimeUnit.DAYS.toMillis(365)); + adjuncts = new AdjunctManager(getServletContext(), pluginManager.uberClassLoader, "adjuncts/" + SESSION_HASH, TimeUnit.DAYS.toMillis(365)); ClassFilterImpl.register(); @@ -1391,7 +1410,7 @@ public int getExpectedPort() { } @RequirePOST - public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doAct(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { j.forceSetSlaveAgentPort(getExpectedPort()); rsp.sendRedirect2(req.getContextPath() + "/manage"); } @@ -1458,9 +1477,9 @@ public void setNoUsageStatistics(Boolean noUsageStatistics) throws IOException { public Api getApi() { /* Do not show "REST API" link in footer when on 404 error page */ - final StaplerRequest req = Stapler.getCurrentRequest(); + final StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req != null) { - final Object attribute = req.getAttribute("javax.servlet.error.message"); + final Object attribute = req.getAttribute("jakarta.servlet.error.message"); if (attribute != null) { return null; } @@ -2506,7 +2525,7 @@ public String getUrlChildPrefix() { if (url != null) { return Util.ensureEndsWith(url, "/"); } - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req != null) return getRootUrlFromRequest(); return null; @@ -2524,7 +2543,7 @@ public String getConfiguredRootUrl() { /** * Is Jenkins running in HTTPS? * - * Note that we can't really trust {@link StaplerRequest#isSecure()} because HTTPS might be terminated + * Note that we can't really trust {@link StaplerRequest2#isSecure()} because HTTPS might be terminated * in the reverse proxy. */ public boolean isRootUrlSecure() { @@ -2550,7 +2569,7 @@ public boolean isRootUrlSecure() { * @since 1.263 */ public @NonNull String getRootUrlFromRequest() { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req == null) { throw new IllegalStateException("cannot call getRootUrlFromRequest from outside a request handling thread"); } @@ -2604,7 +2623,7 @@ public boolean isRootUrlSecure() { * @param defaultValue the value to return if the header is absent. * @return the originating entry of the header or the default value if the header was not present. */ - private static String getXForwardedHeader(StaplerRequest req, String header, String defaultValue) { + private static String getXForwardedHeader(StaplerRequest2 req, String header, String defaultValue) { String value = req.getHeader(header); if (value != null) { int index = value.indexOf(','); @@ -2791,7 +2810,7 @@ public void setSecurityRealm(@CheckForNull SecurityRealm securityRealm) { */ private void resetFilter(@CheckForNull SecurityRealm securityRealm, @CheckForNull IdStrategy oldUserIdStrategy) { try { - HudsonFilter filter = HudsonFilter.get(servletContext); + HudsonFilter filter = HudsonFilter.get(getServletContext()); if (filter == null) { // Fix for JENKINS-3069: This filter is not necessarily initialized before the servlets. // when HudsonFilter does come back, it'll initialize itself. @@ -3263,7 +3282,7 @@ public void onRenamed(TopLevelItem job, String oldName, String newName) throws I } /** - * Called in response to {@link Job#doDoDelete(StaplerRequest, StaplerResponse)} + * Called in response to {@link Job#doDoDelete(StaplerRequest2, StaplerResponse2)} */ @Override public void onDeleted(TopLevelItem item) throws IOException { @@ -4064,7 +4083,7 @@ public Object getDynamic(String token) { * Accepts submission from the configuration page. */ @POST - public synchronized void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public synchronized void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { try (BulkChange bc = new BulkChange(this)) { checkPermission(MANAGE); @@ -4101,11 +4120,11 @@ public void setCrumbIssuer(CrumbIssuer issuer) { crumbIssuer = issuer; } - public synchronized void doTestPost(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doTestPost(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { rsp.sendRedirect("foo"); } - private boolean configureDescriptor(StaplerRequest req, JSONObject json, Descriptor<?> d) throws FormException { + private boolean configureDescriptor(StaplerRequest2 req, JSONObject json, Descriptor<?> d) throws FormException { // collapse the structure to remain backward compatible with the JSON structure before 1. String name = d.getJsonSafeClassName(); JSONObject js = json.has(name) ? json.getJSONObject(name) : new JSONObject(); // if it doesn't have the property, the method returns invalid null object. @@ -4117,7 +4136,7 @@ private boolean configureDescriptor(StaplerRequest req, JSONObject json, Descrip * Accepts submission from the node configuration page. */ @POST - public synchronized void doConfigExecutorsSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public synchronized void doConfigExecutorsSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { checkPermission(ADMINISTER); try (BulkChange bc = new BulkChange(this)) { @@ -4139,7 +4158,7 @@ public synchronized void doConfigExecutorsSubmit(StaplerRequest req, StaplerResp * Accepts the new description. */ @RequirePOST - public synchronized void doSubmitDescription(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized void doSubmitDescription(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { getPrimaryView().doSubmitDescription(req, rsp); } @@ -4227,7 +4246,7 @@ public synchronized HttpRedirect doCancelQuietDown() { } public HttpResponse doToggleCollapse() throws ServletException, IOException { - final StaplerRequest request = Stapler.getCurrentRequest(); + final StaplerRequest2 request = Stapler.getCurrentRequest2(); final String paneId = request.getParameter("paneId"); PaneStatusProperties.forCurrentUser().toggleCollapsed(paneId); @@ -4239,7 +4258,7 @@ public HttpResponse doToggleCollapse() throws ServletException, IOException { * Backward compatibility. Redirect to the thread dump. */ // TODO annotate @GET once baseline includes Stapler version XXX - public void doClassicThreadDump(StaplerResponse rsp) throws IOException, ServletException { + public void doClassicThreadDump(StaplerResponse2 rsp) throws IOException, ServletException { rsp.sendRedirect2("threadDump"); } @@ -4283,7 +4302,7 @@ public Map<String, Map<String, String>> getAllThreadDumps() throws IOException, @Override @RequirePOST - public synchronized TopLevelItem doCreateItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public synchronized TopLevelItem doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { return itemGroupMixIn.createTopLevelItem(req, rsp); } @@ -4308,7 +4327,7 @@ public <T extends TopLevelItem> T copy(T src, String name) throws IOException { } @POST - public synchronized void doCreateView(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public synchronized void doCreateView(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { checkPermission(View.CREATE); addView(View.create(req, rsp, this)); } @@ -4364,7 +4383,7 @@ private static String toPrintableName(String name) { * * @see BasicAuthenticationFilter */ - public void doSecured(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doSecured(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { // TODO fire something in SecurityListener? (seems to be used only for REST calls when LegacySecurityRealm is active) if (req.getUserPrincipal() == null) { @@ -4386,7 +4405,7 @@ public void doSecured(StaplerRequest req, StaplerResponse rsp) throws IOExceptio * Called once the user logs in. Just forward to the top page. * Used only by {@link LegacySecurityRealm}. */ - public void doLoginEntry(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doLoginEntry(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (req.getUserPrincipal() == null) { rsp.sendRedirect2("noPrincipal"); return; @@ -4415,13 +4434,28 @@ public void doLoginEntry(StaplerRequest req, StaplerResponse rsp) throws IOExcep /** * Logs out the user. + * + * @since TODO */ - public void doLogout(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doLogout(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { String user = getAuthentication2().getName(); securityRealm.doLogout(req, rsp); SecurityListener.fireLoggedOut(user); } + /** + * @deprecated use {@link #doLogout(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doLogout(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + doLogout(req != null ? StaplerRequest.toStaplerRequest2(req) : null, rsp != null ? StaplerResponse.toStaplerResponse2(rsp) : null); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Serves jar files for inbound agents. */ @@ -4429,7 +4463,7 @@ public Slave.JnlpJar getJnlpJars(String fileName) { return new Slave.JnlpJar(fileName); } - public Slave.JnlpJar doJnlpJars(StaplerRequest req) { + public Slave.JnlpJar doJnlpJars(StaplerRequest2 req) { return new Slave.JnlpJar(req.getRestOfPath().substring(1)); } @@ -4442,7 +4476,7 @@ public synchronized HttpResponse doReload() throws IOException { getLifecycle().onReload(getAuthentication2().getName(), null); // engage "loading ..." UI and then run the actual task in a separate thread - WebApp.get(servletContext).setApp(new HudsonIsLoading()); + WebApp.get(getServletContext()).setApp(new HudsonIsLoading()); new Thread("Jenkins config reload thread") { @Override @@ -4452,7 +4486,7 @@ public void run() { getLifecycle().onReady(); } catch (Exception e) { LOGGER.log(SEVERE, "Failed to reload Jenkins config", e); - new JenkinsReloadFailed(e).publish(servletContext, root); + new JenkinsReloadFailed(e).publish(getServletContext(), root); } } }.start(); @@ -4481,14 +4515,14 @@ public void reload() throws IOException, InterruptedException, ReactorException User.reload(); queue.load(); - WebApp.get(servletContext).setApp(this); + WebApp.get(getServletContext()).setApp(this); } /** * Do a finger-print check. */ @RequirePOST - public void doDoFingerprintCheck(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doDoFingerprintCheck(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { // Parse the request try (MultipartFormDataParser p = new MultipartFormDataParser(req, 10)) { if (isUseCrumbs() && !getCrumbIssuer().validateCrumb(req, p)) { @@ -4505,7 +4539,7 @@ public void doDoFingerprintCheck(StaplerRequest req, StaplerResponse rsp) throws */ @RequirePOST @SuppressFBWarnings(value = "DM_GC", justification = "for debugging") - public void doGc(StaplerResponse rsp) throws IOException { + public void doGc(StaplerResponse2 rsp) throws IOException { checkPermission(Jenkins.ADMINISTER); System.gc(); rsp.setStatus(HttpServletResponse.SC_OK); @@ -4523,7 +4557,7 @@ public void doException() { } @Override - public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws IOException, JellyException { + public ContextMenu doContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws IOException, JellyException { ContextMenu menu = new ContextMenu().from(this, request, response); for (MenuItem i : menu.items) { if (i.url.equals(request.getContextPath() + "/manage")) { @@ -4535,7 +4569,7 @@ public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse respons } @Override - public ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + public ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { ContextMenu menu = new ContextMenu(); for (View view : getViews()) { menu.add(view.getViewUrl(), view.getDisplayName()); @@ -4579,7 +4613,7 @@ public DirectoryBrowserSupport doUserContent() { * This first replaces "app" to {@link HudsonIsRestarting} */ @CLIMethod(name = "restart") - public void doRestart(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, RestartNotSupportedException { + public void doRestart(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, RestartNotSupportedException { checkPermission(MANAGE); if (req != null && req.getMethod().equals("GET")) { req.getView(this, "_restart.jelly").forward(req, rsp); @@ -4600,7 +4634,7 @@ public void doRestart(StaplerRequest req, StaplerResponse rsp) throws IOExceptio */ @WebMethod(name = "404") @Restricted(NoExternalUse.class) - public void generateNotFoundResponse(StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + public void generateNotFoundResponse(StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { if (ResourceDomainConfiguration.isResourceRequest(req)) { rsp.forward(this, "_404_simple", req); } else { @@ -4620,12 +4654,12 @@ public void generateNotFoundResponse(StaplerRequest req, StaplerResponse rsp) th * Builds that cannot continue while the controller is not running have to finish or pause before it can proceed. * No new builds will be started. No new jobs are accepted. * - * @deprecated use {@link #doSafeRestart(StaplerRequest, String)} instead. + * @deprecated use {@link #doSafeRestart(StaplerRequest2, String)} instead. * */ @Deprecated(since = "2.414") public HttpResponse doSafeRestart(StaplerRequest req) throws IOException, ServletException, RestartNotSupportedException { - return doSafeRestart(req, null); + return doSafeRestart(StaplerRequest.toStaplerRequest2(req), null); } /** @@ -4633,7 +4667,7 @@ public HttpResponse doSafeRestart(StaplerRequest req) throws IOException, Servle * * @since 2.414 */ - public HttpResponse doSafeRestart(StaplerRequest req, @QueryParameter("message") String message) throws IOException, ServletException, RestartNotSupportedException { + public HttpResponse doSafeRestart(StaplerRequest2 req, @QueryParameter("message") String message) throws IOException, ServletException, RestartNotSupportedException { checkPermission(MANAGE); if (req != null && req.getMethod().equals("GET")) { return HttpResponses.forwardToView(this, "_safeRestart.jelly"); @@ -4664,7 +4698,7 @@ private static Lifecycle restartableLifecycle() throws RestartNotSupportedExcept */ public void restart() throws RestartNotSupportedException { final Lifecycle lifecycle = restartableLifecycle(); - servletContext.setAttribute("app", new HudsonIsRestarting()); + getServletContext().setAttribute("app", new HudsonIsRestarting()); new Thread("restart thread") { final String exitUser = getAuthentication2().getName(); @@ -4717,7 +4751,7 @@ public void run() { doQuietDown(true, 0, message, true); // Make sure isQuietingDown is still true. if (isQuietingDown()) { - servletContext.setAttribute("app", new HudsonIsRestarting(true)); + getServletContext().setAttribute("app", new HudsonIsRestarting(true)); // give some time for the browser to load the "reloading" page lifecycle.onStatusUpdate("Restart in 10 seconds"); Thread.sleep(TimeUnit.SECONDS.toMillis(10)); @@ -4763,7 +4797,7 @@ protected RestartCause() { */ @CLIMethod(name = "shutdown") @RequirePOST - public void doExit(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doExit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { checkPermission(ADMINISTER); final String exitUser = getAuthentication2().getName(); final String exitAddr = req != null ? req.getRemoteAddr() : null; @@ -4797,7 +4831,7 @@ public void run() { */ @CLIMethod(name = "safe-shutdown") @RequirePOST - public HttpResponse doSafeExit(StaplerRequest req) throws IOException { + public HttpResponse doSafeExit(StaplerRequest2 req) throws IOException { checkPermission(ADMINISTER); quietDownInfo = new QuietDownInfo(); final String exitUser = getAuthentication2().getName(); @@ -4824,6 +4858,15 @@ public void run() { return HttpResponses.plainText("Shutting down as soon as all jobs are complete"); } + /** + * @deprecated use {@link #doSafeExit(StaplerRequest2)} + */ + @Deprecated + @StaplerNotDispatchable + public HttpResponse doSafeExit(StaplerRequest req) throws IOException { + return doSafeExit(req != null ? StaplerRequest.toStaplerRequest2(req) : null); + } + /** * Gets the {@link Authentication} object that represents the user * associated with the current request. @@ -4852,21 +4895,47 @@ public void run() { * For system diagnostics. * Run arbitrary Groovy script. */ - public void doScript(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doScript(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { _doScript(req, rsp, req.getView(this, "_script.jelly"), FilePath.localChannel, getACL()); } + /** + * @deprecated use {@link #doScript(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doScript(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + _doScript(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), StaplerRequest.toStaplerRequest2(req).getView(this, "_script.jelly"), FilePath.localChannel, getACL()); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Run arbitrary Groovy script and return result as plain text. */ - public void doScriptText(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doScriptText(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { _doScript(req, rsp, req.getView(this, "_scriptText.jelly"), FilePath.localChannel, getACL()); } /** - * @since 1.509.1 + * @deprecated use {@link #doScriptText(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + public void doScriptText(StaplerRequest req, StaplerResponse rsp) throws IOException, javax.servlet.ServletException { + try { + _doScript(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), StaplerRequest.toStaplerRequest2(req).getView(this, "_scriptText.jelly"), FilePath.localChannel, getACL()); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + + /** + * @since TODO */ - public static void _doScript(StaplerRequest req, StaplerResponse rsp, RequestDispatcher view, VirtualChannel channel, ACL acl) throws IOException, ServletException { + public static void _doScript(StaplerRequest2 req, StaplerResponse2 rsp, RequestDispatcher view, VirtualChannel channel, ACL acl) throws IOException, ServletException { // ability to run arbitrary script is dangerous acl.checkPermission(ADMINISTER); @@ -4892,13 +4961,26 @@ public static void _doScript(StaplerRequest req, StaplerResponse rsp, RequestDis view.forward(req, rsp); } + /** + * @deprecated use {@link #_doScript(StaplerRequest2, StaplerResponse2, RequestDispatcher, VirtualChannel, ACL)} + * @since 1.509.1 + */ + @Deprecated + public static void _doScript(StaplerRequest req, StaplerResponse rsp, javax.servlet.RequestDispatcher view, VirtualChannel channel, ACL acl) throws IOException, javax.servlet.ServletException { + try { + _doScript(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), RequestDispatcherWrapper.toJakartaRequestDispatcher(view), channel, acl); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Evaluates the Jelly script submitted by the client. * * This is useful for system administration as well as unit testing. */ @RequirePOST - public void doEval(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doEval(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { checkPermission(ADMINISTER); req.getWebApp().getDispatchValidator().allowDispatch(req, rsp); try { @@ -4913,7 +4995,7 @@ public void doEval(StaplerRequest req, StaplerResponse rsp) throws IOException, /** * Sign up for the user account. */ - public void doSignup(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doSignup(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { if (getSecurityRealm().allowsSignup()) { req.getView(getSecurityRealm(), "signup.jelly").forward(req, rsp); return; @@ -4924,7 +5006,7 @@ public void doSignup(StaplerRequest req, StaplerResponse rsp) throws IOException /** * Changes the icon size by changing the cookie */ - public void doIconSize(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doIconSize(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { String qs = req.getQueryString(); if (qs == null) throw new ServletException(); @@ -4939,7 +5021,7 @@ public void doIconSize(StaplerRequest req, StaplerResponse rsp) throws IOExcepti } @RequirePOST - public void doFingerprintCleanup(StaplerResponse rsp) throws IOException { + public void doFingerprintCleanup(StaplerResponse2 rsp) throws IOException { checkPermission(ADMINISTER); FingerprintCleanupThread.invoke(); rsp.setStatus(HttpServletResponse.SC_OK); @@ -4948,7 +5030,7 @@ public void doFingerprintCleanup(StaplerResponse rsp) throws IOException { } @RequirePOST - public void doWorkspaceCleanup(StaplerResponse rsp) throws IOException { + public void doWorkspaceCleanup(StaplerResponse2 rsp) throws IOException { checkPermission(ADMINISTER); WorkspaceCleanupThread.invoke(); rsp.setStatus(HttpServletResponse.SC_OK); @@ -4959,7 +5041,7 @@ public void doWorkspaceCleanup(StaplerResponse rsp) throws IOException { /** * If the user chose the default JDK, make sure we got 'java' in PATH. */ - public FormValidation doDefaultJDKCheck(StaplerRequest request, @QueryParameter String value) { + public FormValidation doDefaultJDKCheck(StaplerRequest2 request, @QueryParameter String value) { if (!JDK.isDefaultName(value)) // assume the user configured named ones properly in system config --- // or else system config should have reported form field validation errors. @@ -5022,7 +5104,7 @@ public FormValidation doViewExistsCheck(@QueryParameter String value) { * strategy here, though the current implementation is based on * file extensions. */ - public void doResources(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doResources(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { String path = req.getRestOfPath(); // cut off the "..." portion of /resources/.../path/to/file // as this is only used to make path unique (which in turn @@ -5043,7 +5125,7 @@ public void doResources(StaplerRequest req, StaplerResponse rsp) throws IOExcept } /** - * Extension list that {@link #doResources(StaplerRequest, StaplerResponse)} can serve. + * Extension list that {@link #doResources(StaplerRequest2, StaplerResponse2)} can serve. * This set is mutable to allow plugins to add additional extensions. */ @SuppressFBWarnings(value = "MS_MUTABLE_COLLECTION_PKGPROTECT", justification = "mutable to allow plugins to add additional extensions") @@ -5054,12 +5136,12 @@ public void doResources(StaplerRequest req, StaplerResponse rsp) throws IOExcept /** * Checks if container uses UTF-8 to decode URLs. See * http://wiki.jenkins-ci.org/display/JENKINS/Tomcat#Tomcat-i18n - * @deprecated use {@link URICheckEncodingMonitor#doCheckURIEncoding(StaplerRequest)} + * @deprecated use {@link URICheckEncodingMonitor#doCheckURIEncoding(StaplerRequest2)} */ @Restricted(NoExternalUse.class) @RestrictedSince("2.37") @Deprecated - public FormValidation doCheckURIEncoding(StaplerRequest request) throws IOException { + public FormValidation doCheckURIEncoding(StaplerRequest2 request) throws IOException { return ExtensionList.lookupSingleton(URICheckEncodingMonitor.class).doCheckURIEncoding(request); } @@ -5214,7 +5296,7 @@ public Object getTarget() { try { checkPermission(READ); } catch (AccessDeniedException e) { - if (!isSubjectToMandatoryReadPermissionCheck(Stapler.getCurrentRequest().getRestOfPath())) { + if (!isSubjectToMandatoryReadPermissionCheck(Stapler.getCurrentRequest2().getRestOfPath())) { return this; } @@ -5244,7 +5326,7 @@ public boolean isSubjectToMandatoryReadPermissionCheck(String restOfPath) { // TODO SlaveComputer.doSlaveAgentJnlp; there should be an annotation to request unprotected access if ((isAgentJnlpPath(restOfPath, "jenkins") || isAgentJnlpPath(restOfPath, "slave")) - && "true".equals(Stapler.getCurrentRequest().getParameter("encrypt"))) { + && "true".equals(Stapler.getCurrentRequest2().getParameter("encrypt"))) { return false; } @@ -5419,13 +5501,13 @@ public HttpResponse doDoDelete() throws IOException { @Override @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, FormException { Jenkins.get().doConfigExecutorsSubmit(req, rsp); } @WebMethod(name = "config.xml") @Override - public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doConfigDotXml(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { throw HttpResponses.status(SC_BAD_REQUEST); } @@ -5456,7 +5538,7 @@ public List<LogRecord> getLogRecords() throws IOException, InterruptedException @Override @RequirePOST - public void doLaunchSlaveAgent(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public void doLaunchSlaveAgent(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { // this computer never returns null from channel, so // this method shall never be invoked. rsp.sendError(SC_NOT_FOUND); @@ -5586,7 +5668,7 @@ private static void computeVersion(ServletContext context) { /** * Get the stored version of Jenkins, as stored by - * {@link #doConfigSubmit(org.kohsuke.stapler.StaplerRequest, org.kohsuke.stapler.StaplerResponse)}. + * {@link #doConfigSubmit(org.kohsuke.stapler.StaplerRequest2, org.kohsuke.stapler.StaplerResponse2)}. * <p> * Parses the version into {@link VersionNumber}, or null if it's not parseable as a version number * (such as when Jenkins is run with {@code mvn jetty:run}) diff --git a/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java b/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java index 5aa73c17528a..6725c1f669fb 100644 --- a/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java +++ b/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java @@ -12,13 +12,13 @@ import hudson.model.PersistentDescriptor; import hudson.util.FormValidation; import hudson.util.XStream2; +import jakarta.servlet.ServletContext; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletContext; import jenkins.util.SystemProperties; import jenkins.util.UrlHelper; import org.jenkinsci.Symbol; @@ -167,7 +167,7 @@ private boolean isInvalidRootUrl(@Nullable String value) { */ private void updateSecureSessionFlag() { try { - ServletContext context = Jenkins.get().servletContext; + ServletContext context = Jenkins.get().getServletContext(); Method m; try { m = context.getClass().getMethod("getSessionCookieConfig"); @@ -177,7 +177,7 @@ private void updateSecureSessionFlag() { } Object sessionCookieConfig = m.invoke(context); - Class scc = Class.forName("javax.servlet.SessionCookieConfig"); + Class scc = Class.forName("jakarta.servlet.SessionCookieConfig"); Method setSecure = scc.getMethod("setSecure", boolean.class); boolean v = fixNull(jenkinsUrl).startsWith("https"); setSecure.invoke(sessionCookieConfig, v); diff --git a/core/src/main/java/jenkins/model/MasterBuildConfiguration.java b/core/src/main/java/jenkins/model/MasterBuildConfiguration.java index fa95401fb73d..6fefbba1f6af 100644 --- a/core/src/main/java/jenkins/model/MasterBuildConfiguration.java +++ b/core/src/main/java/jenkins/model/MasterBuildConfiguration.java @@ -29,7 +29,7 @@ import java.io.IOException; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Adds the configuration regarding building on the built-in node. @@ -47,7 +47,7 @@ public String getLabelString() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { Jenkins j = Jenkins.get(); try { // for compatibility reasons, this value is stored in Jenkins diff --git a/core/src/main/java/jenkins/model/ModelObjectWithChildren.java b/core/src/main/java/jenkins/model/ModelObjectWithChildren.java index c8d544e03ed8..ed06ea4d7aae 100644 --- a/core/src/main/java/jenkins/model/ModelObjectWithChildren.java +++ b/core/src/main/java/jenkins/model/ModelObjectWithChildren.java @@ -1,9 +1,13 @@ package jenkins.model; +import hudson.Util; import hudson.model.ModelObject; import jenkins.model.ModelObjectWithContextMenu.ContextMenu; +import jenkins.security.stapler.StaplerNotDispatchable; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; /** * {@link ModelObject} that has the children context menu in the breadcrumb. @@ -20,5 +24,26 @@ public interface ModelObjectWithChildren extends ModelObject { /** * Generates the context menu to list up all the children. */ - ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception; + default ContextMenu doChildrenContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { + if (Util.isOverridden(ModelObjectWithChildren.class, getClass(), "doChildrenContextMenu", StaplerRequest.class, StaplerResponse.class)) { + return doChildrenContextMenu(StaplerRequest.fromStaplerRequest2(request), StaplerResponse.fromStaplerResponse2(response)); + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + ModelObjectWithChildren.class.getSimpleName() + "." + "doChildrenContextMenu" + " methods"); + } + } + + /** + * @deprecated use {@link #doChildrenContextMenu(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + default ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + if (Util.isOverridden(ModelObjectWithChildren.class, getClass(), "doChildrenContextMenu", StaplerRequest2.class, StaplerResponse2.class)) { + return doChildrenContextMenu(StaplerRequest.toStaplerRequest2(request), StaplerResponse.toStaplerResponse2(response)); + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + ModelObjectWithChildren.class.getSimpleName() + "." + "doChildrenContextMenu" + " methods"); + } + } } diff --git a/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java b/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java index 26cc3723dabd..2fa50556574c 100644 --- a/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java +++ b/core/src/main/java/jenkins/model/ModelObjectWithContextMenu.java @@ -2,6 +2,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Functions; +import hudson.Util; import hudson.model.Action; import hudson.model.Actionable; import hudson.model.BallColor; @@ -10,14 +11,15 @@ import hudson.model.ModelObject; import hudson.model.Node; import hudson.slaves.Cloud; +import jakarta.servlet.ServletException; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import javax.servlet.ServletException; import jenkins.management.Badge; +import jenkins.security.stapler.StaplerNotDispatchable; import org.apache.commons.jelly.JellyContext; import org.apache.commons.jelly.JellyException; import org.apache.commons.jelly.JellyTagException; @@ -32,7 +34,9 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebApp; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -57,10 +61,31 @@ public interface ModelObjectWithContextMenu extends ModelObject { * Generates the context menu. * * The typical implementation is {@code return new ContextMenu().from(this,request,response);}, - * which implements the default behaviour. See {@link ContextMenu#from(ModelObjectWithContextMenu, StaplerRequest, StaplerResponse)} + * which implements the default behaviour. See {@link ContextMenu#from(ModelObjectWithContextMenu, StaplerRequest2, StaplerResponse2)} * for more details of what it does. This should suit most implementations. */ - ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception; + default ContextMenu doContextMenu(StaplerRequest2 request, StaplerResponse2 response) throws Exception { + if (Util.isOverridden(ModelObjectWithContextMenu.class, getClass(), "doContextMenu", StaplerRequest.class, StaplerResponse.class)) { + return doContextMenu(StaplerRequest.fromStaplerRequest2(request), StaplerResponse.fromStaplerResponse2(response)); + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + ModelObjectWithContextMenu.class.getSimpleName() + ".doContextMenu methods"); + } + } + + /** + * @deprecated use {@link #doContextMenu(StaplerRequest2, StaplerResponse2)} + */ + @Deprecated + @StaplerNotDispatchable + default ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { + if (Util.isOverridden(ModelObjectWithContextMenu.class, getClass(), "doContextMenu", StaplerRequest2.class, StaplerResponse2.class)) { + return doContextMenu(StaplerRequest.toStaplerRequest2(request), StaplerResponse.toStaplerResponse2(response)); + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + + ModelObjectWithContextMenu.class.getSimpleName() + ".doContextMenu methods"); + } + } /** * Data object that represents the context menu. @@ -76,7 +101,7 @@ class ContextMenu implements HttpResponse { public final List<MenuItem> items = new ArrayList<>(); @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object o) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object o) throws IOException, ServletException { rsp.serveExposedBean(req, this, Flavor.JSON); } @@ -98,7 +123,7 @@ public ContextMenu add(Action a) { if (!Functions.isContextMenuVisible(a)) { return this; } - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); String text = a.getDisplayName(); String base = Functions.getIconFilePath(a); if (base == null) return this; @@ -108,7 +133,7 @@ public ContextMenu add(Action a) { Icon icon = Functions.tryGetIcon(base); return add(url, icon.getClassSpec(), text); } else { - String icon = Stapler.getCurrentRequest().getContextPath() + (base.startsWith("images/") ? Functions.getResourcePath() : "") + '/' + base; + String icon = Stapler.getCurrentRequest2().getContextPath() + (base.startsWith("images/") ? Functions.getResourcePath() : "") + '/' + base; return add(url, icon, text); } } @@ -267,14 +292,14 @@ public ContextMenu add(Job job) { * * <p> * Unconventional {@link ModelObject} implementations that do not use {@code sidepanel.groovy} - * can override {@link ModelObjectWithContextMenu#doContextMenu(StaplerRequest, StaplerResponse)} + * can override {@link ModelObjectWithContextMenu#doContextMenu(StaplerRequest2, StaplerResponse2)} * directly to provide alternative semantics. */ - public ContextMenu from(ModelObjectWithContextMenu self, StaplerRequest request, StaplerResponse response) throws JellyException, IOException { + public ContextMenu from(ModelObjectWithContextMenu self, StaplerRequest2 request, StaplerResponse2 response) throws JellyException, IOException { return from(self, request, response, "sidepanel"); } - public ContextMenu from(ModelObjectWithContextMenu self, StaplerRequest request, StaplerResponse response, String view) throws JellyException, IOException { + public ContextMenu from(ModelObjectWithContextMenu self, StaplerRequest2 request, StaplerResponse2 response, String view) throws JellyException, IOException { WebApp webApp = WebApp.getCurrent(); final Script s = webApp.getMetaClass(self).getTearOff(JellyClassTearOff.class).findScript(view); if (s != null) { @@ -401,9 +426,9 @@ public MenuItem() { public MenuItem withUrl(String url) { try { - this.url = new URI(Stapler.getCurrentRequest().getRequestURI()).resolve(new URI(url)).toString(); + this.url = new URI(Stapler.getCurrentRequest2().getRequestURI()).resolve(new URI(url)).toString(); } catch (URISyntaxException x) { - throw new IllegalArgumentException("Bad URI from " + Stapler.getCurrentRequest().getRequestURI() + " vs. " + url, x); + throw new IllegalArgumentException("Bad URI from " + Stapler.getCurrentRequest2().getRequestURI() + " vs. " + url, x); } return this; } @@ -413,7 +438,7 @@ public MenuItem withUrl(String url) { */ public MenuItem withContextRelativeUrl(String url) { if (!url.startsWith("/")) url = '/' + url; - this.url = Stapler.getCurrentRequest().getContextPath() + url; + this.url = Stapler.getCurrentRequest2().getContextPath() + url; return this; } @@ -463,7 +488,7 @@ public MenuItem withDisplayName(ModelObject o) { } private String getResourceUrl() { - return Stapler.getCurrentRequest().getContextPath() + Jenkins.RESOURCE_PATH; + return Stapler.getCurrentRequest2().getContextPath() + Jenkins.RESOURCE_PATH; } } @@ -483,7 +508,7 @@ interface ContextMenuVisibility extends Action { /** * Determines whether to show this action right now. * Can always return false, for an action which should never be in the context menu; - * or could examine {@link Stapler#getCurrentRequest}. + * or could examine {@link Stapler#getCurrentRequest2}. * @return true to display it, false to hide * @see ContextMenu#add(Action) */ diff --git a/core/src/main/java/jenkins/model/OptionalJobProperty.java b/core/src/main/java/jenkins/model/OptionalJobProperty.java index 2b4db11c1b84..1614f33363b1 100644 --- a/core/src/main/java/jenkins/model/OptionalJobProperty.java +++ b/core/src/main/java/jenkins/model/OptionalJobProperty.java @@ -24,11 +24,13 @@ package jenkins.model; +import hudson.Util; import hudson.model.Job; import hudson.model.JobProperty; import hudson.model.JobPropertyDescriptor; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Job property which may or may not be present. @@ -51,11 +53,23 @@ protected OptionalJobPropertyDescriptor(Class<? extends JobProperty<?>> clazz) { protected OptionalJobPropertyDescriptor() {} + @Override + public JobProperty<?> newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { + if (Util.isOverridden(OptionalJobPropertyDescriptor.class, getClass(), "newInstance", StaplerRequest.class, JSONObject.class)) { + return newInstance(req != null ? StaplerRequest.fromStaplerRequest2(req) : null, formData); + } else { + return formData.optBoolean("specified") ? super.newInstance(req, formData) : null; + } + } + + /** + * @deprecated use {@link #newInstance(StaplerRequest2, JSONObject)} + */ + @Deprecated @Override public JobProperty<?> newInstance(StaplerRequest req, JSONObject formData) throws FormException { return formData.optBoolean("specified") ? super.newInstance(req, formData) : null; } - } } diff --git a/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java b/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java index 662ffa9359e2..ea8437510818 100644 --- a/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java +++ b/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java @@ -24,8 +24,8 @@ package jenkins.model; -import static javax.servlet.http.HttpServletResponse.SC_CONFLICT; -import static javax.servlet.http.HttpServletResponse.SC_CREATED; +import static jakarta.servlet.http.HttpServletResponse.SC_CONFLICT; +import static jakarta.servlet.http.HttpServletResponse.SC_CREATED; import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.Util; @@ -51,14 +51,16 @@ import hudson.triggers.Trigger; import hudson.util.AlternativeUiTextProvider; import hudson.views.BuildButtonColumn; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; -import javax.servlet.ServletException; import jenkins.model.lazy.LazyBuildMixIn; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.triggers.SCMTriggerItem; import jenkins.triggers.TriggeredItem; import jenkins.util.TimeDuration; @@ -73,7 +75,9 @@ import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; /** @@ -191,7 +195,7 @@ public final boolean isParameterized() { * Standard implementation of {@link ParameterizedJob#doBuild}. */ @SuppressWarnings("deprecation") - public final void doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { + public final void doBuild(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { if (delay == null) { delay = new TimeDuration(TimeUnit.MILLISECONDS.convert(asJob().getQuietPeriod(), TimeUnit.SECONDS)); } @@ -229,7 +233,7 @@ public final void doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParamet * Standard implementation of {@link ParameterizedJob#doBuildWithParameters}. */ @SuppressWarnings("deprecation") - public final void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { + public final void doBuildWithParameters(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { BuildAuthorizationToken.checkPermission(asJob(), asJob().getAuthToken(), req, rsp); ParametersDefinitionProperty pp = asJob().getProperty(ParametersDefinitionProperty.class); @@ -247,7 +251,7 @@ public final void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp, * Standard implementation of {@link ParameterizedJob#doCancelQueue}. */ @RequirePOST - public final void doCancelQueue(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + public final void doCancelQueue(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { asJob().checkPermission(Item.CANCEL); Jenkins.get().getQueue().cancel(asJob()); rsp.forwardToPreviousPage(req); @@ -269,7 +273,7 @@ public final SearchIndexBuilder extendSearchIndex(SearchIndexBuilder sib) { * Computes the build cause, using RemoteCause or UserCause as appropriate. */ @Restricted(NoExternalUse.class) - public static CauseAction getBuildCause(ParameterizedJob job, StaplerRequest req) { + public static CauseAction getBuildCause(ParameterizedJob job, StaplerRequest2 req) { Cause cause; @SuppressWarnings("deprecation") BuildAuthorizationToken authToken = job.getAuthToken(); @@ -401,8 +405,29 @@ default QueueTaskFuture<RunT> scheduleBuild2(int quietPeriod, Action... actions) * Schedules a new build command. * @see ParameterizedJobMixIn#doBuild */ - default void doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { - getParameterizedJobMixIn().doBuild(req, rsp, delay); + default void doBuild(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { + if (Util.isOverridden(ParameterizedJob.class, getClass(), "doBuild", StaplerRequest.class, StaplerResponse.class, TimeDuration.class)) { + try { + doBuild(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp), delay); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + getParameterizedJobMixIn().doBuild(req, rsp, delay); + } + } + + /** + * @deprecated use {@link #doBuild(StaplerRequest2, StaplerResponse2, TimeDuration)} + */ + @Deprecated + @StaplerNotDispatchable + default void doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, javax.servlet.ServletException { + try { + getParameterizedJobMixIn().doBuild(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), delay); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } /** @@ -410,8 +435,29 @@ default void doBuild(StaplerRequest req, StaplerResponse rsp, @QueryParameter Ti * Currently only String parameters are supported. * @see ParameterizedJobMixIn#doBuildWithParameters */ - default void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { - getParameterizedJobMixIn().doBuildWithParameters(req, rsp, delay); + default void doBuildWithParameters(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter TimeDuration delay) throws IOException, ServletException { + if (Util.isOverridden(ParameterizedJob.class, getClass(), "doBuildWithParameters", StaplerRequest.class, StaplerResponse.class, TimeDuration.class)) { + try { + doBuildWithParameters(StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp), delay); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + getParameterizedJobMixIn().doBuildWithParameters(req, rsp, delay); + } + } + + /** + * @deprecated use {@link #doBuildWithParameters(StaplerRequest2, StaplerResponse2, TimeDuration)} + */ + @Deprecated + @StaplerNotDispatchable + default void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp, @QueryParameter TimeDuration delay) throws IOException, javax.servlet.ServletException { + try { + getParameterizedJobMixIn().doBuildWithParameters(StaplerRequest.toStaplerRequest2(req), StaplerResponse.toStaplerResponse2(rsp), delay); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } /** @@ -419,7 +465,7 @@ default void doBuildWithParameters(StaplerRequest req, StaplerResponse rsp, @Que * @see ParameterizedJobMixIn#doCancelQueue */ @RequirePOST - default void doCancelQueue(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + default void doCancelQueue(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { getParameterizedJobMixIn().doCancelQueue(req, rsp); } @@ -427,7 +473,7 @@ default void doCancelQueue(StaplerRequest req, StaplerResponse rsp) throws IOExc * Schedules a new SCM polling command. */ @SuppressWarnings("deprecation") - default void doPolling(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + default void doPolling(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException { if (!(this instanceof SCMTriggerItem)) { rsp.sendError(404); return; @@ -485,7 +531,7 @@ default void makeDisabled(boolean b) throws IOException { @CLIMethod(name = "disable-job") @RequirePOST - default HttpResponse doDisable() throws IOException, ServletException { + default HttpResponse doDisable() throws IOException { checkPermission(CONFIGURE); makeDisabled(true); return new HttpRedirect("."); @@ -493,7 +539,7 @@ default HttpResponse doDisable() throws IOException, ServletException { @CLIMethod(name = "enable-job") @RequirePOST - default HttpResponse doEnable() throws IOException, ServletException { + default HttpResponse doEnable() throws IOException { checkPermission(CONFIGURE); makeDisabled(false); return new HttpRedirect("."); diff --git a/core/src/main/java/jenkins/model/ProjectNamingStrategy.java b/core/src/main/java/jenkins/model/ProjectNamingStrategy.java index 76e9ff64587f..796519f7d9c8 100644 --- a/core/src/main/java/jenkins/model/ProjectNamingStrategy.java +++ b/core/src/main/java/jenkins/model/ProjectNamingStrategy.java @@ -33,11 +33,11 @@ import hudson.model.Descriptor; import hudson.model.Failure; import hudson.util.FormValidation; +import jakarta.servlet.ServletException; import java.io.IOException; import java.io.Serializable; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import javax.servlet.ServletException; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; diff --git a/core/src/main/java/jenkins/model/experimentalflags/UserExperimentalFlagsProperty.java b/core/src/main/java/jenkins/model/experimentalflags/UserExperimentalFlagsProperty.java index 85332d26973c..06d1a7696e66 100644 --- a/core/src/main/java/jenkins/model/experimentalflags/UserExperimentalFlagsProperty.java +++ b/core/src/main/java/jenkins/model/experimentalflags/UserExperimentalFlagsProperty.java @@ -37,7 +37,7 @@ import net.sf.json.JSONObject; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** @@ -74,7 +74,7 @@ public static final class DescriptorImpl extends UserPropertyDescriptor { } @Override - public UserProperty newInstance(@Nullable StaplerRequest req, @NonNull JSONObject formData) throws FormException { + public UserProperty newInstance(@Nullable StaplerRequest2 req, @NonNull JSONObject formData) throws FormException { JSONObject flagsObj = formData.getJSONObject("flags"); Map<String, String> flags = new HashMap<>(); for (String key : flagsObj.keySet()) { diff --git a/core/src/main/java/jenkins/model/item_category/Categories.java b/core/src/main/java/jenkins/model/item_category/Categories.java index fd9b475cdf10..9e80eb0085fb 100644 --- a/core/src/main/java/jenkins/model/item_category/Categories.java +++ b/core/src/main/java/jenkins/model/item_category/Categories.java @@ -26,16 +26,16 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; +import jakarta.servlet.ServletException; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import javax.servlet.ServletException; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.export.Flavor; @@ -63,7 +63,7 @@ public List<Category> getItems() { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { rsp.serveExposedBean(req, this, Flavor.JSON); } diff --git a/core/src/main/java/jenkins/mvn/GlobalSettingsProvider.java b/core/src/main/java/jenkins/mvn/GlobalSettingsProvider.java index 06aad8ed9ef5..98055fb39b2e 100644 --- a/core/src/main/java/jenkins/mvn/GlobalSettingsProvider.java +++ b/core/src/main/java/jenkins/mvn/GlobalSettingsProvider.java @@ -6,9 +6,11 @@ import hudson.model.AbstractDescribableImpl; import hudson.model.Descriptor; import hudson.model.TaskListener; -import javax.servlet.ServletException; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a> @@ -26,7 +28,10 @@ public abstract class GlobalSettingsProvider extends AbstractDescribableImpl<Glo */ public abstract FilePath supplySettings(AbstractBuild<?, ?> build, TaskListener listener); - public static GlobalSettingsProvider parseSettingsProvider(StaplerRequest req) throws Descriptor.FormException, ServletException { + /** + * @since TODO + */ + public static GlobalSettingsProvider parseSettingsProvider(StaplerRequest2 req) throws Descriptor.FormException, ServletException { JSONObject settings = req.getSubmittedForm().getJSONObject("globalSettings"); if (settings == null) { return new DefaultGlobalSettingsProvider(); @@ -34,6 +39,18 @@ public static GlobalSettingsProvider parseSettingsProvider(StaplerRequest req) t return req.bindJSON(GlobalSettingsProvider.class, settings); } + /** + * @deprecated use {@link #parseSettingsProvider(StaplerRequest2)} + */ + @Deprecated + public static GlobalSettingsProvider parseSettingsProvider(StaplerRequest req) throws Descriptor.FormException, javax.servlet.ServletException { + try { + return parseSettingsProvider(StaplerRequest.toStaplerRequest2(req)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Convenience method handling all {@code null} checks. Provides the path on the (possible) remote settings file. * diff --git a/core/src/main/java/jenkins/mvn/SettingsProvider.java b/core/src/main/java/jenkins/mvn/SettingsProvider.java index 266f9c1cd00c..9173c5dbadf5 100644 --- a/core/src/main/java/jenkins/mvn/SettingsProvider.java +++ b/core/src/main/java/jenkins/mvn/SettingsProvider.java @@ -6,9 +6,11 @@ import hudson.model.AbstractDescribableImpl; import hudson.model.Descriptor; import hudson.model.TaskListener; -import javax.servlet.ServletException; +import io.jenkins.servlet.ServletExceptionWrapper; +import jakarta.servlet.ServletException; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @author <a href="mailto:nicolas.deloof@gmail.com">Nicolas De Loof</a> @@ -24,7 +26,7 @@ public abstract class SettingsProvider extends AbstractDescribableImpl<SettingsP */ public abstract FilePath supplySettings(AbstractBuild<?, ?> build, TaskListener listener); - public static SettingsProvider parseSettingsProvider(StaplerRequest req) throws Descriptor.FormException, ServletException { + public static SettingsProvider parseSettingsProvider(StaplerRequest2 req) throws Descriptor.FormException, ServletException { JSONObject settings = req.getSubmittedForm().getJSONObject("settings"); if (settings == null) { return new DefaultSettingsProvider(); @@ -32,6 +34,18 @@ public static SettingsProvider parseSettingsProvider(StaplerRequest req) throws return req.bindJSON(SettingsProvider.class, settings); } + /** + * @deprecated use {@link #parseSettingsProvider(StaplerRequest2)} + */ + @Deprecated + public static SettingsProvider parseSettingsProvider(StaplerRequest req) throws Descriptor.FormException, javax.servlet.ServletException { + try { + return parseSettingsProvider(StaplerRequest.toStaplerRequest2(req)); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } + /** * Convenience method handling all {@code null} checks. Provides the path on the (possible) remote settings file. * diff --git a/core/src/main/java/jenkins/security/AcegiSecurityExceptionFilter.java b/core/src/main/java/jenkins/security/AcegiSecurityExceptionFilter.java index 5aec5265e166..1441ae5a6165 100644 --- a/core/src/main/java/jenkins/security/AcegiSecurityExceptionFilter.java +++ b/core/src/main/java/jenkins/security/AcegiSecurityExceptionFilter.java @@ -26,17 +26,17 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.security.UnwrapSecurityExceptionFilter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; import java.io.IOException; import java.util.function.Function; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import org.acegisecurity.AcegiSecurityException; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.CompatibleFilter; import org.springframework.security.web.access.ExceptionTranslationFilter; /** @@ -44,7 +44,7 @@ * Used by other filters like {@link UnwrapSecurityExceptionFilter} and {@link ExceptionTranslationFilter}. */ @Restricted(NoExternalUse.class) -public class AcegiSecurityExceptionFilter implements Filter { +public class AcegiSecurityExceptionFilter implements CompatibleFilter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { diff --git a/core/src/main/java/jenkins/security/ApiCrumbExclusion.java b/core/src/main/java/jenkins/security/ApiCrumbExclusion.java index 926eec501882..f001950d3464 100644 --- a/core/src/main/java/jenkins/security/ApiCrumbExclusion.java +++ b/core/src/main/java/jenkins/security/ApiCrumbExclusion.java @@ -26,11 +26,11 @@ import hudson.Extension; import hudson.security.csrf.CrumbExclusion; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; diff --git a/core/src/main/java/jenkins/security/ApiTokenFilter.java b/core/src/main/java/jenkins/security/ApiTokenFilter.java index 986408d62604..355c32d9e254 100644 --- a/core/src/main/java/jenkins/security/ApiTokenFilter.java +++ b/core/src/main/java/jenkins/security/ApiTokenFilter.java @@ -1,7 +1,7 @@ package jenkins.security; +import jakarta.servlet.Filter; import java.util.List; -import javax.servlet.Filter; /** * {@link Filter} that performs HTTP basic authentication based on API token. diff --git a/core/src/main/java/jenkins/security/ApiTokenProperty.java b/core/src/main/java/jenkins/security/ApiTokenProperty.java index 464fdcbdf16c..804b8edbc56e 100644 --- a/core/src/main/java/jenkins/security/ApiTokenProperty.java +++ b/core/src/main/java/jenkins/security/ApiTokenProperty.java @@ -66,7 +66,7 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -274,7 +274,7 @@ public TokenInfoAndStats(@NonNull ApiTokenStore.HashedToken token, @NonNull ApiT * Allow user to rename tokens */ @Override - public UserProperty reconfigure(StaplerRequest req, @CheckForNull JSONObject form) throws FormException { + public UserProperty reconfigure(StaplerRequest2 req, @CheckForNull JSONObject form) throws FormException { if (form == null) { return this; } diff --git a/core/src/main/java/jenkins/security/AuthenticationSuccessHandler.java b/core/src/main/java/jenkins/security/AuthenticationSuccessHandler.java index a5c7cffceeb8..a9dc6ef787b4 100644 --- a/core/src/main/java/jenkins/security/AuthenticationSuccessHandler.java +++ b/core/src/main/java/jenkins/security/AuthenticationSuccessHandler.java @@ -25,8 +25,8 @@ package jenkins.security; import hudson.Util; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.springframework.security.core.Authentication; diff --git a/core/src/main/java/jenkins/security/BasicHeaderApiTokenAuthenticator.java b/core/src/main/java/jenkins/security/BasicHeaderApiTokenAuthenticator.java index d37a59755725..5aab6868ea56 100644 --- a/core/src/main/java/jenkins/security/BasicHeaderApiTokenAuthenticator.java +++ b/core/src/main/java/jenkins/security/BasicHeaderApiTokenAuthenticator.java @@ -4,10 +4,10 @@ import hudson.Extension; import hudson.model.User; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.springframework.security.core.Authentication; diff --git a/core/src/main/java/jenkins/security/BasicHeaderAuthenticator.java b/core/src/main/java/jenkins/security/BasicHeaderAuthenticator.java index 471e0d3900c7..2906a1aa461b 100644 --- a/core/src/main/java/jenkins/security/BasicHeaderAuthenticator.java +++ b/core/src/main/java/jenkins/security/BasicHeaderAuthenticator.java @@ -4,10 +4,13 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.Util; +import io.jenkins.servlet.ServletExceptionWrapper; +import io.jenkins.servlet.http.HttpServletRequestWrapper; +import io.jenkins.servlet.http.HttpServletResponseWrapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.springframework.security.core.Authentication; /** @@ -35,11 +38,42 @@ public abstract class BasicHeaderAuthenticator implements ExtensionPoint { * <p> * When no processor can validate the username/password pair, caller will make * the request processing fail. - * @since 2.266 + * @since TODO */ @CheckForNull public Authentication authenticate2(HttpServletRequest req, HttpServletResponse rsp, String username, String password) throws IOException, ServletException { - if (Util.isOverridden(BasicHeaderAuthenticator.class, getClass(), "authenticate", HttpServletRequest.class, HttpServletResponse.class, String.class, String.class)) { + if (Util.isOverridden(BasicHeaderAuthenticator.class, getClass(), "authenticate2", javax.servlet.http.HttpServletRequest.class, javax.servlet.http.HttpServletResponse.class, String.class, String.class)) { + try { + return authenticate2(HttpServletRequestWrapper.fromJakartaHttpServletRequest(req), HttpServletResponseWrapper.fromJakartaHttpServletResponse(rsp), username, password); + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else if (Util.isOverridden(BasicHeaderAuthenticator.class, getClass(), "authenticate", javax.servlet.http.HttpServletRequest.class, javax.servlet.http.HttpServletResponse.class, String.class, String.class)) { + try { + org.acegisecurity.Authentication a = authenticate(HttpServletRequestWrapper.fromJakartaHttpServletRequest(req), HttpServletResponseWrapper.fromJakartaHttpServletResponse(rsp), username, password); + return a != null ? a.toSpring() : null; + } catch (javax.servlet.ServletException e) { + throw ServletExceptionWrapper.toJakartaServletException(e); + } + } else { + throw new AbstractMethodError("The class " + getClass().getName() + " must override at least one of the " + BasicHeaderAuthenticator.class.getSimpleName() + ".authenticate2 methods"); + } + } + + /** + * @deprecated use {@link #authenticate2(HttpServletRequest, HttpServletResponse, String, String)} + * @since 2.266 + */ + @CheckForNull + @Deprecated + public Authentication authenticate2(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse rsp, String username, String password) throws IOException, javax.servlet.ServletException { + if (Util.isOverridden(BasicHeaderAuthenticator.class, getClass(), "authenticate2", HttpServletRequest.class, HttpServletResponse.class, String.class, String.class)) { + try { + return authenticate2(HttpServletRequestWrapper.toJakartaHttpServletRequest(req), HttpServletResponseWrapper.toJakartaHttpServletResponse(rsp), username, password); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } + } else if (Util.isOverridden(BasicHeaderAuthenticator.class, getClass(), "authenticate", javax.servlet.http.HttpServletRequest.class, javax.servlet.http.HttpServletResponse.class, String.class, String.class)) { org.acegisecurity.Authentication a = authenticate(req, rsp, username, password); return a != null ? a.toSpring() : null; } else { @@ -52,7 +86,7 @@ public Authentication authenticate2(HttpServletRequest req, HttpServletResponse */ @Deprecated @CheckForNull - public org.acegisecurity.Authentication authenticate(HttpServletRequest req, HttpServletResponse rsp, String username, String password) throws IOException, ServletException { + public org.acegisecurity.Authentication authenticate(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse rsp, String username, String password) throws IOException, javax.servlet.ServletException { Authentication a = authenticate2(req, rsp, username, password); return a != null ? org.acegisecurity.Authentication.fromSpring(a) : null; } diff --git a/core/src/main/java/jenkins/security/BasicHeaderProcessor.java b/core/src/main/java/jenkins/security/BasicHeaderProcessor.java index 45b5eb0c70a2..1b31dba65e42 100644 --- a/core/src/main/java/jenkins/security/BasicHeaderProcessor.java +++ b/core/src/main/java/jenkins/security/BasicHeaderProcessor.java @@ -7,20 +7,21 @@ import hudson.security.ACLContext; import hudson.security.SecurityRealm; import hudson.util.Scrambler; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; import java.util.Locale; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.CompatibleFilter; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -43,7 +44,7 @@ * @author Kohsuke Kawaguchi */ @Restricted(NoExternalUse.class) -public class BasicHeaderProcessor implements Filter { +public class BasicHeaderProcessor implements CompatibleFilter { private AuthenticationEntryPoint authenticationEntryPoint; private RememberMeServices rememberMeServices = new NullRememberMeServices(); diff --git a/core/src/main/java/jenkins/security/BasicHeaderRealPasswordAuthenticator.java b/core/src/main/java/jenkins/security/BasicHeaderRealPasswordAuthenticator.java index 1007819c981a..70ef36505683 100644 --- a/core/src/main/java/jenkins/security/BasicHeaderRealPasswordAuthenticator.java +++ b/core/src/main/java/jenkins/security/BasicHeaderRealPasswordAuthenticator.java @@ -19,11 +19,11 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.ExtensionFilter; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; diff --git a/core/src/main/java/jenkins/security/LastGrantedAuthoritiesProperty.java b/core/src/main/java/jenkins/security/LastGrantedAuthoritiesProperty.java index cb8b8accf295..31951b8572fb 100644 --- a/core/src/main/java/jenkins/security/LastGrantedAuthoritiesProperty.java +++ b/core/src/main/java/jenkins/security/LastGrantedAuthoritiesProperty.java @@ -21,7 +21,7 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -44,7 +44,7 @@ public class LastGrantedAuthoritiesProperty extends UserProperty { * Stick to the same object since there's no UI for this. */ @Override - public UserProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { + public UserProperty reconfigure(StaplerRequest2 req, JSONObject form) throws FormException { req.bindJSON(this, form); return this; } diff --git a/core/src/main/java/jenkins/security/NonSerializableSecurityContext.java b/core/src/main/java/jenkins/security/NonSerializableSecurityContext.java index e67e73b8db33..859b0db4ef1b 100644 --- a/core/src/main/java/jenkins/security/NonSerializableSecurityContext.java +++ b/core/src/main/java/jenkins/security/NonSerializableSecurityContext.java @@ -16,7 +16,7 @@ package jenkins.security; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSession; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.springframework.security.core.Authentication; diff --git a/core/src/main/java/jenkins/security/QueueItemAuthenticatorConfiguration.java b/core/src/main/java/jenkins/security/QueueItemAuthenticatorConfiguration.java index b4c033bfad0e..b409d92d9490 100644 --- a/core/src/main/java/jenkins/security/QueueItemAuthenticatorConfiguration.java +++ b/core/src/main/java/jenkins/security/QueueItemAuthenticatorConfiguration.java @@ -11,7 +11,7 @@ import jenkins.model.GlobalConfigurationCategory; import net.sf.json.JSONObject; import org.jenkinsci.Symbol; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Show the {@link QueueItemAuthenticator} configurations on the system config page. @@ -47,7 +47,7 @@ public DescribableList<QueueItemAuthenticator, QueueItemAuthenticatorDescriptor> } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { try { authenticators.rebuildHetero(req, json, QueueItemAuthenticatorDescriptor.all(), "authenticators"); return true; diff --git a/core/src/main/java/jenkins/security/ResourceDomainConfiguration.java b/core/src/main/java/jenkins/security/ResourceDomainConfiguration.java index cd552fc65130..6b03113019d5 100644 --- a/core/src/main/java/jenkins/security/ResourceDomainConfiguration.java +++ b/core/src/main/java/jenkins/security/ResourceDomainConfiguration.java @@ -31,6 +31,7 @@ import hudson.ExtensionList; import hudson.Util; import hudson.util.FormValidation; +import jakarta.servlet.http.HttpServletRequest; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; @@ -43,7 +44,6 @@ import java.util.Base64; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.http.HttpServletRequest; import jenkins.diagnostics.RootUrlNotSetMonitor; import jenkins.model.GlobalConfiguration; import jenkins.model.Jenkins; @@ -57,7 +57,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.verb.POST; /** @@ -134,7 +134,7 @@ private FormValidation checkUrl(String resourceRootUrlString, boolean allowOnlin return FormValidation.error(Messages.ResourceDomainConfiguration_InvalidRootURL(ex.getMessage())); } - StaplerRequest currentRequest = Stapler.getCurrentRequest(); + StaplerRequest2 currentRequest = Stapler.getCurrentRequest2(); if (currentRequest != null) { String currentRequestHost = currentRequest.getServerName(); diff --git a/core/src/main/java/jenkins/security/ResourceDomainFilter.java b/core/src/main/java/jenkins/security/ResourceDomainFilter.java index b88fc7045ff6..4e47dbb2e5cd 100644 --- a/core/src/main/java/jenkins/security/ResourceDomainFilter.java +++ b/core/src/main/java/jenkins/security/ResourceDomainFilter.java @@ -26,14 +26,14 @@ import hudson.Extension; import hudson.Functions; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.util.HttpServletFilter; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; diff --git a/core/src/main/java/jenkins/security/ResourceDomainRootAction.java b/core/src/main/java/jenkins/security/ResourceDomainRootAction.java index fc18071fade7..bd327599bd2f 100644 --- a/core/src/main/java/jenkins/security/ResourceDomainRootAction.java +++ b/core/src/main/java/jenkins/security/ResourceDomainRootAction.java @@ -54,8 +54,8 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UsernameNotFoundException; @@ -101,7 +101,7 @@ public static ResourceDomainRootAction get() { return ExtensionList.lookupSingleton(ResourceDomainRootAction.class); } - public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doIndex(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { if (ResourceDomainConfiguration.isResourceRequest(req)) { rsp.sendError(404, ResourceDomainFilter.ERROR_RESPONSE); } else { @@ -110,7 +110,7 @@ public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException } } - public Object getDynamic(String id, StaplerRequest req, StaplerResponse rsp) throws Exception { + public Object getDynamic(String id, StaplerRequest2 req, StaplerResponse2 rsp) throws Exception { if (!ResourceDomainConfiguration.isResourceRequest(req)) { req.setAttribute(RESOURCE_DOMAIN_ROOT_ACTION_ERROR, true); rsp.sendError(404, "Cannot handle requests to this URL unless on Jenkins resource URL."); @@ -147,7 +147,7 @@ private Redirection(String url) { this.url = url; } - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { String restOfPath = req.getRestOfPath(); String url = Jenkins.get().getRootUrl() + this.url + restOfPath; @@ -169,7 +169,7 @@ private static String getResourceRootUrl() { } /** - * Called from {@link DirectoryBrowserSupport#generateResponse(StaplerRequest, StaplerResponse, Object)} to obtain + * Called from {@link DirectoryBrowserSupport#generateResponse(StaplerRequest2, StaplerResponse2, Object)} to obtain * a token to use when rendering a response. * * @param dbs the {@link DirectoryBrowserSupport} instance requesting the token @@ -177,7 +177,7 @@ private static String getResourceRootUrl() { * @return a token that can be used to redirect users to the {@link ResourceDomainRootAction}. */ @CheckForNull - public Token getToken(@NonNull DirectoryBrowserSupport dbs, @NonNull StaplerRequest req) { + public Token getToken(@NonNull DirectoryBrowserSupport dbs, @NonNull StaplerRequest2 req) { // This is the "restOfPath" of the DirectoryBrowserSupport, i.e. the directory/file/pattern "inside" the DBS. final String dbsFile = req.getOriginalRestOfPath(); @@ -212,7 +212,7 @@ private static class InternalResourceRequest { this.authenticationName = authenticationName; } - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException { String restOfPath = req.getRestOfPath(); String requestUrlSuffix = this.browserUrl; diff --git a/core/src/main/java/jenkins/security/SecureRequester.java b/core/src/main/java/jenkins/security/SecureRequester.java index 18c634a155ac..489deccab1fd 100644 --- a/core/src/main/java/jenkins/security/SecureRequester.java +++ b/core/src/main/java/jenkins/security/SecureRequester.java @@ -2,13 +2,16 @@ import hudson.Extension; import hudson.ExtensionPoint; +import hudson.Util; import hudson.model.Api; import java.util.logging.Logger; import jenkins.model.Jenkins; +import jenkins.security.stapler.StaplerNotDispatchable; import jenkins.util.SystemProperties; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * An extension point for authorizing REST API access to an object where an unsafe result type would be produced. @@ -22,13 +25,37 @@ public interface SecureRequester extends ExtensionPoint { /** * Checks if a Jenkins object can be accessed by a given REST request. - * For instance, if the {@link StaplerRequest#getReferer} matches a given host, or + * For instance, if the {@link StaplerRequest2#getReferer} matches a given host, or * anonymous read is allowed for the given object. * @param req a request going through the REST API * @param bean an exported object of some kind * @return true if this requester should be trusted, false to reject */ - boolean permit(StaplerRequest req, Object bean); + @StaplerNotDispatchable + default boolean permit(StaplerRequest2 req, Object bean) { + return Util.ifOverridden( + () -> permit(StaplerRequest.fromStaplerRequest2(req), bean), + SecureRequester.class, + getClass(), + "permit", + StaplerRequest.class, + Object.class); + } + + /** + * @deprecated use {@link #permit(StaplerRequest2, Object)} + */ + @Deprecated + @StaplerNotDispatchable + default boolean permit(StaplerRequest req, Object bean) { + return Util.ifOverridden( + () -> permit(StaplerRequest.toStaplerRequest2(req), bean), + SecureRequester.class, + getClass(), + "permit", + StaplerRequest2.class, + Object.class); + } @Restricted(NoExternalUse.class) @Extension class Default implements SecureRequester { @@ -42,7 +69,7 @@ public interface SecureRequester extends ExtensionPoint { } } - @Override public boolean permit(StaplerRequest req, Object bean) { + @Override public boolean permit(StaplerRequest2 req, Object bean) { return INSECURE || !Jenkins.get().isUseSecurity(); } diff --git a/core/src/main/java/jenkins/security/SuspiciousRequestFilter.java b/core/src/main/java/jenkins/security/SuspiciousRequestFilter.java index 9b9f413606d8..26a1eb5da845 100644 --- a/core/src/main/java/jenkins/security/SuspiciousRequestFilter.java +++ b/core/src/main/java/jenkins/security/SuspiciousRequestFilter.java @@ -1,22 +1,22 @@ package jenkins.security; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.logging.Logger; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.util.SystemProperties; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.CompatibleFilter; @Restricted(NoExternalUse.class) -public class SuspiciousRequestFilter implements Filter { +public class SuspiciousRequestFilter implements CompatibleFilter { /** System property name set to true or false to indicate whether or not semicolons should be allowed in URL paths. */ public static final String ALLOW_SEMICOLONS_IN_PATH = SuspiciousRequestFilter.class.getName() + ".allowSemicolonsInPath"; diff --git a/core/src/main/java/jenkins/security/UpdateSiteWarningsConfiguration.java b/core/src/main/java/jenkins/security/UpdateSiteWarningsConfiguration.java index da4fc322811e..33638a3c9d65 100644 --- a/core/src/main/java/jenkins/security/UpdateSiteWarningsConfiguration.java +++ b/core/src/main/java/jenkins/security/UpdateSiteWarningsConfiguration.java @@ -40,7 +40,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Configuration for update site-provided warnings. @@ -111,7 +111,7 @@ public Set<UpdateSite.Warning> getApplicableWarnings() { @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { HashSet<String> newIgnoredWarnings = new HashSet<>(); for (Object key : json.keySet()) { String warningKey = key.toString(); diff --git a/core/src/main/java/jenkins/security/seed/UserSeedSecurityListener.java b/core/src/main/java/jenkins/security/seed/UserSeedSecurityListener.java index 1996a5efc174..870e6d7de342 100644 --- a/core/src/main/java/jenkins/security/seed/UserSeedSecurityListener.java +++ b/core/src/main/java/jenkins/security/seed/UserSeedSecurityListener.java @@ -27,12 +27,12 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; import hudson.model.User; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSession; import jenkins.security.SecurityListener; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.core.userdetails.UserDetails; /** @@ -53,7 +53,7 @@ protected void authenticated2(@NonNull UserDetails details) { } private static void putUserSeedInSession(String username, boolean overwriteSessionSeed) { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req == null) { // expected case: CLI // But also HudsonPrivateSecurityRealm because of a redirect from Spring Security, the request is not a Stapler one diff --git a/core/src/main/java/jenkins/security/stapler/StaplerDispatchValidator.java b/core/src/main/java/jenkins/security/stapler/StaplerDispatchValidator.java index eebfcfdacf0e..028b2dba1db3 100644 --- a/core/src/main/java/jenkins/security/stapler/StaplerDispatchValidator.java +++ b/core/src/main/java/jenkins/security/stapler/StaplerDispatchValidator.java @@ -28,6 +28,7 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import jakarta.servlet.ServletContext; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -50,7 +51,6 @@ import java.util.function.Supplier; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletContext; import jenkins.YesNoMaybe; import jenkins.model.Jenkins; import jenkins.util.SystemProperties; @@ -59,8 +59,8 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.CancelRequestHandlingException; import org.kohsuke.stapler.DispatchValidator; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebApp; /** @@ -95,7 +95,7 @@ public class StaplerDispatchValidator implements DispatchValidator { public static /* script-console editable */ boolean DISABLED = SystemProperties.getBoolean(ESCAPE_HATCH); @NonNull - private static YesNoMaybe setStatus(@NonNull StaplerRequest req, @NonNull YesNoMaybe status) { + private static YesNoMaybe setStatus(@NonNull StaplerRequest2 req, @NonNull YesNoMaybe status) { switch (status) { case YES: case NO: @@ -110,7 +110,7 @@ private static YesNoMaybe setStatus(@NonNull StaplerRequest req, @NonNull YesNoM } @NonNull - private static YesNoMaybe computeStatusIfNull(@NonNull StaplerRequest req, @NonNull Supplier<YesNoMaybe> statusIfNull) { + private static YesNoMaybe computeStatusIfNull(@NonNull StaplerRequest2 req, @NonNull Supplier<YesNoMaybe> statusIfNull) { Object requestStatus = req.getAttribute(ATTRIBUTE_NAME); if (requestStatus instanceof Boolean) { return (Boolean) requestStatus ? YesNoMaybe.YES : YesNoMaybe.NO; @@ -127,7 +127,7 @@ public StaplerDispatchValidator() { } @Override - public @CheckForNull Boolean isDispatchAllowed(@NonNull StaplerRequest req, @NonNull StaplerResponse rsp) { + public @CheckForNull Boolean isDispatchAllowed(@NonNull StaplerRequest2 req, @NonNull StaplerResponse2 rsp) { if (DISABLED) { return true; } @@ -145,7 +145,7 @@ public StaplerDispatchValidator() { } @Override - public @CheckForNull Boolean isDispatchAllowed(@NonNull StaplerRequest req, @NonNull StaplerResponse rsp, @NonNull String viewName, @CheckForNull Object node) { + public @CheckForNull Boolean isDispatchAllowed(@NonNull StaplerRequest2 req, @NonNull StaplerResponse2 rsp, @NonNull String viewName, @CheckForNull Object node) { if (DISABLED) { return true; } @@ -163,7 +163,7 @@ public StaplerDispatchValidator() { } @Override - public void allowDispatch(@NonNull StaplerRequest req, @NonNull StaplerResponse rsp) { + public void allowDispatch(@NonNull StaplerRequest2 req, @NonNull StaplerResponse2 rsp) { if (DISABLED) { return; } @@ -171,7 +171,7 @@ public void allowDispatch(@NonNull StaplerRequest req, @NonNull StaplerResponse } @Override - public void requireDispatchAllowed(@NonNull StaplerRequest req, @NonNull StaplerResponse rsp) throws CancelRequestHandlingException { + public void requireDispatchAllowed(@NonNull StaplerRequest2 req, @NonNull StaplerResponse2 rsp) throws CancelRequestHandlingException { if (DISABLED) { return; } diff --git a/core/src/main/java/jenkins/security/stapler/StaplerFilteredActionListener.java b/core/src/main/java/jenkins/security/stapler/StaplerFilteredActionListener.java index cc658c275fcf..ad8837c19d83 100644 --- a/core/src/main/java/jenkins/security/stapler/StaplerFilteredActionListener.java +++ b/core/src/main/java/jenkins/security/stapler/StaplerFilteredActionListener.java @@ -29,8 +29,8 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Function; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.event.FilteredDispatchTriggerListener; import org.kohsuke.stapler.event.FilteredDoActionTriggerListener; import org.kohsuke.stapler.event.FilteredFieldTriggerListener; @@ -49,7 +49,7 @@ public class StaplerFilteredActionListener implements FilteredDoActionTriggerLis "Learn more: https://www.jenkins.io/redirect/stapler-routing"; @Override - public boolean onDoActionTrigger(Function f, StaplerRequest req, StaplerResponse rsp, Object node) { + public boolean onDoActionTrigger(Function f, StaplerRequest2 req, StaplerResponse2 rsp, Object node) { LOGGER.log(Level.FINER, LOG_MESSAGE, new Object[]{ req.getPathInfo(), f.getSignature(), @@ -58,7 +58,7 @@ public boolean onDoActionTrigger(Function f, StaplerRequest req, StaplerResponse } @Override - public boolean onGetterTrigger(Function f, StaplerRequest req, StaplerResponse rsp, Object node, String expression) { + public boolean onGetterTrigger(Function f, StaplerRequest2 req, StaplerResponse2 rsp, Object node, String expression) { LOGGER.log(Level.FINER, LOG_MESSAGE, new Object[]{ req.getPathInfo(), f.getSignature(), @@ -67,7 +67,7 @@ public boolean onGetterTrigger(Function f, StaplerRequest req, StaplerResponse r } @Override - public boolean onFieldTrigger(FieldRef f, StaplerRequest req, StaplerResponse staplerResponse, Object node, String expression) { + public boolean onFieldTrigger(FieldRef f, StaplerRequest2 req, StaplerResponse2 staplerResponse, Object node, String expression) { LOGGER.log(Level.FINER, LOG_MESSAGE, new Object[]{ req.getPathInfo(), f.getSignature(), @@ -76,7 +76,7 @@ public boolean onFieldTrigger(FieldRef f, StaplerRequest req, StaplerResponse st } @Override - public boolean onDispatchTrigger(StaplerRequest req, StaplerResponse rsp, Object node, String viewName) { + public boolean onDispatchTrigger(StaplerRequest2 req, StaplerResponse2 rsp, Object node, String viewName) { LOGGER.finer(() -> "New Stapler dispatch rules result in the URL \"" + req.getPathInfo() + "\" no longer being allowed. " + "If you consider it safe to use, add the following to the whitelist: \"" + node.getClass().getName() + " " + viewName + "\". " + "Learn more: https://www.jenkins.io/redirect/stapler-facet-restrictions"); diff --git a/core/src/main/java/jenkins/security/stapler/StaticRoutingDecisionProvider.java b/core/src/main/java/jenkins/security/stapler/StaticRoutingDecisionProvider.java index abc61baf042b..5706504bd8f5 100644 --- a/core/src/main/java/jenkins/security/stapler/StaticRoutingDecisionProvider.java +++ b/core/src/main/java/jenkins/security/stapler/StaticRoutingDecisionProvider.java @@ -123,7 +123,7 @@ synchronized void resetAndSave() { private void resetMetaClassCache() { // to allow the change to be effective, i.e. rebuild the MetaClass using the new whitelist - WebApp.get(Jenkins.get().servletContext).clearMetaClassCache(); + WebApp.get(Jenkins.get().getServletContext()).clearMetaClassCache(); } private synchronized void reloadFromDefault() { diff --git a/core/src/main/java/jenkins/security/stapler/WebMethodConstants.java b/core/src/main/java/jenkins/security/stapler/WebMethodConstants.java index 90e14912005d..3227945cb293 100644 --- a/core/src/main/java/jenkins/security/stapler/WebMethodConstants.java +++ b/core/src/main/java/jenkins/security/stapler/WebMethodConstants.java @@ -24,20 +24,22 @@ package jenkins.security.stapler; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.lang.annotation.Annotation; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.Header; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.bind.JavaScriptMethod; import org.kohsuke.stapler.json.JsonBody; @@ -49,10 +51,14 @@ final class WebMethodConstants { * If a method has at least one of those parameters, it is considered as an implicit web method */ private static final List<Class<?>> WEB_METHOD_PARAMETERS = List.of( + StaplerRequest2.class, StaplerRequest.class, HttpServletRequest.class, + javax.servlet.http.HttpServletRequest.class, + StaplerResponse2.class, StaplerResponse.class, - HttpServletResponse.class + HttpServletResponse.class, + javax.servlet.http.HttpServletResponse.class ); static final Set<String> WEB_METHOD_PARAMETERS_NAMES = Collections.unmodifiableSet( diff --git a/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java b/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java index 9dac60c0500c..dd68f02376f4 100644 --- a/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java +++ b/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java @@ -5,6 +5,11 @@ import hudson.security.Permission; import hudson.slaves.SlaveComputer; import hudson.util.Secret; +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.WriteListener; +import jakarta.servlet.http.HttpServletResponseWrapper; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintWriter; @@ -17,15 +22,10 @@ import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.WriteListener; -import javax.servlet.http.HttpServletResponseWrapper; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.ResponseImpl; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Serves the JNLP file. @@ -70,11 +70,11 @@ public EncryptedSlaveAgentJnlpFile(AccessControlled it, String viewName, String } @Override - public void generateResponse(StaplerRequest req, final StaplerResponse res, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, final StaplerResponse2 res, Object node) throws IOException, ServletException { RequestDispatcher view = req.getView(it, viewName); if ("true".equals(req.getParameter("encrypt"))) { final CapturingServletOutputStream csos = new CapturingServletOutputStream(); - StaplerResponse temp = new ResponseImpl(req.getStapler(), new HttpServletResponseWrapper(res) { + StaplerResponse2 temp = new ResponseImpl(req.getStapler(), new HttpServletResponseWrapper(res) { @Override public ServletOutputStream getOutputStream() { return csos; } diff --git a/core/src/main/java/jenkins/tasks/filters/EnvVarsFilterGlobalConfiguration.java b/core/src/main/java/jenkins/tasks/filters/EnvVarsFilterGlobalConfiguration.java index 9e2258c5abed..230b1a700115 100644 --- a/core/src/main/java/jenkins/tasks/filters/EnvVarsFilterGlobalConfiguration.java +++ b/core/src/main/java/jenkins/tasks/filters/EnvVarsFilterGlobalConfiguration.java @@ -37,7 +37,7 @@ import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.Beta; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Configuration of the filter rules that are applied globally, @@ -75,7 +75,7 @@ public GlobalConfigurationCategory getCategory() { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + public boolean configure(StaplerRequest2 req, JSONObject json) throws FormException { try { activatedGlobalRules.rebuildHetero(req, json, getAllGlobalRules(), "rules"); } catch (IOException e) { diff --git a/core/src/main/java/jenkins/telemetry/impl/StaplerDispatches.java b/core/src/main/java/jenkins/telemetry/impl/StaplerDispatches.java index 66078caa3d33..5cf16e0b0e49 100644 --- a/core/src/main/java/jenkins/telemetry/impl/StaplerDispatches.java +++ b/core/src/main/java/jenkins/telemetry/impl/StaplerDispatches.java @@ -38,7 +38,7 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.EvaluationTrace; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Telemetry implementation gathering information about Stapler dispatch routes. @@ -86,7 +86,7 @@ private Object buildDispatches() { public static class StaplerTrace extends EvaluationTrace.ApplicationTracer { @Override - protected void record(StaplerRequest staplerRequest, String s) { + protected void record(StaplerRequest2 staplerRequest, String s) { if (Telemetry.isDisabled()) { // do not collect traces while usage statistics are disabled return; diff --git a/core/src/main/java/jenkins/telemetry/impl/UserLanguages.java b/core/src/main/java/jenkins/telemetry/impl/UserLanguages.java index 8bf24d1b01a9..0a03b0fe653c 100644 --- a/core/src/main/java/jenkins/telemetry/impl/UserLanguages.java +++ b/core/src/main/java/jenkins/telemetry/impl/UserLanguages.java @@ -26,6 +26,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.LocalDate; import java.util.Map; @@ -33,9 +36,6 @@ import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.telemetry.Telemetry; import jenkins.util.HttpServletFilter; import net.sf.json.JSONObject; diff --git a/core/src/main/java/jenkins/tools/GlobalToolConfiguration.java b/core/src/main/java/jenkins/tools/GlobalToolConfiguration.java index bcca8506c5dd..47208f942958 100644 --- a/core/src/main/java/jenkins/tools/GlobalToolConfiguration.java +++ b/core/src/main/java/jenkins/tools/GlobalToolConfiguration.java @@ -32,17 +32,17 @@ import hudson.model.ManagementLink; import hudson.security.Permission; import hudson.util.FormApply; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.function.Predicate; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; @Extension(ordinal = Integer.MAX_VALUE - 220) @@ -81,13 +81,13 @@ public Category getCategory() { } @POST - public synchronized void doConfigure(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException { + public synchronized void doConfigure(StaplerRequest2 req, StaplerResponse2 rsp) throws IOException, ServletException, Descriptor.FormException { boolean result = configure(req, req.getSubmittedForm()); LOGGER.log(Level.FINE, "tools saved: " + result); FormApply.success(req.getContextPath() + "/manage").generateResponse(req, rsp, null); } - private boolean configure(StaplerRequest req, JSONObject json) throws Descriptor.FormException, IOException { + private boolean configure(StaplerRequest2 req, JSONObject json) throws Descriptor.FormException, IOException { Jenkins j = Jenkins.get(); j.checkPermission(Jenkins.ADMINISTER); @@ -100,7 +100,7 @@ private boolean configure(StaplerRequest req, JSONObject json) throws Descriptor return result; } - private boolean configureDescriptor(StaplerRequest req, JSONObject json, Descriptor<?> d) throws Descriptor.FormException { + private boolean configureDescriptor(StaplerRequest2 req, JSONObject json, Descriptor<?> d) throws Descriptor.FormException { String name = d.getJsonSafeClassName(); JSONObject js = json.has(name) ? json.getJSONObject(name) : new JSONObject(); // if it doesn't have the property, the method returns invalid null object. json.putAll(js); diff --git a/core/src/main/java/jenkins/util/FullDuplexHttpService.java b/core/src/main/java/jenkins/util/FullDuplexHttpService.java index 01f79b029125..28b9334204e4 100644 --- a/core/src/main/java/jenkins/util/FullDuplexHttpService.java +++ b/core/src/main/java/jenkins/util/FullDuplexHttpService.java @@ -30,6 +30,8 @@ import hudson.security.csrf.CrumbExclusion; import hudson.util.ChunkedInputStream; import hudson.util.ChunkedOutputStream; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -38,13 +40,11 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Server-side counterpart to {@link FullDuplexHttpStream}. @@ -86,7 +86,7 @@ protected FullDuplexHttpService(UUID uuid) { * <p> * If this connection is lost, we'll abort the channel. */ - public synchronized void download(StaplerRequest req, StaplerResponse rsp) throws InterruptedException, IOException { + public synchronized void download(StaplerRequest2 req, StaplerResponse2 rsp) throws InterruptedException, IOException { rsp.setStatus(HttpServletResponse.SC_OK); // server->client channel. @@ -129,7 +129,7 @@ public synchronized void download(StaplerRequest req, StaplerResponse rsp) throw /** * This is where we receive inputs from the client. */ - public synchronized void upload(StaplerRequest req, StaplerResponse rsp) throws InterruptedException, IOException { + public synchronized void upload(StaplerRequest2 req, StaplerResponse2 rsp) throws InterruptedException, IOException { rsp.setStatus(HttpServletResponse.SC_OK); InputStream in = req.getInputStream(); if (DIY_CHUNKING) { @@ -163,7 +163,7 @@ protected Response(Map<UUID, FullDuplexHttpService> services) { } @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { try { // do not require any permission to establish a CLI connection // the actual authentication for the connecting Channel is done by CLICommand @@ -198,7 +198,7 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod } } - protected abstract FullDuplexHttpService createService(StaplerRequest req, UUID uuid) throws IOException, InterruptedException; + protected abstract FullDuplexHttpService createService(StaplerRequest2 req, UUID uuid) throws IOException, InterruptedException; } diff --git a/core/src/main/java/jenkins/util/HttpServletFilter.java b/core/src/main/java/jenkins/util/HttpServletFilter.java index b83b37d1174d..da00b32b2908 100644 --- a/core/src/main/java/jenkins/util/HttpServletFilter.java +++ b/core/src/main/java/jenkins/util/HttpServletFilter.java @@ -29,17 +29,18 @@ import hudson.init.Initializer; import hudson.security.csrf.CrumbExclusion; import hudson.util.PluginServletFilter; +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; +import org.kohsuke.stapler.CompatibleFilter; /** * More convenient and declarative way to use {@link PluginServletFilter}. @@ -63,7 +64,7 @@ public interface HttpServletFilter extends ExtensionPoint { @Restricted(DoNotUse.class) @Initializer static void register() throws ServletException { - PluginServletFilter.addFilter(new Filter() { + PluginServletFilter.addFilter(new CompatibleFilter() { @Override public void doFilter(ServletRequest req, ServletResponse rsp, FilterChain chain) throws IOException, ServletException { if (req instanceof HttpServletRequest && rsp instanceof HttpServletResponse) { diff --git a/core/src/main/java/jenkins/util/HttpSessionListener.java b/core/src/main/java/jenkins/util/HttpSessionListener.java index 7f3649fd2381..85ff806ac6e6 100644 --- a/core/src/main/java/jenkins/util/HttpSessionListener.java +++ b/core/src/main/java/jenkins/util/HttpSessionListener.java @@ -28,11 +28,13 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.ExtensionList; import hudson.ExtensionPoint; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionEvent; +import hudson.Util; +import io.jenkins.servlet.http.HttpSessionEventWrapper; +import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSessionEvent; /** - * {@link javax.servlet.http.HttpSessionListener} {@link ExtensionPoint} for Jenkins. + * {@link jakarta.servlet.http.HttpSessionListener} {@link ExtensionPoint} for Jenkins. * <p> * Allows plugins to listen to {@link HttpSession} lifecycle events. * @@ -40,7 +42,7 @@ * @since 2.2 */ @SuppressFBWarnings(value = "NM_SAME_SIMPLE_NAME_AS_INTERFACE", justification = "Should shadow HttpSessionListener") -public abstract class HttpSessionListener implements ExtensionPoint, javax.servlet.http.HttpSessionListener { +public abstract class HttpSessionListener implements ExtensionPoint, jakarta.servlet.http.HttpSessionListener, javax.servlet.http.HttpSessionListener { /** * Get all of the {@link HttpSessionListener} implementations. @@ -52,9 +54,37 @@ public static ExtensionList<HttpSessionListener> all() { @Override public void sessionCreated(HttpSessionEvent httpSessionEvent) { + if (Util.isOverridden(HttpSessionListener.class, getClass(), "sessionCreated", javax.servlet.http.HttpSessionEvent.class)) { + sessionCreated(HttpSessionEventWrapper.fromJakartaHttpSessionEvent(httpSessionEvent)); + } } @Override public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { + if (Util.isOverridden(HttpSessionListener.class, getClass(), "sessionCreated", javax.servlet.http.HttpSessionEvent.class)) { + sessionCreated(HttpSessionEventWrapper.fromJakartaHttpSessionEvent(httpSessionEvent)); + } + } + + /** + * @deprecated use {@link #sessionCreated(HttpSessionEvent)} + */ + @Deprecated + @Override + public void sessionCreated(javax.servlet.http.HttpSessionEvent httpSessionEvent) { + if (Util.isOverridden(HttpSessionListener.class, getClass(), "sessionCreated", HttpSessionEvent.class)) { + sessionCreated(HttpSessionEventWrapper.toJakartaHttpSessionEvent(httpSessionEvent)); + } + } + + /** + * @deprecated use {@link #sessionDestroyed(HttpSessionEvent)} + */ + @Deprecated + @Override + public void sessionDestroyed(javax.servlet.http.HttpSessionEvent httpSessionEvent) { + if (Util.isOverridden(HttpSessionListener.class, getClass(), "sessionDestroyed", HttpSessionEvent.class)) { + sessionDestroyed(HttpSessionEventWrapper.toJakartaHttpSessionEvent(httpSessionEvent)); + } } } diff --git a/core/src/main/java/jenkins/util/JSONSignatureValidator.java b/core/src/main/java/jenkins/util/JSONSignatureValidator.java index 3cc10ebd4038..e6f5429f43bc 100644 --- a/core/src/main/java/jenkins/util/JSONSignatureValidator.java +++ b/core/src/main/java/jenkins/util/JSONSignatureValidator.java @@ -252,12 +252,12 @@ protected Set<TrustAnchor> loadTrustAnchors(CertificateFactory cf) throws IOExce // which isn't useful at all Set<TrustAnchor> anchors = new HashSet<>(); // CertificateUtil.getDefaultRootCAs(); Jenkins j = Jenkins.get(); - for (String cert : j.servletContext.getResourcePaths("/WEB-INF/update-center-rootCAs")) { + for (String cert : j.getServletContext().getResourcePaths("/WEB-INF/update-center-rootCAs")) { if (cert.endsWith("/") || cert.endsWith(".txt")) { continue; // skip directories also any text files that are meant to be documentation } Certificate certificate; - try (InputStream in = j.servletContext.getResourceAsStream(cert)) { + try (InputStream in = j.getServletContext().getResourceAsStream(cert)) { if (in == null) continue; // our test for paths ending in / should prevent this from happening certificate = cf.generateCertificate(in); if (certificate instanceof X509Certificate) { diff --git a/core/src/main/java/jenkins/util/JenkinsJVM.java b/core/src/main/java/jenkins/util/JenkinsJVM.java index fafe1223a389..c13389493f41 100644 --- a/core/src/main/java/jenkins/util/JenkinsJVM.java +++ b/core/src/main/java/jenkins/util/JenkinsJVM.java @@ -1,7 +1,7 @@ package jenkins.util; import hudson.WebAppMain; -import javax.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextEvent; import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; diff --git a/core/src/main/java/jenkins/util/ProgressiveRendering.java b/core/src/main/java/jenkins/util/ProgressiveRendering.java index 460ac3afd82b..9dc2102b5bcc 100644 --- a/core/src/main/java/jenkins/util/ProgressiveRendering.java +++ b/core/src/main/java/jenkins/util/ProgressiveRendering.java @@ -26,6 +26,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.AbstractItem; +import jakarta.servlet.http.HttpServletRequest; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @@ -39,7 +40,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.http.HttpServletRequest; import net.sf.json.JSON; import net.sf.json.JSONObject; import org.kohsuke.stapler.Ancestor; @@ -103,7 +103,7 @@ protected ProgressiveRendering() { * For internal use. */ @JavaScriptMethod public final void start() { - Ancestor ancestor = Stapler.getCurrentRequest().findAncestor(BoundObjectTable.class); + Ancestor ancestor = Stapler.getCurrentRequest2().findAncestor(BoundObjectTable.class); if (ancestor == null) { throw new IllegalStateException("no BoundObjectTable"); } @@ -159,7 +159,7 @@ private void release() { */ @java.lang.SuppressWarnings({"rawtypes", "unchecked"}) // public RequestImpl ctor requires List<AncestorImpl> yet AncestorImpl is not public! API design flaw private static RequestImpl createMockRequest() { - RequestImpl currentRequest = (RequestImpl) Stapler.getCurrentRequest(); + RequestImpl currentRequest = (RequestImpl) Stapler.getCurrentRequest2(); HttpServletRequest original = (HttpServletRequest) currentRequest.getRequest(); final Map<String, Object> getters = new HashMap<>(); for (Method method : HttpServletRequest.class.getMethods()) { @@ -205,7 +205,7 @@ private static void setCurrentRequest(RequestImpl request) { /** * Actually do the work. * <p>The security context will be that in effect when the web request was made. - * {@link Stapler#getCurrentRequest} will also be similar to that in effect when the web request was made; + * {@link Stapler#getCurrentRequest2} will also be similar to that in effect when the web request was made; * at least, {@link Ancestor}s and basic request properties (URI, locale, and so on) will be available. * @throws Exception whenever you like; the progress bar will indicate that an error occurred but details go to the log only */ diff --git a/core/src/main/java/jenkins/util/ScriptListener.java b/core/src/main/java/jenkins/util/ScriptListener.java index b07603c17f2a..f75596b8c85d 100644 --- a/core/src/main/java/jenkins/util/ScriptListener.java +++ b/core/src/main/java/jenkins/util/ScriptListener.java @@ -36,7 +36,7 @@ import java.nio.charset.Charset; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * A listener to track in-process script use. @@ -44,7 +44,7 @@ * <p>Note that (unsandboxed) script execution can easily result in logging configuration being changed, so if you rely * on complete logging of scripting actions, make sure to set up logging to remote systems.</p> * - * @see jenkins.model.Jenkins#_doScript(StaplerRequest, org.kohsuke.stapler.StaplerResponse, javax.servlet.RequestDispatcher, hudson.remoting.VirtualChannel, hudson.security.ACL) + * @see jenkins.model.Jenkins#_doScript(StaplerRequest2, org.kohsuke.stapler.StaplerResponse2, jakarta.servlet.RequestDispatcher, hudson.remoting.VirtualChannel, hudson.security.ACL) * @see hudson.cli.GroovyCommand * @see hudson.cli.GroovyshCommand * @see jenkins.util.groovy.GroovyHookScript diff --git a/core/src/main/java/jenkins/util/SystemProperties.java b/core/src/main/java/jenkins/util/SystemProperties.java index d32a91e2db79..e3818b69f921 100644 --- a/core/src/main/java/jenkins/util/SystemProperties.java +++ b/core/src/main/java/jenkins/util/SystemProperties.java @@ -34,6 +34,9 @@ import hudson.model.TaskListener; import hudson.remoting.Channel; import hudson.slaves.ComputerListener; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; import java.io.IOException; import java.util.Collections; import java.util.HashMap; @@ -42,9 +45,6 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; import jenkins.security.MasterToSlaveCallable; import jenkins.util.io.OnMaster; import org.kohsuke.accmod.Restricted; diff --git a/core/src/main/java/jenkins/util/groovy/GroovyHookScript.java b/core/src/main/java/jenkins/util/groovy/GroovyHookScript.java index eeb816f31ffd..1539d75715c5 100644 --- a/core/src/main/java/jenkins/util/groovy/GroovyHookScript.java +++ b/core/src/main/java/jenkins/util/groovy/GroovyHookScript.java @@ -8,6 +8,8 @@ import groovy.lang.GroovyCodeSource; import groovy.lang.GroovyShell; import hudson.model.User; +import io.jenkins.servlet.ServletContextWrapper; +import jakarta.servlet.ServletContext; import java.io.File; import java.io.IOException; import java.net.URL; @@ -15,7 +17,6 @@ import java.util.Set; import java.util.TreeSet; import java.util.logging.Logger; -import javax.servlet.ServletContext; import jenkins.model.Jenkins; import jenkins.util.ScriptListener; import jenkins.util.SystemProperties; @@ -55,7 +56,7 @@ public GroovyHookScript(String hook) { } private GroovyHookScript(String hook, Jenkins j) { - this(hook, j.servletContext, j.getRootDir(), j.getPluginManager().uberClassLoader); + this(hook, j.getServletContext(), j.getRootDir(), j.getPluginManager().uberClassLoader); } public GroovyHookScript(String hook, @NonNull ServletContext servletContext, @NonNull File jenkinsHome, @NonNull ClassLoader loader) { @@ -65,6 +66,14 @@ public GroovyHookScript(String hook, @NonNull ServletContext servletContext, @No this.loader = loader; } + /** + * @deprecated use {@link #GroovyHookScript(String, ServletContext, File, ClassLoader)} + */ + @Deprecated + public GroovyHookScript(String hook, @NonNull javax.servlet.ServletContext servletContext, @NonNull File jenkinsHome, @NonNull ClassLoader loader) { + this(hook, ServletContextWrapper.toJakartaServletContext(servletContext), jenkinsHome, loader); + } + public GroovyHookScript bind(String name, Object o) { bindings.setProperty(name, o); return this; diff --git a/core/src/main/java/jenkins/websocket/WebSockets.java b/core/src/main/java/jenkins/websocket/WebSockets.java index 0f275864c23f..5e0152381e3e 100644 --- a/core/src/main/java/jenkins/websocket/WebSockets.java +++ b/core/src/main/java/jenkins/websocket/WebSockets.java @@ -24,6 +24,9 @@ package jenkins.websocket; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.nio.channels.ClosedChannelException; import java.util.Iterator; @@ -31,13 +34,11 @@ import java.util.ServiceLoader; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.Beta; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * Support for serving WebSocket responses. @@ -65,11 +66,16 @@ private static Provider findProvider() { // TODO ability to handle subprotocols? public static HttpResponse upgrade(WebSocketSession session) { - return (req, rsp, node) -> upgradeResponse(session, req, rsp); + return new HttpResponse() { + @Override + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { + upgradeResponse(session, req, rsp); + } + }; } /** - * Variant of {@link #upgrade} that does not presume a {@link StaplerRequest}. + * Variant of {@link #upgrade} that does not presume a {@link StaplerRequest2}. * @since 2.446 */ public static void upgradeResponse(WebSocketSession session, HttpServletRequest req, HttpServletResponse rsp) throws IOException, ServletException { diff --git a/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServices.java b/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServices.java index 853905eb1c6a..379dd1b4d15e 100644 --- a/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServices.java +++ b/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServices.java @@ -24,8 +24,8 @@ package org.acegisecurity.ui.rememberme; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.acegisecurity.Authentication; /** diff --git a/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServicesSpringImpl.java b/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServicesSpringImpl.java index 5a0cd0d63d86..5dca4372020f 100644 --- a/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServicesSpringImpl.java +++ b/core/src/main/java/org/acegisecurity/ui/rememberme/RememberMeServicesSpringImpl.java @@ -24,8 +24,8 @@ package org.acegisecurity.ui.rememberme; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.acegisecurity.Authentication; final class RememberMeServicesSpringImpl implements org.springframework.security.web.authentication.RememberMeServices { diff --git a/core/src/main/resources/jenkins/model/Jenkins/_404.jelly b/core/src/main/resources/jenkins/model/Jenkins/_404.jelly index 4605b5926760..7230e4f31acc 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/_404.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/_404.jelly @@ -29,8 +29,8 @@ THE SOFTWARE. Generally kept very similar to 'oops.jelly'. --> <st:statusCode value="${response.getStatus()}" /> - ${request.session.setAttribute('from', request.getAttribute('javax.servlet.error.request_uri'))} - <l:layout title="${%title(javax.servlet.error.message?:'Not Found')}" type="one-column"> + ${request.session.setAttribute('from', request.getAttribute('jakarta.servlet.error.request_uri'))} + <l:layout title="${%title(jakarta.servlet.error.message?:'Not Found')}" type="one-column"> <l:header /> <l:main-panel> <h1 style="text-align: center"> @@ -38,7 +38,7 @@ THE SOFTWARE. <span style="font-size:50px"><st:nbsp/>${%Oops!}</span> </h1> <div id="error-description" style="text-align: center"> - <h2>${%title(javax.servlet.error.message?:'Not Found')}</h2> + <h2>${%title(jakarta.servlet.error.message?:'Not Found')}</h2> <j:if test="${!request.getAttribute('jenkins.security.ResourceDomainRootAction.error')}"> <p> <j:choose> diff --git a/core/src/main/resources/jenkins/model/Jenkins/_404_simple.jelly b/core/src/main/resources/jenkins/model/Jenkins/_404_simple.jelly index c6a876bb2955..e59083103a55 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/_404_simple.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/_404_simple.jelly @@ -39,7 +39,7 @@ THE SOFTWARE. <st:statusCode value="${response.getStatus()}" /> <html> <head> - <title>${%title(javax.servlet.error.message?:'Not Found')}</title> + <title>${%title(jakarta.servlet.error.message?:'Not Found')}</title> <link rel="icon" href="${resURL}/favicon.svg" type="image/svg+xml" /> <link rel="alternate icon" href="${resURL}/favicon.ico" sizes="any" /> <!-- TODO Determine need for these --> @@ -52,7 +52,7 @@ THE SOFTWARE. <span style="font-size:50px"><st:nbsp/>${%Oops!}</span> </h1> <div style="text-align: center"> - <h2>${%title(javax.servlet.error.message?:'Not Found')}</h2> + <h2>${%title(jakarta.servlet.error.message?:'Not Found')}</h2> <a href="${h.inferHudsonURL(request)}">${%Back to Jenkins}</a> </div> </body> diff --git a/core/src/main/resources/jenkins/model/Jenkins/oops.jelly b/core/src/main/resources/jenkins/model/Jenkins/oops.jelly index 28238c660253..436b4a8fc0a6 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/oops.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/oops.jelly @@ -41,7 +41,7 @@ THE SOFTWARE. <j:if test="${app.shouldShowStackTrace()}"> <p>${%checkJIRA} ${%vote} ${%pleaseReport} ${%stackTracePlease} ${%checkML}</p> <h2>${%Stack trace}</h2> - <pre style="margin:2em; clear:both">${h.printThrowable(request.getAttribute('javax.servlet.error.exception'))}</pre> + <pre style="margin:2em; clear:both">${h.printThrowable(request.getAttribute('jakarta.servlet.error.exception'))}</pre> </j:if> </l:main-panel> </l:layout> diff --git a/core/src/test/java/hudson/FunctionsTest.java b/core/src/test/java/hudson/FunctionsTest.java index 95d5def0bbda..5a0df319bfcc 100644 --- a/core/src/test/java/hudson/FunctionsTest.java +++ b/core/src/test/java/hudson/FunctionsTest.java @@ -61,7 +61,7 @@ import org.jvnet.hudson.test.Issue; import org.kohsuke.stapler.Ancestor; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.mockito.MockedStatic; public class FunctionsTest { @@ -96,14 +96,14 @@ public void testGetActionUrl_absoluteUriWithoutAuthority() { @Test public void testGetActionUrl_absolutePath() { String contextPath = "/jenkins"; - StaplerRequest req = createMockRequest(contextPath); + StaplerRequest2 req = createMockRequest(contextPath); String[] paths = { "/", "/foo/bar", }; try (MockedStatic<Stapler> mocked = mockStatic(Stapler.class)) { - mocked.when(Stapler::getCurrentRequest).thenReturn(req); + mocked.when(Stapler::getCurrentRequest2).thenReturn(req); for (String path : paths) { String result = Functions.getActionUrl(null, createMockAction(path)); assertEquals(contextPath + path, result); @@ -115,14 +115,14 @@ public void testGetActionUrl_absolutePath() { public void testGetActionUrl_relativePath() { String contextPath = "/jenkins"; String itUrl = "iturl/"; - StaplerRequest req = createMockRequest(contextPath); + StaplerRequest2 req = createMockRequest(contextPath); String[] paths = { "foo/bar", "./foo/bar", "../foo/bar", }; try (MockedStatic<Stapler> mocked = mockStatic(Stapler.class)) { - mocked.when(Stapler::getCurrentRequest).thenReturn(req); + mocked.when(Stapler::getCurrentRequest2).thenReturn(req); for (String path : paths) { String result = Functions.getActionUrl(itUrl, createMockAction(path)); assertEquals(contextPath + "/" + itUrl + path, result); @@ -133,14 +133,14 @@ public void testGetActionUrl_relativePath() { @Test public void testGetRelativeLinkTo_JobContainedInView() { String contextPath = "/jenkins"; - StaplerRequest req = createMockRequest(contextPath); + StaplerRequest2 req = createMockRequest(contextPath); try ( MockedStatic<Stapler> mocked = mockStatic(Stapler.class); MockedStatic<Jenkins> mockedJenkins = mockStatic(Jenkins.class) ) { Jenkins j = createMockJenkins(mockedJenkins); ItemGroup parent = j; - mocked.when(Stapler::getCurrentRequest).thenReturn(req); + mocked.when(Stapler::getCurrentRequest2).thenReturn(req); View view = mock(View.class); when(view.getOwner()).thenReturn(j); when(j.getItemGroup()).thenReturn(j); @@ -155,14 +155,14 @@ public void testGetRelativeLinkTo_JobContainedInView() { @Test public void testGetRelativeLinkTo_JobFromComputer() { String contextPath = "/jenkins"; - StaplerRequest req = createMockRequest(contextPath); + StaplerRequest2 req = createMockRequest(contextPath); try ( MockedStatic<Stapler> mocked = mockStatic(Stapler.class); MockedStatic<Jenkins> mockedJenkins = mockStatic(Jenkins.class) ) { Jenkins j = createMockJenkins(mockedJenkins); ItemGroup parent = j; - mocked.when(Stapler::getCurrentRequest).thenReturn(req); + mocked.when(Stapler::getCurrentRequest2).thenReturn(req); Computer computer = mock(Computer.class); createMockAncestors(req, createAncestor(computer, "."), createAncestor(j, "../..")); TopLevelItem i = createMockItem(parent, "job/i/"); @@ -175,14 +175,14 @@ public void testGetRelativeLinkTo_JobFromComputer() { @Test public void testGetRelativeLinkTo_JobNotContainedInView() { String contextPath = "/jenkins"; - StaplerRequest req = createMockRequest(contextPath); + StaplerRequest2 req = createMockRequest(contextPath); try ( MockedStatic<Stapler> mocked = mockStatic(Stapler.class); MockedStatic<Jenkins> mockedJenkins = mockStatic(Jenkins.class) ) { Jenkins j = createMockJenkins(mockedJenkins); ItemGroup parent = j; - mocked.when(Stapler::getCurrentRequest).thenReturn(req); + mocked.when(Stapler::getCurrentRequest2).thenReturn(req); View view = mock(View.class); when(view.getOwner().getItemGroup()).thenReturn(parent); createMockAncestors(req, createAncestor(j, "../.."), createAncestor(view, ".")); @@ -198,7 +198,7 @@ private interface TopLevelItemAndItemGroup<T extends TopLevelItem> extends TopLe @Test public void testGetRelativeLinkTo_JobContainedInViewWithinItemGroup() { String contextPath = "/jenkins"; - StaplerRequest req = createMockRequest(contextPath); + StaplerRequest2 req = createMockRequest(contextPath); try ( MockedStatic<Stapler> mocked = mockStatic(Stapler.class); MockedStatic<Jenkins> mockedJenkins = mockStatic(Jenkins.class) @@ -206,7 +206,7 @@ public void testGetRelativeLinkTo_JobContainedInViewWithinItemGroup() { Jenkins j = createMockJenkins(mockedJenkins); TopLevelItemAndItemGroup parent = mock(TopLevelItemAndItemGroup.class); when(parent.getShortUrl()).thenReturn("parent/"); - mocked.when(Stapler::getCurrentRequest).thenReturn(req); + mocked.when(Stapler::getCurrentRequest2).thenReturn(req); View view = mock(View.class); when(view.getOwner()).thenReturn(parent); when(parent.getItemGroup()).thenReturn(parent); @@ -220,13 +220,13 @@ public void testGetRelativeLinkTo_JobContainedInViewWithinItemGroup() { @Issue("JENKINS-17713") @Test public void getRelativeLinkTo_MavenModules() { - StaplerRequest req = createMockRequest("/jenkins"); + StaplerRequest2 req = createMockRequest("/jenkins"); try ( MockedStatic<Stapler> mocked = mockStatic(Stapler.class); MockedStatic<Jenkins> mockedJenkins = mockStatic(Jenkins.class) ) { Jenkins j = createMockJenkins(mockedJenkins); - mocked.when(Stapler::getCurrentRequest).thenReturn(req); + mocked.when(Stapler::getCurrentRequest2).thenReturn(req); TopLevelItemAndItemGroup ms = mock(TopLevelItemAndItemGroup.class); when(ms.getShortUrl()).thenReturn("job/ms/"); // TODO "." (in second ancestor) is what Stapler currently fails to do. Could edit test to use ".." but set a different request path? @@ -266,7 +266,7 @@ public void testGetRelativeDisplayNameInsideItemGroup() { assertEquals(".. » top", Functions.getRelativeDisplayNameFrom(i2, ig)); } - private void createMockAncestors(StaplerRequest req, Ancestor... ancestors) { + private void createMockAncestors(StaplerRequest2 req, Ancestor... ancestors) { List<Ancestor> ancestorsList = Arrays.asList(ancestors); when(req.getAncestors()).thenReturn(ancestorsList); } @@ -307,8 +307,8 @@ private static Action createMockAction(String uri) { return action; } - private static StaplerRequest createMockRequest(String contextPath) { - StaplerRequest req = mock(StaplerRequest.class); + private static StaplerRequest2 createMockRequest(String contextPath) { + StaplerRequest2 req = mock(StaplerRequest2.class); when(req.getContextPath()).thenReturn(contextPath); return req; } diff --git a/core/src/test/java/hudson/GetLocaleStaticHelpUrlTest.java b/core/src/test/java/hudson/GetLocaleStaticHelpUrlTest.java index a61fc0d54656..f139475b1013 100644 --- a/core/src/test/java/hudson/GetLocaleStaticHelpUrlTest.java +++ b/core/src/test/java/hudson/GetLocaleStaticHelpUrlTest.java @@ -37,7 +37,7 @@ import java.util.Locale; import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.lang.Klass; public class GetLocaleStaticHelpUrlTest { @@ -45,7 +45,7 @@ public class GetLocaleStaticHelpUrlTest { @Test public void getStaticHelpUrlAcceptEnResDefault() { // Accept-Language: en - StaplerRequest req = mockStaplerRequest( + StaplerRequest2 req = mockStaplerRequest2( Locale.ENGLISH ); @@ -60,7 +60,7 @@ public void getStaticHelpUrlAcceptEnResDefault() { @Test public void getStaticHelpUrlAcceptDeResDeNoCountry() { // Accept-Language: de-DE,de;q=0.9,en;q=0.8 - StaplerRequest req = mockStaplerRequest( + StaplerRequest2 req = mockStaplerRequest2( Locale.GERMANY, Locale.GERMAN, Locale.ENGLISH @@ -78,7 +78,7 @@ public void getStaticHelpUrlAcceptDeResDeNoCountry() { @Test public void getStaticHelpUrlAcceptDeResDeCountry() { // Accept-Language: de-DE,de;q=0.9,en;q=0.8 - StaplerRequest req = mockStaplerRequest( + StaplerRequest2 req = mockStaplerRequest2( Locale.GERMANY, Locale.GERMAN, Locale.ENGLISH @@ -96,7 +96,7 @@ public void getStaticHelpUrlAcceptDeResDeCountry() { @Test public void getStaticHelpUrlAcceptDeResBoth() { // Accept-Language: de-DE,de;q=0.9,en;q=0.8 - StaplerRequest req = mockStaplerRequest( + StaplerRequest2 req = mockStaplerRequest2( Locale.GERMANY, Locale.GERMAN, Locale.ENGLISH @@ -115,7 +115,7 @@ public void getStaticHelpUrlAcceptDeResBoth() { @Test public void getStaticHelpUrlAcceptZhResDefault() { // Accept-Language: zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6 - StaplerRequest req = mockStaplerRequest( + StaplerRequest2 req = mockStaplerRequest2( Locale.CHINESE, Locale.SIMPLIFIED_CHINESE, Locale.ENGLISH, @@ -134,7 +134,7 @@ public void getStaticHelpUrlAcceptZhResDefault() { @Test public void getStaticHelpUrlAcceptZhResZhCountry() { // Accept-Language: zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6 - StaplerRequest req = mockStaplerRequest( + StaplerRequest2 req = mockStaplerRequest2( Locale.CHINESE, Locale.SIMPLIFIED_CHINESE, Locale.ENGLISH, @@ -154,7 +154,7 @@ public void getStaticHelpUrlAcceptZhResZhCountry() { @Test public void getStaticHelpUrlAcceptZhResBoth() { // Accept-Language: zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6 - StaplerRequest req = mockStaplerRequest( + StaplerRequest2 req = mockStaplerRequest2( Locale.CHINESE, Locale.SIMPLIFIED_CHINESE, Locale.ENGLISH, @@ -174,7 +174,7 @@ public void getStaticHelpUrlAcceptZhResBoth() { @Test public void getStaticHelpUrlAcceptZhResMore() { // Accept-Language: zh,zh-CN;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6 - StaplerRequest req = mockStaplerRequest( + StaplerRequest2 req = mockStaplerRequest2( Locale.CHINESE, Locale.SIMPLIFIED_CHINESE, Locale.ENGLISH, @@ -196,7 +196,7 @@ public void getStaticHelpUrlAcceptZhResMore() { @Test public void getStaticHelpUrlAcceptEnFirst() { // Accept-Language: en-US,en;q=0.9,de;q=0.8 - StaplerRequest req = mockStaplerRequest( + StaplerRequest2 req = mockStaplerRequest2( Locale.US, Locale.ENGLISH, Locale.GERMAN @@ -210,8 +210,8 @@ public void getStaticHelpUrlAcceptEnFirst() { assertThatLocaleResourceIs(id, "help-id.html"); } - private StaplerRequest mockStaplerRequest(Locale... localeArr) { - StaplerRequest req = mock(StaplerRequest.class); + private StaplerRequest2 mockStaplerRequest2(Locale... localeArr) { + StaplerRequest2 req = mock(StaplerRequest2.class); Enumeration<Locale> locales = Collections.enumeration(Arrays.asList(localeArr)); when(req.getLocales()).thenReturn(locales); return req; diff --git a/core/src/test/java/hudson/model/QueueTest.java b/core/src/test/java/hudson/model/QueueTest.java index 1a338371ff41..9e3320124e89 100644 --- a/core/src/test/java/hudson/model/QueueTest.java +++ b/core/src/test/java/hudson/model/QueueTest.java @@ -3,16 +3,16 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletResponse; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.jvnet.hudson.test.Issue; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; @@ -20,7 +20,7 @@ public class QueueTest { @Mock - StaplerResponse resp; + StaplerResponse2 resp; @Mock Queue.Task task; @Mock diff --git a/core/src/test/java/hudson/model/ViewTest.java b/core/src/test/java/hudson/model/ViewTest.java index cd76ea6250e3..51b45ab6fb10 100644 --- a/core/src/test/java/hudson/model/ViewTest.java +++ b/core/src/test/java/hudson/model/ViewTest.java @@ -13,8 +13,8 @@ import java.util.List; import org.junit.Test; import org.jvnet.hudson.test.Issue; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.mockito.Mockito; public class ViewTest { @@ -186,11 +186,11 @@ public boolean contains(TopLevelItem item) { } @Override - protected void submit(StaplerRequest req) { + protected void submit(StaplerRequest2 req) { } @Override - public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) { + public Item doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) { return null; } } diff --git a/core/src/test/java/hudson/util/FormValidationTest.java b/core/src/test/java/hudson/util/FormValidationTest.java index 51deec680af7..a783665c5309 100644 --- a/core/src/test/java/hudson/util/FormValidationTest.java +++ b/core/src/test/java/hudson/util/FormValidationTest.java @@ -35,7 +35,6 @@ import java.io.IOException; import java.net.URI; import java.util.Arrays; -import javax.servlet.ServletException; import org.junit.Test; /** @@ -122,10 +121,10 @@ public void formValidationException() { } @Test - public void testUrlCheck() throws IOException, ServletException { + public void testUrlCheck() throws IOException { FormValidation.URLCheck urlCheck = new FormValidation.URLCheck() { @Override - protected FormValidation check() throws ServletException, IOException { + protected FormValidation check() throws IOException { String uri = "https://www.jenkins.io/"; try { if (findText(open(URI.create(uri)), "Jenkins")) { diff --git a/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java b/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java index 620616a15081..51706cf18680 100644 --- a/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java +++ b/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java @@ -36,7 +36,7 @@ import org.junit.Test; import org.jvnet.hudson.test.Issue; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -45,14 +45,14 @@ public class JenkinsGetRootUrlTest { private Jenkins jenkins; - private StaplerRequest staplerRequest; + private StaplerRequest2 staplerRequest; private JenkinsLocationConfiguration config; @Before public void setUp() { jenkins = mock(Jenkins.class, Mockito.CALLS_REAL_METHODS); config = mock(JenkinsLocationConfiguration.class); - staplerRequest = mock(StaplerRequest.class); + staplerRequest = mock(StaplerRequest2.class); } @Test @@ -62,7 +62,7 @@ public void getConfiguredRootUrl() { MockedStatic<Stapler> mockedStapler = mockStatic(Stapler.class) ) { mocked.when(JenkinsLocationConfiguration::get).thenReturn(config); - mockedStapler.when(Stapler::getCurrentRequest).thenReturn(staplerRequest); + mockedStapler.when(Stapler::getCurrentRequest2).thenReturn(staplerRequest); configured("http://configured.host"); @@ -77,7 +77,7 @@ public void getAccessedRootUrl() { MockedStatic<Stapler> mockedStapler = mockStatic(Stapler.class) ) { mocked.when(JenkinsLocationConfiguration::get).thenReturn(config); - mockedStapler.when(Stapler::getCurrentRequest).thenReturn(staplerRequest); + mockedStapler.when(Stapler::getCurrentRequest2).thenReturn(staplerRequest); accessing("https://real.host/jenkins/"); @@ -92,7 +92,7 @@ public void preferConfiguredOverAccessed() { MockedStatic<Stapler> mockedStapler = mockStatic(Stapler.class) ) { mocked.when(JenkinsLocationConfiguration::get).thenReturn(config); - mockedStapler.when(Stapler::getCurrentRequest).thenReturn(staplerRequest); + mockedStapler.when(Stapler::getCurrentRequest2).thenReturn(staplerRequest); configured("http://configured.host/"); accessing("http://real.host/"); @@ -108,7 +108,7 @@ public void doNotInheritProtocolWhenDispatchingRequest() { MockedStatic<Stapler> mockedStapler = mockStatic(Stapler.class) ) { mocked.when(JenkinsLocationConfiguration::get).thenReturn(config); - mockedStapler.when(Stapler::getCurrentRequest).thenReturn(staplerRequest); + mockedStapler.when(Stapler::getCurrentRequest2).thenReturn(staplerRequest); configured("http://configured.host/"); accessing("https://real.host/"); @@ -124,7 +124,7 @@ public void doNotInheritProtocolWhenDispatchingRequest2() { MockedStatic<Stapler> mockedStapler = mockStatic(Stapler.class) ) { mocked.when(JenkinsLocationConfiguration::get).thenReturn(config); - mockedStapler.when(Stapler::getCurrentRequest).thenReturn(staplerRequest); + mockedStapler.when(Stapler::getCurrentRequest2).thenReturn(staplerRequest); configured("https://ci/jenkins/"); accessing("http://localhost:8080/"); rootUrlIs("https://ci/jenkins/"); @@ -139,7 +139,7 @@ public void useForwardedProtoWhenPresent() { MockedStatic<Stapler> mockedStapler = mockStatic(Stapler.class) ) { mocked.when(JenkinsLocationConfiguration::get).thenReturn(config); - mockedStapler.when(Stapler::getCurrentRequest).thenReturn(staplerRequest); + mockedStapler.when(Stapler::getCurrentRequest2).thenReturn(staplerRequest); configured("https://ci/jenkins/"); // Without a forwarded protocol, it should use the request protocol @@ -180,7 +180,7 @@ public void useForwardedProtoWithIPv6WhenPresent() { MockedStatic<Stapler> mockedStapler = mockStatic(Stapler.class) ) { mocked.when(JenkinsLocationConfiguration::get).thenReturn(config); - mockedStapler.when(Stapler::getCurrentRequest).thenReturn(staplerRequest); + mockedStapler.when(Stapler::getCurrentRequest2).thenReturn(staplerRequest); configured("http://[::1]/jenkins/"); // Without a forwarded protocol, it should use the request protocol @@ -219,7 +219,7 @@ private void configured(final String configuredHost) { } private void withHeader(String name, final String value) { - final StaplerRequest req = Stapler.getCurrentRequest(); + final StaplerRequest2 req = Stapler.getCurrentRequest2(); when(req.getHeader(name)).thenReturn(value); } @@ -227,7 +227,7 @@ private void accessing(final String realUrl) { final URL url = getUrl(realUrl); - final StaplerRequest req = mock(StaplerRequest.class); + final StaplerRequest2 req = mock(StaplerRequest2.class); when(req.getScheme()).thenReturn(url.getProtocol()); when(req.getServerName()).thenReturn(url.getHost()); when(req.getServerPort()).thenReturn(url.getPort() == -1 ? "https".equals(url.getProtocol()) ? 443 : 80 : url.getPort()); @@ -235,12 +235,12 @@ private void accessing(final String realUrl) { when(req.getIntHeader(anyString())).thenAnswer(new Answer<Integer>() { @Override public Integer answer(InvocationOnMock invocation) { String name = (String) invocation.getArguments()[0]; - String value = ((StaplerRequest) invocation.getMock()).getHeader(name); + String value = ((StaplerRequest2) invocation.getMock()).getHeader(name); return value != null ? Integer.parseInt(value) : -1; } }); - when(Stapler.getCurrentRequest()).thenReturn(req); + when(Stapler.getCurrentRequest2()).thenReturn(req); } private URL getUrl(final String realUrl) { diff --git a/core/src/test/java/jenkins/security/stapler/StaplerSignaturesTest.java b/core/src/test/java/jenkins/security/stapler/StaplerSignaturesTest.java index 2da9082c820e..74812507e246 100644 --- a/core/src/test/java/jenkins/security/stapler/StaplerSignaturesTest.java +++ b/core/src/test/java/jenkins/security/stapler/StaplerSignaturesTest.java @@ -9,8 +9,8 @@ import org.junit.Test; import org.kohsuke.stapler.Function; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.json.JsonResponse; import org.kohsuke.stapler.lang.FieldRef; @@ -40,7 +40,7 @@ public static class SomeClass { "staticMethod jenkins.security.stapler.StaplerSignaturesTest$SomeClass getFoo int", "staticMethod jenkins.security.stapler.StaplerSignaturesTest$SomeClass getFoo long", "method jenkins.security.stapler.StaplerSignaturesTest$SomeClass getFoo jenkins.security.stapler.StaplerSignaturesTest$SomeClass", - "method jenkins.security.stapler.StaplerSignaturesTest$SomeClass doFoo org.kohsuke.stapler.StaplerRequest org.kohsuke.stapler.StaplerResponse", + "method jenkins.security.stapler.StaplerSignaturesTest$SomeClass doFoo org.kohsuke.stapler.StaplerRequest2 org.kohsuke.stapler.StaplerResponse2", "method jenkins.security.stapler.StaplerSignaturesTest$SomeClass doWhatever java.lang.String", "method java.lang.Object getClass", "method java.lang.Object equals java.lang.Object", @@ -63,7 +63,7 @@ public static void getFoo(long arg) {} public void getFoo(SomeClass arg) {} - public void doFoo(StaplerRequest req, StaplerResponse rsp) {} + public void doFoo(StaplerRequest2 req, StaplerResponse2 rsp) {} @StaplerDispatchable @JsonResponse public void doWhatever(@QueryParameter String arg) {} @@ -91,7 +91,7 @@ public static class SomeSubclass extends SomeClass { "staticMethod jenkins.security.stapler.StaplerSignaturesTest$SomeClass getFoo int", "staticMethod jenkins.security.stapler.StaplerSignaturesTest$SomeClass getFoo long", "method jenkins.security.stapler.StaplerSignaturesTest$SomeClass getFoo jenkins.security.stapler.StaplerSignaturesTest$SomeClass", - "method jenkins.security.stapler.StaplerSignaturesTest$SomeClass doFoo org.kohsuke.stapler.StaplerRequest org.kohsuke.stapler.StaplerResponse", + "method jenkins.security.stapler.StaplerSignaturesTest$SomeClass doFoo org.kohsuke.stapler.StaplerRequest2 org.kohsuke.stapler.StaplerResponse2", "method jenkins.security.stapler.StaplerSignaturesTest$SomeClass doWhatever java.lang.String", "method java.lang.Object getClass", "method java.lang.Object equals java.lang.Object", diff --git a/pom.xml b/pom.xml index c3052864caba..47a9714fef3c 100644 --- a/pom.xml +++ b/pom.xml @@ -52,8 +52,7 @@ THE SOFTWARE. <modules> <module>bom</module> <module>websocket/spi</module> - <module>websocket/jetty10</module> - <module>websocket/jetty12-ee8</module> + <module>websocket/jetty12-ee9</module> <module>core</module> <module>war</module> <module>test</module> @@ -98,7 +97,7 @@ THE SOFTWARE. <bridge-method-injector.version>1.29</bridge-method-injector.version> <spotless.check.skip>false</spotless.check.skip> <!-- Make sure to keep the jetty-maven-plugin version in war/pom.xml in sync with the Jetty release in Winstone: --> - <winstone.version>7.0</winstone.version> + <winstone.version>8.0</winstone.version> </properties> <!-- diff --git a/test/src/test/java/hudson/CustomPluginManagerTest.java b/test/src/test/java/hudson/CustomPluginManagerTest.java index ff91daeaa6a3..3ce9ae08eb8d 100644 --- a/test/src/test/java/hudson/CustomPluginManagerTest.java +++ b/test/src/test/java/hudson/CustomPluginManagerTest.java @@ -32,10 +32,10 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import jakarta.servlet.ServletContext; import java.io.File; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.servlet.ServletContext; import jenkins.model.Jenkins; import org.junit.Rule; import org.junit.Test; diff --git a/test/src/test/java/hudson/PluginManagerCheckUpdateCenterTest.java b/test/src/test/java/hudson/PluginManagerCheckUpdateCenterTest.java index f15daf63781a..89ed65ab1b09 100644 --- a/test/src/test/java/hudson/PluginManagerCheckUpdateCenterTest.java +++ b/test/src/test/java/hudson/PluginManagerCheckUpdateCenterTest.java @@ -9,10 +9,10 @@ import hudson.model.UpdateSiteTest; import hudson.util.HttpResponses; import hudson.util.Retrier; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import org.htmlunit.Page; import org.htmlunit.html.HtmlPage; @@ -23,8 +23,8 @@ import org.jvnet.hudson.test.LoggerRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.xml.sax.SAXException; public class PluginManagerCheckUpdateCenterTest { @@ -152,7 +152,7 @@ public String getUrlName() { return "updateSite502"; } - public HttpResponse doGetJson(StaplerRequest request) { + public HttpResponse doGetJson(StaplerRequest2 request) { return HttpResponses.error(502, "Gateway error"); } } @@ -175,7 +175,7 @@ public String getUrlName() { return "updateSiteWrongJson"; } - public void doGetJson(StaplerRequest request, StaplerResponse response) throws IOException { + public void doGetJson(StaplerRequest2 request, StaplerResponse2 response) throws IOException { response.setContentType("text/json"); response.setStatus(200); response.getWriter().append("{wrongjson}"); @@ -201,7 +201,7 @@ public String getUrlName() { } // The url has to end in update-center.json. See: UpdateSite#getMetadataUrlForDownloadable - public void doDynamic(StaplerRequest staplerRequest, StaplerResponse staplerResponse) throws ServletException, IOException { + public void doDynamic(StaplerRequest2 staplerRequest, StaplerResponse2 staplerResponse) throws ServletException, IOException { staplerResponse.setContentType("text/json"); staplerResponse.setStatus(200); staplerResponse.serveFile(staplerRequest, UpdateSiteTest.extract("update-center.json")); diff --git a/test/src/test/java/hudson/PluginManagerTest.java b/test/src/test/java/hudson/PluginManagerTest.java index 91a236db0266..b75d8fc2f66f 100644 --- a/test/src/test/java/hudson/PluginManagerTest.java +++ b/test/src/test/java/hudson/PluginManagerTest.java @@ -52,6 +52,7 @@ import hudson.security.ACLContext; import hudson.util.FormValidation; import hudson.util.PersistedList; +import jakarta.servlet.ServletException; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; @@ -83,7 +84,6 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import javax.servlet.ServletException; import jenkins.ClassLoaderReflectionToolkit; import jenkins.RestartRequiredException; import jenkins.model.GlobalConfiguration; @@ -108,8 +108,8 @@ import org.jvnet.hudson.test.Url; import org.jvnet.hudson.test.recipes.WithPlugin; import org.jvnet.hudson.test.recipes.WithPluginManager; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * @author Kohsuke Kawaguchi @@ -178,7 +178,7 @@ public String getUrlName() { return "pluginManagerGetPlugin"; } - public void doDynamic(StaplerRequest staplerRequest, StaplerResponse staplerResponse) throws ServletException, IOException { + public void doDynamic(StaplerRequest2 staplerRequest, StaplerResponse2 staplerResponse) throws ServletException, IOException { staplerResponse.setContentType("application/octet-stream"); staplerResponse.setStatus(200); staplerResponse.serveFile(staplerRequest, PluginManagerTest.class.getClassLoader().getResource("plugins/htmlpublisher.jpi")); @@ -880,7 +880,7 @@ public String getUrlName() { return "security3037UpdateCenter"; } - public void doDynamic(StaplerRequest staplerRequest, StaplerResponse staplerResponse) throws ServletException, IOException { + public void doDynamic(StaplerRequest2 staplerRequest, StaplerResponse2 staplerResponse) throws ServletException, IOException { staplerResponse.setContentType("application/json"); staplerResponse.setStatus(200); staplerResponse.serveFile(staplerRequest, PluginManagerTest.class.getResource("/plugins/security3037-update-center.json")); @@ -905,7 +905,7 @@ public String getUrlName() { return "pluginManagerGetPlugin"; } - public void doDynamic(StaplerRequest staplerRequest, StaplerResponse staplerResponse) throws ServletException, IOException { + public void doDynamic(StaplerRequest2 staplerRequest, StaplerResponse2 staplerResponse) throws ServletException, IOException { staplerResponse.setContentType("application/octet-stream"); staplerResponse.setStatus(200); staplerResponse.serveFile(staplerRequest, PluginManagerTest.class.getClassLoader().getResource("plugins/htmlpublisher.jpi")); diff --git a/test/src/test/java/hudson/PluginTest.java b/test/src/test/java/hudson/PluginTest.java index 79cf3703a39a..7328d36f9381 100644 --- a/test/src/test/java/hudson/PluginTest.java +++ b/test/src/test/java/hudson/PluginTest.java @@ -25,9 +25,9 @@ package hudson; import hudson.model.UpdateCenter; +import jakarta.servlet.http.HttpServletResponse; import java.util.List; import java.util.concurrent.Future; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.junit.Ignore; import org.junit.Rule; diff --git a/test/src/test/java/hudson/cli/BuildCommandTest.java b/test/src/test/java/hudson/cli/BuildCommandTest.java index 3cacae4d0177..8afae30d3edf 100644 --- a/test/src/test/java/hudson/cli/BuildCommandTest.java +++ b/test/src/test/java/hudson/cli/BuildCommandTest.java @@ -76,7 +76,7 @@ import org.jvnet.hudson.test.SmokeTest; import org.jvnet.hudson.test.TestBuilder; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * {@link BuildCommand} test. @@ -274,7 +274,7 @@ public ParameterValue createValue(String value) { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { return createValue("BAR"); } diff --git a/test/src/test/java/hudson/cli/CLITest.java b/test/src/test/java/hudson/cli/CLITest.java index 9471d04224b4..229a99eec51d 100644 --- a/test/src/test/java/hudson/cli/CLITest.java +++ b/test/src/test/java/hudson/cli/CLITest.java @@ -37,6 +37,10 @@ import hudson.model.UnprotectedRootAction; import hudson.security.csrf.CrumbExclusion; import hudson.util.StreamTaskListener; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -46,10 +50,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.apache.commons.io.FileUtils; import org.apache.commons.io.output.TeeOutputStream; @@ -68,8 +68,8 @@ import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; public class CLITest { @@ -150,11 +150,11 @@ public static final class NoJenkinsAction extends CrumbExclusion implements Unpr } @Override public Object getTarget() { - doDynamic(Stapler.getCurrentRequest(), Stapler.getCurrentResponse()); + doDynamic(Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2()); return this; } - public void doDynamic(StaplerRequest req, StaplerResponse rsp) { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) { rsp.setStatus(200); } @@ -230,15 +230,15 @@ public static final class CliProxyAction extends CrumbExclusion implements Unpro } @Override public Object getTarget() { - throw doDynamic(Stapler.getCurrentRequest(), Stapler.getCurrentResponse()); + throw doDynamic(Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2()); } - public HttpResponses.HttpResponseException doDynamic(StaplerRequest req, StaplerResponse rsp) { + public HttpResponses.HttpResponseException doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) { final String url = req.getRequestURIWithQueryString().replaceFirst("/cli-proxy", ""); // Custom written redirect so no traces of Jenkins are present in headers return new HttpResponses.HttpResponseException() { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException { rsp.setHeader("Location", url); rsp.setContentType("text/html"); rsp.setStatus(HttpURLConnection.HTTP_MOVED_TEMP); diff --git a/test/src/test/java/hudson/diagnosis/OldDataMonitorTest.java b/test/src/test/java/hudson/diagnosis/OldDataMonitorTest.java index 2124f8c19755..54f68a43b66c 100644 --- a/test/src/test/java/hudson/diagnosis/OldDataMonitorTest.java +++ b/test/src/test/java/hudson/diagnosis/OldDataMonitorTest.java @@ -92,7 +92,7 @@ public class OldDataMonitorTest { /** * Note that this doesn't actually run slowly, it just ensures that * the {@link OldDataMonitor#changeListener}'s {@code onChange()} can complete - * while {@link OldDataMonitor#doDiscard(org.kohsuke.stapler.StaplerRequest, org.kohsuke.stapler.StaplerResponse)} + * while {@link OldDataMonitor#doDiscard(org.kohsuke.stapler.StaplerRequest2, org.kohsuke.stapler.StaplerResponse2)} * is still running. * */ @@ -114,7 +114,7 @@ public class OldDataMonitorTest { ExecutorService executors = Executors.newSingleThreadExecutor(); Future<Void> discardFuture = executors.submit(() -> { - oldDataMonitor.doDiscard(Stapler.getCurrentRequest(), Stapler.getCurrentResponse()); + oldDataMonitor.doDiscard(Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2()); return null; }); diff --git a/test/src/test/java/hudson/model/ApiTest.java b/test/src/test/java/hudson/model/ApiTest.java index 7422ec78fd98..1ac268423114 100644 --- a/test/src/test/java/hudson/model/ApiTest.java +++ b/test/src/test/java/hudson/model/ApiTest.java @@ -32,10 +32,10 @@ import static org.junit.Assert.fail; import edu.umd.cs.findbugs.annotations.CheckForNull; +import jakarta.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; -import javax.servlet.http.HttpServletResponse; import net.sf.json.JSONObject; import org.htmlunit.Page; import org.htmlunit.WebResponse; diff --git a/test/src/test/java/hudson/model/ComputerConfigDotXmlTest.java b/test/src/test/java/hudson/model/ComputerConfigDotXmlTest.java index ce7f987ad532..8eea0a4a7890 100644 --- a/test/src/test/java/hudson/model/ComputerConfigDotXmlTest.java +++ b/test/src/test/java/hudson/model/ComputerConfigDotXmlTest.java @@ -43,6 +43,10 @@ import hudson.security.AccessDeniedException3; import hudson.security.GlobalMatrixAuthorizationStrategy; import hudson.slaves.DumbSlave; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; +import jakarta.servlet.ServletOutputStream; +import jakarta.servlet.WriteListener; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -50,10 +54,6 @@ import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletOutputStream; -import javax.servlet.WriteListener; import jenkins.model.Jenkins; import org.htmlunit.FailingHttpStatusCodeException; import org.htmlunit.HttpMethod; @@ -68,8 +68,8 @@ import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.PretendSlave; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.security.core.context.SecurityContext; @@ -85,8 +85,8 @@ public class ComputerConfigDotXmlTest { @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); - @Mock private StaplerRequest req; - @Mock private StaplerResponse rsp; + @Mock private StaplerRequest2 req; + @Mock private StaplerResponse2 rsp; private Computer computer; private SecurityContext oldSecurityContext; diff --git a/test/src/test/java/hudson/model/DescriptorTest.java b/test/src/test/java/hudson/model/DescriptorTest.java index 2a0b09d74b79..d608360e69ed 100644 --- a/test/src/test/java/hudson/model/DescriptorTest.java +++ b/test/src/test/java/hudson/model/DescriptorTest.java @@ -49,7 +49,7 @@ import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; @SuppressWarnings({"unchecked", "rawtypes"}) public class DescriptorTest { @@ -115,7 +115,7 @@ private static final class DescriptorImpl extends BuildStepDescriptor<Builder> { return id; } - @Override public Builder newInstance(StaplerRequest req, JSONObject formData) { + @Override public Builder newInstance(StaplerRequest2 req, JSONObject formData) { return new BuilderImpl(id); } @@ -213,7 +213,7 @@ public D3D(String id) { return id; } - @Override public D3 newInstance(StaplerRequest req, JSONObject formData) { + @Override public D3 newInstance(StaplerRequest2 req, JSONObject formData) { return new D3(id); } } @@ -242,7 +242,7 @@ public void presentStacktraceFromFormException() { final Descriptor.FormException fe = new Descriptor.FormException("My Message", cause, "fake"); FailingHttpStatusCodeException ex = assertThrows(FailingHttpStatusCodeException.class, () -> rule.executeOnServer((Callable<Void>) () -> { - fe.generateResponse(Stapler.getCurrentRequest(), Stapler.getCurrentResponse(), Jenkins.get()); + fe.generateResponse(Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2(), Jenkins.get()); return null; })); String response = ex.getResponse().getContentAsString(); diff --git a/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java b/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java index 24c978e78f8d..fbd1173909df 100644 --- a/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java +++ b/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java @@ -97,8 +97,8 @@ import org.jvnet.hudson.test.SingleFileSCM; import org.jvnet.hudson.test.TestBuilder; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; /** * @author Kohsuke Kawaguchi @@ -381,7 +381,7 @@ public String getDisplayName() { return null; } - public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws Exception { + public void doDynamic(StaplerRequest2 req, StaplerResponse2 rsp) throws Exception { String hash = req.getRestOfPath().substring(1); for (byte[] file : files) { if (Util.getDigestOf(new ByteArrayInputStream(file)).equals(hash)) { diff --git a/test/src/test/java/hudson/model/JobPropertyTest.java b/test/src/test/java/hudson/model/JobPropertyTest.java index ecd16a70fae7..97343823e332 100644 --- a/test/src/test/java/hudson/model/JobPropertyTest.java +++ b/test/src/test/java/hudson/model/JobPropertyTest.java @@ -41,7 +41,7 @@ import org.jvnet.hudson.test.LoggerRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; public class JobPropertyTest { @@ -124,7 +124,7 @@ public JobPropertyWithConfigImpl(String name) { @TestExtension("configRoundtrip") public static class DescriptorImpl extends JobPropertyDescriptor { @Override - public JobProperty<?> newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public JobProperty<?> newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { JobPropertyWithConfigImpl prop = (JobPropertyWithConfigImpl) super.newInstance(req, formData); return prop.name.isEmpty() ? null : prop; } @@ -147,7 +147,7 @@ public static class InvisibleImpl extends JobProperty<Job<?, ?>> { InvisibleImpl() {} @Override - public JobProperty<?> reconfigure(StaplerRequest req, JSONObject form) { + public JobProperty<?> reconfigure(StaplerRequest2 req, JSONObject form) { return this; } diff --git a/test/src/test/java/hudson/model/ListViewTest.java b/test/src/test/java/hudson/model/ListViewTest.java index 4eef645d6608..c401cc3f9001 100644 --- a/test/src/test/java/hudson/model/ListViewTest.java +++ b/test/src/test/java/hudson/model/ListViewTest.java @@ -46,6 +46,8 @@ import hudson.security.Permission; import hudson.views.StatusFilter; import hudson.views.ViewJobFilter; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -58,8 +60,6 @@ import java.util.Set; import java.util.TreeSet; import java.util.concurrent.atomic.AtomicBoolean; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; import jenkins.model.Jenkins; import org.apache.commons.io.IOUtils; import org.htmlunit.AlertHandler; @@ -75,8 +75,8 @@ import org.jvnet.hudson.test.JenkinsRule.WebClient; import org.jvnet.hudson.test.MockFolder; import org.jvnet.hudson.test.recipes.LocalData; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.springframework.security.core.Authentication; import org.xml.sax.SAXException; @@ -258,8 +258,8 @@ private void checkLinkFromItemExistsAndIsValid(Item item, ItemGroup ig, Item top @Test public void addJobUsingAPI() throws Exception { ListView v = new ListView("view", j.jenkins); j.jenkins.addView(v); - StaplerRequest req = mock(StaplerRequest.class); - StaplerResponse rsp = mock(StaplerResponse.class); + StaplerRequest2 req = mock(StaplerRequest2.class); + StaplerResponse2 rsp = mock(StaplerResponse2.class); String configXml = IOUtils.toString(getClass().getResourceAsStream(String.format("%s/%s/config.xml", getClass().getSimpleName(), testName.getMethodName())), StandardCharsets.UTF_8); diff --git a/test/src/test/java/hudson/model/ParametersDefinitionPropertyTest.java b/test/src/test/java/hudson/model/ParametersDefinitionPropertyTest.java index 54d3b3a0c847..732deb13d767 100644 --- a/test/src/test/java/hudson/model/ParametersDefinitionPropertyTest.java +++ b/test/src/test/java/hudson/model/ParametersDefinitionPropertyTest.java @@ -43,7 +43,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.LoggerRule; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; public class ParametersDefinitionPropertyTest { @@ -79,12 +79,12 @@ public KrazyParameterDefinition(String name, String description, String field) { } @Override - public ParameterValue createValue(StaplerRequest req, JSONObject jo) { + public ParameterValue createValue(StaplerRequest2 req, JSONObject jo) { throw new UnsupportedOperationException(); } @Override - public ParameterValue createValue(StaplerRequest req) { + public ParameterValue createValue(StaplerRequest2 req) { throw new UnsupportedOperationException(); } @@ -92,7 +92,7 @@ public ParameterValue createValue(StaplerRequest req) { public static class DescriptorImpl extends ParameterDescriptor { @Override - public ParameterDefinition newInstance(StaplerRequest req, JSONObject formData) { + public ParameterDefinition newInstance(StaplerRequest2 req, JSONObject formData) { return new KrazyParameterDefinition(formData.getString("name"), formData.getString("description"), formData.getString("field").toLowerCase(Locale.ENGLISH)); } diff --git a/test/src/test/java/hudson/model/ProjectTest.java b/test/src/test/java/hudson/model/ProjectTest.java index e3f2d84493e3..389837e46a42 100644 --- a/test/src/test/java/hudson/model/ProjectTest.java +++ b/test/src/test/java/hudson/model/ProjectTest.java @@ -108,6 +108,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestBuilder; import org.jvnet.hudson.test.TestExtension; +import org.kohsuke.stapler.StaplerRequest2; /** * @@ -573,7 +574,7 @@ public void testDoDoDelete() throws Exception { j.jenkins.setSecurityRealm(j.createDummySecurityRealm()); User user = User.getById("john", true); try (ACLContext as = ACL.as(user)) { - assertThrows("User should not have permission to build project", AccessDeniedException3.class, () -> project.doDoDelete(null, null)); + assertThrows("User should not have permission to build project", AccessDeniedException3.class, () -> project.doDoDelete((StaplerRequest2) null, null)); } auth.add(Jenkins.READ, user.getId()); auth.add(Item.READ, user.getId()); diff --git a/test/src/test/java/hudson/model/QueueTest.java b/test/src/test/java/hudson/model/QueueTest.java index fa76fd88ae0d..a28f6bae0da5 100644 --- a/test/src/test/java/hudson/model/QueueTest.java +++ b/test/src/test/java/hudson/model/QueueTest.java @@ -78,6 +78,7 @@ import hudson.triggers.SCMTrigger.SCMTriggerCause; import hudson.triggers.TimerTrigger.TimerTriggerCause; import hudson.util.OneShotEvent; +import jakarta.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; @@ -101,7 +102,6 @@ import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.ServletException; import jenkins.model.BlockedBecauseOfBuildInProgress; import jenkins.model.Jenkins; import jenkins.model.queue.QueueIdStrategy; diff --git a/test/src/test/java/hudson/model/UpdateCenterCustomTest.java b/test/src/test/java/hudson/model/UpdateCenterCustomTest.java index dc37e2b3c875..2a3a9296c1be 100644 --- a/test/src/test/java/hudson/model/UpdateCenterCustomTest.java +++ b/test/src/test/java/hudson/model/UpdateCenterCustomTest.java @@ -28,7 +28,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; -import javax.servlet.ServletContext; +import jakarta.servlet.ServletContext; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; @@ -59,10 +59,10 @@ private static final class CustomUpdateCenterRule extends JenkinsRule { } @Override - protected ServletContext createWebServer() throws Exception { + protected ServletContext createWebServer2() throws Exception { _oldValue = System.getProperty(PROPERTY_NAME); System.setProperty(PROPERTY_NAME, updateCenterClassName); - return super.createWebServer(); + return super.createWebServer2(); } @Override diff --git a/test/src/test/java/hudson/model/UsageStatisticsTest.java b/test/src/test/java/hudson/model/UsageStatisticsTest.java index 015203308e25..bffd2af0f445 100644 --- a/test/src/test/java/hudson/model/UsageStatisticsTest.java +++ b/test/src/test/java/hudson/model/UsageStatisticsTest.java @@ -116,7 +116,7 @@ public void roundtrip() throws Exception { // that would cause issues with parsing/analyzing uploaded usage statistics assertEquals(1, o.getInt("stat")); assertEquals(jenkins.getLegacyInstanceId(), o.getString("install")); - assertEquals(jenkins.servletContext.getServerInfo(), o.getString("servletContainer")); + assertEquals(jenkins.getServletContext().getServerInfo(), o.getString("servletContainer")); assertEquals(Jenkins.VERSION, o.getString("version")); assertTrue(o.has("plugins")); diff --git a/test/src/test/java/hudson/model/ViewDescriptorTest.java b/test/src/test/java/hudson/model/ViewDescriptorTest.java index facfaecd1d77..b4e34cf5a701 100644 --- a/test/src/test/java/hudson/model/ViewDescriptorTest.java +++ b/test/src/test/java/hudson/model/ViewDescriptorTest.java @@ -42,7 +42,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockFolder; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; public class ViewDescriptorTest { @@ -156,7 +156,7 @@ public String getSomeProperty() { } @Override - public ViewProperty reconfigure(StaplerRequest req, JSONObject form) { + public ViewProperty reconfigure(StaplerRequest2 req, JSONObject form) { return this; } diff --git a/test/src/test/java/hudson/model/ViewPropertyTest.java b/test/src/test/java/hudson/model/ViewPropertyTest.java index 6ebad1958b1d..4f253bb9971f 100644 --- a/test/src/test/java/hudson/model/ViewPropertyTest.java +++ b/test/src/test/java/hudson/model/ViewPropertyTest.java @@ -38,7 +38,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @author Kohsuke Kawaguchi @@ -100,7 +100,7 @@ public static class InvisiblePropertyImpl extends ViewProperty { } @Override - public ViewProperty reconfigure(StaplerRequest req, JSONObject form) { + public ViewProperty reconfigure(StaplerRequest2 req, JSONObject form) { return this; } diff --git a/test/src/test/java/hudson/model/ViewTest.java b/test/src/test/java/hudson/model/ViewTest.java index 4355d82ad063..63dd879d25cc 100644 --- a/test/src/test/java/hudson/model/ViewTest.java +++ b/test/src/test/java/hudson/model/ViewTest.java @@ -100,8 +100,8 @@ import org.jvnet.hudson.test.TestExtension; import org.jvnet.hudson.test.recipes.LocalData; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.w3c.dom.Text; /** @@ -488,7 +488,7 @@ public void testSave() throws Exception { view.save(); j.jenkins.doReload(); //wait until all configuration are reloaded - if (j.jenkins.servletContext.getAttribute("app") instanceof HudsonIsLoading) { + if (j.jenkins.getServletContext().getAttribute("app") instanceof HudsonIsLoading) { Thread.sleep(500); } assertTrue("View does not contains job free after load.", j.jenkins.getView(view.getDisplayName()).contains(j.jenkins.getItem(job.getName()))); @@ -1081,11 +1081,11 @@ public boolean contains(TopLevelItem item) { } @Override - protected void submit(StaplerRequest req) { + protected void submit(StaplerRequest2 req) { } @Override - public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) { + public Item doCreateItem(StaplerRequest2 req, StaplerResponse2 rsp) { return null; } } diff --git a/test/src/test/java/hudson/pages/SystemConfigurationTestCase.java b/test/src/test/java/hudson/pages/SystemConfigurationTestCase.java index 83f9bc9f20a0..7265655b4982 100644 --- a/test/src/test/java/hudson/pages/SystemConfigurationTestCase.java +++ b/test/src/test/java/hudson/pages/SystemConfigurationTestCase.java @@ -35,7 +35,7 @@ import org.junit.Test; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; public class SystemConfigurationTestCase { @@ -70,7 +70,7 @@ private static class PageDecoratorImpl extends PageDecorator { private String decoratorId; @Override - public boolean configure(StaplerRequest req, JSONObject json) { + public boolean configure(StaplerRequest2 req, JSONObject json) { decoratorId = json.getString("decoratorId"); return true; } diff --git a/test/src/test/java/hudson/security/LoginTest.java b/test/src/test/java/hudson/security/LoginTest.java index 0829a6bc41f6..30b016d717c4 100644 --- a/test/src/test/java/hudson/security/LoginTest.java +++ b/test/src/test/java/hudson/security/LoginTest.java @@ -1,6 +1,6 @@ package hudson.security; -import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; +import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertFalse; diff --git a/test/src/test/java/hudson/security/SecurityRealmTest.java b/test/src/test/java/hudson/security/SecurityRealmTest.java index 6ebe98e71bf1..5121086085b2 100644 --- a/test/src/test/java/hudson/security/SecurityRealmTest.java +++ b/test/src/test/java/hudson/security/SecurityRealmTest.java @@ -152,10 +152,10 @@ public void getPostLogOutUrl() throws Exception { j.jenkins.setSecurityRealm(osr); j.executeOnServer(() -> { assertEquals("/jenkins/", j.jenkins.getSecurityRealm().getPostLogOutUrl(Stapler.getCurrentRequest(), Jenkins.ANONYMOUS)); - assertEquals("/jenkins/", j.jenkins.getSecurityRealm().getPostLogOutUrl2(Stapler.getCurrentRequest(), Jenkins.ANONYMOUS2)); + assertEquals("/jenkins/", j.jenkins.getSecurityRealm().getPostLogOutUrl2(Stapler.getCurrentRequest2(), Jenkins.ANONYMOUS2)); osr.special = true; assertEquals("/jenkins/custom", j.jenkins.getSecurityRealm().getPostLogOutUrl(Stapler.getCurrentRequest(), Jenkins.ANONYMOUS)); - assertEquals("/jenkins/custom", j.jenkins.getSecurityRealm().getPostLogOutUrl2(Stapler.getCurrentRequest(), Jenkins.ANONYMOUS2)); + assertEquals("/jenkins/custom", j.jenkins.getSecurityRealm().getPostLogOutUrl2(Stapler.getCurrentRequest2(), Jenkins.ANONYMOUS2)); return null; }); } diff --git a/test/src/test/java/hudson/security/TokenBasedRememberMeServices2Test.java b/test/src/test/java/hudson/security/TokenBasedRememberMeServices2Test.java index e7597adaf8fd..0798c39ad2cd 100644 --- a/test/src/test/java/hudson/security/TokenBasedRememberMeServices2Test.java +++ b/test/src/test/java/hudson/security/TokenBasedRememberMeServices2Test.java @@ -299,7 +299,7 @@ public void rememberMeToken_shouldLoadUserDetailsOnlyOnce() throws Exception { JenkinsRule.WebClient wc = j.createWebClient(); wc.getCookieManager().addCookie(cookie); // trigger remember me - String sessionSeed = wc.executeOnServer(() -> Stapler.getCurrentRequest().getSession(false).getAttribute(UserSeedProperty.USER_SESSION_SEED).toString()); + String sessionSeed = wc.executeOnServer(() -> Stapler.getCurrentRequest2().getSession(false).getAttribute(UserSeedProperty.USER_SESSION_SEED).toString()); realm.verifyInvocations(1); String userSeed = alice.getProperty(UserSeedProperty.class).getSeed(); diff --git a/test/src/test/java/hudson/security/WhoAmITest.java b/test/src/test/java/hudson/security/WhoAmITest.java index 819b98984e88..a92b25f0269c 100644 --- a/test/src/test/java/hudson/security/WhoAmITest.java +++ b/test/src/test/java/hudson/security/WhoAmITest.java @@ -31,11 +31,11 @@ import static org.hamcrest.Matchers.nullValue; import hudson.model.User; +import jakarta.servlet.http.HttpSession; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Collection; import java.util.Collections; -import javax.servlet.http.HttpSession; import jenkins.model.Jenkins; import jenkins.security.ApiTokenProperty; import jenkins.security.apitoken.TokenUuidAndPlainValue; @@ -73,7 +73,7 @@ public void whoAmI_regular_doesNotProvideSensitiveInformation() throws Exception String content = whoAmIPage.getWebResponse().getContentAsString(); String sessionId = wc.executeOnServer(() -> { - HttpSession session = Stapler.getCurrentRequest().getSession(false); + HttpSession session = Stapler.getCurrentRequest2().getSession(false); return session != null ? session.getId() : null; }); @@ -114,7 +114,7 @@ public void whoAmI_regularApi_doesNotProvideSensitiveInformation() throws Except String content = whoAmIPage.getWebResponse().getContentAsString(); String sessionId = wc.executeOnServer(() -> { - HttpSession session = Stapler.getCurrentRequest().getSession(false); + HttpSession session = Stapler.getCurrentRequest2().getSession(false); return session != null ? session.getId() : null; }); diff --git a/test/src/test/java/hudson/security/csrf/CrumbExclusionTest.java b/test/src/test/java/hudson/security/csrf/CrumbExclusionTest.java index adb2184ff239..def3f5746783 100644 --- a/test/src/test/java/hudson/security/csrf/CrumbExclusionTest.java +++ b/test/src/test/java/hudson/security/csrf/CrumbExclusionTest.java @@ -31,12 +31,12 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.ExtensionList; import hudson.model.UnprotectedRootAction; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URL; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import org.htmlunit.FailingHttpStatusCodeException; import org.htmlunit.HttpMethod; diff --git a/test/src/test/java/hudson/security/csrf/DefaultCrumbIssuerTest.java b/test/src/test/java/hudson/security/csrf/DefaultCrumbIssuerTest.java index 2904af69fc4d..65141fa93cdd 100644 --- a/test/src/test/java/hudson/security/csrf/DefaultCrumbIssuerTest.java +++ b/test/src/test/java/hudson/security/csrf/DefaultCrumbIssuerTest.java @@ -16,9 +16,9 @@ import static org.junit.Assert.assertTrue; import hudson.model.User; +import jakarta.servlet.http.HttpServletResponse; import java.net.HttpURLConnection; import java.net.URI; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.htmlunit.FailingHttpStatusCodeException; diff --git a/test/src/test/java/hudson/slaves/CloudTest.java b/test/src/test/java/hudson/slaves/CloudTest.java index 7ad4dff33aa6..04bb7a04f212 100644 --- a/test/src/test/java/hudson/slaves/CloudTest.java +++ b/test/src/test/java/hudson/slaves/CloudTest.java @@ -28,7 +28,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.jvnet.hudson.test.WithoutJenkins; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; public class CloudTest { @@ -127,7 +127,7 @@ public static final class TaskCloudAction implements Action { return "task"; } - public void doIndex(StaplerResponse rsp) throws IOException { + public void doIndex(StaplerResponse2 rsp) throws IOException { rsp.getOutputStream().println("doIndex called"); } } diff --git a/test/src/test/java/hudson/slaves/NodePropertyTest.java b/test/src/test/java/hudson/slaves/NodePropertyTest.java index 6aef28929b11..dc78979910fe 100644 --- a/test/src/test/java/hudson/slaves/NodePropertyTest.java +++ b/test/src/test/java/hudson/slaves/NodePropertyTest.java @@ -19,7 +19,7 @@ import org.jvnet.hudson.test.LoggerRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @author Kohsuke Kawaguchi @@ -52,7 +52,7 @@ public static class InvisibleProperty extends NodeProperty<Slave> { boolean reconfigured = false; @Override - public NodeProperty<?> reconfigure(StaplerRequest req, JSONObject form) { + public NodeProperty<?> reconfigure(StaplerRequest2 req, JSONObject form) { reconfigured = true; return this; } diff --git a/test/src/test/java/hudson/util/BootFailureTest.java b/test/src/test/java/hudson/util/BootFailureTest.java index d083a74a2e26..b8ba0bd8a630 100644 --- a/test/src/test/java/hudson/util/BootFailureTest.java +++ b/test/src/test/java/hudson/util/BootFailureTest.java @@ -8,6 +8,8 @@ import hudson.WebAppMain; import hudson.model.Hudson; import hudson.model.listeners.ItemListener; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletContextEvent; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -16,8 +18,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; import jenkins.model.Jenkins; import org.junit.After; import org.junit.Rule; @@ -25,7 +25,7 @@ import org.junit.rules.TemporaryFolder; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; -import org.jvnet.hudson.test.NoListenerConfiguration; +import org.jvnet.hudson.test.NoListenerConfiguration2; import org.jvnet.hudson.test.TestEnvironment; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.WebApp; @@ -66,13 +66,13 @@ public WebAppMain.FileAndDescription getHomeDir(ServletContextEvent event) { // Without this gymnastic, the jenkins-test-harness adds a NoListenerConfiguration // that prevents us to inject our own custom WebAppMain // With this approach we can make the server calls the regular contextInitialized - ServletContext ws = createWebServer((context, server) -> { - NoListenerConfiguration noListenerConfiguration = context.getBean(NoListenerConfiguration.class); + ServletContext ws = createWebServer2((context, server) -> { + NoListenerConfiguration2 noListenerConfiguration = context.getBean(NoListenerConfiguration2.class); // future-proof assertNotNull(noListenerConfiguration); if (noListenerConfiguration != null) { context.removeBean(noListenerConfiguration); - context.addBean(new NoListenerConfiguration(context) { + context.addBean(new NoListenerConfiguration2(context) { @Override protected void doStart() { // default behavior of noListenerConfiguration diff --git a/test/src/test/java/hudson/util/HudsonIsLoadingTest.java b/test/src/test/java/hudson/util/HudsonIsLoadingTest.java index 21ae31734e30..0a49084ad336 100644 --- a/test/src/test/java/hudson/util/HudsonIsLoadingTest.java +++ b/test/src/test/java/hudson/util/HudsonIsLoadingTest.java @@ -1,6 +1,6 @@ package hudson.util; -import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; +import static jakarta.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; @@ -19,7 +19,7 @@ public class HudsonIsLoadingTest { @Test @Issue("JENKINS-55062") public void withPrefix() throws Exception { - j.jenkins.servletContext.setAttribute("app", new HudsonIsLoading()); + j.jenkins.getServletContext().setAttribute("app", new HudsonIsLoading()); JenkinsRule.WebClient wc = j.createWebClient() // this is a failure page already .withThrowExceptionOnFailingStatusCode(false) diff --git a/test/src/test/java/hudson/util/HudsonIsRestartingTest.java b/test/src/test/java/hudson/util/HudsonIsRestartingTest.java index 464f16e72da9..d70ea9c33959 100644 --- a/test/src/test/java/hudson/util/HudsonIsRestartingTest.java +++ b/test/src/test/java/hudson/util/HudsonIsRestartingTest.java @@ -1,6 +1,6 @@ package hudson.util; -import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; +import static jakarta.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; @@ -20,7 +20,7 @@ public class HudsonIsRestartingTest { @Test @Issue("JENKINS-55062") public void withPrefix() throws Exception { - j.jenkins.servletContext.setAttribute("app", new HudsonIsRestarting(false)); + j.jenkins.getServletContext().setAttribute("app", new HudsonIsRestarting(false)); JenkinsRule.WebClient wc = j.createWebClient() // this is a failure page already .withThrowExceptionOnFailingStatusCode(false) diff --git a/test/src/test/java/hudson/util/RobustReflectionConverterTest.java b/test/src/test/java/hudson/util/RobustReflectionConverterTest.java index ff0b255114e1..570c4dfb8f04 100644 --- a/test/src/test/java/hudson/util/RobustReflectionConverterTest.java +++ b/test/src/test/java/hudson/util/RobustReflectionConverterTest.java @@ -61,7 +61,7 @@ import org.jvnet.hudson.test.TestExtension; import org.jvnet.hudson.test.recipes.LocalData; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; public class RobustReflectionConverterTest { @@ -123,7 +123,7 @@ public String getDisplayName() { } @Override - public AcceptOnlySpecificKeyword newInstance(StaplerRequest req, JSONObject formData) + public AcceptOnlySpecificKeyword newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { AcceptOnlySpecificKeyword instance = super.newInstance(req, formData); if (!instance.isAcceptable()) { @@ -160,7 +160,7 @@ public String getDisplayName() { } @Override - public JobProperty<?> newInstance(StaplerRequest req, JSONObject formData) + public JobProperty<?> newInstance(StaplerRequest2 req, JSONObject formData) throws FormException { // unfortunately, default newInstance bypasses newInstances for members. formData = formData.getJSONObject("keywordProperty"); diff --git a/test/src/test/java/hudson/util/XStream2Security383Test.java b/test/src/test/java/hudson/util/XStream2Security383Test.java index 2d8002eb4a9e..6fe7b5377e81 100644 --- a/test/src/test/java/hudson/util/XStream2Security383Test.java +++ b/test/src/test/java/hudson/util/XStream2Security383Test.java @@ -5,14 +5,14 @@ import static org.mockito.Mockito.when; import hudson.model.Items; +import jakarta.servlet.ReadListener; +import jakarta.servlet.ServletInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.logging.Level; -import javax.servlet.ReadListener; -import javax.servlet.ServletInputStream; import jenkins.security.ClassFilterImpl; import org.apache.commons.io.IOUtils; import org.junit.After; @@ -23,8 +23,8 @@ import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.LoggerRule; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -40,10 +40,10 @@ public class XStream2Security383Test { public LoggerRule logging = new LoggerRule().record(ClassFilterImpl.class, Level.FINE); @Mock - private StaplerRequest req; + private StaplerRequest2 req; @Mock - private StaplerResponse rsp; + private StaplerResponse2 rsp; private AutoCloseable mocks; diff --git a/test/src/test/java/hudson/views/GlobalDefaultViewConfigurationTest.java b/test/src/test/java/hudson/views/GlobalDefaultViewConfigurationTest.java index ca0a67e4fe42..7a6de7d6c55f 100644 --- a/test/src/test/java/hudson/views/GlobalDefaultViewConfigurationTest.java +++ b/test/src/test/java/hudson/views/GlobalDefaultViewConfigurationTest.java @@ -35,7 +35,7 @@ import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.kohsuke.stapler.MockStaplerRequestBuilder; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Tests of {@link GlobalDefaultViewConfiguration}. @@ -52,7 +52,7 @@ public void shouldNotFailIfTheDefaultViewIsMissing() { String viewName = "NonExistentView"; GlobalDefaultViewConfiguration c = new GlobalDefaultViewConfiguration(); - StaplerRequest create = new MockStaplerRequestBuilder(j, "/configure").build(); + StaplerRequest2 create = new MockStaplerRequestBuilder(j, "/configure").build(); JSONObject params = new JSONObject(); params.accumulate("primaryView", viewName); try { diff --git a/test/src/test/java/jenkins/diagnostics/URICheckEncodingMonitorTest.java b/test/src/test/java/jenkins/diagnostics/URICheckEncodingMonitorTest.java index ca3fd62b9e4e..dc444f431de5 100644 --- a/test/src/test/java/jenkins/diagnostics/URICheckEncodingMonitorTest.java +++ b/test/src/test/java/jenkins/diagnostics/URICheckEncodingMonitorTest.java @@ -22,7 +22,7 @@ public class URICheckEncodingMonitorTest { public void emptyValueInResponse() throws Exception { j.executeOnServer(() -> { URICheckEncodingMonitor monitor = new URICheckEncodingMonitor(); - FormValidation validation = monitor.doCheckURIEncoding(Stapler.getCurrentRequest()); + FormValidation validation = monitor.doCheckURIEncoding(Stapler.getCurrentRequest2()); assertThat(validation.kind, is(FormValidation.Kind.WARNING)); assertThat(validation.getMessage(), containsString("Your container doesn’t use UTF-8 to decode URLs.")); return null; diff --git a/test/src/test/java/jenkins/install/InstallUtilTest.java b/test/src/test/java/jenkins/install/InstallUtilTest.java index 9a7d6534f1a4..0047ecc5aa31 100644 --- a/test/src/test/java/jenkins/install/InstallUtilTest.java +++ b/test/src/test/java/jenkins/install/InstallUtilTest.java @@ -33,6 +33,7 @@ import hudson.model.UpdateCenter.DownloadJob.Success; import hudson.model.UpdateCenter.UpdateCenterJob; import hudson.model.UpdateSite; +import jakarta.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -40,7 +41,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import javax.servlet.ServletException; import jenkins.model.Jenkins; import net.sf.json.JSONArray; import net.sf.json.JSONObject; diff --git a/test/src/test/java/jenkins/model/ContextMenuTest.java b/test/src/test/java/jenkins/model/ContextMenuTest.java index 313455de02fd..37c994d89017 100644 --- a/test/src/test/java/jenkins/model/ContextMenuTest.java +++ b/test/src/test/java/jenkins/model/ContextMenuTest.java @@ -55,7 +55,7 @@ public class ContextMenuTest { @Issue("JENKINS-19173") @Test public void contextMenuVisibility() throws Exception { final FreeStyleProject p = j.createFreeStyleProject("p"); - Callable<ContextMenu> doContextMenu = () -> p.doContextMenu(Stapler.getCurrentRequest(), Stapler.getCurrentResponse()); + Callable<ContextMenu> doContextMenu = () -> p.doContextMenu(Stapler.getCurrentRequest2(), Stapler.getCurrentResponse2()); ActionFactory f = j.jenkins.getExtensionList(TransientProjectActionFactory.class).get(ActionFactory.class); f.visible = true; ContextMenu menu = j.executeOnServer(doContextMenu); diff --git a/test/src/test/java/jenkins/model/GlobalSCMRetryCountConfigurationTest.java b/test/src/test/java/jenkins/model/GlobalSCMRetryCountConfigurationTest.java index 3d42450274e3..74e612cc8432 100644 --- a/test/src/test/java/jenkins/model/GlobalSCMRetryCountConfigurationTest.java +++ b/test/src/test/java/jenkins/model/GlobalSCMRetryCountConfigurationTest.java @@ -52,17 +52,17 @@ public void shouldExceptOnNullScmRetryCount() throws Exception { GlobalConfiguration.all().getDynamic("jenkins.model.GlobalSCMRetryCountConfiguration"); json.element("scmCheckoutRetryCount", 5); - gc.configure(Stapler.getCurrentRequest(), json); + gc.configure(Stapler.getCurrentRequest2(), json); assertThat("Wrong value, it should be equal to 5", j.getInstance().getScmCheckoutRetryCount(), equalTo(5)); json.element("scmCheckoutRetryCount", 3); - gc.configure(Stapler.getCurrentRequest(), json); + gc.configure(Stapler.getCurrentRequest2(), json); assertThat("Wrong value, it should be equal to 3", j.getInstance().getScmCheckoutRetryCount(), equalTo(3)); JSONObject emptyJson = new JSONObject(); - gc.configure(Stapler.getCurrentRequest(), emptyJson); + gc.configure(Stapler.getCurrentRequest2(), emptyJson); } catch (Descriptor.FormException e) { assertThat("Scm Retry count value changed! This shouldn't happen.", j.getInstance().getScmCheckoutRetryCount(), equalTo(3)); diff --git a/test/src/test/java/jenkins/model/ParameterizedJobMixInTest.java b/test/src/test/java/jenkins/model/ParameterizedJobMixInTest.java index f873a69d30e6..c066ce6452cb 100644 --- a/test/src/test/java/jenkins/model/ParameterizedJobMixInTest.java +++ b/test/src/test/java/jenkins/model/ParameterizedJobMixInTest.java @@ -34,8 +34,8 @@ import hudson.model.ParametersDefinitionProperty; import hudson.model.Queue; import hudson.model.StringParameterDefinition; +import jakarta.servlet.http.HttpServletResponse; import java.net.URL; -import javax.servlet.http.HttpServletResponse; import org.htmlunit.FailingHttpStatusCodeException; import org.htmlunit.HttpMethod; import org.htmlunit.WebRequest; @@ -45,6 +45,7 @@ import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; + /** * Tests of {@link ParameterizedJobMixIn}. * @author Oleg Nenashev diff --git a/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java b/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java index 162ac231b664..cd4f898b3d22 100644 --- a/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java +++ b/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java @@ -21,6 +21,7 @@ import hudson.model.User; import hudson.security.ACL; import hudson.security.ACLContext; +import jakarta.servlet.http.HttpServletResponse; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; @@ -28,7 +29,6 @@ import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; -import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.security.apitoken.ApiTokenPropertyConfiguration; import jenkins.security.apitoken.ApiTokenStore; diff --git a/test/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerHtmlTest.java b/test/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerHtmlTest.java index 3a5614dedb9f..0fe9b8865d16 100644 --- a/test/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerHtmlTest.java +++ b/test/src/test/java/jenkins/security/RedactSecretJsonInErrorMessageSanitizerHtmlTest.java @@ -53,8 +53,8 @@ import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; @Restricted(NoExternalUse.class) @@ -121,7 +121,7 @@ public static class TestPassword implements RootAction { public JSONObject lastJsonReceived; - public void doSubmitTest(StaplerRequest req, StaplerResponse res) throws Exception { + public void doSubmitTest(StaplerRequest2 req, StaplerResponse2 res) throws Exception { lastJsonReceived = req.getSubmittedForm(); res.setStatus(200); @@ -250,7 +250,7 @@ public static class TestDescribablePage implements RootAction { public TestDescribable testDescribable; @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws Exception { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws Exception { Jenkins.get().getDescriptorOrDie(TestDescribable.class).newInstance(req, req.getSubmittedForm()); } @@ -276,7 +276,7 @@ public static class TestStaplerPage implements RootAction { public TestDescribable testDescribable; @POST - public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws Exception { + public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws Exception { req.bindJSON(TestDescribable.class, req.getSubmittedForm()); } diff --git a/test/src/test/java/jenkins/security/Security3030Test.java b/test/src/test/java/jenkins/security/Security3030Test.java index 5e712bdc4e31..3363d7bb9aca 100644 --- a/test/src/test/java/jenkins/security/Security3030Test.java +++ b/test/src/test/java/jenkins/security/Security3030Test.java @@ -33,6 +33,7 @@ import hudson.model.RootAction; import hudson.util.HttpResponses; import hudson.util.MultipartFormDataParser; +import jakarta.servlet.ServletException; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -42,7 +43,6 @@ import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Random; -import javax.servlet.ServletException; import org.apache.commons.fileupload2.core.FileUploadByteCountLimitException; import org.apache.commons.fileupload2.core.FileUploadException; import org.apache.commons.fileupload2.core.FileUploadFileCountLimitException; @@ -56,57 +56,57 @@ import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.RequestImpl; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.verb.POST; public class Security3030Test { - // TODO Consider parameterizing with Stapler (RequestImpl/StaplerRequestFormAction) + Jenkins (MultipartFormDataParser/MultipartFormDataParserAction) + // TODO Consider parameterizing with Stapler (RequestImpl/StaplerRequest2FormAction) + Jenkins (MultipartFormDataParser/MultipartFormDataParserAction) @Rule public JenkinsRule j = new JenkinsRule(); @Test public void fewFilesStapler() throws IOException { - assertSubmissionOK(StaplerRequestFormAction.instance(), 20, 10, 1024 * 1024); - assertSubmissionOK(StaplerRequestFormAction.instance(), 10, 41, 10); + assertSubmissionOK(StaplerRequest2FormAction.instance(), 20, 10, 1024 * 1024); + assertSubmissionOK(StaplerRequest2FormAction.instance(), 10, 41, 10); } @Test public void tooManyFilesStapler() throws Exception { - ServletException ex = assertSubmissionThrows(StaplerRequestFormAction.instance(), 10, 1000, 20, FileUploadFileCountLimitException.class); + ServletException ex = assertSubmissionThrows(StaplerRequest2FormAction.instance(), 10, 1000, 20, FileUploadFileCountLimitException.class); assertThat(ex.getMessage(), containsString(RequestImpl.class.getName() + ".FILEUPLOAD_MAX_FILES")); - ex = assertSubmissionThrows(StaplerRequestFormAction.instance(), 1000, 10, 10, FileUploadFileCountLimitException.class); + ex = assertSubmissionThrows(StaplerRequest2FormAction.instance(), 1000, 10, 10, FileUploadFileCountLimitException.class); assertThat(ex.getMessage(), containsString(RequestImpl.class.getName() + ".FILEUPLOAD_MAX_FILES")); try (FieldValue v = withStaticField(RequestImpl.class, "FILEUPLOAD_MAX_FILES", 10_000)) { - assertSubmissionOK(StaplerRequestFormAction.instance(), 1000, 10, 10); - ex = assertSubmissionThrows(StaplerRequestFormAction.instance(), 10_000, 10, 10, FileUploadFileCountLimitException.class); + assertSubmissionOK(StaplerRequest2FormAction.instance(), 1000, 10, 10); + ex = assertSubmissionThrows(StaplerRequest2FormAction.instance(), 10_000, 10, 10, FileUploadFileCountLimitException.class); assertThat(ex.getMessage(), containsString(RequestImpl.class.getName() + ".FILEUPLOAD_MAX_FILES")); } - ex = assertSubmissionThrows(StaplerRequestFormAction.instance(), 10, 1000, 20, FileUploadFileCountLimitException.class); + ex = assertSubmissionThrows(StaplerRequest2FormAction.instance(), 10, 1000, 20, FileUploadFileCountLimitException.class); assertThat(ex.getMessage(), containsString(RequestImpl.class.getName() + ".FILEUPLOAD_MAX_FILES")); - ex = assertSubmissionThrows(StaplerRequestFormAction.instance(), 1000, 10, 10, FileUploadFileCountLimitException.class); + ex = assertSubmissionThrows(StaplerRequest2FormAction.instance(), 1000, 10, 10, FileUploadFileCountLimitException.class); assertThat(ex.getMessage(), containsString(RequestImpl.class.getName() + ".FILEUPLOAD_MAX_FILES")); } @Test public void tooLargeFilesStapler() throws Exception { - assertSubmissionOK(StaplerRequestFormAction.instance(), 1, 50, 10 * 1024 * 1024); + assertSubmissionOK(StaplerRequest2FormAction.instance(), 1, 50, 10 * 1024 * 1024); try (FieldValue v = withStaticField(RequestImpl.class, "FILEUPLOAD_MAX_FILE_SIZE", 1024 * 1024)) { - assertSubmissionOK(StaplerRequestFormAction.instance(), 200, 100, 1024); - ServletException ex = assertSubmissionThrows(StaplerRequestFormAction.instance(), 1, 50, 10 * 1024 * 1024, FileUploadByteCountLimitException.class); + assertSubmissionOK(StaplerRequest2FormAction.instance(), 200, 100, 1024); + ServletException ex = assertSubmissionThrows(StaplerRequest2FormAction.instance(), 1, 50, 10 * 1024 * 1024, FileUploadByteCountLimitException.class); assertThat(ex.getMessage(), containsString(RequestImpl.class.getName() + ".FILEUPLOAD_MAX_FILE_SIZE")); } - assertSubmissionOK(StaplerRequestFormAction.instance(), 1, 50, 10 * 1024 * 1024); + assertSubmissionOK(StaplerRequest2FormAction.instance(), 1, 50, 10 * 1024 * 1024); } @Test public void tooLargeSubmissionStapler() throws Exception { - assertSubmissionOK(StaplerRequestFormAction.instance(), 1, 50, 10 * 1024 * 1024); + assertSubmissionOK(StaplerRequest2FormAction.instance(), 1, 50, 10 * 1024 * 1024); try (FieldValue v = withStaticField(RequestImpl.class, "FILEUPLOAD_MAX_SIZE", 1024 * 1024)) { - assertSubmissionOK(StaplerRequestFormAction.instance(), 200, 100, 1024); - ServletException ex = assertSubmissionThrows(StaplerRequestFormAction.instance(), 1, 50, 10 * 1024 * 1024, FileUploadSizeException.class); + assertSubmissionOK(StaplerRequest2FormAction.instance(), 200, 100, 1024); + ServletException ex = assertSubmissionThrows(StaplerRequest2FormAction.instance(), 1, 50, 10 * 1024 * 1024, FileUploadSizeException.class); assertThat(ex.getMessage(), containsString(RequestImpl.class.getName() + ".FILEUPLOAD_MAX_SIZE")); } - assertSubmissionOK(StaplerRequestFormAction.instance(), 1, 50, 10 * 1024 * 1024); + assertSubmissionOK(StaplerRequest2FormAction.instance(), 1, 50, 10 * 1024 * 1024); } @Test @@ -265,7 +265,7 @@ public String getUrlName() { } @POST - public HttpResponse doSubmitMultipart(StaplerRequest req) throws FileUploadException, ServletException, IOException { + public HttpResponse doSubmitMultipart(StaplerRequest2 req) throws FileUploadException, ServletException, IOException { if (expectedWrapped == null) { actualWrapped = null; actual = null; @@ -284,7 +284,7 @@ public HttpResponse doSubmitMultipart(StaplerRequest req) throws FileUploadExcep } } - private HttpResponse processMultipartAndUnwrap(StaplerRequest req) throws FileUploadException, ServletException, IOException { + private HttpResponse processMultipartAndUnwrap(StaplerRequest2 req) throws FileUploadException, ServletException, IOException { try { return processMultipart(req); } catch (ServletException ex) { @@ -298,7 +298,7 @@ private HttpResponse processMultipartAndUnwrap(StaplerRequest req) throws FileUp } } - protected abstract HttpResponse processMultipart(StaplerRequest req) throws ServletException, IOException; + protected abstract HttpResponse processMultipart(StaplerRequest2 req) throws ServletException, IOException; public void setExpectedWrapped(Class<? extends T> expectedWrapped) { this.expectedWrapped = expectedWrapped; @@ -314,12 +314,12 @@ public ServletException getActual() { } @TestExtension - public static class StaplerRequestFormAction extends FileUploadAction<FileUploadException> { - public static StaplerRequestFormAction instance() { - return ExtensionList.lookupSingleton(StaplerRequestFormAction.class); + public static class StaplerRequest2FormAction extends FileUploadAction<FileUploadException> { + public static StaplerRequest2FormAction instance() { + return ExtensionList.lookupSingleton(StaplerRequest2FormAction.class); } - protected HttpResponse processMultipart(StaplerRequest req) throws ServletException, IOException { + protected HttpResponse processMultipart(StaplerRequest2 req) throws ServletException, IOException { req.getFileItem2("any-name"); return HttpResponses.ok(); } @@ -331,7 +331,7 @@ public static MultipartFormDataParserAction instance() { return ExtensionList.lookupSingleton(MultipartFormDataParserAction.class); } - protected HttpResponse processMultipart(StaplerRequest req) throws ServletException { + protected HttpResponse processMultipart(StaplerRequest2 req) throws ServletException { new MultipartFormDataParser(req); return HttpResponses.ok(); } diff --git a/test/src/test/java/jenkins/security/Security3135Test.java b/test/src/test/java/jenkins/security/Security3135Test.java index 358d4ae6c6c3..27ec5f8b0f61 100644 --- a/test/src/test/java/jenkins/security/Security3135Test.java +++ b/test/src/test/java/jenkins/security/Security3135Test.java @@ -14,8 +14,8 @@ import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; public class Security3135Test { public static final String ACTION_URL = "security3135"; @@ -72,7 +72,7 @@ public boolean isRequestMade() { return requestMade; } - public void doValidate(StaplerRequest request, StaplerResponse response) { + public void doValidate(StaplerRequest2 request, StaplerResponse2 response) { requestMade = true; } } diff --git a/test/src/test/java/jenkins/security/SuspiciousRequestFilterTest.java b/test/src/test/java/jenkins/security/SuspiciousRequestFilterTest.java index c0f6e95f0e57..cfc20a6bcb55 100644 --- a/test/src/test/java/jenkins/security/SuspiciousRequestFilterTest.java +++ b/test/src/test/java/jenkins/security/SuspiciousRequestFilterTest.java @@ -8,8 +8,8 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.ExtensionList; import hudson.model.UnprotectedRootAction; +import jakarta.servlet.http.HttpServletResponse; import java.net.URL; -import javax.servlet.http.HttpServletResponse; import org.htmlunit.WebRequest; import org.htmlunit.WebResponse; import org.junit.Ignore; diff --git a/test/src/test/java/jenkins/security/seed/UserSeedSecurityListenerTest.java b/test/src/test/java/jenkins/security/seed/UserSeedSecurityListenerTest.java index 88e25398ff83..a5f48b49a860 100644 --- a/test/src/test/java/jenkins/security/seed/UserSeedSecurityListenerTest.java +++ b/test/src/test/java/jenkins/security/seed/UserSeedSecurityListenerTest.java @@ -27,7 +27,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import javax.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSession; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.Issue; @@ -48,7 +48,7 @@ public void authenticateSecondaryUserWhileLoggedIn_shouldNotOverwritePrimaryUser AuthenticationManager authenticationManager = j.jenkins.getSecurityRealm().getSecurityComponents().manager2; JenkinsRule.WebClient wc = j.createWebClient(); wc.login("alice").executeOnServer(() -> { - HttpSession session = Stapler.getCurrentRequest().getSession(); + HttpSession session = Stapler.getCurrentRequest2().getSession(); String existingSeed = (String) session.getAttribute(UserSeedProperty.USER_SESSION_SEED); assertNotNull(existingSeed); authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("bob", "bob")); diff --git a/test/src/test/java/jenkins/security/stapler/CustomRoutingDecisionProviderTest.java b/test/src/test/java/jenkins/security/stapler/CustomRoutingDecisionProviderTest.java index f808733d5d19..6ad9cd8e6eea 100644 --- a/test/src/test/java/jenkins/security/stapler/CustomRoutingDecisionProviderTest.java +++ b/test/src/test/java/jenkins/security/stapler/CustomRoutingDecisionProviderTest.java @@ -40,7 +40,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; @Issue("SECURITY-400") @@ -99,7 +99,7 @@ public void valid() { } private static void replyOk() { - StaplerResponse resp = Stapler.getCurrentResponse(); + StaplerResponse2 resp = Stapler.getCurrentResponse2(); try { resp.getWriter().write("ok"); resp.flushBuffer(); diff --git a/test/src/test/java/jenkins/security/stapler/DoActionFilterTest.java b/test/src/test/java/jenkins/security/stapler/DoActionFilterTest.java index c6584f673e14..b79bed760d5b 100644 --- a/test/src/test/java/jenkins/security/stapler/DoActionFilterTest.java +++ b/test/src/test/java/jenkins/security/stapler/DoActionFilterTest.java @@ -4,16 +4,16 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URL; import java.util.Collections; import java.util.List; import java.util.Map; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.htmlunit.FailingHttpStatusCodeException; @@ -36,8 +36,8 @@ import org.kohsuke.stapler.RequestImpl; import org.kohsuke.stapler.ResponseImpl; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.bind.JavaScriptMethod; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -111,17 +111,17 @@ public static class TestNewRulesOk extends AbstractUnprotectedRootAction { * Method signature */ - public static void doStaticWithRequest(StaplerRequest request) { replyOk(); } + public static void doStaticWithRequest(StaplerRequest2 request) { replyOk(); } - public void doWithRequest(StaplerRequest request) { replyOk(); } + public void doWithRequest(StaplerRequest2 request) { replyOk(); } public void doWithHttpRequest(HttpServletRequest request) { replyOk(); } // the return type is not taken into consideration if it's not a HttpResponse, it will not prevent the method // to be considered as a web method - public String doWithRequestAndReturnString(StaplerRequest request) { return "ok"; } + public String doWithRequestAndReturnString(StaplerRequest2 request) { return "ok"; } - public void doWithResponse(StaplerResponse response) { replyOk(); } + public void doWithResponse(StaplerResponse2 response) { replyOk(); } public void doWithHttpResponse(HttpServletResponse response) { replyOk(); } @@ -198,14 +198,14 @@ public Map<String, Object> doAnnotatedJsonResponse() { * Parameter annotation */ - public void do_CallMeBecauseOfMyUnderscore(StaplerRequest request) { replyOk(); } + public void do_CallMeBecauseOfMyUnderscore(StaplerRequest2 request) { replyOk(); } - public void do$CallMeBecauseOfMyDollar(StaplerRequest request) { replyOk(); } + public void do$CallMeBecauseOfMyDollar(StaplerRequest2 request) { replyOk(); } } public static class HttpResponseChild implements HttpResponse { @Override - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 req, StaplerResponse2 rsp, Object node) throws IOException, ServletException { replyOk(); } } @@ -215,7 +215,7 @@ public abstract static class HttpResponseExceptionChild extends HttpResponses.Ht public static class ExceptionImplementingOnlyHttpResponse extends RuntimeException implements HttpResponse { @Override - public void generateResponse(StaplerRequest staplerRequest, StaplerResponse staplerResponse, Object o) throws IOException, ServletException { + public void generateResponse(StaplerRequest2 staplerRequest, StaplerResponse2 staplerResponse, Object o) throws IOException, ServletException { replyOk(); } } @@ -329,12 +329,12 @@ public void testAnnotatedMethodOk_annotatedRequirePost() throws Exception { public void testAnnotatedMethodOk_annotatedJavaScriptScriptMethod() throws Exception { webApp.setCrumbIssuer(new CrumbIssuer() { @Override - public String issueCrumb(StaplerRequest request) { + public String issueCrumb(StaplerRequest2 request) { return "test"; } @Override - public void validateCrumb(StaplerRequest request, String submittedCrumb) { + public void validateCrumb(StaplerRequest2 request, String submittedCrumb) { // no exception thrown = validated } }); @@ -455,7 +455,7 @@ public void testSpecialCasesOk() throws Exception { @TestExtension public static class TestNewRulesNotOk extends AbstractUnprotectedRootAction { // do not respect the do[^a-z].* format - public void dontCallMeBecauseOfMyDont(StaplerRequest request) { replyOk(); } + public void dontCallMeBecauseOfMyDont(StaplerRequest2 request) { replyOk(); } // do not seem to be an expected web method, in case a developer has such methods, // addition of WebMethod annotation is sufficient diff --git a/test/src/test/java/jenkins/security/stapler/DynamicTest.java b/test/src/test/java/jenkins/security/stapler/DynamicTest.java index a413b1b3bd69..cee1474fface 100644 --- a/test/src/test/java/jenkins/security/stapler/DynamicTest.java +++ b/test/src/test/java/jenkins/security/stapler/DynamicTest.java @@ -13,7 +13,7 @@ import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; @Issue("SECURITY-400") public class DynamicTest { @@ -58,7 +58,7 @@ public HttpResponse doResponse2() { return null; } - public void doDynamic(StaplerRequest req) { + public void doDynamic(StaplerRequest2 req) { throw HttpResponses.errorWithoutStack(200, req.getRestOfPath()); } diff --git a/test/src/test/java/jenkins/security/stapler/PreventRoutingTest.java b/test/src/test/java/jenkins/security/stapler/PreventRoutingTest.java index dbf2f5b16e44..7839ddaf7fa2 100644 --- a/test/src/test/java/jenkins/security/stapler/PreventRoutingTest.java +++ b/test/src/test/java/jenkins/security/stapler/PreventRoutingTest.java @@ -34,7 +34,7 @@ import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; public class PreventRoutingTest extends StaplerAbstractTest { @@ -105,7 +105,7 @@ public Renderable getLegitRoutable2() { } private static void notStaplerGetter(@NonNull Object o) { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); if (req != null) { List<Ancestor> ancestors = req.getAncestors(); if (!ancestors.isEmpty() && ancestors.get(ancestors.size() - 1).getObject() == o) { diff --git a/test/src/test/java/jenkins/security/stapler/Security400Test.java b/test/src/test/java/jenkins/security/stapler/Security400Test.java index c2b64323c65e..3ce8826dea97 100644 --- a/test/src/test/java/jenkins/security/stapler/Security400Test.java +++ b/test/src/test/java/jenkins/security/stapler/Security400Test.java @@ -84,7 +84,7 @@ public class Security400Test { @Before public void prepareFilterListener() { - WebApp webApp = WebApp.get(j.jenkins.servletContext); + WebApp webApp = WebApp.get(j.jenkins.getServletContext()); webApp.setFilteredDoActionTriggerListener((f, req, rsp, node) -> { filteredDoActionTriggered = true; return false; diff --git a/test/src/test/java/jenkins/security/stapler/StaplerAbstractTest.java b/test/src/test/java/jenkins/security/stapler/StaplerAbstractTest.java index b36b0de579be..a9f8cb2df164 100644 --- a/test/src/test/java/jenkins/security/stapler/StaplerAbstractTest.java +++ b/test/src/test/java/jenkins/security/stapler/StaplerAbstractTest.java @@ -46,7 +46,7 @@ import org.junit.ClassRule; import org.jvnet.hudson.test.JenkinsRule; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.WebApp; import org.kohsuke.stapler.WebMethod; @@ -66,7 +66,7 @@ public void setUp() throws Exception { j = rule; j.jenkins.setCrumbIssuer(null); - this.webApp = (WebApp) j.jenkins.servletContext.getAttribute(WebApp.class.getName()); + this.webApp = (WebApp) j.jenkins.getServletContext().getAttribute(WebApp.class.getName()); webApp.setFilteredGetterTriggerListener((f, req, rst, node, expression) -> { filteredGetMethodTriggered = true; @@ -134,7 +134,7 @@ public void doIndex() { //================================= utility methods ================================= protected static void replyOk() { - StaplerResponse resp = Stapler.getCurrentResponse(); + StaplerResponse2 resp = Stapler.getCurrentResponse2(); try { resp.getWriter().write("ok"); resp.flushBuffer(); diff --git a/test/src/test/java/jenkins/security/stapler/StaplerDispatchValidatorTest.java b/test/src/test/java/jenkins/security/stapler/StaplerDispatchValidatorTest.java index 0483b2825e43..2ebf2cbb5c1f 100644 --- a/test/src/test/java/jenkins/security/stapler/StaplerDispatchValidatorTest.java +++ b/test/src/test/java/jenkins/security/stapler/StaplerDispatchValidatorTest.java @@ -47,7 +47,7 @@ public class StaplerDispatchValidatorTest { @Before public void setUp() throws Exception { - StaplerDispatchValidator validator = StaplerDispatchValidator.getInstance(j.jenkins.servletContext); + StaplerDispatchValidator validator = StaplerDispatchValidator.getInstance(j.jenkins.getServletContext()); try (InputStream whitelist = getClass().getResourceAsStream("StaplerDispatchValidatorTest/whitelist.txt")) { validator.loadWhitelist(whitelist); } diff --git a/test/src/test/java/jenkins/security/stapler/StaplerRoutableActionTest.java b/test/src/test/java/jenkins/security/stapler/StaplerRoutableActionTest.java index 02acda598ccc..15b6965ce9b2 100644 --- a/test/src/test/java/jenkins/security/stapler/StaplerRoutableActionTest.java +++ b/test/src/test/java/jenkins/security/stapler/StaplerRoutableActionTest.java @@ -6,7 +6,7 @@ import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.WebMethod; @Issue("SECURITY-400") @@ -29,7 +29,7 @@ public void doWebMethod3() throws HttpResponses.HttpResponseException { replyOk(); } - public void doWebMethod4(StaplerRequest request) { + public void doWebMethod4(StaplerRequest2 request) { replyOk(); } diff --git a/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProviderTest.java b/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProviderTest.java index 9e849a227864..9fed43b27781 100644 --- a/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProviderTest.java +++ b/test/src/test/java/jenkins/security/stapler/StaticRoutingDecisionProviderTest.java @@ -41,7 +41,7 @@ import org.junit.Test; import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.WebMethod; @Issue("SECURITY-400") @@ -224,30 +224,30 @@ public static class ActionWithWhitelist extends AbstractUnprotectedRootAction { return "do-action"; } - public static String DO_ACTION_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doAction org.kohsuke.stapler.StaplerRequest"; + public static String DO_ACTION_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doAction org.kohsuke.stapler.StaplerRequest2"; - public void doAction(StaplerRequest request) { + public void doAction(StaplerRequest2 request) { replyOk(); } - public static String DO_ACTION_STAPLER_ROUTABLE_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doActionWithStaplerDispatchable org.kohsuke.stapler.StaplerRequest"; + public static String DO_ACTION_STAPLER_ROUTABLE_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doActionWithStaplerDispatchable org.kohsuke.stapler.StaplerRequest2"; @StaplerDispatchable - public void doActionWithStaplerDispatchable(StaplerRequest request) { + public void doActionWithStaplerDispatchable(StaplerRequest2 request) { replyOk(); } - public static String DO_ACTION_STAPLER_NONROUTABLE_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doActionWithStaplerNotDispatchable org.kohsuke.stapler.StaplerRequest"; + public static String DO_ACTION_STAPLER_NONROUTABLE_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doActionWithStaplerNotDispatchable org.kohsuke.stapler.StaplerRequest2"; @StaplerNotDispatchable - public void doActionWithStaplerNotDispatchable(StaplerRequest request) { + public void doActionWithStaplerNotDispatchable(StaplerRequest2 request) { replyOk(); } - public static String DO_ACTION_STAPLER_WEBMETHOD_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doActionWithWebMethod org.kohsuke.stapler.StaplerRequest"; + public static String DO_ACTION_STAPLER_WEBMETHOD_SIGNATURE = "method jenkins.security.stapler.StaticRoutingDecisionProviderTest$ActionWithWhitelist doActionWithWebMethod org.kohsuke.stapler.StaplerRequest2"; @WebMethod(name = "actionWithWebMethod") - public void doActionWithWebMethod(StaplerRequest request) { + public void doActionWithWebMethod(StaplerRequest2 request) { replyOk(); } } diff --git a/test/src/test/java/jenkins/security/stapler/TypedFilterTest.java b/test/src/test/java/jenkins/security/stapler/TypedFilterTest.java index fdebee225bad..ac0ea1bf155d 100644 --- a/test/src/test/java/jenkins/security/stapler/TypedFilterTest.java +++ b/test/src/test/java/jenkins/security/stapler/TypedFilterTest.java @@ -4,7 +4,7 @@ import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.StaplerProxy; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; @Issue("SECURITY-400") public class TypedFilterTest extends StaplerAbstractTest { @@ -48,7 +48,7 @@ public void getTarget_withArg_isNotRoutableWithStaplerNotDispatchable() throws E @TestExtension public static class GetTarget4 extends AbstractUnprotectedRootAction { - public Renderable getTarget(StaplerRequest req) { + public Renderable getTarget(StaplerRequest2 req) { return new Renderable(); } } @@ -98,7 +98,7 @@ public void getStaplerFallback_withArg_isNotRoutableWithStaplerNotDispatchable() @TestExtension public static class GetStaplerFallback4 extends AbstractUnprotectedRootAction { - public Renderable getStaplerFallback(StaplerRequest req) { + public Renderable getStaplerFallback(StaplerRequest2 req) { return new Renderable(); } } @@ -203,7 +203,7 @@ public void getDynamic_withArgStartingWithString_isRoutable() throws Exception { @TestExtension public static class GetDynamic3 extends AbstractUnprotectedRootAction { - public Renderable getDynamic(StaplerRequest req, String someArgs) { + public Renderable getDynamic(StaplerRequest2 req, String someArgs) { return new Renderable(); } } @@ -216,7 +216,7 @@ public void getDynamic_withArgNotStartingWithString_isNotRoutable() throws Excep @TestExtension public static class GetDynamic4 extends AbstractUnprotectedRootAction { - public Renderable getDynamic(StaplerRequest req) { + public Renderable getDynamic(StaplerRequest2 req) { return new Renderable(); } } diff --git a/test/src/test/java/jenkins/telemetry/TelemetryTest.java b/test/src/test/java/jenkins/telemetry/TelemetryTest.java index f465fdf2fd8a..701ffa7e4d0e 100644 --- a/test/src/test/java/jenkins/telemetry/TelemetryTest.java +++ b/test/src/test/java/jenkins/telemetry/TelemetryTest.java @@ -15,6 +15,10 @@ import hudson.ExtensionList; import hudson.model.UnprotectedRootAction; import hudson.security.csrf.CrumbExclusion; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; @@ -26,10 +30,6 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.regex.Pattern; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import net.sf.json.JSONObject; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.IOUtils; @@ -39,8 +39,8 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.LoggerRule; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; public class TelemetryTest { @Rule @@ -304,7 +304,7 @@ public boolean process(HttpServletRequest request, HttpServletResponse response, @TestExtension public static class TelemetryReceiver implements UnprotectedRootAction { - public void doEvents(StaplerRequest request, StaplerResponse response) throws IOException { + public void doEvents(StaplerRequest2 request, StaplerResponse2 response) throws IOException { StringWriter sw = new StringWriter(); IOUtils.copy(request.getInputStream(), sw, StandardCharsets.UTF_8); JSONObject json = JSONObject.fromObject(sw.toString()); diff --git a/test/src/test/java/jenkins/util/FullDuplexHttpServiceTest.java b/test/src/test/java/jenkins/util/FullDuplexHttpServiceTest.java index e39d906ff51b..461588cd3480 100644 --- a/test/src/test/java/jenkins/util/FullDuplexHttpServiceTest.java +++ b/test/src/test/java/jenkins/util/FullDuplexHttpServiceTest.java @@ -30,6 +30,10 @@ import hudson.model.InvisibleAction; import hudson.model.RootAction; import hudson.security.csrf.CrumbExclusion; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -38,17 +42,13 @@ import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.LoggerRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; public class FullDuplexHttpServiceTest { @@ -83,7 +83,7 @@ public String getUrlName() { public HttpResponse doIndex() { return new FullDuplexHttpService.Response(duplexServices) { @Override - protected FullDuplexHttpService createService(StaplerRequest req, UUID uuid) throws IOException, InterruptedException { + protected FullDuplexHttpService createService(StaplerRequest2 req, UUID uuid) throws IOException, InterruptedException { return new FullDuplexHttpService(uuid) { @Override protected void run(InputStream upload, OutputStream download) throws IOException, InterruptedException { diff --git a/test/src/test/java/jenkins/util/SystemPropertiesTest.java b/test/src/test/java/jenkins/util/SystemPropertiesTest.java index d0b498f88e57..d29655b765ac 100644 --- a/test/src/test/java/jenkins/util/SystemPropertiesTest.java +++ b/test/src/test/java/jenkins/util/SystemPropertiesTest.java @@ -28,8 +28,8 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.nullValue; -import javax.servlet.ServletContextEvent; -import org.eclipse.jetty.ee8.webapp.WebAppContext; +import jakarta.servlet.ServletContextEvent; +import org.eclipse.jetty.ee9.webapp.WebAppContext; import org.hamcrest.Matchers; import org.junit.After; import org.junit.Assume; @@ -49,7 +49,7 @@ public class SystemPropertiesTest { @Before public void setUp() { - new SystemProperties.Listener().contextInitialized(new ServletContextEvent(j.jenkins.servletContext)); + new SystemProperties.Listener().contextInitialized(new ServletContextEvent(j.jenkins.getServletContext())); } @After @@ -103,7 +103,7 @@ public void shouldReturnWebAppPropertyIfSystemPropertyNotSetAndDefaultIsSet() th * @param value value of the property */ protected void setWebAppInitParameter(String property, String value) { - Assume.assumeThat(j.jenkins.servletContext, Matchers.instanceOf(WebAppContext.Context.class)); - ((WebAppContext.Context) j.jenkins.servletContext).getContextHandler().getInitParams().put(property, value); + Assume.assumeThat(j.jenkins.getServletContext(), Matchers.instanceOf(WebAppContext.Context.class)); + ((WebAppContext.Context) j.jenkins.getServletContext()).getContextHandler().getInitParams().put(property, value); } } diff --git a/test/src/test/java/lib/form/AdvancedButtonTest.java b/test/src/test/java/lib/form/AdvancedButtonTest.java index 9d19a00c05f0..9b41fd1df8f4 100644 --- a/test/src/test/java/lib/form/AdvancedButtonTest.java +++ b/test/src/test/java/lib/form/AdvancedButtonTest.java @@ -16,7 +16,7 @@ import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @@ -54,7 +54,7 @@ public String getUrlName() { return "self"; } - public FormValidation doSubmitNestedOptionalBlock(StaplerRequest req) throws Exception { + public FormValidation doSubmitNestedOptionalBlock(StaplerRequest2 req) throws Exception { JSONObject f = req.getSubmittedForm(); assertEquals("avalue", f.getString("a")); assertEquals("bvalue", f.getString("b")); diff --git a/test/src/test/java/lib/form/BooleanRadioTest.java b/test/src/test/java/lib/form/BooleanRadioTest.java index 185acee61d96..072937f157a2 100644 --- a/test/src/test/java/lib/form/BooleanRadioTest.java +++ b/test/src/test/java/lib/form/BooleanRadioTest.java @@ -16,7 +16,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; public class BooleanRadioTest { @@ -46,7 +46,7 @@ public static final class DescriptorImpl extends Descriptor<BooleanRadioTestDesc @TestExtension public static final class RootActionImpl extends InvisibleAction implements RootAction { - public FormValidation doSubmitTest1(StaplerRequest req) throws Exception { + public FormValidation doSubmitTest1(StaplerRequest2 req) throws Exception { JSONObject f = req.getSubmittedForm(); System.out.println(f); BooleanRadioTestDescribable r = req.bindJSON(BooleanRadioTestDescribable.class, f); diff --git a/test/src/test/java/lib/form/DropdownListTest.java b/test/src/test/java/lib/form/DropdownListTest.java index 6ae425d3629c..e8ec382de4f0 100644 --- a/test/src/test/java/lib/form/DropdownListTest.java +++ b/test/src/test/java/lib/form/DropdownListTest.java @@ -10,7 +10,7 @@ import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @author Kohsuke Kawaguchi @@ -33,7 +33,7 @@ public String getUrlName() { return "self"; } - public FormValidation doSubmitTest1(StaplerRequest req) throws Exception { + public FormValidation doSubmitTest1(StaplerRequest2 req) throws Exception { JSONObject f = req.getSubmittedForm(); System.out.println(f); return FormValidation.ok(); diff --git a/test/src/test/java/lib/form/EnumSetTest.java b/test/src/test/java/lib/form/EnumSetTest.java index 2b3289254513..c63a9341c13b 100644 --- a/test/src/test/java/lib/form/EnumSetTest.java +++ b/test/src/test/java/lib/form/EnumSetTest.java @@ -15,7 +15,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @author Kohsuke Kawaguchi @@ -46,7 +46,7 @@ public static final class DescriptorImpl extends Descriptor<EnumSetTestDescribab @TestExtension public static final class RootActionImpl extends InvisibleAction implements RootAction { - public FormValidation doSubmitTest1(StaplerRequest req) throws Exception { + public FormValidation doSubmitTest1(StaplerRequest2 req) throws Exception { JSONObject f = req.getSubmittedForm(); System.out.println(f); EnumSetTestDescribable r = req.bindJSON(EnumSetTestDescribable.class, f); diff --git a/test/src/test/java/lib/form/EnumTest.java b/test/src/test/java/lib/form/EnumTest.java index 5f37deecafe5..92fecd3c300f 100644 --- a/test/src/test/java/lib/form/EnumTest.java +++ b/test/src/test/java/lib/form/EnumTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; public class EnumTest { @Rule @@ -61,7 +61,7 @@ public static class Form extends InvisibleAction implements RootAction, Describa public BallColor enum1 = BallColor.YELLOW; public BallColor enum2 = null; - public void doSubmitForm(StaplerRequest req) throws Exception { + public void doSubmitForm(StaplerRequest2 req) throws Exception { JSONObject json = req.getSubmittedForm(); System.out.println(json); } diff --git a/test/src/test/java/lib/form/ExpandableTextboxTest.java b/test/src/test/java/lib/form/ExpandableTextboxTest.java index 5e40ea263b30..52dda457594f 100644 --- a/test/src/test/java/lib/form/ExpandableTextboxTest.java +++ b/test/src/test/java/lib/form/ExpandableTextboxTest.java @@ -53,7 +53,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.WebMethod; import org.w3c.dom.NodeList; @@ -147,7 +147,7 @@ public String getUrlName() { } @WebMethod(name = "submit") - public HttpResponse doSubmit(StaplerRequest request) { + public HttpResponse doSubmit(StaplerRequest2 request) { return HttpResponses.plainText("method:" + request.getMethod()); } } diff --git a/test/src/test/java/lib/form/NameRefTest.java b/test/src/test/java/lib/form/NameRefTest.java index b343d6e46fde..b1980745931b 100644 --- a/test/src/test/java/lib/form/NameRefTest.java +++ b/test/src/test/java/lib/form/NameRefTest.java @@ -33,7 +33,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Tests the handling of @nameRef in the form tree. @@ -50,7 +50,7 @@ public class NameRefTest { public static class JenkinsRuleWithJelly extends JenkinsRule { - public HttpResponse doSubmitTest1(StaplerRequest req) throws Exception { + public HttpResponse doSubmitTest1(StaplerRequest2 req) throws Exception { JSONObject f = req.getSubmittedForm(); f.remove("Submit"); System.out.println(f); diff --git a/test/src/test/java/lib/form/PasswordTest.java b/test/src/test/java/lib/form/PasswordTest.java index e71fb93f8e8b..facb1d7418df 100644 --- a/test/src/test/java/lib/form/PasswordTest.java +++ b/test/src/test/java/lib/form/PasswordTest.java @@ -84,7 +84,7 @@ import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.springframework.security.core.Authentication; public class PasswordTest { @@ -244,7 +244,7 @@ public static class DescriptorImpl extends JobPropertyDescriptor { static String checkedSecret; public FormValidation doCheckSecret(@QueryParameter String value) { - StaplerRequest req = Stapler.getCurrentRequest(); + StaplerRequest2 req = Stapler.getCurrentRequest2(); incomingURL = req.getRequestURIWithQueryString(); System.err.println("processing " + incomingURL + " via " + req.getMethod() + ": " + value); checkedSecret = value; diff --git a/test/src/test/java/lib/form/RepeatableTest.java b/test/src/test/java/lib/form/RepeatableTest.java index 56dd22430811..996132434cae 100644 --- a/test/src/test/java/lib/form/RepeatableTest.java +++ b/test/src/test/java/lib/form/RepeatableTest.java @@ -55,7 +55,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @author Alan.Harder@sun.com @@ -658,7 +658,7 @@ public DescriptorExtensionList<Fruit, Descriptor<Fruit>> getFruitDescriptors() { return Jenkins.get().getDescriptorList(Fruit.class); } - public void doSubmitTest(StaplerRequest req) throws Exception { + public void doSubmitTest(StaplerRequest2 req) throws Exception { formData = req.getSubmittedForm(); if (bindClass != null) { bindResult = req.bindJSONToList(bindClass, formData.get("items")); diff --git a/test/src/test/java/lib/form/RowSetTest.java b/test/src/test/java/lib/form/RowSetTest.java index cb24e173038a..b775b24d77e2 100644 --- a/test/src/test/java/lib/form/RowSetTest.java +++ b/test/src/test/java/lib/form/RowSetTest.java @@ -11,7 +11,7 @@ import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @author Kohsuke Kawaguchi @@ -28,7 +28,7 @@ public void json() throws Exception { @TestExtension public static class Subject extends InvisibleAction implements RootAction { - public void doSubmitTest1(StaplerRequest req) throws Exception { + public void doSubmitTest1(StaplerRequest2 req) throws Exception { JSONObject json = req.getSubmittedForm(); json.remove(CrumbIssuer.DEFAULT_CRUMB_NAME); json.remove("Submit"); diff --git a/test/src/test/java/lib/form/RowVisibilityGroupTest.java b/test/src/test/java/lib/form/RowVisibilityGroupTest.java index 6b090cc28dbe..6508193392c3 100644 --- a/test/src/test/java/lib/form/RowVisibilityGroupTest.java +++ b/test/src/test/java/lib/form/RowVisibilityGroupTest.java @@ -25,7 +25,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * Tests the 'rowvg-start' and 'rowvg-end' CSS attributes and their effects. @@ -162,7 +162,7 @@ public static final class RootActionImpl extends InvisibleAction implements Desc public Drink drink; private Beer beer; - public void doSubmitTest2(StaplerRequest req) throws Exception { + public void doSubmitTest2(StaplerRequest2 req) throws Exception { JSONObject json = req.getSubmittedForm(); System.out.println(json); beer = (Beer) req.bindJSON(Drink.class, json.getJSONObject("drink")); diff --git a/test/src/test/java/lib/form/ValidateButtonTest.java b/test/src/test/java/lib/form/ValidateButtonTest.java index da9bc286be14..675795a6e323 100644 --- a/test/src/test/java/lib/form/ValidateButtonTest.java +++ b/test/src/test/java/lib/form/ValidateButtonTest.java @@ -56,7 +56,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; /** * @@ -214,7 +214,7 @@ public static final class DescriptorImpl extends Descriptor<NoInjectionArePossib public String paramMethod = "validateInjection"; public String paramWith = null; - public void doValidateInjection(StaplerRequest request) { + public void doValidateInjection(StaplerRequest2 request) { wasCalled = true; } } @@ -267,7 +267,7 @@ public static class ValidateProperty extends JobProperty<Job<?, ?>> { public static class DescriptorImpl extends JobPropertyDescriptor { public boolean called = false; - public void doSomething(StaplerRequest req) { + public void doSomething(StaplerRequest2 req) { called = true; } } diff --git a/test/src/test/java/lib/layout/ConfirmationLinkTest.java b/test/src/test/java/lib/layout/ConfirmationLinkTest.java index 42a52cc3c6e8..dca6f81f73f2 100644 --- a/test/src/test/java/lib/layout/ConfirmationLinkTest.java +++ b/test/src/test/java/lib/layout/ConfirmationLinkTest.java @@ -46,7 +46,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.WebMethod; public class ConfirmationLinkTest { @@ -202,7 +202,7 @@ public String getUrlName() { } @WebMethod(name = "submit") - public HttpResponse doSubmit(StaplerRequest request) { + public HttpResponse doSubmit(StaplerRequest2 request) { return HttpResponses.plainText("method:" + request.getMethod()); } } diff --git a/test/src/test/java/lib/layout/StopButtonTest.java b/test/src/test/java/lib/layout/StopButtonTest.java index e29aa99c7198..79c0d0ee68b5 100644 --- a/test/src/test/java/lib/layout/StopButtonTest.java +++ b/test/src/test/java/lib/layout/StopButtonTest.java @@ -42,7 +42,7 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestExtension; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerRequest2; import org.kohsuke.stapler.WebMethod; public class StopButtonTest { @@ -143,7 +143,7 @@ public static class TestRootAction implements UnprotectedRootAction { } @WebMethod(name = "submit") - public HttpResponse doSubmit(StaplerRequest request) { + public HttpResponse doSubmit(StaplerRequest2 request) { return HttpResponses.plainText("method:" + request.getMethod()); } } diff --git a/test/src/test/java/lib/layout/TaskTest.java b/test/src/test/java/lib/layout/TaskTest.java index 4e6918d2be0a..9dfac80a1c4a 100644 --- a/test/src/test/java/lib/layout/TaskTest.java +++ b/test/src/test/java/lib/layout/TaskTest.java @@ -27,8 +27,8 @@ import static org.junit.Assert.assertTrue; import hudson.model.UnprotectedRootAction; +import jakarta.servlet.ServletException; import java.io.IOException; -import javax.servlet.ServletException; import org.htmlunit.html.HtmlElementUtil; import org.htmlunit.html.HtmlPage; import org.junit.Rule; @@ -36,8 +36,8 @@ import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.JenkinsRule.WebClient; import org.jvnet.hudson.test.TestExtension; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.interceptor.RequirePOST; public class TaskTest { @@ -56,7 +56,7 @@ public class TaskTest { public static class MockAction implements UnprotectedRootAction { private boolean called = false; - @RequirePOST public void doPost(StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { + @RequirePOST public void doPost(StaplerRequest2 req, StaplerResponse2 rsp) throws ServletException, IOException { if (called) throw new AssertionError(); called = true; rsp.forwardToPreviousPage(req); diff --git a/test/src/test/java/org/kohsuke/stapler/MockStaplerRequestBuilder.java b/test/src/test/java/org/kohsuke/stapler/MockStaplerRequestBuilder.java index cf8b1eee4fcc..2e9e9c1c793b 100644 --- a/test/src/test/java/org/kohsuke/stapler/MockStaplerRequestBuilder.java +++ b/test/src/test/java/org/kohsuke/stapler/MockStaplerRequestBuilder.java @@ -25,16 +25,16 @@ package org.kohsuke.stapler; import edu.umd.cs.findbugs.annotations.NonNull; +import jakarta.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.servlet.http.HttpServletRequest; import org.jvnet.hudson.test.JenkinsRule; import org.mockito.Mockito; /** - * Mocked version of {@link StaplerRequest}. + * Mocked version of {@link StaplerRequest2}. * @author Oleg Nenashev */ public class MockStaplerRequestBuilder { @@ -66,7 +66,7 @@ public MockStaplerRequestBuilder withAncestor(AncestorImpl ancestor) { return this; } - public StaplerRequest build() { + public StaplerRequest2 build() { HttpServletRequest rawRequest = Mockito.mock(HttpServletRequest.class); return new RequestImpl(stapler != null ? stapler : new Stapler(), rawRequest, ancestors, tokens); } diff --git a/test/src/test/java/org/kohsuke/stapler/Security1097Test.java b/test/src/test/java/org/kohsuke/stapler/Security1097Test.java index 650304e5bc40..28e63811e712 100644 --- a/test/src/test/java/org/kohsuke/stapler/Security1097Test.java +++ b/test/src/test/java/org/kohsuke/stapler/Security1097Test.java @@ -6,11 +6,11 @@ import hudson.Extension; import hudson.model.InvisibleAction; import hudson.model.RootAction; +import jakarta.servlet.ServletException; import java.lang.reflect.Field; import java.net.HttpURLConnection; import java.util.Arrays; import java.util.List; -import javax.servlet.ServletException; import net.sf.json.JSONObject; import org.htmlunit.FailingHttpStatusCodeException; import org.htmlunit.html.HtmlPage; @@ -74,7 +74,7 @@ public String getUrlName() { } /* Deliberate CSRF vulnerability */ - public void doConfigSubmit1(StaplerRequest req) throws ServletException { + public void doConfigSubmit1(StaplerRequest2 req) throws ServletException { req.getSubmittedForm(); } diff --git a/war/pom.xml b/war/pom.xml index e6b4bf8251b7..e9ba3dfc6f9e 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -87,12 +87,7 @@ THE SOFTWARE. </dependency> <dependency> <groupId>org.jenkins-ci.main</groupId> - <artifactId>websocket-jetty10</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.jenkins-ci.main</groupId> - <artifactId>websocket-jetty12-ee8</artifactId> + <artifactId>websocket-jetty12-ee9</artifactId> <version>${project.version}</version> </dependency> <dependency> @@ -161,13 +156,22 @@ THE SOFTWARE. <exclude>org.jenkins-ci:commons-jelly</exclude> <exclude>org.jenkins-ci.main:cli</exclude> <exclude>org.jenkins-ci.main:jenkins-core</exclude> - <exclude>org.jenkins-ci.main:websocket-jetty10</exclude> - <exclude>org.jenkins-ci.main:websocket-jetty12-ee8</exclude> + <exclude>org.jenkins-ci.main:websocket-jetty12-ee9</exclude> <exclude>org.jenkins-ci.main:websocket-spi</exclude> + <exclude>org.jvnet.hudson:commons-jelly-tags-define</exclude> <exclude>org.jvnet.winp:winp</exclude> <exclude>org.kohsuke.stapler:stapler</exclude> <exclude>org.kohsuke.stapler:stapler-groovy</exclude> <exclude>org.kohsuke.stapler:stapler-jelly</exclude> + <exclude>org.springframework.security:spring-security-core</exclude> + <exclude>org.springframework.security:spring-security-crypto</exclude> + <exclude>org.springframework.security:spring-security-web</exclude> + <exclude>org.springframework:spring-aop</exclude> + <exclude>org.springframework:spring-beans</exclude> + <exclude>org.springframework:spring-context</exclude> + <exclude>org.springframework:spring-core</exclude> + <exclude>org.springframework:spring-expression</exclude> + <exclude>org.springframework:spring-web</exclude> </excludes> </enforceBytecodeVersion> </rules> @@ -636,8 +640,8 @@ THE SOFTWARE. </configuration> </plugin> <plugin> - <groupId>org.eclipse.jetty.ee8</groupId> - <artifactId>jetty-ee8-maven-plugin</artifactId> + <groupId>org.eclipse.jetty.ee9</groupId> + <artifactId>jetty-ee9-maven-plugin</artifactId> <version>12.0.12</version> <configuration> <!-- diff --git a/websocket/jetty10/pom.xml b/websocket/jetty10/pom.xml deleted file mode 100644 index 5147b02b81d6..000000000000 --- a/websocket/jetty10/pom.xml +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -The MIT License - -Copyright (c) 2019, CloudBees, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.jenkins-ci.main</groupId> - <artifactId>jenkins-parent</artifactId> - <version>${revision}${changelist}</version> - <relativePath>../..</relativePath> - </parent> - - <artifactId>websocket-jetty10</artifactId> - <name>Jetty 10 implementation for WebSocket</name> - <description>An implementation of the WebSocket handler that works with Jetty 10.</description> - - <dependencyManagement> - <dependencies> - <dependency> - <groupId>org.jenkins-ci.main</groupId> - <artifactId>jenkins-bom</artifactId> - <version>${project.version}</version> - <type>pom</type> - <scope>import</scope> - </dependency> - </dependencies> - </dependencyManagement> - - <dependencies> - <dependency> - <groupId>org.jenkins-ci</groupId> - <artifactId>winstone</artifactId> - <version>6.21</version> - <optional>true</optional> - </dependency> - <dependency> - <groupId>org.jenkins-ci.main</groupId> - <artifactId>websocket-spi</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.kohsuke</groupId> - <artifactId>access-modifier-annotation</artifactId> - </dependency> - <dependency> - <groupId>org.kohsuke.metainf-services</groupId> - <artifactId>metainf-services</artifactId> - <optional>true</optional> - </dependency> - </dependencies> - - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-javadoc-plugin</artifactId> - <configuration> - <skip>true</skip> - </configuration> - </plugin> - </plugins> - </build> -</project> diff --git a/websocket/jetty10/src/main/java/jenkins/websocket/Jetty10Provider.java b/websocket/jetty10/src/main/java/jenkins/websocket/Jetty10Provider.java deleted file mode 100644 index b5243e627f52..000000000000 --- a/websocket/jetty10/src/main/java/jenkins/websocket/Jetty10Provider.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * The MIT License - * - * Copyright 2022 CloudBees, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package jenkins.websocket; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.time.Duration; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.WebSocketListener; -import org.eclipse.jetty.websocket.api.WriteCallback; -import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest; -import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse; -import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer; -import org.kohsuke.MetaInfServices; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - -@Restricted(NoExternalUse.class) -@MetaInfServices(Provider.class) -public class Jetty10Provider implements Provider { - - /** - * Number of seconds a WebsocketConnection may stay idle until it expires. - * Zero to disable. - * This value must be higher than the <code>jenkins.websocket.pingInterval</code>. - * Per <a href=https://www.eclipse.org/jetty/documentation/jetty-10/programming-guide/index.html#pg-websocket-session-ping>Jetty 10 documentation</a> - * a ping mechanism should keep the websocket active. Therefore, the idle timeout must be higher than the ping - * interval to avoid timeout issues. - */ - private static long IDLE_TIMEOUT_SECONDS = Long.getLong("jenkins.websocket.idleTimeout", 60L); - - private static final String ATTR_LISTENER = Jetty10Provider.class.getName() + ".listener"; - - private boolean initialized = false; - - public Jetty10Provider() { - JettyWebSocketServerContainer.class.hashCode(); - } - - private void init(HttpServletRequest req) { - if (!initialized) { - JettyWebSocketServerContainer.getContainer(req.getServletContext()).setIdleTimeout(Duration.ofSeconds(IDLE_TIMEOUT_SECONDS)); - initialized = true; - } - } - - @Override - public Handler handle(HttpServletRequest req, HttpServletResponse rsp, Listener listener) throws Exception { - init(req); - req.setAttribute(ATTR_LISTENER, listener); - // TODO Jetty 10 has no obvious equivalent to WebSocketServerFactory.isUpgradeRequest; RFC6455Negotiation? - if (!"websocket".equalsIgnoreCase(req.getHeader("Upgrade"))) { - rsp.sendError(HttpServletResponse.SC_BAD_REQUEST, "only WS connections accepted here"); - return null; - } - if (!JettyWebSocketServerContainer.getContainer(req.getServletContext()).upgrade(Jetty10Provider::createWebSocket, req, rsp)) { - rsp.sendError(HttpServletResponse.SC_BAD_REQUEST, "did not manage to upgrade"); - return null; - } - return new Handler() { - @Override - public Future<Void> sendBinary(ByteBuffer data) throws IOException { - CompletableFuture<Void> f = new CompletableFuture<>(); - session().getRemote().sendBytes(data, new WriteCallbackImpl(f)); - return f; - } - - @Override - public void sendBinary(ByteBuffer partialByte, boolean isLast) throws IOException { - session().getRemote().sendPartialBytes(partialByte, isLast); - } - - @Override - public Future<Void> sendText(String text) throws IOException { - CompletableFuture<Void> f = new CompletableFuture<>(); - session().getRemote().sendString(text, new WriteCallbackImpl(f)); - return f; - } - - @Override - public Future<Void> sendPing(ByteBuffer applicationData) throws IOException { - CompletableFuture<Void> f = new CompletableFuture<>(); - session().getRemote().sendPing(applicationData, new WriteCallbackImpl(f)); - return f; - } - - @Override - public void close() throws IOException { - session().close(); - } - - private Session session() { - Session session = (Session) listener.getProviderSession(); - if (session == null) { - throw new IllegalStateException("missing session"); - } - return session; - } - }; - } - - private static final class WriteCallbackImpl implements WriteCallback { - private final CompletableFuture<Void> f; - - WriteCallbackImpl(CompletableFuture<Void> f) { - this.f = f; - } - - @Override - public void writeSuccess() { - f.complete(null); - } - - @Override - public void writeFailed(Throwable x) { - f.completeExceptionally(x); - } - } - - private static Object createWebSocket(JettyServerUpgradeRequest req, JettyServerUpgradeResponse resp) { - Listener listener = (Listener) req.getHttpServletRequest().getAttribute(ATTR_LISTENER); - if (listener == null) { - throw new IllegalStateException("missing listener attribute"); - } - return new WebSocketListener() { - @Override - public void onWebSocketBinary(byte[] payload, int offset, int length) { - listener.onWebSocketBinary(payload, offset, length); - } - - @Override - public void onWebSocketText(String message) { - listener.onWebSocketText(message); - } - - @Override - public void onWebSocketClose(int statusCode, String reason) { - listener.onWebSocketClose(statusCode, reason); - } - - @Override - public void onWebSocketConnect(Session session) { - listener.onWebSocketConnect(session); - } - - @Override - public void onWebSocketError(Throwable cause) { - listener.onWebSocketError(cause); - } - }; - } - -} diff --git a/websocket/jetty12-ee8/pom.xml b/websocket/jetty12-ee9/pom.xml similarity index 95% rename from websocket/jetty12-ee8/pom.xml rename to websocket/jetty12-ee9/pom.xml index 9a7a9ca94545..2253163b3c4c 100644 --- a/websocket/jetty12-ee8/pom.xml +++ b/websocket/jetty12-ee9/pom.xml @@ -32,9 +32,9 @@ THE SOFTWARE. <relativePath>../..</relativePath> </parent> - <artifactId>websocket-jetty12-ee8</artifactId> - <name>Jetty 12 (EE 8) implementation for WebSocket</name> - <description>An implementation of the WebSocket handler that works with Jetty 12 (EE 8).</description> + <artifactId>websocket-jetty12-ee9</artifactId> + <name>Jetty 12 (EE 9) implementation for WebSocket</name> + <description>An implementation of the WebSocket handler that works with Jetty 12 (EE 9).</description> <dependencyManagement> <dependencies> diff --git a/websocket/jetty12-ee8/src/main/java/jenkins/websocket/Jetty12EE8Provider.java b/websocket/jetty12-ee9/src/main/java/jenkins/websocket/Jetty12EE9Provider.java similarity index 90% rename from websocket/jetty12-ee8/src/main/java/jenkins/websocket/Jetty12EE8Provider.java rename to websocket/jetty12-ee9/src/main/java/jenkins/websocket/Jetty12EE9Provider.java index cc006b180f26..bf6ff9671056 100644 --- a/websocket/jetty12-ee8/src/main/java/jenkins/websocket/Jetty12EE8Provider.java +++ b/websocket/jetty12-ee9/src/main/java/jenkins/websocket/Jetty12EE9Provider.java @@ -24,26 +24,26 @@ package jenkins.websocket; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.nio.ByteBuffer; import java.time.Duration; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.ee8.websocket.api.Session; -import org.eclipse.jetty.ee8.websocket.api.WebSocketListener; -import org.eclipse.jetty.ee8.websocket.api.WriteCallback; -import org.eclipse.jetty.ee8.websocket.server.JettyServerUpgradeRequest; -import org.eclipse.jetty.ee8.websocket.server.JettyServerUpgradeResponse; -import org.eclipse.jetty.ee8.websocket.server.JettyWebSocketServerContainer; +import org.eclipse.jetty.ee9.websocket.api.Session; +import org.eclipse.jetty.ee9.websocket.api.WebSocketListener; +import org.eclipse.jetty.ee9.websocket.api.WriteCallback; +import org.eclipse.jetty.ee9.websocket.server.JettyServerUpgradeRequest; +import org.eclipse.jetty.ee9.websocket.server.JettyServerUpgradeResponse; +import org.eclipse.jetty.ee9.websocket.server.JettyWebSocketServerContainer; import org.kohsuke.MetaInfServices; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @Restricted(NoExternalUse.class) @MetaInfServices(Provider.class) -public class Jetty12EE8Provider implements Provider { +public class Jetty12EE9Provider implements Provider { /** * Number of seconds a WebsocketConnection may stay idle until it expires. @@ -55,11 +55,11 @@ public class Jetty12EE8Provider implements Provider { */ private static long IDLE_TIMEOUT_SECONDS = Long.getLong("jenkins.websocket.idleTimeout", 60L); - private static final String ATTR_LISTENER = Jetty12EE8Provider.class.getName() + ".listener"; + private static final String ATTR_LISTENER = Jetty12EE9Provider.class.getName() + ".listener"; private boolean initialized = false; - public Jetty12EE8Provider() { + public Jetty12EE9Provider() { JettyWebSocketServerContainer.class.hashCode(); } @@ -79,7 +79,7 @@ public Handler handle(HttpServletRequest req, HttpServletResponse rsp, Listener rsp.sendError(HttpServletResponse.SC_BAD_REQUEST, "only WS connections accepted here"); return null; } - if (!JettyWebSocketServerContainer.getContainer(req.getServletContext()).upgrade(Jetty12EE8Provider::createWebSocket, req, rsp)) { + if (!JettyWebSocketServerContainer.getContainer(req.getServletContext()).upgrade(Jetty12EE9Provider::createWebSocket, req, rsp)) { rsp.sendError(HttpServletResponse.SC_BAD_REQUEST, "did not manage to upgrade"); return null; } diff --git a/websocket/spi/pom.xml b/websocket/spi/pom.xml index a99aada6a446..178413f92c8e 100644 --- a/websocket/spi/pom.xml +++ b/websocket/spi/pom.xml @@ -52,7 +52,7 @@ THE SOFTWARE. <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> - <version>4.0.4</version> + <version>5.0.0</version> </dependency> </dependencies> diff --git a/websocket/spi/src/main/java/jenkins/websocket/Provider.java b/websocket/spi/src/main/java/jenkins/websocket/Provider.java index 19f50f1eaf26..fdb8ec408011 100644 --- a/websocket/spi/src/main/java/jenkins/websocket/Provider.java +++ b/websocket/spi/src/main/java/jenkins/websocket/Provider.java @@ -24,11 +24,11 @@ package jenkins.websocket; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.nio.ByteBuffer; import java.util.concurrent.Future; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; /** * Defines a way for Jenkins core to serve WebSocket connections.