Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion .github/DEPENDENCY_DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Initial review: 2026-09-26. Focused API follow-up: 2026-09-27. Dependabot
proposal-policy follow-up: 2026-09-28. Jackson and proposal-routing follow-up:
2026-10-05.
2026-10-05. Maven 3.10.0 wrapper follow-up: 2026-10-11.

PRs [#176](https://github.com/OWASP/owasp-java-encoder/pull/176) and
[#188](https://github.com/OWASP/owasp-java-encoder/pull/188) mixed ordinary build
Expand Down Expand Up @@ -100,6 +100,32 @@ platform brings the same or a newer Jackson, remove the pin, its ignore rules an
the policy assertion together. Enforcer rules do not inspect plugin realms, so a
stale exact pin would silently downgrade Boot's own Jackson.

## Maven 3.10.0 wrapper — 2026-10-11

Accept the Maven **3.10.0** distribution proposed by Dependabot PR
[#235](https://github.com/OWASP/owasp-java-encoder/pull/235). That PR failed only
on the wrapper version assertion and re-committed `mvnw.cmd` with CRLF in the index,
so a separate change completes the checklist above. The wrapper scripts remain
Apache Maven Wrapper 3.3.4 and `mvnw.cmd` is unchanged. The signing profile now
requires exactly 3.10.0. Ordinary builds keep the `[3.9.16,)` minimum.

The ZIP's SHA-256 matches the wrapper properties and the SHA-512 published by
Apache, and its detached signature verifies against a key in Apache Maven's
`KEYS` file. Maven 3.10.0 moves to Resolver 2, breadth-first classpath ordering,
stricter model validation, origin-scoped repository credentials and a Super POM
without plugin management or `release-profile`
([release notes](https://maven.apache.org/docs/3.10.0/release-notes.html)).
This build already declares its plugin versions, `attach-sources`/`attach-javadocs`
executions, encodings and `outputTimestamp`. Effective POMs from 3.9.16 and 3.10.0
differ only in two unused Super POM plugin-management entries (assembly and
release) and, with `performRelease=true`, a redundant `<inherited>true</inherited>`
on the source, Javadoc and deploy plugins. Payload evidence is in the
[Maven 3.10.0 validation](../releases/maven-3.10.0-validation.md).

Credential scoping is the one release-path change this review cannot exercise
without the project's Central token. The first signed `clean deploy` under 3.10.0
should confirm that staging still authenticates before the release relies on it.

## Deferred proposals and reconsideration conditions

| Proposal | Disposition and required evidence before reconsideration |
Expand Down
4 changes: 2 additions & 2 deletions .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.16/apache-maven-3.9.16-bin.zip
distributionSha256Sum=5af3b743dd8b876b5c45da33b676251e5f1687712644abb4ee519ca56e1d89ce
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.10.0/apache-maven-3.10.0-bin.zip
distributionSha256Sum=1f6d9909266510f039f59aa0e13dcd2c66da85f043e56276e41f2918f8bddaff
4 changes: 2 additions & 2 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

Use JDK 17+ and the committed `./mvnw` (`mvnw.cmd` on Windows). The wrapper is
Apache Maven Wrapper 3.3.4's unmodified `only-script` distribution; no wrapper
JAR executes before the download check. It pins Maven 3.9.16 and its SHA-256.
JAR executes before the download check. It pins Maven 3.10.0 and its SHA-256.
The downloaded Maven ZIP was independently compared to the SHA-512 served at
[Apache's distribution site](https://downloads.apache.org/maven/maven-3/3.9.16/binaries/).
[Apache's distribution site](https://downloads.apache.org/maven/maven-3/3.10.0/binaries/).
Wrapper archive SHA-256: `6cb584c2bc907b849a0b931d8266d3ff3214cdd3127115ed4f49fb7176413d36`.
Both bootstrap paths are CI gates, including a deliberately wrong checksum with
an empty wrapper cache. `.mvn/maven.config` requires strict transfer checksums.
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ unchanged. [1.5.0 is available from Central](releases/1.5.0-central-publication.
- Route Jackson plugin-realm pins and Maven wrapper upgrades out of the grouped
Dependabot PR for individual review, and keep Jackson on its 3.1 line until the
Boot parent moves. Security updates remain eligible.
- Build with Maven 3.10.0 through the committed wrapper and require it for signed
releases. Ordinary builds still accept Maven 3.9.16 or later. Library JARs and
module POMs are byte-identical to 3.9.16 builds
([validation](releases/maven-3.10.0-validation.md)).

## 1.5.0 — 2026-09-28 UTC

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ container or downstream dependency combination.

## Building and contributing

Build with JDK 17 and the committed wrapper (Maven 3.9.16); use `mvnw.cmd` on Windows:
Build with JDK 17 and the committed wrapper (Maven 3.10.0); use `mvnw.cmd` on Windows:

```sh
./mvnw clean verify
Expand Down
2 changes: 1 addition & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ existing Maven version.
## Prepare and verify

1. Use a clean checkout, **Eclipse Temurin 17.0.20.1+1** and the committed
wrapper (**Maven 3.9.16**). The signing profile enforces vendor, exact runtime
wrapper (**Maven 3.10.0**). The signing profile enforces vendor, exact runtime
and Maven versions, and a non-SNAPSHOT project version. Ordinary builds allow
JDK 17+; the release path is stricter because javac output changes on newer
JDKs. Record the full Git commit and operating system/architecture. Build with a fresh Maven local repository so
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@
<requireReleaseVersion/>
<requireJavaVendor><includes><include>Eclipse Adoptium</include></includes></requireJavaVendor>
<requireProperty><property>java.runtime.version</property><regex>17\.0\.20\.1\+1</regex></requireProperty>
<requireMavenVersion><version>[3.9.16]</version></requireMavenVersion>
<requireMavenVersion><version>[3.10.0]</version></requireMavenVersion>
</rules></configuration>
</execution>
</executions>
Expand Down
83 changes: 83 additions & 0 deletions releases/maven-3.10.0-validation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Maven 3.10.0 wrapper validation — 2026-10-11

This record supports the toolchain decision in the
[dependency decision record](../.github/DEPENDENCY_DECISIONS.md) and replaces
Dependabot PR [#235](https://github.com/OWASP/owasp-java-encoder/pull/235).
The local checks below ran on macOS 27.0.1 (26A434) arm64. Windows wrapper
bootstrap and the other runtime jobs are checked by required PR CI and are not
claimed here.

## Distribution

`apache-maven-3.10.0-bin.zip` from `downloads.apache.org` and from Maven Central
are byte-identical. Its SHA-512 matches the `.sha512` file Apache publishes, and its
SHA-256 `1f6d9909266510f039f59aa0e13dcd2c66da85f043e56276e41f2918f8bddaff`
matches `distributionSha256Sum`. The detached signature is a good signature from
key `88BE34F94BDB2B5357044E2E3A387D43964143E3` (Tamas Cservenak, made
2026-09-27), checked in an isolated keyring that held only Apache Maven's `KEYS`.
`KEYS` and the ZIP come from the same publisher, so the signature check does not
independently establish publisher identity. The wrapper scripts stay Apache Maven
Wrapper 3.3.4, and `mvnw.cmd` is unchanged and LF in the index.

## Build and wrapper

With 3.10.0, `./mvnw -B -ntp clean verify` passed with Homebrew OpenJDK 17.0.20.1
and a warm local repository: 2,280 unit tests, seven integration tests,
Checkstyle, API and Java 8 signature checks, coverage and both packaged JSP
engines. `python3 scripts/check-wrapper.py` bootstrapped 3.10.0 from an empty
wrapper cache and rejected an incorrect checksum. All 35 policy tests passed.

Resolver 2 fetches `.meta/prefixes.txt` from every remote repository it consults.
The legacy `jvnet-nexus-releases` repository declared by `net.java:jvnet-parent:5`
fails that request on TLS certificate validation. That produces one warning per
build and no failed resolution, because Central serves every artifact.

## Effective POMs

`help:effective-pom` from 3.9.16 and 3.10.0 was compared per module and per
plugin, both by default and with `-DperformRelease=true`. The only differences are
the Super POM's plugin-management entries for the unused assembly and release
plugins and, in release mode, a redundant `<inherited>true</inherited>` on the
source, Javadoc and deploy plugins. That second difference comes from the Super
POM `release-profile` that 3.10.0 removes. Plugin versions, executions, goals,
phases, configuration, properties, dependencies and repositories are unchanged.

## Reproducibility

`scripts/check-reproducible.py` ran with reference Eclipse Temurin 17.0.20.1+1,
whose archive matched its published SHA-256
`196d13ba5f10414bef7f6a05a9b3f00edacb18ebacef2b99485db9e2ee18f0e8`. Each run
used two fresh `git archive` exports with separate empty Maven repositories and
wrapper caches.

- Implementation commit `07b92e07b2444f6c4b6a08f3af44c720a61defd1` (Maven
3.10.0) produced identical copies of all 13 payloads.
- Compared with a build of `main` at
`ee1e2a88893b43c5b494dcc86cb83be4d0d68660` (Maven 3.9.16), all nine JARs and
three module POMs are byte-identical. The parent POM differs only in the
release enforcer's `[3.9.16]` → `[3.10.0]` line.

| Payload | SHA-256 (Maven 3.10.0, both builds) |
| --- | --- |
| `encoder-1.5.1-SNAPSHOT-javadoc.jar` | `1dea3061f4ed78c79672472889a84793c4fb1c48bde1a5766389314aa0a9c176` |
| `encoder-1.5.1-SNAPSHOT-sources.jar` | `6eba5c35b89c9d4a8c457f9e774e29560084b2223b1b6799f29eea166bf17f32` |
| `encoder-1.5.1-SNAPSHOT.jar` | `a10cd22386265d8e631ac7793e8a5eb9645a95ae050ec76d0c916d43b9b6291b` |
| `encoder-1.5.1-SNAPSHOT.pom` | `19791032b4a05bdfc855bf4c476437cda8251784b6aa1ebaba77e783bbaf0f66` |
| `encoder-jakarta-jsp-1.5.1-SNAPSHOT-javadoc.jar` | `498f81f2f618452d9b5e180223a17b8128a26c469ad66223e249a568860d02d1` |
| `encoder-jakarta-jsp-1.5.1-SNAPSHOT-sources.jar` | `69ff116828ee2db0223b4d509a9486b653a3984d78787af4ebac8bd3cc4a1b77` |
| `encoder-jakarta-jsp-1.5.1-SNAPSHOT.jar` | `463131114b7d34e2f4627918ecba0d18b53ac9b274945062d3fe04c2ab589836` |
| `encoder-jakarta-jsp-1.5.1-SNAPSHOT.pom` | `ddbfb208fabcc84ceb9cef0ce0e62ea55987eee57d73f6c0de9c192ec154538d` |
| `encoder-jsp-1.5.1-SNAPSHOT-javadoc.jar` | `77b56a2071429e122967647f4512098010bab6c3043b6b30ccf58b36192a1718` |
| `encoder-jsp-1.5.1-SNAPSHOT-sources.jar` | `94193083573ef1752c12284f37e5cf59a5901ce5d7cd80032dc915afe7deccb7` |
| `encoder-jsp-1.5.1-SNAPSHOT.jar` | `fb8d852f656f408697245a9d0aae19035057dbdcf5742d25cf3994c990549c2c` |
| `encoder-jsp-1.5.1-SNAPSHOT.pom` | `0b35d49c56a8c8a6746c09146ccd79a6be2ed10f6b5cc8da2e024f77396f3575` |
| `encoder-parent-1.5.1-SNAPSHOT.pom` | `061a61e632b989732a7ba2db1cc9383e75deaedcf182ff42b15ab349e2052060` |

Later documentation-only commits on this change do not alter artifact inputs.

## Not exercised

No signing, Central Portal staging, tag or release operation ran. Maven 3.10.0
scopes repository credentials to their origins. The first signed `clean deploy`
under 3.10.0 should confirm that Central staging still authenticates with the
`central` server entry.
2 changes: 1 addition & 1 deletion scripts/check-reproducible.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def main():
raise ValueError('Expected thirteen release payload files')
results.append(hashes)
differences = [name for name in results[0] if results[0][name] != results[1][name]]
report = {'commit': commit, 'java': props, 'maven': '3.9.16',
report = {'commit': commit, 'java': props, 'maven': '3.10.0',
'hashes': results, 'differences': differences}
(directory / 'comparison.json').write_text(json.dumps(report, indent=2) + '\n')
require_identical(results[0], results[1])
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def bootstrap(directory, bad_hash):
if result.returncode == 0 or 'SHA-256' not in result.stdout:
raise ValueError('Checksum rejection did not work: ' + result.stdout)
else:
if result.returncode != 0 or 'Apache Maven 3.9.16' not in result.stdout:
if result.returncode != 0 or 'Apache Maven 3.10.0' not in result.stdout:
raise ValueError('Wrapper bootstrap failed: ' + result.stdout)
print(('Rejected incorrect checksum' if bad_hash else 'Verified bootstrap'), WRAPPER)

Expand Down
Loading