Merge branch 'apache:2.3-gae' into make-build-reproducible
diff --git a/build.gradle.kts b/build.gradle.kts
index 7d39c9b..bc8cad3 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -37,6 +37,21 @@
     options.encoding = "UTF-8"
 }
 
+tasks.withType<AbstractArchiveTask>().configureEach {
+
+  if (archiveFileName.get().endsWith(".jar")) {  
+    // make contents of freemarker.jar reproducible
+    isPreserveFileTimestamps = false
+    isReproducibleFileOrder = true
+    filePermissions {
+        unix("rw-r--r--")
+    }
+    dirPermissions {
+        unix("rwxr-xr-x")
+    }
+  }
+}
+
 freemarkerRoot {
     configureSourceSet(SourceSet.MAIN_SOURCE_SET_NAME) { enableTests() }
     configureSourceSet("javaxServlet") { enableTests() }
diff --git a/freemarker-core/src/main/resource-templates/freemarker/version.properties b/freemarker-core/src/main/resource-templates/freemarker/version.properties
index 95cd4ef..f7803f0 100644
--- a/freemarker-core/src/main/resource-templates/freemarker/version.properties
+++ b/freemarker-core/src/main/resource-templates/freemarker/version.properties
@@ -26,8 +26,12 @@
 #   Qualifier :: = NightlyQualifier
 #                  |
 #                  ( ('pre'|'rc') twoDigitPositiveInteger ('-' NightlyQualifier)? )
-#   NightlyQualifier :: = 'nightly_@timestampInVersion@'
-#
+#   NightlyQualifier :: = 'nightly_[timestampInVersion]'
+# 
+# Note: In comments in this file we sourround timestampInVersion with 
+# square brackets instead of @@, to avoid replacement with a timestamp
+# during build which is required for reproducible builds.
+# 
 # This format is compatible both with Maven and JSR 277, and it must
 # remain so. Stable versions must not have a qualifier.
 # Note that qualifiers are compared with String.compareTo,
@@ -37,11 +41,11 @@
 #   Version number        Means
 #   3.0.0                 3.0.0 stable release
 #   3.3.12                3.3.12 stable release
-#   3.3.13-nightly_@timestampInVersion@
+#   3.3.13-nightly_[timestampInVersion]
 #                         Modified version after 3.3.12, which will
 #                         become to 3.3.13 one day.
 #   3.4.0-pre03           The 3rd preview of version 3.4.0
-#   3.4.0-pre04-nightly_@timestampInVersion@
+#   3.4.0-pre04-nightly_[timestampInVersion]
 #                         Unreleased nightly version of the yet unfinished
 #                         3.4.0-pre04.
 #   3.4.0-rc01            1st release candidate of 3.4.0
@@ -58,7 +62,7 @@
 #   compatibility violations are allowed, but still should be avoided.
 version=2.3.33-nightly_@timestampInVersion@
 # This exists as for Maven we use "-SNAPSHOT" for nightly releases,
-# and no _nightly_@timestampInVersion@. For final releases it's the
+# and no _nightly_[timestampInVersion]. For final releases it's the
 # same as "version".
 mavenVersion=2.3.33-SNAPSHOT
 
@@ -72,7 +76,7 @@
 #   2.4.0.stable
 #   2.4.0.rc01
 #   2.4.0.pre01
-#   2.4.0.nightly_@timestampInVersion@
+#   2.4.0.nightly_[timestampInVersion]
 versionForOSGi=2.3.33.nightly_@timestampInVersion@
 
 # Version string that conforms to legacy MF
@@ -95,7 +99,10 @@
 versionForMf=2.3.32.97
 
 # The date of the build.
-# This should be automatically filled by the building tool (Ant).
-buildTimestamp=@timestampNice@
+# For reproducible builds we set it to a fixed date.
+# Although this is rather meaningless now
+# it is kept for backwards compatibility (tests and Version.java)
+# until decided to drop it completely
+buildTimestamp=1980-02-01T00:00:00Z
 
 isGAECompliant=true
diff --git a/osgi.bnd b/osgi.bnd
index 9cbe266..cac520e 100644
--- a/osgi.bnd
+++ b/osgi.bnd
@@ -51,6 +51,11 @@
 # "Compiling against more than is required"
 Bundle-RequiredExecutionEnvironment: JavaSE-16, JavaSE-15, JavaSE-14, JavaSE-13, JavaSE-12, JavaSE-11, JavaSE-10, JavaSE-9, JavaSE-1.8
 
+# for reproducible build (see https://bnd.bndtools.org/instructions/reproducible.html 
+# and https://bnd.bndtools.org/instructions/noextraheaders.html)
+-reproducible: true
+-noextraheaders: true
+
 # Non-OSGi meta:
 Main-Class: freemarker.core.CommandLine
 Extension-name: FreeMarker
diff --git a/settings.gradle.kts b/settings.gradle.kts
index eb1de9c..e74adfb 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -21,6 +21,10 @@
 
 apply(from = rootDir.toPath().resolve("gradle").resolve("repositories.gradle.kts"))
 
+plugins {
+    id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
+}
+
 dependencyResolutionManagement {
     versionCatalogs {
         create("libs") {