diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f09f812..504219d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -34,12 +34,22 @@ jobs:
java-version: ${{ matrix.java }}
cache: maven
+ - name: Set up Gradle
+ if: matrix.java == '17'
+ uses: gradle/actions/setup-gradle@v6
+ with:
+ gradle-version: "9.5.1"
+
- run: ./mvnw --batch-mode --no-transfer-progress verify
- - name: Verify clean consumer
+ - name: Verify clean Maven consumers
if: matrix.java == '17'
run: ./scripts/verify-consumer.sh
+ - name: Verify clean Gradle consumer
+ if: matrix.java == '17'
+ run: ./scripts/verify-gradle-consumer.sh
+
- name: Run shared conformance harness
run: ./scripts/run-conformance.sh
env:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 7422859..19fc4e9 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -77,6 +77,11 @@ jobs:
server-username-env-var: CENTRAL_USERNAME
server-password-env-var: CENTRAL_PASSWORD
+ - name: Set up Gradle
+ uses: gradle/actions/setup-gradle@v6
+ with:
+ gradle-version: "9.5.1"
+
- name: Set up pnpm
uses: pnpm/action-setup@v6
with:
@@ -103,9 +108,15 @@ jobs:
env:
ODP_NODE_DIR: .conformance/odp-node
- - name: Verify clean consumer
+ - name: Verify clean Maven consumers
run: ./scripts/verify-consumer.sh
+ - name: Verify clean Gradle consumer
+ run: ./scripts/verify-gradle-consumer.sh
+
+ - name: Inspect release artifacts
+ run: ./scripts/verify-release-artifacts.sh
+
- name: Publish Maven artifacts
if: steps.release.outputs.published != 'true'
run: ./mvnw --batch-mode --no-transfer-progress -Prelease -Dgpg.signer=bc deploy
@@ -120,15 +131,18 @@ jobs:
with:
subject-path: |
odp-core/target/odp-core-${{ steps.release.outputs.version }}*.jar
+ odp-json-jackson2/target/odp-json-jackson2-${{ steps.release.outputs.version }}*.jar
+ odp-json-jackson3/target/odp-json-jackson3-${{ steps.release.outputs.version }}*.jar
odp-directory/target/odp-directory-${{ steps.release.outputs.version }}*.jar
odp-agent/target/odp-agent-${{ steps.release.outputs.version }}*.jar
odp-service/target/odp-service-${{ steps.release.outputs.version }}*.jar
+ odp-bom/pom.xml
- name: Wait for Maven Central availability
env:
VERSION: ${{ steps.release.outputs.version }}
run: |
- artifact="https://repo1.maven.org/maven2/org/offeringprotocol/odp-core/$VERSION/odp-core-$VERSION.pom"
+ artifact="https://repo1.maven.org/maven2/org/offeringprotocol/odp-bom/$VERSION/odp-bom-$VERSION.pom"
for attempt in {1..60}; do
if curl --fail --silent --show-error --head "$artifact" >/dev/null; then
exit 0
@@ -138,11 +152,16 @@ jobs:
echo "Maven Central did not expose $artifact within 10 minutes." >&2
exit 1
- - name: Verify Maven Central consumer
+ - name: Verify Maven Central consumers
run: ./scripts/verify-consumer.sh
env:
ODP_CONSUMER_SOURCE: central
+ - name: Verify Maven Central Gradle consumer
+ run: ./scripts/verify-gradle-consumer.sh
+ env:
+ ODP_CONSUMER_SOURCE: central
+
- name: Create release tag
env:
TAG: ${{ steps.release.outputs.tag }}
@@ -161,6 +180,7 @@ jobs:
.conformance/reports/agent.json#odp-java-agent-conformance.json
.conformance/reports/service.json#odp-java-service-conformance.json
--generate-notes
+ --notes "Published artifacts include org.offeringprotocol:odp-bom for Maven and Gradle dependency alignment."
--title "ODP Java ${{ steps.release.outputs.tag }}"
--verify-tag
env:
diff --git a/.gitignore b/.gitignore
index 18c8197..1234276 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
.DS_Store
.conformance/
+.gradle/
.idea/
.project
.classpath
@@ -7,4 +8,5 @@
.vscode/
target/
**/target/
+**/build/
*.iml
diff --git a/README.md b/README.md
index a1d4837..28eb528 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,7 @@ Choose the module that matches the role your application implements:
| An ODP Service | [`odp-service`](./odp-service/README.md) | Service document, fixed routes, static or storage-backed operations |
| A directory-only integration | [`odp-directory`](./odp-directory/README.md) | Canonical production or sandbox Service search |
| An ODP validator or protocol implementation | [`odp-core`](./odp-core/README.md) | Models, bundled schemas, identity, references, and pagination |
+| Compatible ODP dependency versions | [`odp-bom`](./odp-bom/README.md) | Version alignment without a parent-POM relationship |
Every application also selects one JSON provider: `odp-json-jackson2` for applications using
Jackson 2, or `odp-json-jackson3` for applications using Jackson 3. The role modules do not force a
@@ -39,18 +40,32 @@ directory behavior.
## Installation
+Import `odp-bom` once to keep every explicitly selected ODP module on a compatible release:
+
+```xml
+
+
+
+ org.offeringprotocol
+ odp-bom
+ 0.2.1
+ pom
+ import
+
+
+
+```
+
For an Agent application:
```xml
org.offeringprotocol
odp-agent
- 0.2.0
org.offeringprotocol
odp-json-jackson2
- 0.2.0
```
@@ -60,22 +75,28 @@ For a Service integration:
org.offeringprotocol
odp-service
- 0.2.0
org.offeringprotocol
odp-json-jackson2
- 0.2.0
```
Gradle uses the same coordinates:
```kotlin
-implementation("org.offeringprotocol:odp-agent:0.2.0")
-implementation("org.offeringprotocol:odp-json-jackson2:0.2.0")
+implementation(platform("org.offeringprotocol:odp-bom:0.2.1"))
+implementation("org.offeringprotocol:odp-agent")
+implementation("org.offeringprotocol:odp-json-jackson2")
```
+The BOM manages ODP module versions only. It does not add modules, select a Jackson generation, or
+manage Jackson itself. Applications select the role modules they use and exactly one JSON provider.
+
+Consumers that prefer direct versions can omit the BOM and specify the same ODP release on each
+dependency, for example `org.offeringprotocol:odp-agent:0.2.1` and
+`org.offeringprotocol:odp-json-jackson2:0.2.1`.
+
Replace `odp-json-jackson2` with `odp-json-jackson3` when the application uses Jackson 3. Exactly
one provider must be present at runtime; `OdpJson` discovers it through Java `ServiceLoader`.
Maven resolves the required Core and Directory modules transitively. Applications should not add
@@ -195,6 +216,7 @@ Verify the published module boundaries from an isolated consumer project with:
```sh
./scripts/verify-consumer.sh
+./scripts/verify-gradle-consumer.sh
```
Format Java sources with:
diff --git a/examples/pom.xml b/examples/pom.xml
index d627ee8..20e8f3e 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -7,7 +7,7 @@
org.offeringprotocol
odp-java
- 0.2.0
+ 0.2.1
odp-examples
diff --git a/odp-agent/README.md b/odp-agent/README.md
index 4a9296a..ccca78e 100644
--- a/odp-agent/README.md
+++ b/odp-agent/README.md
@@ -9,23 +9,8 @@ capability checks, Collections, Offerings, localization, and continuations.
## Install
-```xml
-
- org.offeringprotocol
- odp-agent
- 0.2.0
-
-
- org.offeringprotocol
- odp-json-jackson2
- 0.2.0
-
-```
-
-```kotlin
-implementation("org.offeringprotocol:odp-agent:0.2.0")
-implementation("org.offeringprotocol:odp-json-jackson2:0.2.0")
-```
+Follow the canonical [installation guide](../README.md#installation), selecting `odp-agent` and
+exactly one JSON provider.
The Agent module brings in `odp-directory` and `odp-core` transitively. Replace
`odp-json-jackson2` with `odp-json-jackson3` in a Jackson 3 application. Exactly one provider must
diff --git a/odp-agent/pom.xml b/odp-agent/pom.xml
index 4e8e446..00fb6d2 100644
--- a/odp-agent/pom.xml
+++ b/odp-agent/pom.xml
@@ -7,7 +7,7 @@
org.offeringprotocol
odp-java
- 0.2.0
+ 0.2.1
odp-agent
diff --git a/odp-bom/README.md b/odp-bom/README.md
new file mode 100644
index 0000000..dd9934c
--- /dev/null
+++ b/odp-bom/README.md
@@ -0,0 +1,12 @@
+# ODP Bill of Materials
+
+`odp-bom` manages compatible versions for the public ODP Java modules. It contains no runtime code
+and does not add any dependency to an application. Importing it ensures that explicitly selected
+ODP modules use one release version.
+
+Every application that uses ODP JSON must explicitly depend on exactly one of
+`odp-json-jackson2` or `odp-json-jackson3`. The BOM supplies that module's version after the
+application selects it; the BOM does not select a Jackson generation or add Jackson itself.
+
+See the root [installation guide](../README.md#installation) for Maven and Gradle usage and the
+supported direct-version alternative.
diff --git a/odp-bom/pom.xml b/odp-bom/pom.xml
new file mode 100644
index 0000000..b703810
--- /dev/null
+++ b/odp-bom/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+
+ org.offeringprotocol
+ odp-java
+ 0.2.1
+
+
+ odp-bom
+ pom
+ ODP Bill of Materials
+ Compatible versions for the official ODP Java modules.
+
+
+
+
+ ${project.groupId}
+ odp-core
+ ${project.version}
+
+
+ ${project.groupId}
+ odp-json-jackson2
+ ${project.version}
+
+
+ ${project.groupId}
+ odp-json-jackson3
+ ${project.version}
+
+
+ ${project.groupId}
+ odp-directory
+ ${project.version}
+
+
+ ${project.groupId}
+ odp-agent
+ ${project.version}
+
+
+ ${project.groupId}
+ odp-service
+ ${project.version}
+
+
+
+
diff --git a/odp-core/README.md b/odp-core/README.md
index 874cbaa..d6a091f 100644
--- a/odp-core/README.md
+++ b/odp-core/README.md
@@ -9,23 +9,8 @@ ODP models without Agent or Service HTTP behavior.
## Install
-```xml
-
- org.offeringprotocol
- odp-core
- 0.2.0
-
-
- org.offeringprotocol
- odp-json-jackson2
- 0.2.0
-
-```
-
-```kotlin
-implementation("org.offeringprotocol:odp-core:0.2.0")
-implementation("org.offeringprotocol:odp-json-jackson2:0.2.0")
-```
+Follow the canonical [installation guide](../README.md#installation), selecting `odp-core` and
+exactly one JSON provider.
Use `odp-json-jackson2` with Jackson 2 applications or replace it with `odp-json-jackson3` for
Jackson 3. Add exactly one provider. `OdpJson` discovers the provider through Java `ServiceLoader`
diff --git a/odp-core/pom.xml b/odp-core/pom.xml
index 5350655..b7e6bac 100644
--- a/odp-core/pom.xml
+++ b/odp-core/pom.xml
@@ -7,7 +7,7 @@
org.offeringprotocol
odp-java
- 0.2.0
+ 0.2.1
odp-core
@@ -22,6 +22,7 @@
com.fasterxml.jackson.core
jackson-annotations
+ ${jackson-annotations.version}
diff --git a/odp-directory/README.md b/odp-directory/README.md
index 59c371d..55bccbd 100644
--- a/odp-directory/README.md
+++ b/odp-directory/README.md
@@ -9,23 +9,8 @@ Service's Collections and Offerings with [`odp-agent`](../odp-agent/README.md).
## Install
-```xml
-
- org.offeringprotocol
- odp-directory
- 0.2.0
-
-
- org.offeringprotocol
- odp-json-jackson2
- 0.2.0
-
-```
-
-```kotlin
-implementation("org.offeringprotocol:odp-directory:0.2.0")
-implementation("org.offeringprotocol:odp-json-jackson2:0.2.0")
-```
+Follow the canonical [installation guide](../README.md#installation), selecting `odp-directory`
+and exactly one JSON provider.
Replace `odp-json-jackson2` with `odp-json-jackson3` in a Jackson 3 application. Add exactly one
provider; it is discovered automatically at runtime.
diff --git a/odp-directory/pom.xml b/odp-directory/pom.xml
index 96dffad..1f6534b 100644
--- a/odp-directory/pom.xml
+++ b/odp-directory/pom.xml
@@ -7,7 +7,7 @@
org.offeringprotocol
odp-java
- 0.2.0
+ 0.2.1
odp-directory
diff --git a/odp-json-jackson2/README.md b/odp-json-jackson2/README.md
index 839bff6..b830fc8 100644
--- a/odp-json-jackson2/README.md
+++ b/odp-json-jackson2/README.md
@@ -2,15 +2,8 @@
Jackson 2 encoding, decoding, and JSON Schema validation for `odp-core`.
-Add this artifact alongside an ODP role module when the application uses Jackson 2:
-
-```xml
-
- org.offeringprotocol
- odp-json-jackson2
- 0.2.0
-
-```
+Add this artifact alongside an ODP role module when the application uses Jackson 2. Follow the
+canonical [installation guide](../README.md#installation) for BOM and direct-version usage.
`OdpJson` discovers the provider through Java `ServiceLoader`. Do not also add
`odp-json-jackson3`; exactly one provider must be present at runtime.
diff --git a/odp-json-jackson2/pom.xml b/odp-json-jackson2/pom.xml
index 713a56b..46b8366 100644
--- a/odp-json-jackson2/pom.xml
+++ b/odp-json-jackson2/pom.xml
@@ -7,7 +7,7 @@
org.offeringprotocol
odp-java
- 0.2.0
+ 0.2.1
odp-json-jackson2
@@ -18,6 +18,16 @@
org.offeringprotocol.odp.json.jackson2
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ ${jackson-annotations.version}
+
+
+
+
${project.groupId}
diff --git a/odp-json-jackson3/README.md b/odp-json-jackson3/README.md
index b21e6ed..784227b 100644
--- a/odp-json-jackson3/README.md
+++ b/odp-json-jackson3/README.md
@@ -2,15 +2,8 @@
Jackson 3 encoding, decoding, and JSON Schema validation for `odp-core`.
-Add this artifact alongside an ODP role module when the application uses Jackson 3:
-
-```xml
-
- org.offeringprotocol
- odp-json-jackson3
- 0.2.0
-
-```
+Add this artifact alongside an ODP role module when the application uses Jackson 3. Follow the
+canonical [installation guide](../README.md#installation) for BOM and direct-version usage.
`OdpJson` discovers the provider through Java `ServiceLoader`. Do not also add
`odp-json-jackson2`; exactly one provider must be present at runtime.
diff --git a/odp-json-jackson3/pom.xml b/odp-json-jackson3/pom.xml
index ac40cda..6e030d7 100644
--- a/odp-json-jackson3/pom.xml
+++ b/odp-json-jackson3/pom.xml
@@ -7,7 +7,7 @@
org.offeringprotocol
odp-java
- 0.2.0
+ 0.2.1
odp-json-jackson3
@@ -18,6 +18,18 @@
org.offeringprotocol.odp.json.jackson3
+
+
+
+ tools.jackson
+ jackson-bom
+ ${jackson3.version}
+ pom
+ import
+
+
+
+
${project.groupId}
diff --git a/odp-service/README.md b/odp-service/README.md
index d53ac3a..3a8b993 100644
--- a/odp-service/README.md
+++ b/odp-service/README.md
@@ -9,23 +9,8 @@ it does not load, copy, sort, or index a storage-backed catalog.
## Install
-```xml
-
- org.offeringprotocol
- odp-service
- 0.2.0
-
-
- org.offeringprotocol
- odp-json-jackson2
- 0.2.0
-
-```
-
-```kotlin
-implementation("org.offeringprotocol:odp-service:0.2.0")
-implementation("org.offeringprotocol:odp-json-jackson2:0.2.0")
-```
+Follow the canonical [installation guide](../README.md#installation), selecting `odp-service` and
+exactly one JSON provider.
The Service module brings in `odp-core` transitively and does not depend on Agent or directory
behavior. Replace `odp-json-jackson2` with `odp-json-jackson3` in a Jackson 3 application. Exactly
diff --git a/odp-service/pom.xml b/odp-service/pom.xml
index 2b34d8d..ff722a5 100644
--- a/odp-service/pom.xml
+++ b/odp-service/pom.xml
@@ -7,7 +7,7 @@
org.offeringprotocol
odp-java
- 0.2.0
+ 0.2.1
odp-service
diff --git a/pom.xml b/pom.xml
index 4e81fff..175ed3c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.offeringprotocol
odp-java
- 0.2.0
+ 0.2.1
pom
Offering Discovery Protocol for Java
@@ -38,6 +38,7 @@
+ odp-bom
odp-core
odp-json-jackson2
odp-json-jackson3
@@ -54,6 +55,7 @@
UTF-8
6.1.3
+ 2.22
2.18.3
3.2.2
2.0.0
@@ -76,29 +78,11 @@
3.10.0
-
-
-
- org.junit
- junit-bom
- ${junit.version}
- pom
- import
-
-
- tools.jackson
- jackson-bom
- ${jackson3.version}
- pom
- import
-
-
-
-
org.junit.jupiter
junit-jupiter
+ ${junit.version}
test
diff --git a/scripts/install-consumer-artifacts.sh b/scripts/install-consumer-artifacts.sh
new file mode 100755
index 0000000..bd96632
--- /dev/null
+++ b/scripts/install-consumer-artifacts.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+set -eu
+
+if [ "$#" -ne 2 ]; then
+ echo "Usage: $0 REPOSITORY VERSION" >&2
+ exit 2
+fi
+
+root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+repository=$1
+version=$2
+
+"$root/mvnw" --batch-mode --no-transfer-progress \
+ --file "$root/pom.xml" \
+ -DskipTests \
+ package
+
+install_artifact() {
+ file=$1
+ pom=$2
+ "$root/mvnw" --batch-mode --no-transfer-progress \
+ org.apache.maven.plugins:maven-install-plugin:3.1.4:install-file \
+ -Dfile="$file" \
+ -DpomFile="$pom" \
+ -DlocalRepositoryPath="$repository"
+}
+
+install_artifact "$root/pom.xml" "$root/pom.xml"
+install_artifact "$root/odp-bom/pom.xml" "$root/odp-bom/pom.xml"
+for artifact in odp-core odp-json-jackson2 odp-json-jackson3 odp-directory odp-agent odp-service; do
+ install_artifact \
+ "$root/$artifact/target/$artifact-$version.jar" \
+ "$root/$artifact/pom.xml"
+done
diff --git a/scripts/verify-consumer.sh b/scripts/verify-consumer.sh
index e41d0d2..a616782 100755
--- a/scripts/verify-consumer.sh
+++ b/scripts/verify-consumer.sh
@@ -14,32 +14,21 @@ version=$(
-q
)
-if [ "${ODP_CONSUMER_SOURCE:-local}" = "local" ]; then
- "$root/mvnw" --batch-mode --no-transfer-progress \
- --file "$root/pom.xml" \
- -DskipTests \
- package
-
- install_artifact() {
- file=$1
- pom=$2
- "$root/mvnw" --batch-mode --no-transfer-progress \
- org.apache.maven.plugins:maven-install-plugin:3.1.4:install-file \
- -Dfile="$file" \
- -DpomFile="$pom" \
- -DlocalRepositoryPath="$repository"
- }
+case "${ODP_CONSUMER_SOURCE:-local}" in
+ local)
+ "$root/scripts/install-consumer-artifacts.sh" "$repository" "$version"
+ ;;
+ central) ;;
+ *)
+ echo "ODP_CONSUMER_SOURCE must be local or central." >&2
+ exit 2
+ ;;
+esac
- install_artifact "$root/pom.xml" "$root/pom.xml"
- for artifact in odp-core odp-json-jackson2 odp-directory odp-agent odp-service; do
- install_artifact \
- "$root/$artifact/target/$artifact-$version.jar" \
- "$root/$artifact/pom.xml"
- done
-fi
-
-"$root/mvnw" --batch-mode --no-transfer-progress \
- --file "$root/testdata/consumer/pom.xml" \
- -Dmaven.repo.local="$repository" \
- -Dodp.version="$version" \
- verify
+for consumer in consumer consumer-direct; do
+ "$root/mvnw" --batch-mode --no-transfer-progress \
+ --file "$root/testdata/$consumer/pom.xml" \
+ -Dmaven.repo.local="$repository" \
+ -Dodp.version="$version" \
+ verify
+done
diff --git a/scripts/verify-gradle-consumer.sh b/scripts/verify-gradle-consumer.sh
new file mode 100755
index 0000000..1e7ae60
--- /dev/null
+++ b/scripts/verify-gradle-consumer.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+set -eu
+
+root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+repository=$(mktemp -d)
+gradle_home=$(mktemp -d)
+trap 'rm -rf "$repository" "$gradle_home"' EXIT INT TERM
+
+version=$(
+ "$root/mvnw" --batch-mode --no-transfer-progress \
+ --file "$root/pom.xml" \
+ help:evaluate \
+ -Dexpression=project.version \
+ -DforceStdout \
+ -q
+)
+
+case "${ODP_CONSUMER_SOURCE:-local}" in
+ local)
+ "$root/scripts/install-consumer-artifacts.sh" "$repository" "$version"
+ ;;
+ central) ;;
+ *)
+ echo "ODP_CONSUMER_SOURCE must be local or central." >&2
+ exit 2
+ ;;
+esac
+
+if [ "${ODP_CONSUMER_SOURCE:-local}" = "local" ]; then
+ GRADLE_USER_HOME="$gradle_home" gradle \
+ --no-daemon \
+ --console=plain \
+ --project-dir "$root/testdata/consumer-gradle" \
+ -PodpVersion="$version" \
+ -PodpRepository="$repository" \
+ verifyConsumer
+else
+ GRADLE_USER_HOME="$gradle_home" gradle \
+ --no-daemon \
+ --console=plain \
+ --project-dir "$root/testdata/consumer-gradle" \
+ -PodpVersion="$version" \
+ verifyConsumer
+fi
diff --git a/scripts/verify-release-artifacts.sh b/scripts/verify-release-artifacts.sh
new file mode 100755
index 0000000..7e95b8e
--- /dev/null
+++ b/scripts/verify-release-artifacts.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+set -eu
+
+root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+settings=$(mktemp)
+effective_bom=$(mktemp)
+trap 'rm -f "$settings" "$effective_bom"' EXIT INT TERM
+printf '%s\n' \
+ '' \
+ ' ' \
+ ' ' \
+ ' central' \
+ ' dry-run' \
+ ' dry-run' \
+ ' ' \
+ ' ' \
+ '' \
+ > "$settings"
+version=$(
+ "$root/mvnw" --batch-mode --no-transfer-progress \
+ --file "$root/pom.xml" \
+ help:evaluate \
+ -Dexpression=project.version \
+ -DforceStdout \
+ -q
+)
+
+case "$version" in
+ *-SNAPSHOT)
+ echo "Release verification requires a stable project version." >&2
+ exit 1
+ ;;
+esac
+
+"$root/mvnw" --batch-mode --no-transfer-progress \
+ --file "$root/pom.xml" \
+ --settings "$settings" \
+ -Prelease \
+ -Dgpg.skip=true \
+ -DskipPublishing=true \
+ clean deploy
+
+for artifact in odp-core odp-json-jackson2 odp-json-jackson3 odp-directory odp-agent odp-service; do
+ for classifier in "" -sources -javadoc; do
+ file="$root/$artifact/target/$artifact-$version$classifier.jar"
+ if [ ! -s "$file" ]; then
+ echo "Missing release artifact: $file" >&2
+ exit 1
+ fi
+ done
+done
+
+"$root/mvnw" --batch-mode --no-transfer-progress \
+ --file "$root/odp-bom/pom.xml" \
+ help:effective-pom \
+ -Doutput="$effective_bom"
+
+if grep -Eq '(junit-bom|jackson-bom)' "$effective_bom"; then
+ echo "odp-bom must not manage JUnit or Jackson." >&2
+ exit 1
+fi
+
+for artifact in odp-core odp-json-jackson2 odp-json-jackson3 odp-directory odp-agent odp-service; do
+ if ! grep -q "$artifact" "$effective_bom"; then
+ echo "odp-bom does not manage $artifact." >&2
+ exit 1
+ fi
+done
+
+managed_dependencies=$(sed -n '//,/<\/dependencyManagement>/p' "$root/odp-bom/pom.xml")
+for artifact in odp-java odp-examples odp-conformance; do
+ if printf '%s\n' "$managed_dependencies" | grep -q "$artifact"; then
+ echo "odp-bom must not manage $artifact." >&2
+ exit 1
+ fi
+done
diff --git a/testdata/consumer-direct/pom.xml b/testdata/consumer-direct/pom.xml
new file mode 100644
index 0000000..c1cfcb2
--- /dev/null
+++ b/testdata/consumer-direct/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+ org.offeringprotocol.example
+ odp-java-direct-version-consumer
+ 1.0.0
+
+
+ 0.2.1
+ 17
+ UTF-8
+
+
+
+
+ org.offeringprotocol
+ odp-json-jackson2
+ ${odp.version}
+
+
+ org.offeringprotocol
+ odp-core
+ ${odp.version}
+
+
+ org.offeringprotocol
+ odp-directory
+ ${odp.version}
+
+
+ org.offeringprotocol
+ odp-agent
+ ${odp.version}
+
+
+ org.offeringprotocol
+ odp-service
+ ${odp.version}
+
+
+
+
+ ../consumer/src/main/java
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.15.0
+
+
+
+
diff --git a/testdata/consumer-gradle/build.gradle.kts b/testdata/consumer-gradle/build.gradle.kts
new file mode 100644
index 0000000..eee55b0
--- /dev/null
+++ b/testdata/consumer-gradle/build.gradle.kts
@@ -0,0 +1,42 @@
+plugins {
+ java
+}
+
+val odpVersion = providers.gradleProperty("odpVersion").getOrElse("0.2.1")
+
+repositories {
+ providers.gradleProperty("odpRepository").orNull?.let {
+ maven {
+ url = uri(it)
+ }
+ }
+ mavenCentral()
+}
+
+dependencies {
+ implementation(platform("org.offeringprotocol:odp-bom:$odpVersion"))
+ implementation("org.offeringprotocol:odp-json-jackson2")
+ implementation("org.offeringprotocol:odp-core")
+ implementation("org.offeringprotocol:odp-directory")
+ implementation("org.offeringprotocol:odp-agent")
+ implementation("org.offeringprotocol:odp-service")
+}
+
+java {
+ toolchain {
+ languageVersion = JavaLanguageVersion.of(17)
+ }
+}
+
+sourceSets {
+ main {
+ java {
+ srcDir("../consumer/src/main/java")
+ }
+ }
+}
+
+tasks.register("verifyConsumer") {
+ classpath = sourceSets.main.get().runtimeClasspath
+ mainClass = "org.offeringprotocol.example.Consumer"
+}
diff --git a/testdata/consumer-gradle/settings.gradle.kts b/testdata/consumer-gradle/settings.gradle.kts
new file mode 100644
index 0000000..a32864f
--- /dev/null
+++ b/testdata/consumer-gradle/settings.gradle.kts
@@ -0,0 +1 @@
+rootProject.name = "odp-java-gradle-consumer"
diff --git a/testdata/consumer/pom.xml b/testdata/consumer/pom.xml
index 6a7661f..2d124ff 100644
--- a/testdata/consumer/pom.xml
+++ b/testdata/consumer/pom.xml
@@ -9,35 +9,43 @@
1.0.0
+ 0.2.1
17
UTF-8
+
+
+
+ org.offeringprotocol
+ odp-bom
+ ${odp.version}
+ pom
+ import
+
+
+
+
org.offeringprotocol
odp-json-jackson2
- ${odp.version}
org.offeringprotocol
odp-core
- ${odp.version}
org.offeringprotocol
odp-directory
- ${odp.version}
org.offeringprotocol
odp-agent
- ${odp.version}
org.offeringprotocol
odp-service
- ${odp.version}
diff --git a/tools/odp-conformance/pom.xml b/tools/odp-conformance/pom.xml
index c8e7218..9517799 100644
--- a/tools/odp-conformance/pom.xml
+++ b/tools/odp-conformance/pom.xml
@@ -7,7 +7,7 @@
org.offeringprotocol
odp-java
- 0.2.0
+ 0.2.1
../../pom.xml