This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new 7e5bd7eace build: add juneau-bom and curated dependency bundles
(jetty/tomcat/springboot)
7e5bd7eace is described below
commit 7e5bd7eace6e66a27052ea8db8aafc387b4c1c02
Author: James Bognar <[email protected]>
AuthorDate: Thu Jun 18 15:02:26 2026 -0400
build: add juneau-bom and curated dependency bundles
(jetty/tomcat/springboot)
---
juneau-bom/pom.xml | 124 ++++++++++++++++
.../juneau-microservice-jetty-bundle/pom.xml | 59 ++++++++
.../juneau-microservice-tomcat-bundle/pom.xml | 59 ++++++++
juneau-bundles/juneau-springboot-bundle/pom.xml | 59 ++++++++
juneau-bundles/pom.xml | 40 ++++++
juneau-distrib/pom.xml | 25 ++++
.../juneau-rest-server-metrics-micrometer/pom.xml | 2 +-
.../juneau-rest-server-tracing-otel/pom.xml | 2 +-
juneau-rest/juneau-rest-server/pom.xml | 4 +-
pom.xml | 7 +
scripts/check-bom-completeness.py | 160 +++++++++++++++++++++
scripts/push.py | 14 ++
12 files changed, 551 insertions(+), 4 deletions(-)
diff --git a/juneau-bom/pom.xml b/juneau-bom/pom.xml
new file mode 100644
index 0000000000..9d374f785a
--- /dev/null
+++ b/juneau-bom/pom.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau</artifactId>
+ <version>10.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>juneau-bom</artifactId>
+ <packaging>pom</packaging>
+
+ <name>Apache Juneau Bill of Materials</name>
+ <description>Bill-of-materials (BOM) for version-aligning Apache Juneau
modules. Import it (scope=import, type=pom) and drop explicit versions from
your Juneau dependencies. Enumerates the consumer-facing Juneau modules plus
the small set of starter-relevant third-party versions the curated *-bundle
POMs pin; it does NOT mirror a whole-world third-party BOM.</description>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <!--
=====================================================================================
-->
+ <!-- juneau-core
-->
+ <!--
=====================================================================================
-->
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-commons</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-marshall</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-marshall-rdf</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-config</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-assertions</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bct</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-junit5</artifactId><version>${project.version}</version></dependency>
+
+ <!--
=====================================================================================
-->
+ <!-- juneau-rest
-->
+ <!--
=====================================================================================
-->
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-common</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-common-classic</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-rdf</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-mcp</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-auth-jwt</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-auth-saml</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-auth-oauth</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-auth-oidc-rp</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-metrics-micrometer</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-tracing-otel</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-reactive</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-reactive-reactor</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-view-jsp</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-view-thymeleaf</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-view-mustache</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-view-freemarker</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-springboot</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-client</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-client-classic</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-mock</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-client-apache-httpclient-45</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-client-apache-httpclient-50</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-client-okhttp</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-client-jetty</artifactId><version>${project.version}</version></dependency>
+
+ <!--
=====================================================================================
-->
+ <!-- juneau-microservice
-->
+ <!--
=====================================================================================
-->
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-microservice</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-microservice-jetty</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-microservice-tomcat</artifactId><version>${project.version}</version></dependency>
+
+ <!--
=====================================================================================
-->
+ <!-- juneau-bean
-->
+ <!--
=====================================================================================
-->
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-common</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-atom</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-html5</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-hal</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-rfc7807</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-jsonpatch</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-jsonapi</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-jsonschema</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-mcp</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-openapi-v3</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-bean-swagger-v2</artifactId><version>${project.version}</version></dependency>
+
+ <!--
=====================================================================================
-->
+ <!-- juneau-sc
-->
+ <!--
=====================================================================================
-->
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-sc-client</artifactId><version>${project.version}</version></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-sc-server</artifactId><version>${project.version}</version></dependency>
+
+ <!--
=====================================================================================
-->
+ <!-- Curated dependency bundles (transitive module sets
per deployment shape) -->
+ <!--
=====================================================================================
-->
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-microservice-jetty-bundle</artifactId><version>${project.version}</version><type>pom</type></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-microservice-tomcat-bundle</artifactId><version>${project.version}</version><type>pom</type></dependency>
+
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-springboot-bundle</artifactId><version>${project.version}</version><type>pom</type></dependency>
+
+ <!--
=====================================================================================
-->
+ <!-- Starter-relevant third-party versions (the small
set the curated bundles need to be -->
+ <!-- coherent). NOT a whole-world third-party BOM (see
TODO-174c Q2). -->
+ <!--
=====================================================================================
-->
+
<dependency><groupId>io.micrometer</groupId><artifactId>micrometer-core</artifactId><version>${micrometer.version}</version></dependency>
+
<dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-api</artifactId><version>${opentelemetry.version}</version></dependency>
+
<dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>${jakarta.servlet-api.version}</version></dependency>
+
<dependency><groupId>jakarta.validation</groupId><artifactId>jakarta.validation-api</artifactId><version>${jakarta.validation-api.version}</version></dependency>
+
+ </dependencies>
+ </dependencyManagement>
+
+</project>
diff --git a/juneau-bundles/juneau-microservice-jetty-bundle/pom.xml
b/juneau-bundles/juneau-microservice-jetty-bundle/pom.xml
new file mode 100644
index 0000000000..52af05a1a3
--- /dev/null
+++ b/juneau-bundles/juneau-microservice-jetty-bundle/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-bundles</artifactId>
+ <version>10.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>juneau-microservice-jetty-bundle</artifactId>
+ <packaging>pom</packaging>
+
+ <name>Apache Juneau Jetty Microservice Bundle</name>
+ <description>Curated dependency bundle for a Jetty-backed Juneau
microservice. Depend on this single artifact to transitively pull the
embedded-Jetty microservice stack (juneau-microservice-jetty, which itself
brings juneau-microservice + juneau-rest-server) plus the REST client for
typical service-to-service calls. This is a dependency aggregator only ā it
registers no configurations and performs no classpath auto-discovery; wire your
servers explicitly via Microservice.Builder.confi [...]
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-bom</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <!-- Embedded-Jetty microservice stack (transitively brings
juneau-microservice + juneau-rest-server). -->
+ <dependency>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-microservice-jetty</artifactId>
+ </dependency>
+ <!-- REST client for typical service-to-service calls. -->
+ <dependency>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-rest-client</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/juneau-bundles/juneau-microservice-tomcat-bundle/pom.xml
b/juneau-bundles/juneau-microservice-tomcat-bundle/pom.xml
new file mode 100644
index 0000000000..7c56646e89
--- /dev/null
+++ b/juneau-bundles/juneau-microservice-tomcat-bundle/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-bundles</artifactId>
+ <version>10.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>juneau-microservice-tomcat-bundle</artifactId>
+ <packaging>pom</packaging>
+
+ <name>Apache Juneau Tomcat Microservice Bundle</name>
+ <description>Curated dependency bundle for a Tomcat-backed Juneau
microservice. Depend on this single artifact to transitively pull the
embedded-Tomcat microservice stack (juneau-microservice-tomcat, which itself
brings juneau-microservice + juneau-rest-server) plus the REST client for
typical service-to-service calls. This is a dependency aggregator only ā it
registers no configurations and performs no classpath auto-discovery; wire your
servers explicitly via Microservice.Builder.co [...]
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-bom</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <!-- Embedded-Tomcat microservice stack (transitively brings
juneau-microservice + juneau-rest-server). -->
+ <dependency>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-microservice-tomcat</artifactId>
+ </dependency>
+ <!-- REST client for typical service-to-service calls. -->
+ <dependency>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-rest-client</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/juneau-bundles/juneau-springboot-bundle/pom.xml
b/juneau-bundles/juneau-springboot-bundle/pom.xml
new file mode 100644
index 0000000000..fa1dba8e5f
--- /dev/null
+++ b/juneau-bundles/juneau-springboot-bundle/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-bundles</artifactId>
+ <version>10.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>juneau-springboot-bundle</artifactId>
+ <packaging>pom</packaging>
+
+ <name>Apache Juneau Spring Boot Bundle</name>
+ <description>Curated dependency bundle for running Juneau REST
resources under Spring Boot. Depend on this single artifact to transitively
pull the Spring Boot bridge (juneau-rest-server-springboot, which brings
juneau-rest-server + spring-boot-starter-web) plus the REST client. This is a
dependency aggregator only ā it registers no configurations and performs no
classpath auto-discovery; wire your resources explicitly. Not to be confused
with the external clone-and-go juneau-microse [...]
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-bom</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <!-- Spring Boot bridge (transitively brings juneau-rest-server
+ spring-boot-starter-web). -->
+ <dependency>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-rest-server-springboot</artifactId>
+ </dependency>
+ <!-- REST client for typical service-to-service calls. -->
+ <dependency>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau-rest-client</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/juneau-bundles/pom.xml b/juneau-bundles/pom.xml
new file mode 100644
index 0000000000..f2c4b1eae6
--- /dev/null
+++ b/juneau-bundles/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.juneau</groupId>
+ <artifactId>juneau</artifactId>
+ <version>10.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>juneau-bundles</artifactId>
+ <packaging>pom</packaging>
+
+ <name>Apache Juneau Dependency Bundles</name>
+ <description>Aggregator for the curated *-bundle dependency POMs. Each
bundle transitively pulls a coherent Juneau module set for one deployment shape
(Jetty microservice, Tomcat microservice, Spring Boot bridge). Bundles are
dependency aggregators only ā they do NOT register configurations or
auto-discover anything (explicit-over-magic).</description>
+
+ <modules>
+ <module>juneau-microservice-jetty-bundle</module>
+ <module>juneau-microservice-tomcat-bundle</module>
+ <module>juneau-springboot-bundle</module>
+ </modules>
+
+</project>
diff --git a/juneau-distrib/pom.xml b/juneau-distrib/pom.xml
index 172ba9e984..fadb66c95f 100644
--- a/juneau-distrib/pom.xml
+++ b/juneau-distrib/pom.xml
@@ -833,6 +833,31 @@
<destFileName>org.apache.juneau.microservice.jetty_${project.version}.jar</destFileName>
</artifactItem>
+ <!--
juneau-microservice-tomcat -->
+ <artifactItem>
+
<outputDirectory>${project.build.directory}/src/lib</outputDirectory>
+
<groupId>org.apache.juneau</groupId>
+
<artifactId>juneau-microservice-tomcat</artifactId>
+
<version>${project.version}</version>
+
<type>jar</type>
+
<classifier>sources</classifier>
+
<destFileName>apache-juneau-microservice-tomcat-${project.version}-sources.jar</destFileName>
+ </artifactItem>
+ <artifactItem>
+
<outputDirectory>${project.build.directory}/bin/lib</outputDirectory>
+
<groupId>org.apache.juneau</groupId>
+
<artifactId>juneau-microservice-tomcat</artifactId>
+
<version>${project.version}</version>
+
<destFileName>apache-juneau-microservice-tomcat-${project.version}.jar</destFileName>
+ </artifactItem>
+ <artifactItem>
+
<outputDirectory>${project.build.directory}/bin/osgi</outputDirectory>
+
<groupId>org.apache.juneau</groupId>
+
<artifactId>juneau-microservice-tomcat</artifactId>
+
<version>${project.version}</version>
+
<destFileName>org.apache.juneau.microservice.tomcat_${project.version}.jar</destFileName>
+ </artifactItem>
+
<!--
juneau-sc-client -->
<artifactItem>
<outputDirectory>${project.build.directory}/src/lib</outputDirectory>
diff --git a/juneau-rest/juneau-rest-server-metrics-micrometer/pom.xml
b/juneau-rest/juneau-rest-server-metrics-micrometer/pom.xml
index 32ba27b215..af6bb75ac5 100644
--- a/juneau-rest/juneau-rest-server-metrics-micrometer/pom.xml
+++ b/juneau-rest/juneau-rest-server-metrics-micrometer/pom.xml
@@ -32,7 +32,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <micrometer.version>1.13.6</micrometer.version>
+ <!-- micrometer.version is hoisted to the root pom so the
juneau-bom can pin it. -->
</properties>
<dependencies>
diff --git a/juneau-rest/juneau-rest-server-tracing-otel/pom.xml
b/juneau-rest/juneau-rest-server-tracing-otel/pom.xml
index b6f900db4b..c6bb83263a 100644
--- a/juneau-rest/juneau-rest-server-tracing-otel/pom.xml
+++ b/juneau-rest/juneau-rest-server-tracing-otel/pom.xml
@@ -32,7 +32,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <opentelemetry.version>1.62.0</opentelemetry.version>
+ <!-- opentelemetry.version is hoisted to the root pom so the
juneau-bom can pin it. -->
</properties>
<dependencies>
diff --git a/juneau-rest/juneau-rest-server/pom.xml
b/juneau-rest/juneau-rest-server/pom.xml
index 4eacd2f583..2a914c3801 100644
--- a/juneau-rest/juneau-rest-server/pom.xml
+++ b/juneau-rest/juneau-rest-server/pom.xml
@@ -73,7 +73,7 @@
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
- <version>6.1.0</version>
+ <version>${jakarta.servlet-api.version}</version>
</dependency>
<!--
@@ -85,7 +85,7 @@
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
- <version>3.0.2</version>
+ <version>${jakarta.validation-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
diff --git a/pom.xml b/pom.xml
index 08314c8e7e..682c60dae6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -69,9 +69,16 @@
<sonar.cpd.exclusions>**/rest/server/Rest*Annotation.java,**/rest/server/RestOp.java,**/rest/server/RestGet.java,**/rest/server/RestPut.java,**/rest/server/RestPost.java,**/rest/server/RestDelete.java,**/rest/server/RestPatch.java,**/rest/server/RestOptions.java,**/rest/server/RestPreCall.java,**/rest/server/RestPostCall.java,**/rest/server/RestStartCall.java,**/rest/server/RestEndCall.java,**/rest/server/RestInit.java,**/rest/server/RestDestroy.java,**/rest/server/RestPostInit.java,**
[...]
<sonar.coverage.exclusions>**/juneau-examples/**,**/juneau-petstore/**,**/*-microservice/**,**/juneau-sc-server/**,**/juneau-core/juneau-test-utils/**</sonar.coverage.exclusions>
<jena.version>5.6.0</jena.version>
+ <!-- Hoisted from owning modules so the juneau-bom + curated
bundles can pin one coherent version source. -->
+ <micrometer.version>1.13.6</micrometer.version>
+ <opentelemetry.version>1.62.0</opentelemetry.version>
+ <jakarta.servlet-api.version>6.1.0</jakarta.servlet-api.version>
+
<jakarta.validation-api.version>3.0.2</jakarta.validation-api.version>
</properties>
<modules>
+ <module>juneau-bom</module>
+ <module>juneau-bundles</module>
<module>juneau-core</module>
<module>juneau-rest</module>
<module>juneau-microservice</module>
diff --git a/scripts/check-bom-completeness.py
b/scripts/check-bom-completeness.py
new file mode 100755
index 0000000000..e54990838c
--- /dev/null
+++ b/scripts/check-bom-completeness.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python3
+#
***************************************************************************************************************************
+# * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file
+# * distributed with this work for additional information regarding copyright
ownership. The ASF licenses this file
+# * to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance
+# * with the License. You may obtain a copy of the License at
+# *
+# * http://www.apache.org/licenses/LICENSE-2.0
+# *
+# * Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an
+# * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied. See the License for the
+# * specific language governing permissions and limitations under the License.
+#
***************************************************************************************************************************
+"""
+Drift guard for the published juneau-bom.
+
+Every consumer-facing reactor module must be enumerated in juneau-bom/pom.xml's
+<dependencyManagement>. This catches the common failure mode where a new
+publishable module is added to the reactor but the maintainer forgets to add it
+to the BOM, so downstreams importing the BOM silently can't omit its version.
+
+A module is "consumer-facing publishable" when it is a leaf artifact
+(packaging jar/bundle, or a leaf packaging=pom dependency bundle with no
+<modules>) AND it is not one of the documented non-published modules:
+
+ - reactor aggregators (packaging=pom WITH <modules>) - not artifacts
+ - juneau-bom itself
+ - juneau-test-utils (test-only support)
+ - juneau-shaded/* (uber-jars, not BOM-managed)
+ - juneau-examples/*, juneau-petstore/* (sample apps, not published)
+ - juneau-integration-tests (test-only)
+ - juneau-distrib (assembly only)
+
+Exit 0 when the BOM is complete (and free of stale entries); exit 1 otherwise.
+"""
+
+from __future__ import annotations
+
+import sys
+import xml.etree.ElementTree as ET
+from pathlib import Path
+
+NS = {"m": "http://maven.apache.org/POM/4.0.0"}
+
+# Path-prefix-based exclusions (relative to repo root).
+EXCLUDED_PATH_PREFIXES = (
+ "juneau-shaded/",
+ "juneau-examples/",
+ "juneau-petstore/",
+ "juneau-distrib/",
+)
+
+# Artifact-id-based exclusions (leaf artifacts that are intentionally not
published via the BOM).
+EXCLUDED_ARTIFACTS = {
+ "juneau-bom", # the BOM cannot manage itself
+ "juneau-test-utils", # test-only support module
+ "juneau-integration-tests", # cross-module test harness, not published
+ "juneau", # reactor root (defensive; also an aggregator)
+}
+
+
+def _text(el: ET.Element, tag: str) -> str | None:
+ child = el.find(f"m:{tag}", NS)
+ return child.text.strip() if child is not None and child.text else None
+
+
+def repo_root() -> Path:
+ # scripts/ lives directly under the reactor root.
+ return Path(__file__).resolve().parent.parent
+
+
+def own_artifact_id(root: ET.Element) -> str | None:
+ """The module's own artifactId - the direct <project><artifactId>, not the
<parent> one."""
+ return _text(root, "artifactId")
+
+
+def is_aggregator(root: ET.Element) -> bool:
+ """A reactor aggregator: packaging=pom AND declares <modules>."""
+ packaging = _text(root, "packaging") or "jar"
+ has_modules = root.find("m:modules", NS) is not None
+ return packaging == "pom" and has_modules
+
+
+def collect_publishable(root_dir: Path) -> dict[str, Path]:
+ """Map of consumer-facing publishable artifactId -> pom path."""
+ out: dict[str, Path] = {}
+ for pom in sorted(root_dir.rglob("pom.xml")):
+ rel = pom.relative_to(root_dir).as_posix()
+ if "/target/" in f"/{rel}":
+ continue
+ if any(rel.startswith(p) for p in EXCLUDED_PATH_PREFIXES):
+ continue
+ try:
+ root = ET.parse(pom).getroot()
+ except ET.ParseError as e:
+ print(f"WARNING: could not parse {rel}: {e}", file=sys.stderr)
+ continue
+ aid = own_artifact_id(root)
+ if not aid or aid in EXCLUDED_ARTIFACTS:
+ continue
+ if is_aggregator(root):
+ continue
+ # Skip the integration-tests reactor module (artifactId 'juneau',
already excluded) and
+ # any build-overlay helper poms living under an excluded tree (handled
by path prefixes).
+ out[aid] = pom
+ return out
+
+
+def collect_bom_entries(bom_pom: Path) -> set[str]:
+ root = ET.parse(bom_pom).getroot()
+ dm = root.find("m:dependencyManagement", NS)
+ if dm is None:
+ return set()
+ out: set[str] = set()
+ for dep in dm.iterfind("m:dependencies/m:dependency", NS):
+ group = _text(dep, "groupId")
+ if group != "org.apache.juneau":
+ continue
+ aid = _text(dep, "artifactId")
+ if aid:
+ out.add(aid)
+ return out
+
+
+def main() -> int:
+ root_dir = repo_root()
+ bom_pom = root_dir / "juneau-bom" / "pom.xml"
+ if not bom_pom.is_file():
+ print(f"ERROR: BOM not found at {bom_pom}", file=sys.stderr)
+ return 1
+
+ publishable = collect_publishable(root_dir)
+ bom = collect_bom_entries(bom_pom)
+
+ missing = sorted(set(publishable) - bom)
+ stale = sorted(bom - set(publishable))
+
+ if not missing and not stale:
+ print(f"OK: juneau-bom enumerates all {len(publishable)}
consumer-facing modules.")
+ return 0
+
+ if missing:
+ print("ERROR: the following published modules are MISSING from
juneau-bom:", file=sys.stderr)
+ for aid in missing:
+ print(f" - {aid}
({publishable[aid].relative_to(root_dir).as_posix()})", file=sys.stderr)
+ if stale:
+ print("ERROR: juneau-bom lists artifacts that are NOT consumer-facing
reactor modules:", file=sys.stderr)
+ for aid in stale:
+ print(f" - {aid}", file=sys.stderr)
+ print(
+ "\nFix: add the missing <dependency> entries to juneau-bom/pom.xml (or
remove stale ones), "
+ "or update the exclusion lists in scripts/check-bom-completeness.py if
the module is "
+ "intentionally not published.",
+ file=sys.stderr,
+ )
+ return 1
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/scripts/push.py b/scripts/push.py
index 0921409b88..8385f9089b 100755
--- a/scripts/push.py
+++ b/scripts/push.py
@@ -534,6 +534,8 @@ Examples:
if not args.skip_tests:
print(f" {step_num}. Verify container test tags: python3
scripts/check-container-tags.py")
step_num += 1
+ print(f" {step_num}. Verify BOM completeness: python3
scripts/check-bom-completeness.py")
+ step_num += 1
print(f" {step_num}. Run tests with timing capture: python3
scripts/test.py --full --timing-log
~/.cache/juneau-push-timings/<branch>.jsonl")
step_num += 1
print(f" {step_num}. Print timing deltas: python3
scripts/push-timings.py --log ~/.cache/juneau-push-timings/<branch>.jsonl")
@@ -575,6 +577,18 @@ Examples:
return 1
step_num += 1
+ check_bom = script_dir / "check-bom-completeness.py"
+ if check_bom.exists():
+ if not run_command(
+ [sys.executable, str(check_bom)],
+ f"š Step {step_num}: Checking BOM completeness...",
+ juneau_root
+ ):
+ print("\nā Build process aborted: juneau-bom is out of sync
with the reactor.")
+ play_sound(success=False)
+ return 1
+ step_num += 1
+
test_script = script_dir / 'test.py'
timing_file = timing_log_path(juneau_root)
if test_script.exists():