This is an automated email from the ASF dual-hosted git repository.

mridulpathak pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 17bbbc662c Improved: Upgrade Gradle to 9.8.2 and CodeNarc to 4.0.0 
(OFBIZ-13208)
17bbbc662c is described below

commit 17bbbc662cec6ee7c908d90201d874e77e8e52f8
Author: Mridul Pathak <[email protected]>
AuthorDate: Fri Oct 23 13:16:42 2026 +0530

    Improved: Upgrade Gradle to 9.8.2 and CodeNarc to 4.0.0 (OFBIZ-13208)
    
    - Bump the Gradle wrapper from 8.14.6 to 9.8.2 and regenerate gradlew and 
gradlew.bat with the 9.8.2 wrapper task.
    - Import groovy.xml.XmlParser in build.gradle and common.gradle, since 
Gradle 9 embeds Groovy 4, which no longer provides groovy.util.XmlParser.
    - Run external processes from task actions through an injected 
ExecOperations (terminateOfbiz, gitInfoFooter, generateDBPassword, 
generateEncryptedSecret, reEncryptAllSecrets and pullPlugin), since Gradle 9 
removed Project.exec and Project.javaexec.
    - Read git output at configuration time through providers.exec instead of 
String.execute(), which Gradle 9.8 deprecates at configuration time.
    - Collect the cleanAll dependencies from tasks.names, since 
DomainObjectCollection.findAll(Closure) is deprecated.
    - Bump CodeNarc from 3.7.0-groovy-4.0 to 4.0.0, which is built on Groovy 5 
and runs on Java 17. The plain version also lets Dependabot propose future 
CodeNarc updates, which it skipped while the current version carried the 
-groovy-4.0 suffix.
    
    The Java source and target compatibility stay at 17.
---
 build.gradle                             | 51 ++++++++++++++-----
 common.gradle                            |  1 +
 gradle/libs.versions.toml                |  5 +-
 gradle/wrapper/gradle-wrapper.properties |  4 +-
 gradlew                                  | 11 ++--
 gradlew.bat                              | 86 +++++++++++++++++++-------------
 6 files changed, 101 insertions(+), 57 deletions(-)

diff --git a/build.gradle b/build.gradle
index 88a02e105a..5200d349d0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -17,9 +17,12 @@
  * under the License.
  */
 import groovy.xml.MarkupBuilder
+import groovy.xml.XmlParser
 import groovy.xml.XmlSlurper
+import javax.inject.Inject
 import org.apache.tools.ant.filters.ReplaceTokens
 import org.asciidoctor.gradle.jvm.AsciidoctorTask
+import org.gradle.process.ExecOperations
 
 /* ========================================================
  * Project setup
@@ -242,7 +245,16 @@ processResources {
 
 // Only used for release branches
 def getCurrentGitBranch() {
-    return "git branch --show-current".execute().text.trim()
+    return gitOutput('branch', '--show-current')
+}
+
+// Returns the trimmed standard output of a git command, or an empty string if 
it fails
+// (e.g. when building from a source release that is not a git checkout).
+def gitOutput(String... gitArgs) {
+    return providers.exec {
+        commandLine(['git', '-C', rootDir.path] + gitArgs.toList())
+        ignoreExitValue = true
+    }.standardOutput.asText.get().trim()
 }
 
 // defines the footer files for git info
@@ -387,7 +399,7 @@ checkstyle {
 gitHooks {
     // Resolve the real .git dir so this also works from a linked worktree,
     // where "$rootDir/.git" (the plugin's default) is a gitlink file, not a 
directory.
-    def gitCommonDir = "git -C ${rootDir} rev-parse 
--git-common-dir".execute().text.trim()
+    def gitCommonDir = gitOutput('rev-parse', '--git-common-dir')
     hooksDirectory.set(new File(rootDir, 
gitCommonDir).toPath().resolve('hooks').toFile())
     hooks = ['pre-push': 'checkstyleMain checkstyleTest codenarcMain 
codenarcTest']
 }
@@ -703,20 +715,28 @@ task testIntegration(group: ofbizServer) {
     description = 'Run OFBiz integration tests; You must run loadAll before 
running this task'
 }
 
+// Gives tasks access to ExecOperations, which replaces Project.exec and 
Project.javaexec
+// (removed in Gradle 9) for running external processes from a task action.
+interface InjectedExecOps {
+    @Inject
+    ExecOperations getExecOps()
+}
+
 task terminateOfbiz(group: ofbizServer,
     description: 'Force termination of any running OFBiz servers, only use if 
\"--shutdown\" command fails') {
+    def execOps = objects.newInstance(InjectedExecOps).execOps
     doLast {
         if (os.contains('windows')) {
             Runtime.getRuntime().exec("wmic process where \"CommandLine Like 
\'%org.apache.ofbiz.base.start.Start%\'\" Call Terminate")
         } else {
             def processOutput = new ByteArrayOutputStream()
-            exec {
+            execOps.exec {
                 commandLine 'ps', 'ax'
                 standardOutput = processOutput
             }
             processOutput.toString().split(System.lineSeparator()).each { line 
->
                 if (line ==~ /.*org\.apache\.ofbiz\.base\.start\.Start.*/) {
-                    exec { commandLine 'kill', '-9', line.tokenize().first() }
+                    execOps.exec { commandLine 'kill', '-9', 
line.tokenize().first() }
                 }
             }
         }
@@ -1000,6 +1020,7 @@ task generateAllPluginsDocumentation(group: docsGroup,
 // (applied above) - kept out of this file since they're self-contained and 
sizable.
 
 task gitInfoFooter(group: sysadminGroup, description: 'Update the Git 
Branch-revision info in the footer if Git is used') {
+    def execOps = objects.newInstance(InjectedExecOps).execOps
     doLast {
         def branch
         def revision
@@ -1012,13 +1033,13 @@ task gitInfoFooter(group: sysadminGroup, description: 
'Update the Git Branch-rev
         }
 
         def branchOutput = new ByteArrayOutputStream()
-        exec {
+        execOps.exec {
             commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
             standardOutput = branchOutput
         }
         branch = branchOutput.toString()
         def revisionOutput = new ByteArrayOutputStream()
-        exec {
+        execOps.exec {
             commandLine 'git', 'rev-parse', 'HEAD'
             standardOutput = revisionOutput
         }
@@ -1080,13 +1101,14 @@ task generateDBPassword(group: sysadminGroup,
                 + 'If -PdbPassword is omitted, you will be prompted for it via 
masked console input '
                 + '(run with --no-daemon --console=plain). The master key is 
taken from -PmasterKey, '
                 + 'falling back to the OFBIZ_MASTER_KEY environment 
variable.') {
+    def execOps = objects.newInstance(InjectedExecOps).execOps
     doLast {
         def secret = project.hasProperty('dbPassword') ? 
project.property('dbPassword')
                 : promptSecret('Enter database password: ')
         def masterKey = project.hasProperty('masterKey') ? 
project.property('masterKey') : System.getenv('OFBIZ_MASTER_KEY')
         if (masterKey) {
             def output = new java.io.ByteArrayOutputStream()
-            javaexec {
+            execOps.javaexec {
                 classpath = sourceSets.main.runtimeClasspath
                 mainClass = 'org.apache.ofbiz.base.crypto.ConfigCryptoUtil'
                 args masterKey, secret
@@ -1112,6 +1134,7 @@ task generateEncryptedSecret(group: sysadminGroup,
                 + 'Any of -PsecretPassword/-PlookupKey/-PmasterKey may be 
omitted to be prompted for '
                 + 'interactively (run with --no-daemon --console=plain); the 
master key also falls back '
                 + 'to the OFBIZ_MASTER_KEY environment variable.') {
+    def execOps = objects.newInstance(InjectedExecOps).execOps
     doLast {
         def secret = project.hasProperty('secretPassword') ? 
project.property('secretPassword')
                 : promptSecret('Enter secret value: ')
@@ -1129,7 +1152,7 @@ task generateEncryptedSecret(group: sysadminGroup,
         }
 
         def output = new java.io.ByteArrayOutputStream()
-        javaexec {
+        execOps.javaexec {
             classpath = sourceSets.main.runtimeClasspath
             mainClass = 'org.apache.ofbiz.base.crypto.ConfigCryptoUtil'
             args masterKey, secret
@@ -1147,13 +1170,14 @@ task reEncryptAllSecrets(group: sysadminGroup,
                 + 'Keys may also be supplied via the OFBIZ_OLD_MASTER_KEY / 
OFBIZ_NEW_MASTER_KEY env vars '
                 + 'or entered interactively (run with --no-daemon 
--console=plain).') {
     dependsOn classes
+    def execOps = objects.newInstance(InjectedExecOps).execOps
     doLast {
         def oldKey = project.hasProperty('oldMasterKey') ? 
project.property('oldMasterKey')
                 : (System.getenv('OFBIZ_OLD_MASTER_KEY') ?: 
promptSecret('Enter OLD master key: '))
         def newKey = project.hasProperty('newMasterKey') ? 
project.property('newMasterKey')
                 : (System.getenv('OFBIZ_NEW_MASTER_KEY') ?: 
promptSecret('Enter NEW master key: '))
         def dryRun = project.hasProperty('dryRun') ? 
project.property('dryRun') : 'false'
-        javaexec {
+        execOps.javaexec {
             classpath = sourceSets.main.runtimeClasspath
             mainClass = 'org.apache.ofbiz.base.crypto.ReEncryptSecretsMain'
             args oldKey, newKey, dryRun
@@ -1363,6 +1387,7 @@ task pushPlugin(group: ofbizPlugin, description: 'push an 
existing plugin to loc
 }
 
 task pullPlugin(group: ofbizPlugin, description: 'Download and install a 
plugin with all dependencies') {
+    def execOps = objects.newInstance(InjectedExecOps).execOps
     doLast {
         if (!project.hasProperty('dependencyId')) {
             throw new GradleException('You must pass the dependencyId of the 
plugin')
@@ -1400,7 +1425,7 @@ task pullPlugin(group: ofbizPlugin, description: 
'Download and install a plugin
                 from zipTree(pluginArchive)
                 into "${pluginsDir}/${pluginId}"
             }
-            gradlewSubprocess(['installPlugin', "-PpluginId=${pluginId}"])
+            gradlewSubprocess(execOps, ['installPlugin', 
"-PpluginId=${pluginId}"])
         }
     }
 }
@@ -1453,7 +1478,7 @@ task cleanFooterFiles(group: cleanupGroup, description: 
'clean generated footer
  * declaration is important because it means that it will automatically
  * run whenever the task cleanAll executes (dependency matched by regex)
  */
-def cleanTasks = tasks.findAll { it.name ==~ /^clean.+/ }
+def cleanTasks = tasks.names.findAll { it ==~ /^clean.+/ }
 task cleanAll(group: cleanupGroup, dependsOn: [cleanTasks, clean]) {
     description = 'Execute all cleaning tasks.'
 }
@@ -1588,8 +1613,8 @@ def taskExistsInproject(fullyQualifiedProject, taskName) {
         .anyMatch { it.name == taskName }
 }
 
-def gradlewSubprocess(commandList) {
-    exec { commandLine(gradlew, '--no-daemon', *commandList) }
+def gradlewSubprocess(ExecOperations execOps, commandList) {
+    execOps.exec { commandLine(gradlew, '--no-daemon', *commandList) }
 }
 
 
diff --git a/common.gradle b/common.gradle
index 3c7db5020d..17aaa761b1 100644
--- a/common.gradle
+++ b/common.gradle
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import groovy.xml.XmlParser
 import java.util.stream.Stream
 import java.util.stream.Collectors
 
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 2c3de3e0c6..ae5d61e876 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -98,8 +98,9 @@ barcode4j = "2.1"
 avalon-framework-impl = "4.3.1"
 h2 = "2.5.252"
 geronimo-jaxrpc-spec = "2.1"
-# Specify last codenarc version for java 17 compliance.
-codenarc = "3.7.0-groovy-4.0"
+# Keep the plain CodeNarc version (built for Groovy 5), not a "-groovy-x.y" 
variant: Dependabot
+# only proposes versions carrying the same suffix as the current one.
+codenarc = "4.0.0"
 # CVE-2024-21742
 apache-mime4j-core = "0.8.15"
 # CVE-2024-29857, CVE-2024-30171, CVE-2024-30172, CVE-2024-34447
diff --git a/gradle/wrapper/gradle-wrapper.properties 
b/gradle/wrapper/gradle-wrapper.properties
index d3f0219867..91c4fc64aa 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,9 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.6-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.2-bin.zip
 networkTimeout=10000
+retries=0
+retryBackOffMs=500
 validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 23d15a9367..249efbb032 100755
--- a/gradlew
+++ b/gradlew
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright © 2015-2021 the original authors.
+# Copyright © 2015 the original authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
 
 ##############################################################################
 #
-#   Gradle start up script for POSIX generated by Gradle.
+#   gradlew start up script for POSIX generated by Gradle.
 #
 #   Important for running:
 #
@@ -29,7 +29,7 @@
 #       bash, then to run this script, type that shell name before the whole
 #       command line, like:
 #
-#           ksh Gradle
+#           ksh gradlew
 #
 #       Busybox and similar reduced shells will NOT work, because this script
 #       requires all of these POSIX shell features:
@@ -57,7 +57,7 @@
 #       Darwin, MinGW, and NonStop.
 #
 #   (3) This script is generated from the Groovy template
-#       
https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       
https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
 #       within the Gradle project.
 #
 #       You can find Gradle at https://github.com/gradle/gradle/.
@@ -114,7 +114,6 @@ case "$( uname )" in                #(
   NONSTOP* )        nonstop=true ;;
 esac
 
-CLASSPATH="\\\"\\\""
 
 
 # Determine the Java command to use to start the JVM.
@@ -172,7 +171,6 @@ fi
 # For Cygwin or MSYS, switch paths to Windows format before running java
 if "$cygwin" || "$msys" ; then
     APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
-    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
 
     JAVACMD=$( cygpath --unix "$JAVACMD" )
 
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
 
 set -- \
         "-Dorg.gradle.appname=$APP_BASE_NAME" \
-        -classpath "$CLASSPATH" \
         -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
         "$@"
 
diff --git a/gradlew.bat b/gradlew.bat
index db3a6ac207..3185a43f78 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -19,12 +19,39 @@
 @if "%DEBUG%"=="" @echo off
 @rem ##########################################################################
 @rem
-@rem  Gradle startup script for Windows
+@rem  gradlew startup script for Windows
 @rem
 @rem ##########################################################################
 
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
+@rem Set local scope for the variables, and ensure extensions are enabled
+setlocal EnableExtensions
+
+@rem Catch executions from older scripts and ensure they exit cleanly.
+@rem This can be removed once we can be reasonably confident that few people
+@rem will be migrating directly to this new wrapper.
+goto afterSafetyNet
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+goto exitWithErrorLevel
+:afterSafetyNet
 
 set DIRNAME=%~dp0
 if "%DIRNAME%"=="" set DIRNAME=.
@@ -45,13 +72,14 @@ set JAVA_EXE=java.exe
 %JAVA_EXE% -version >NUL 2>&1
 if %ERRORLEVEL% equ 0 goto execute
 
-echo. 1>&2
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your 
PATH. 1>&2
-echo. 1>&2
-echo Please set the JAVA_HOME variable in your environment to match the 1>&2
-echo location of your Java installation. 1>&2
+1>&2 echo.
+1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in 
your PATH.
+1>&2 echo.
+1>&2 echo Please set the JAVA_HOME variable in your environment to match the
+1>&2 echo location of your Java installation.
 
-goto fail
+"%COMSPEC%" /c exit 1
+goto exitWithErrorLevel
 
 :findJavaFromJavaHome
 set JAVA_HOME=%JAVA_HOME:"=%
@@ -59,36 +87,26 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 
 if exist "%JAVA_EXE%" goto execute
 
-echo. 1>&2
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
-echo. 1>&2
-echo Please set the JAVA_HOME variable in your environment to match the 1>&2
-echo location of your Java installation. 1>&2
+1>&2 echo.
+1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+1>&2 echo.
+1>&2 echo Please set the JAVA_HOME variable in your environment to match the
+1>&2 echo location of your Java installation.
 
-goto fail
+"%COMSPEC%" /c exit 1
+goto exitWithErrorLevel
 
 :execute
 @rem Setup the command line
 
-set CLASSPATH=
 
 
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% 
"-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar 
"%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
+@rem Execute gradlew
+@rem endlocal doesn't take effect until after the line is parsed and variables 
are expanded
+@rem which allows us to clear the local environment before executing the java 
command
+endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% 
"-Dorg.gradle.appname=%APP_BASE_NAME%" -jar 
"%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel & 
goto exitWithErrorLevel
 
-:end
-@rem End local scope for the variables with windows NT shell
-if %ERRORLEVEL% equ 0 goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code 
instead of
-rem the _cmd.exe /c_ return code!
-set EXIT_CODE=%ERRORLEVEL%
-if %EXIT_CODE% equ 0 set EXIT_CODE=1
-if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
-exit /b %EXIT_CODE%
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@rem This label must not be changed. We rely on old scripts being able to jump 
to this point.
+:exitWithErrorLevel
+@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
+"%COMSPEC%" /c exit %ERRORLEVEL%

Reply via email to