From 7006cded64f63f788ae91dd7b7587a4a39e70273 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Tue, 3 Sep 2024 14:59:04 -0700 Subject: [PATCH] [JENKINS-73278] Migrate core from EE 8 to EE 9 (#9672) Co-authored-by: Kevin Guerroudj <91883215+Kevin-CB@users.noreply.github.com> Co-authored-by: Daniel Beck <1831569+daniel-beck@users.noreply.github.com> --- .github/renovate.json | 11 - .idea/encodings.xml | 9 +- bom/pom.xml | 14 +- core/pom.xml | 20 +- .../java/hudson/DescriptorExtensionList.java | 2 +- .../main/java/hudson/ExpressionFactory2.java | 4 +- core/src/main/java/hudson/FilePath.java | 2 +- core/src/main/java/hudson/Functions.java | 166 ++++++++++--- .../main/java/hudson/LocalPluginManager.java | 15 +- core/src/main/java/hudson/Plugin.java | 66 +++++- core/src/main/java/hudson/PluginManager.java | 91 ++++++-- core/src/main/java/hudson/PluginWrapper.java | 6 +- .../hudson/ProxyConfigurationManager.java | 4 +- .../java/hudson/ResponseHeaderFilter.java | 16 +- core/src/main/java/hudson/Util.java | 14 +- core/src/main/java/hudson/WebAppMain.java | 22 +- core/src/main/java/hudson/cli/CLIAction.java | 16 +- .../java/hudson/cli/CliCrumbExclusion.java | 8 +- .../cli/ReloadConfigurationCommand.java | 2 +- .../java/hudson/cli/UpdateNodeCommand.java | 2 +- .../hudson/console/AnnotatedLargeText.java | 61 ++++- .../console/ConsoleAnnotationDescriptor.java | 10 +- .../console/ConsoleAnnotatorFactory.java | 10 +- .../java/hudson/console/HyperlinkNote.java | 4 +- .../java/hudson/diagnosis/OldDataMonitor.java | 12 +- .../diagnosis/ReverseProxySetupMonitor.java | 4 +- .../diagnosis/TooManyJobsButNoView.java | 6 +- .../hudson/init/impl/GroovyInitScript.java | 2 +- .../impl/InstallUncaughtExceptionHandler.java | 18 +- .../lifecycle/WindowsInstallerLink.java | 16 +- .../main/java/hudson/logging/LogRecorder.java | 12 +- .../hudson/logging/LogRecorderManager.java | 12 +- .../java/hudson/markup/MarkupFormatter.java | 25 +- .../main/java/hudson/model/AbstractBuild.java | 13 +- .../main/java/hudson/model/AbstractItem.java | 107 ++++++++- .../hudson/model/AbstractModelObject.java | 53 ++++- .../java/hudson/model/AbstractProject.java | 80 +++++-- .../main/java/hudson/model/Actionable.java | 46 +++- .../hudson/model/AdministrativeMonitor.java | 8 +- core/src/main/java/hudson/model/AllView.java | 28 ++- core/src/main/java/hudson/model/Api.java | 71 +++++- .../model/AutoCompletionCandidates.java | 8 +- .../src/main/java/hudson/model/BallColor.java | 2 +- .../model/BooleanParameterDefinition.java | 4 +- .../hudson/model/BuildAuthorizationToken.java | 32 ++- .../hudson/model/BuildTimelineWidget.java | 20 +- .../model/ChoiceParameterDefinition.java | 6 +- core/src/main/java/hudson/model/Computer.java | 34 +-- .../main/java/hudson/model/ComputerSet.java | 20 +- .../main/java/hudson/model/Descriptor.java | 157 ++++++++++--- .../hudson/model/DirectlyModifiableView.java | 2 +- .../hudson/model/DirectoryBrowserSupport.java | 23 +- core/src/main/java/hudson/model/Executor.java | 3 +- core/src/main/java/hudson/model/Failure.java | 10 +- .../hudson/model/FileParameterDefinition.java | 8 +- .../java/hudson/model/FileParameterValue.java | 8 +- core/src/main/java/hudson/model/Hudson.java | 42 +++- core/src/main/java/hudson/model/Item.java | 4 +- .../java/hudson/model/ItemGroupMixIn.java | 25 +- core/src/main/java/hudson/model/Job.java | 102 ++++++-- .../main/java/hudson/model/JobProperty.java | 22 ++ .../hudson/model/JobPropertyDescriptor.java | 19 ++ core/src/main/java/hudson/model/Label.java | 6 +- core/src/main/java/hudson/model/ListView.java | 39 +++- .../hudson/model/ManageJenkinsAction.java | 8 +- .../hudson/model/ModifiableItemGroup.java | 49 +++- .../hudson/model/MultiStageTimeSeries.java | 8 +- core/src/main/java/hudson/model/MyView.java | 28 ++- .../java/hudson/model/MyViewsProperty.java | 10 +- core/src/main/java/hudson/model/Node.java | 18 ++ .../hudson/model/PaneStatusProperties.java | 6 +- .../hudson/model/ParameterDefinition.java | 58 ++++- .../java/hudson/model/ParameterValue.java | 6 +- .../model/ParametersDefinitionProperty.java | 37 +-- .../model/PasswordParameterDefinition.java | 4 +- core/src/main/java/hudson/model/Project.java | 36 ++- .../src/main/java/hudson/model/ProxyView.java | 37 ++- core/src/main/java/hudson/model/Queue.java | 8 +- core/src/main/java/hudson/model/RSS.java | 57 ++++- .../model/ReconfigurableDescribable.java | 31 ++- core/src/main/java/hudson/model/Run.java | 93 +++++++- .../hudson/model/RunParameterDefinition.java | 6 +- .../model/SimpleParameterDefinition.java | 4 +- core/src/main/java/hudson/model/Slave.java | 14 +- .../java/hudson/model/StockStatusIcon.java | 4 +- .../model/StringParameterDefinition.java | 4 +- .../main/java/hudson/model/TaskAction.java | 14 +- .../hudson/model/TextParameterDefinition.java | 4 +- .../hudson/model/TopLevelItemDescriptor.java | 2 +- .../main/java/hudson/model/UpdateCenter.java | 40 +++- .../java/hudson/model/UsageStatistics.java | 6 +- core/src/main/java/hudson/model/User.java | 20 +- .../main/java/hudson/model/UserProperty.java | 16 ++ core/src/main/java/hudson/model/View.java | 147 ++++++++++-- .../java/hudson/model/ViewDescriptor.java | 6 +- core/src/main/java/hudson/model/ViewJob.java | 30 ++- .../main/java/hudson/model/ViewProperty.java | 16 ++ .../java/hudson/model/labels/LabelAtom.java | 10 +- .../UserPropertyCategoryAccountAction.java | 8 +- .../UserPropertyCategoryAction.java | 8 +- .../java/hudson/scm/AbstractScmTagAction.java | 34 ++- .../java/hudson/scm/RepositoryBrowsers.java | 17 +- core/src/main/java/hudson/scm/SCMS.java | 22 +- core/src/main/java/hudson/search/Search.java | 59 ++++- .../hudson/search/UserSearchProperty.java | 4 +- .../security/AccessDeniedException2.java | 3 +- .../security/AccessDeniedException3.java | 15 +- .../security/AccessDeniedHandlerImpl.java | 8 +- .../AuthenticationProcessingFilter2.java | 10 +- .../security/AuthorizationStrategy.java | 4 +- .../security/BasicAuthenticationFilter.java | 28 +-- .../hudson/security/ChainedServletFilter.java | 19 +- .../security/ContainerAuthentication.java | 4 +- .../security/FederatedLoginService.java | 8 +- .../security/GlobalSecurityConfiguration.java | 12 +- .../HttpSessionContextIntegrationFilter2.java | 12 +- .../HudsonAuthenticationEntryPoint.java | 8 +- .../java/hudson/security/HudsonFilter.java | 19 +- .../security/HudsonPrivateSecurityRealm.java | 63 ++--- .../hudson/security/LegacySecurityRealm.java | 4 +- .../main/java/hudson/security/NoopFilter.java | 15 +- .../security/RememberMeServicesProxy.java | 4 +- .../java/hudson/security/SecurityRealm.java | 106 +++++++-- .../TokenBasedRememberMeServices2.java | 4 +- .../UnwrapSecurityExceptionFilter.java | 14 +- .../hudson/security/csrf/CrumbExclusion.java | 65 +++++- .../hudson/security/csrf/CrumbFilter.java | 20 +- .../hudson/security/csrf/CrumbIssuer.java | 109 ++++++++- .../security/csrf/DefaultCrumbIssuer.java | 9 +- .../csrf/GlobalCrumbIssuerConfiguration.java | 4 +- core/src/main/java/hudson/slaves/Cloud.java | 26 ++- .../EnvironmentVariablesNodeProperty.java | 2 +- .../java/hudson/slaves/NodeDescriptor.java | 8 +- .../main/java/hudson/slaves/NodeProperty.java | 19 ++ .../java/hudson/slaves/SlaveComputer.java | 16 +- .../java/hudson/tasks/ArtifactArchiver.java | 4 +- .../main/java/hudson/tasks/BuildTrigger.java | 4 +- .../main/java/hudson/tasks/Fingerprinter.java | 4 +- core/src/main/java/hudson/tasks/Maven.java | 4 +- core/src/main/java/hudson/tasks/Shell.java | 4 +- .../java/hudson/tools/ToolDescriptor.java | 21 +- .../main/java/hudson/triggers/SCMTrigger.java | 8 +- .../main/java/hudson/util/BootFailure.java | 2 +- .../hudson/util/CharacterEncodingFilter.java | 16 +- .../main/java/hudson/util/ComboBoxModel.java | 8 +- .../java/hudson/util/DescribableList.java | 23 +- .../main/java/hudson/util/DescriptorList.java | 2 +- .../main/java/hudson/util/ErrorObject.java | 10 +- core/src/main/java/hudson/util/FormApply.java | 21 +- .../java/hudson/util/FormFillFailure.java | 12 +- .../main/java/hudson/util/FormValidation.java | 18 +- core/src/main/java/hudson/util/Graph.java | 46 +++- .../main/java/hudson/util/HttpResponses.java | 8 +- .../java/hudson/util/HudsonIsLoading.java | 12 +- .../java/hudson/util/HudsonIsRestarting.java | 12 +- .../main/java/hudson/util/ListBoxModel.java | 37 ++- .../hudson/util/MultipartFormDataParser.java | 50 +++- .../java/hudson/util/PluginServletFilter.java | 69 ++++-- .../java/hudson/util/QueryParameterMap.java | 10 +- .../java/hudson/util/RemotingDiagnostics.java | 6 +- .../views/GlobalDefaultViewConfiguration.java | 4 +- .../java/hudson/views/ListViewColumn.java | 3 +- .../main/java/hudson/views/MyViewsTabBar.java | 4 +- .../main/java/hudson/views/ViewsTabBar.java | 4 +- .../java/hudson/widgets/HistoryWidget.java | 12 +- .../hudson/widgets/RenderOnDemandClosure.java | 12 +- .../java/jenkins/ErrorAttributeFilter.java | 16 +- core/src/main/java/jenkins/I18n.java | 4 +- .../jenkins/JenkinsHttpSessionListener.java | 4 +- .../main/java/jenkins/agents/CloudSet.java | 29 ++- .../java/jenkins/agents/WebSocketAgents.java | 6 +- .../AppearanceGlobalConfiguration.java | 12 +- .../jenkins/console/ConsoleUrlProvider.java | 4 +- ...ConsoleUrlProviderGlobalConfiguration.java | 4 +- .../ControllerExecutorsAgents.java | 6 +- .../ControllerExecutorsNoAgents.java | 6 +- .../diagnostics/SecurityIsOffMonitor.java | 6 +- .../diagnostics/URICheckEncodingMonitor.java | 4 +- .../GlobalFingerprintConfiguration.java | 4 +- .../java/jenkins/install/SetupWizard.java | 31 +-- .../management/AdministrativeMonitorsApi.java | 10 +- .../AdministrativeMonitorsConfiguration.java | 4 +- .../AdministrativeMonitorsDecorator.java | 4 +- .../java/jenkins/management/ShutdownLink.java | 10 +- .../model/ArtifactManagerConfiguration.java | 4 +- .../main/java/jenkins/model/AssetManager.java | 10 +- .../jenkins/model/BuiltInNodeMigration.java | 8 +- .../GlobalBuildDiscarderConfiguration.java | 4 +- .../jenkins/model/GlobalConfiguration.java | 23 +- .../GlobalNodePropertiesConfiguration.java | 4 +- .../model/GlobalPluginConfiguration.java | 6 +- ...balProjectNamingStrategyConfiguration.java | 4 +- .../model/GlobalQuietPeriodConfiguration.java | 4 +- .../GlobalSCMRetryCountConfiguration.java | 4 +- core/src/main/java/jenkins/model/Jenkins.java | 220 ++++++++++++------ .../model/JenkinsLocationConfiguration.java | 6 +- .../model/MasterBuildConfiguration.java | 4 +- .../model/ModelObjectWithChildren.java | 27 ++- .../model/ModelObjectWithContextMenu.java | 53 +++-- .../jenkins/model/OptionalJobProperty.java | 16 +- .../jenkins/model/ParameterizedJobMixIn.java | 76 ++++-- .../jenkins/model/ProjectNamingStrategy.java | 2 +- .../UserExperimentalFlagsProperty.java | 4 +- .../model/item_category/Categories.java | 8 +- .../jenkins/mvn/GlobalSettingsProvider.java | 21 +- .../java/jenkins/mvn/SettingsProvider.java | 18 +- .../AcegiSecurityExceptionFilter.java | 14 +- .../jenkins/security/ApiCrumbExclusion.java | 8 +- .../java/jenkins/security/ApiTokenFilter.java | 2 +- .../jenkins/security/ApiTokenProperty.java | 4 +- .../AuthenticationSuccessHandler.java | 4 +- .../BasicHeaderApiTokenAuthenticator.java | 6 +- .../security/BasicHeaderAuthenticator.java | 46 +++- .../security/BasicHeaderProcessor.java | 19 +- .../BasicHeaderRealPasswordAuthenticator.java | 6 +- .../LastGrantedAuthoritiesProperty.java | 4 +- .../NonSerializableSecurityContext.java | 2 +- .../QueueItemAuthenticatorConfiguration.java | 4 +- .../security/ResourceDomainConfiguration.java | 6 +- .../security/ResourceDomainFilter.java | 6 +- .../security/ResourceDomainRootAction.java | 16 +- .../jenkins/security/SecureRequester.java | 33 ++- .../security/SuspiciousRequestFilter.java | 18 +- .../UpdateSiteWarningsConfiguration.java | 4 +- .../seed/UserSeedSecurityListener.java | 6 +- .../stapler/StaplerDispatchValidator.java | 18 +- .../StaplerFilteredActionListener.java | 12 +- .../StaticRoutingDecisionProvider.java | 2 +- .../security/stapler/WebMethodConstants.java | 12 +- .../slaves/EncryptedSlaveAgentJnlpFile.java | 18 +- .../EnvVarsFilterGlobalConfiguration.java | 4 +- .../telemetry/impl/StaplerDispatches.java | 4 +- .../jenkins/telemetry/impl/UserLanguages.java | 6 +- .../tools/GlobalToolConfiguration.java | 12 +- .../jenkins/util/FullDuplexHttpService.java | 16 +- .../java/jenkins/util/HttpServletFilter.java | 19 +- .../jenkins/util/HttpSessionListener.java | 38 ++- .../jenkins/util/JSONSignatureValidator.java | 4 +- .../main/java/jenkins/util/JenkinsJVM.java | 2 +- .../jenkins/util/ProgressiveRendering.java | 8 +- .../java/jenkins/util/ScriptListener.java | 4 +- .../java/jenkins/util/SystemProperties.java | 6 +- .../jenkins/util/groovy/GroovyHookScript.java | 13 +- .../java/jenkins/websocket/WebSockets.java | 18 +- .../ui/rememberme/RememberMeServices.java | 4 +- .../RememberMeServicesSpringImpl.java | 4 +- .../jenkins/model/Jenkins/_404.jelly | 6 +- .../jenkins/model/Jenkins/_404_simple.jelly | 4 +- .../jenkins/model/Jenkins/oops.jelly | 2 +- core/src/test/java/hudson/FunctionsTest.java | 36 +-- .../hudson/GetLocaleStaticHelpUrlTest.java | 24 +- .../src/test/java/hudson/model/QueueTest.java | 8 +- core/src/test/java/hudson/model/ViewTest.java | 8 +- .../java/hudson/util/FormValidationTest.java | 5 +- .../jenkins/model/JenkinsGetRootUrlTest.java | 28 +-- .../stapler/StaplerSignaturesTest.java | 10 +- pom.xml | 5 +- .../java/hudson/CustomPluginManagerTest.java | 2 +- .../PluginManagerCheckUpdateCenterTest.java | 12 +- .../test/java/hudson/PluginManagerTest.java | 12 +- test/src/test/java/hudson/PluginTest.java | 2 +- .../java/hudson/cli/BuildCommandTest.java | 4 +- test/src/test/java/hudson/cli/CLITest.java | 22 +- .../hudson/diagnosis/OldDataMonitorTest.java | 4 +- test/src/test/java/hudson/model/ApiTest.java | 2 +- .../model/ComputerConfigDotXmlTest.java | 16 +- .../java/hudson/model/DescriptorTest.java | 8 +- .../model/DirectoryBrowserSupportTest.java | 6 +- .../java/hudson/model/JobPropertyTest.java | 6 +- .../test/java/hudson/model/ListViewTest.java | 12 +- .../ParametersDefinitionPropertyTest.java | 8 +- .../test/java/hudson/model/ProjectTest.java | 3 +- .../src/test/java/hudson/model/QueueTest.java | 2 +- .../hudson/model/UpdateCenterCustomTest.java | 6 +- .../hudson/model/UsageStatisticsTest.java | 2 +- .../java/hudson/model/ViewDescriptorTest.java | 4 +- .../java/hudson/model/ViewPropertyTest.java | 4 +- test/src/test/java/hudson/model/ViewTest.java | 10 +- .../pages/SystemConfigurationTestCase.java | 4 +- .../test/java/hudson/security/LoginTest.java | 2 +- .../hudson/security/SecurityRealmTest.java | 4 +- .../TokenBasedRememberMeServices2Test.java | 2 +- .../test/java/hudson/security/WhoAmITest.java | 6 +- .../security/csrf/CrumbExclusionTest.java | 8 +- .../security/csrf/DefaultCrumbIssuerTest.java | 2 +- .../test/java/hudson/slaves/CloudTest.java | 4 +- .../java/hudson/slaves/NodePropertyTest.java | 4 +- .../java/hudson/util/BootFailureTest.java | 12 +- .../java/hudson/util/HudsonIsLoadingTest.java | 4 +- .../hudson/util/HudsonIsRestartingTest.java | 4 +- .../util/RobustReflectionConverterTest.java | 6 +- .../hudson/util/XStream2Security383Test.java | 12 +- .../GlobalDefaultViewConfigurationTest.java | 4 +- .../URICheckEncodingMonitorTest.java | 2 +- .../java/jenkins/install/InstallUtilTest.java | 2 +- .../java/jenkins/model/ContextMenuTest.java | 2 +- .../GlobalSCMRetryCountConfigurationTest.java | 6 +- .../model/ParameterizedJobMixInTest.java | 3 +- .../security/ApiTokenPropertyTest.java | 2 +- ...etJsonInErrorMessageSanitizerHtmlTest.java | 10 +- .../jenkins/security/Security3030Test.java | 54 ++--- .../jenkins/security/Security3135Test.java | 6 +- .../security/SuspiciousRequestFilterTest.java | 2 +- .../seed/UserSeedSecurityListenerTest.java | 4 +- .../CustomRoutingDecisionProviderTest.java | 4 +- .../security/stapler/DoActionFilterTest.java | 36 +-- .../jenkins/security/stapler/DynamicTest.java | 4 +- .../security/stapler/PreventRoutingTest.java | 4 +- .../security/stapler/Security400Test.java | 2 +- .../security/stapler/StaplerAbstractTest.java | 6 +- .../stapler/StaplerDispatchValidatorTest.java | 2 +- .../stapler/StaplerRoutableActionTest.java | 4 +- .../StaticRoutingDecisionProviderTest.java | 18 +- .../security/stapler/TypedFilterTest.java | 10 +- .../java/jenkins/telemetry/TelemetryTest.java | 14 +- .../util/FullDuplexHttpServiceTest.java | 12 +- .../jenkins/util/SystemPropertiesTest.java | 10 +- .../java/lib/form/AdvancedButtonTest.java | 4 +- .../test/java/lib/form/BooleanRadioTest.java | 4 +- .../test/java/lib/form/DropdownListTest.java | 4 +- test/src/test/java/lib/form/EnumSetTest.java | 4 +- test/src/test/java/lib/form/EnumTest.java | 4 +- .../java/lib/form/ExpandableTextboxTest.java | 4 +- test/src/test/java/lib/form/NameRefTest.java | 4 +- test/src/test/java/lib/form/PasswordTest.java | 4 +- .../test/java/lib/form/RepeatableTest.java | 4 +- test/src/test/java/lib/form/RowSetTest.java | 4 +- .../java/lib/form/RowVisibilityGroupTest.java | 4 +- .../java/lib/form/ValidateButtonTest.java | 6 +- .../java/lib/layout/ConfirmationLinkTest.java | 4 +- .../test/java/lib/layout/StopButtonTest.java | 4 +- test/src/test/java/lib/layout/TaskTest.java | 8 +- .../stapler/MockStaplerRequestBuilder.java | 6 +- .../org/kohsuke/stapler/Security1097Test.java | 4 +- war/pom.xml | 24 +- websocket/jetty10/pom.xml | 85 ------- .../jenkins/websocket/Jetty10Provider.java | 179 -------------- .../{jetty12-ee8 => jetty12-ee9}/pom.xml | 6 +- .../websocket/Jetty12EE9Provider.java} | 24 +- websocket/spi/pom.xml | 2 +- .../main/java/jenkins/websocket/Provider.java | 4 +- 341 files changed, 3991 insertions(+), 1872 deletions(-) delete mode 100644 websocket/jetty10/pom.xml delete mode 100644 websocket/jetty10/src/main/java/jenkins/websocket/Jetty10Provider.java rename websocket/{jetty12-ee8 => jetty12-ee9}/pom.xml (95%) rename websocket/{jetty12-ee8/src/main/java/jenkins/websocket/Jetty12EE8Provider.java => jetty12-ee9/src/main/java/jenkins/websocket/Jetty12EE9Provider.java} (90%) 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 @@ - - - - - - + + + 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. 2.0.0-M2 - 1896.v8170998149d0 + 1903.v994a_db_314d58 2.4.21 @@ -62,15 +62,15 @@ THE SOFTWARE. org.springframework spring-framework-bom - 5.3.39 + 6.1.12 pom import - + org.springframework.security spring-security-bom - 5.8.14 + 6.3.3 pom import @@ -154,12 +154,12 @@ THE SOFTWARE. jakarta.servlet jakarta.servlet-api - 4.0.4 + 5.0.0 jakarta.servlet.jsp.jstl jakarta.servlet.jsp.jstl-api - 1.2.7 + 2.0.0 jaxen @@ -295,7 +295,7 @@ THE SOFTWARE. org.jvnet.hudson commons-jelly-tags-define - 1.1-jenkins-20240510 + 1.1-jenkins-20240903 org.jvnet.localizer 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. jakarta.servlet.jsp.jstl jakarta.servlet.jsp.jstl-api + + + jakarta.el + jakarta.el-api + + + jakarta.servlet + jakarta.servlet-api + + + jakarta.xml.bind + jakarta.xml.bind-api + + jaxen @@ -288,7 +302,7 @@ THE SOFTWARE. org.apache.commons - commons-fileupload2-javax + commons-fileupload2-jakarta-servlet5 org.codehaus.groovy @@ -427,6 +441,10 @@ THE SOFTWARE. org.springframework.security spring-security-web + + io.micrometer + micrometer-observation + org.springframework spring-jcl 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 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 Iterable reverse(Collection 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 ancs = Stapler.getCurrentRequest().getAncestors(); + List 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 ancs = Stapler.getCurrentRequest().getAncestors(); + List 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 ancs = Stapler.getCurrentRequest().getAncestors(); + List 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 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> 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 getRequestHeaders(String name) { List 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: *
    - *
  • {@code config.jelly}, {@link #configure(StaplerRequest, JSONObject)}, {@link #load}, and {@link #save} + *
  • {@code config.jelly}, {@link #configure(StaplerRequest2, JSONObject)}, {@link #load}, and {@link #save} * can be replaced by {@link GlobalConfiguration} *
  • {@link #start} and {@link #postInitialize} can be replaced by {@link Initializer} (or {@link ItemListener#onLoaded}) *
  • {@link #stop} can be replaced by {@link Terminator} - *
  • {@link #setServletContext} can be replaced by {@link Jenkins#servletContext} + *
  • {@link #setServletContext} can be replaced by {@link Jenkins#getServletContext} *
* 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, *

* 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 klass, return klass.getConstructor(Jenkins.class).newInstance(jenkins); } }, + SC_FILE2 { + @Override + @NonNull PluginManager doCreate(@NonNull Class 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 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 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 loadPluginsFromWar(@NonNull String fromPath, @CheckForNull FilenameFilter filter) { Set names = new HashSet<>(); - ServletContext context = Jenkins.get().servletContext; + ServletContext context = Jenkins.get().getServletContext(); Set plugins = Util.fixNull(context.getResourcePaths(fromPath)); Set copiedPlugins = new HashSet<>(); Set dependencies = new HashSet<>(); @@ -723,7 +749,7 @@ protected static void addDependencies(URL hpiResUrl, String fromPath, Set 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 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 upload = new JavaxServletDiskFileUpload(DiskFileItemFactory.builder().setFile(tmpDir).get()); + JakartaServletFileUpload upload = new JakartaServletDiskFileUpload(DiskFileItemFactory.builder().setFile(tmpDir).get()); List 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 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 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 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 getNearestAncestorOfTypeOrThrow(@NonNull StaplerRequest request, @NonNull Class clazz) { + public static @NonNull T getNearestAncestorOfTypeOrThrow(@NonNull StaplerRequest2 request, @NonNull Class 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 getNearestAncestorOfTypeOrThrow(@NonNull StaplerRequest request, @NonNull Class 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 createAnnotator(StaplerRequest req) throws IOException { + private ConsoleAnnotator 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 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 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 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 logs) throws IOException, ServletException { + /*package*/ static void doRss(StaplerRequest2 req, StaplerResponse2 rsp, List 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 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 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 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 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 }. {@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 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 > List buildDescribable(StaplerRequest req, List> descriptors, String prefix) throws FormException, ServletException { - return buildDescribable(req, descriptors); + protected final > List buildDescribable(StaplerRequest req, List> descriptors, String prefix) throws FormException, javax.servlet.ServletException { + try { + return buildDescribable(StaplerRequest.toStaplerRequest2(req), descriptors); + } catch (ServletException e) { + throw ServletExceptionWrapper.fromJakartaServletException(e); + } } - protected final > List buildDescribable(StaplerRequest req, List> descriptors) + protected final > List buildDescribable(StaplerRequest2 req, List> descriptors) throws FormException, ServletException { JSONObject data = req.getSubmittedForm(); @@ -1860,7 +1904,7 @@ protected final > List 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 getAction(Class 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. *

*

* 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 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 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. * *

@@ -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 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 bindJSON(StaplerRequest2 req, Class type, JSONObject src) { + return bindJSON(req, type, src, false); + } + + /** + * @deprecated use {@link #bindJSON(StaplerRequest2, Class, JSONObject)} * @since 2.342 */ + @Deprecated public static T bindJSON(StaplerRequest req, Class type, JSONObject src) { - return bindJSON(req, type, src, false); + return bindJSON(StaplerRequest.toStaplerRequest2(req), type, src); } - private static T bindJSON(StaplerRequest req, Class type, JSONObject src, boolean fromNewInstance) { + private static T bindJSON(StaplerRequest2 req, Class type, JSONObject src, boolean fromNewInstance) { BindInterceptor oldInterceptor = req.getBindInterceptor(); try { NewInstanceBindInterceptor interceptor; @@ -631,9 +661,9 @@ private static T bindJSON(StaplerRequest req, Class 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 the developer documentation. * @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 getPossibleViewNames(String baseName) { List 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, T> toMap(Iterable describables) { * List of descriptors to create instances from. * @return * Can be empty but never null. + * @since TODO */ public static > - List newInstancesFromHeteroList(StaplerRequest req, JSONObject formData, String key, + List newInstancesFromHeteroList(StaplerRequest2 req, JSONObject formData, String key, Collection> descriptors) throws FormException { return newInstancesFromHeteroList(req, formData.get(key), descriptors); } + /** + * @deprecated use {@link #newInstancesFromHeteroList(StaplerRequest2, JSONObject, String, Collection)} + */ + @Deprecated + public static > + List newInstancesFromHeteroList(StaplerRequest req, JSONObject formData, String key, + Collection> descriptors) throws FormException { + return newInstancesFromHeteroList(StaplerRequest.toStaplerRequest2(req), formData, key, descriptors); + } + + /** + * @since TODO + */ public static > - List newInstancesFromHeteroList(StaplerRequest req, Object formData, + List newInstancesFromHeteroList(StaplerRequest2 req, Object formData, Collection> descriptors) throws FormException { List items = new ArrayList<>(); @@ -1086,7 +1181,7 @@ List 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 newInstancesFromHeteroList(StaplerRequest req, Object formData, return items; } + /** + * @deprecated use {@link #newInstancesFromHeteroList(StaplerRequest2, JSONObject, String, Collection)} + */ + @Deprecated + public static > + List newInstancesFromHeteroList(StaplerRequest req, Object formData, + Collection> 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 Map 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 ig = getOwner().getItemGroup(); if (ig instanceof ModifiableItemGroup) { TopLevelItem item = ((ModifiableItemGroup) 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 extends ItemGroup { * 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 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 @@ *

* 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 @@ *

config.jelly

* {@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. * *

index.jelly

* 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. * *

- * 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 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 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. * *

- * 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 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 void forwardToRss(String title, String url, Collection entries, FeedAdapter adapter, StaplerRequest req, HttpServletResponse rsp) throws IOException, ServletException { + public static void forwardToRss(String title, String url, Collection entries, FeedAdapter 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 void forwardToRss(String title, String url, Collection void forwardToRss(String title, String url, Collection entries, FeedAdapter 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 void forwardToRss(String title, String url, Collection feedAdapter) throws IOException, ServletException { + public static void rss(StaplerRequest2 req, StaplerResponse2 rsp, String title, String url, RunList runList, FeedAdapter feedAdapter) throws IOException, ServletException { final FeedAdapter 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 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 @@ * Invisible Property: * 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}. * *

@@ -78,5 +81,29 @@ public interface ReconfigurableDescribable 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() { *

* 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 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 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 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 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 allByCategoryClass(@NonNull Class - * 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 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 all() { /** * Returns the {@link ViewDescriptor} instances that can be instantiated for the {@link ViewGroup} in the current - * {@link StaplerRequest}. + * {@link StaplerRequest2}. *

- * NOTE: Historically this method is only ever called from a {@link StaplerRequest} - * @return the list of instantiable {@link ViewDescriptor} instances for the current {@link StaplerRequest} + * NOTE: Historically this method is only ever called from a {@link StaplerRequest2} + * @return the list of instantiable {@link ViewDescriptor} instances for the current {@link StaplerRequest2} */ @NonNull public static List allInstantiable() { List 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> 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> getColumnsDescriptors() { * Possible {@link ViewJobFilter} types that can be used with this view. */ public List> 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 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 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 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 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>> filter(Class @@ -82,13 +83,23 @@ T createInstance(Class 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 createInstance(Class type, StaplerRequest req, JSONObject parent, String fieldName) throws FormException { + T createInstance(Class 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 createInstance(Class 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 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 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 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}. * *

* 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> getCaptchaSupportDescriptors() { * *

* 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" * @@ -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 filters = new ArrayList<>(); @@ -639,7 +707,7 @@ protected final List 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 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) { *

  • an implementation specific guarded secret. * */ - 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 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, 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 toMap() { * @param json * Structured form data that includes the data for nested descriptor list. */ - public void rebuild(StaplerRequest req, JSONObject json, List> descriptors) throws FormException, IOException { + public void rebuild(StaplerRequest2 req, JSONObject json, List> descriptors) throws FormException, IOException { List newList = new ArrayList<>(); for (Descriptor d : descriptors) { @@ -193,9 +194,17 @@ public void rebuild(StaplerRequest req, JSONObject json, List> 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> descriptors, String prefix) throws FormException, IOException { @@ -210,10 +219,18 @@ public void rebuild(StaplerRequest req, JSONObject json, List> descriptors, String key) throws FormException, IOException { + public void rebuildHetero(StaplerRequest2 req, JSONObject formData, Collection> 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> 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 } 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.) *

    @@ -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("