From 91a6a69d8888072510a458b56b74a43ecb5710a7 Mon Sep 17 00:00:00 2001 From: Christian Bush Date: Fri, 20 Mar 2026 22:28:45 -0700 Subject: [PATCH 1/7] docs: clarify PUT table requirements for baseTableVersion and tableProperties The Update a Table example in SETUP.md was missing two critical pieces: - baseTableVersion must come from the GET response's tableVersion field (not hardcoded as 'INITIAL_VERSION', which causes 409 after first update) - tableProperties must include all openhouse.* properties from GET; omitting them causes a 500 NPE in the cross-cluster eligibility check --- SETUP.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/SETUP.md b/SETUP.md index 5ab4ea542..e3988e9b8 100644 --- a/SETUP.md +++ b/SETUP.md @@ -173,13 +173,27 @@ curl "${curlArgs[@]}" -XGET http://localhost:8000/v1/databases/d3/tables/t1 #### Update a Table +The PUT request requires two values from a prior GET response: + +- **`baseTableVersion`** — use the `tableVersion` field from GET (after the first update this becomes a metadata file path, not `"INITIAL_VERSION"`) +- **`tableProperties`** — must include all `openhouse.*` properties from the GET response merged with any user-defined properties; omitting them causes a 500 in the server's cross-cluster eligibility check + +First GET the current state: + +``` +curl "${curlArgs[@]}" -XGET http://localhost:8000/v1/databases/d3/tables/t1 +``` + +Then PUT with the returned `tableVersion` and `tableProperties`: + ``` curl "${curlArgs[@]}" -XPUT http://localhost:8000/v1/databases/d3/tables/t1 \ --data-raw '{ "tableId": "t1", "databaseId": "d3", - "baseTableVersion": - "clusterId": "", + "clusterId": "", + "tableType": "PRIMARY_TABLE", + "baseTableVersion": "", "schema": "{\"type\": \"struct\", \"fields\": [{\"id\": 1,\"required\": true,\"name\": \"id\",\"type\": \"string\"},{\"id\": 2,\"required\": true,\"name\": \"name\",\"type\": \"string\"},{\"id\": 3,\"required\": true,\"name\": \"ts\",\"type\": \"timestamp\"}, {\"id\": 4,\"required\": true,\"name\": \"country\",\"type\": \"string\"}]}", "timePartitioning": { "columnName": "ts", @@ -191,6 +205,7 @@ curl "${curlArgs[@]}" -XPUT http://localhost:8000/v1/databases/d3/tables/t1 \ } ], "tableProperties": { + "": "...", "key": "value" } }' From a81f51fc0198dc0e10cc95e638083b8af67cf445 Mon Sep 17 00:00:00 2001 From: Christian Bush Date: Fri, 20 Mar 2026 22:57:27 -0700 Subject: [PATCH 2/7] build: unify Hadoop logging through Log4j2 by removing slf4j-log4j12 Hadoop's hadoop-client transitively introduces slf4j-log4j12 (SLF4J -> Log4j 1.x bridge) alongside log4j-slf4j-impl (SLF4J -> Log4j2 bridge) in the fat JAR. When both are on the classpath, SLF4J emits a 'multiple bindings' warning and picks one arbitrarily -- in practice slf4j-log4j12 wins, meaning Hadoop loggers (DFSClient, ipc.Client, RetryInvocationHandler, etc.) route to Log4j 1.x and are invisible to Spring Boot Actuator's /actuator/loggers endpoint. Fix: - Globally exclude slf4j-log4j12 and log4j:log4j from all Spring Boot service configurations, consistent with the existing exclusion of logback-classic. - Add log4j-1.2-api, which provides the Log4j 1.x API but routes all calls to Log4j2. This preserves compatibility for any code using the Log4j 1.x API directly while keeping Log4j2 as the single logging implementation. After this change, all loggers -- including Hadoop HDFS client loggers -- are visible to the Spring Boot Actuator /actuator/loggers endpoint and can be dynamically adjusted at runtime without restarting the service. --- .../groovy/openhouse.springboot-conventions.gradle | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle b/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle index 8cc60564e..dbe7936ea 100644 --- a/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle +++ b/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle @@ -18,6 +18,11 @@ configurations { // Standardizing on slf4j + log4j2 as implementation. all*.exclude module : 'spring-boot-starter-logging' all*.exclude module : 'logback-classic' + // Exclude Log4j 1.x and its SLF4J bridge so Hadoop transitive deps don't introduce + // a competing SLF4J binding alongside log4j-slf4j-impl. log4j-1.2-api below provides + // the Log4j 1.x API compatibility layer that routes to Log4j2 instead. + all*.exclude group: 'org.slf4j', module: 'slf4j-log4j12' + all*.exclude group: 'log4j', module: 'log4j' } dependencies { @@ -25,6 +30,11 @@ dependencies { api 'org.springframework.boot:spring-boot-starter-web:' + springVersion implementation 'org.springframework.boot:spring-boot-starter-log4j2:' + springLog4jVersion + // Bridge Log4j 1.x API calls (from Hadoop) to Log4j2, completing the logging unification. + // With slf4j-log4j12 and log4j:log4j excluded above, this is the sole provider of the + // Log4j 1.x API and routes all calls through Log4j2, making them visible to Spring + // Boot Actuator's /actuator/loggers endpoint. + implementation 'org.apache.logging.log4j:log4j-1.2-api:2.13.3' api 'org.springframework.boot:spring-boot-starter-actuator:2.7.8' api 'org.springframework.boot:spring-boot-starter-validation:' + springVersion annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:' + springVersion From 0e01cc150d6f5b9a7064755e14a4edab477abe48 Mon Sep 17 00:00:00 2001 From: Christian Bush Date: Sat, 21 Mar 2026 00:05:29 -0700 Subject: [PATCH 3/7] build: bump log4j-1.2-api to 2.25.3 to match log4j-core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit log4j-core is forced to 2.25.3 by transitive resolution. log4j-1.2-api must match exactly — OptionConverter.convertLevel() signature changed between 2.13.3 and 2.25.3, causing NoSuchMethodError at startup when processing the Log4j 1.x XML config. --- .../src/main/groovy/openhouse.springboot-conventions.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle b/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle index dbe7936ea..eb50d0b1f 100644 --- a/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle +++ b/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle @@ -34,7 +34,7 @@ dependencies { // With slf4j-log4j12 and log4j:log4j excluded above, this is the sole provider of the // Log4j 1.x API and routes all calls through Log4j2, making them visible to Spring // Boot Actuator's /actuator/loggers endpoint. - implementation 'org.apache.logging.log4j:log4j-1.2-api:2.13.3' + implementation 'org.apache.logging.log4j:log4j-1.2-api:2.25.3' api 'org.springframework.boot:spring-boot-starter-actuator:2.7.8' api 'org.springframework.boot:spring-boot-starter-validation:' + springVersion annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:' + springVersion From ea4603ab98b7c33e9df9f3fa046dfc8bdbe87358 Mon Sep 17 00:00:00 2001 From: Christian Bush Date: Sun, 22 Mar 2026 16:23:39 -0700 Subject: [PATCH 4/7] build: exclude log4j-slf4j-impl and add log4j-slf4j2-impl for SLF4J 2.x log4j-1.2-api:2.25.3 transitively pulls log4j-core:2.25.3 which depends on slf4j-api:2.0.x. The old log4j-slf4j-impl artifact only implements the SLF4J 1.x StaticLoggerBinder interface; SLF4J 2.x ignores it and falls back to Hadoop's slf4j-log4j12, routing all logging through log4j 1.x. Fix: exclude log4j-slf4j-impl and add log4j-slf4j2-impl:2.25.3, which implements SLF4JServiceProvider (SLF4J 2.x ServiceLoader API). SLF4J now routes all calls through log4j2 and Spring Boot Actuator /actuator/loggers gains full control over Hadoop and Iceberg log levels at runtime. --- .../groovy/openhouse.springboot-conventions.gradle | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle b/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle index eb50d0b1f..985fd6b07 100644 --- a/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle +++ b/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle @@ -19,10 +19,16 @@ configurations { all*.exclude module : 'spring-boot-starter-logging' all*.exclude module : 'logback-classic' // Exclude Log4j 1.x and its SLF4J bridge so Hadoop transitive deps don't introduce - // a competing SLF4J binding alongside log4j-slf4j-impl. log4j-1.2-api below provides + // a competing SLF4J binding alongside log4j-slf4j2-impl. log4j-1.2-api below provides // the Log4j 1.x API compatibility layer that routes to Log4j2 instead. all*.exclude group: 'org.slf4j', module: 'slf4j-log4j12' all*.exclude group: 'log4j', module: 'log4j' + // Exclude the SLF4J 1.x binding for log4j2. log4j-1.2-api:2.25.3 transitively pulls in + // log4j-core:2.25.3 which requires SLF4J 2.x (slf4j-api:2.0.x). log4j-slf4j-impl (1.x + // binding) has no SLF4JServiceProvider and causes SLF4J 2.x to fall back to Hadoop's + // slf4j-log4j12 at runtime, routing all logging through log4j 1.x instead of log4j2. + // log4j-slf4j2-impl below provides the correct SLF4J 2.x binding. + all*.exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl' } dependencies { @@ -35,6 +41,12 @@ dependencies { // Log4j 1.x API and routes all calls through Log4j2, making them visible to Spring // Boot Actuator's /actuator/loggers endpoint. implementation 'org.apache.logging.log4j:log4j-1.2-api:2.25.3' + // SLF4J 2.x binding for log4j2. log4j-1.2-api:2.25.3 transitively brings in + // log4j-core:2.25.3, which pulls in slf4j-api:2.0.x. The old log4j-slf4j-impl + // artifact only supports SLF4J 1.x (StaticLoggerBinder). log4j-slf4j2-impl provides + // the SLF4J 2.x ServiceProvider so SLF4J routes to log4j2 instead of falling back + // to Hadoop's slf4j-log4j12 at runtime. + implementation 'org.apache.logging.log4j:log4j-slf4j2-impl:2.25.3' api 'org.springframework.boot:spring-boot-starter-actuator:2.7.8' api 'org.springframework.boot:spring-boot-starter-validation:' + springVersion annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:' + springVersion From dca7c3eb13dfef8013c30c943e1adb71f345a4a2 Mon Sep 17 00:00:00 2001 From: Christian Bush Date: Sun, 22 Mar 2026 18:15:33 -0700 Subject: [PATCH 5/7] tables: remove redundant management.endpoint.loggers.enabled (default is true) --- services/tables/src/main/resources/application.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/services/tables/src/main/resources/application.properties b/services/tables/src/main/resources/application.properties index beda2746b..fabc0290a 100644 --- a/services/tables/src/main/resources/application.properties +++ b/services/tables/src/main/resources/application.properties @@ -17,7 +17,6 @@ management.endpoint.health.enabled=true management.endpoint.shutdown.enabled=true management.endpoint.prometheus.enabled=true management.endpoint.beans.enabled=true -management.endpoint.loggers.enabled=true management.metrics.distribution.percentiles-histogram.all=true management.metrics.distribution.maximum-expected-value.catalog_metadata_retrieval_latency=600s server.shutdown=graceful From 1a6308fea02f9be9608a1291e0aad903b18051f2 Mon Sep 17 00:00:00 2001 From: Christian Bush Date: Thu, 26 Mar 2026 15:48:58 -0700 Subject: [PATCH 6/7] scripts: add enable-hdfs-debug.sh for runtime HDFS/Iceberg log level control Adds a helper script that uses the Spring Boot Actuator /actuator/loggers endpoint to enable DEBUG logging on HDFS and Iceberg loggers at runtime, without requiring a service restart. Targets the local docker-compose stack started via `./gradlew dockerUp -Precipe=oh-hadoop`. Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/enable-hdfs-debug.sh | 120 +++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100755 scripts/enable-hdfs-debug.sh diff --git a/scripts/enable-hdfs-debug.sh b/scripts/enable-hdfs-debug.sh new file mode 100755 index 000000000..07272d215 --- /dev/null +++ b/scripts/enable-hdfs-debug.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash +# +# enable-hdfs-debug.sh — Enable HDFS/Iceberg debug logging on a local OpenHouse cluster. +# +# Targets the tables-service running via: +# ./gradlew dockerUp -Precipe=oh-hadoop +# +# Sets DEBUG on the key Hadoop, HDFS, and Iceberg loggers via the Spring Boot +# Actuator /actuator/loggers endpoint at runtime. No restart required. +# +# Usage: +# ./scripts/enable-hdfs-debug.sh # Enable DEBUG logging +# ./scripts/enable-hdfs-debug.sh --undo # Reset to INFO +# +# To target a non-default host/port: +# ./scripts/enable-hdfs-debug.sh --host localhost --port 8000 +# +# To set a specific logger manually: +# curl -X POST http://localhost:8000/actuator/loggers/org.apache.hadoop.hdfs.DFSClient \ +# -H 'Content-Type: application/json' \ +# -d '{"configuredLevel": "DEBUG"}' +# +# To check the current effective level of a logger: +# curl -s http://localhost:8000/actuator/loggers/org.apache.hadoop.hdfs.DFSClient \ +# | python3 -m json.tool +# +# To reset a logger to its inherited level: +# curl -X POST http://localhost:8000/actuator/loggers/org.apache.hadoop.hdfs.DFSClient \ +# -H 'Content-Type: application/json' \ +# -d '{"configuredLevel": null}' +# +set -euo pipefail + +HOST="localhost" +PORT="8000" +UNDO=false + +LOGGERS=( + # Filesystem layer — logs on FileSystem init and mount table refresh + "org.apache.hadoop.fs" + # NameNode HA proxy provider — covers all variants (IPFailover, ObserverRead, RequestHedging) + "org.apache.hadoop.hdfs.server.namenode.ha" + # IPC/RPC layer — connection establishment and retry events + "org.apache.hadoop.ipc.Client" + "org.apache.hadoop.io.retry.RetryInvocationHandler" + # HDFS client data path — silent on healthy ops; verbose on block errors/retries + "org.apache.hadoop.hdfs.DFSClient" + "org.apache.hadoop.hdfs.DFSInputStream" + "org.apache.hadoop.hdfs.DFSOutputStream" + "org.apache.hadoop.hdfs.DataStreamer" + # Iceberg metadata operations — table refresh, commit, CAS + "org.apache.iceberg" +) + +usage() { + cat <<'EOF' +Usage: enable-hdfs-debug.sh [OPTIONS] + +Enable or disable HDFS/Iceberg debug logging on a local OpenHouse cluster. + +Options: + --host HOST tables-service host (default: localhost) + --port PORT tables-service port (default: 8000) + --undo Reset loggers to inherited level + -h, --help Show this help +EOF + exit 0 +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --host) HOST="$2"; shift 2 ;; + --port) PORT="$2"; shift 2 ;; + --undo) UNDO=true; shift ;; + -h|--help) usage ;; + *) echo "Unknown option: $1"; usage ;; + esac +done + +BASE_URL="http://${HOST}:${PORT}" + +if ! curl -sf "${BASE_URL}/actuator/health" &>/dev/null; then + echo "ERROR: tables-service not responding at ${BASE_URL}." + echo " Start the cluster: ./gradlew dockerUp -Precipe=oh-hadoop" + exit 1 +fi + +if $UNDO; then + echo "Resetting HDFS debug loggers at ${BASE_URL} ..." + for logger in "${LOGGERS[@]}"; do + rc=$(curl -s -o /dev/null -w '%{http_code}' \ + -X POST "${BASE_URL}/actuator/loggers/${logger}" \ + -H 'Content-Type: application/json' \ + -d '{"configuredLevel": null}') + [[ "$rc" == "204" || "$rc" == "200" ]] && echo " RESET $logger" || echo " FAILED $logger (HTTP $rc)" + done + echo "" + echo "Done. Logging restored to defaults." +else + echo "Enabling HDFS debug logging at ${BASE_URL} ..." + echo "" + FAILED=0 + for logger in "${LOGGERS[@]}"; do + rc=$(curl -s -o /dev/null -w '%{http_code}' \ + -X POST "${BASE_URL}/actuator/loggers/${logger}" \ + -H 'Content-Type: application/json' \ + -d '{"configuredLevel": "DEBUG"}') + if [[ "$rc" == "204" || "$rc" == "200" ]]; then + echo " DEBUG $logger" + else + echo " FAILED $logger (HTTP $rc)" + FAILED=$((FAILED + 1)) + fi + done + echo "" + [[ $FAILED -gt 0 ]] && echo "WARNING: $FAILED logger(s) failed to set." + echo "HDFS debug logging active. Run table operations to generate log output." + echo "" + echo "When done: $0 --undo" +fi From 88f37efb6c3f5a5b46957d7880c5ed6b60ac6b61 Mon Sep 17 00:00:00 2001 From: Christian Bush Date: Sun, 29 Mar 2026 21:26:55 -0700 Subject: [PATCH 7/7] build: scope logging unification and keep fixtures neutral Apply Hadoop/Log4j2 unification only when the Spring Boot plugin is present so library modules do not leak logging decisions transitively. Exclude logging stacks on the fixtures -> services:tables edge so consumers own their classpath while preserving deterministic test classpaths. Made-with: Cursor --- .../openhouse.springboot-conventions.gradle | 76 ++++++++++++------- ...enhouse.tables-test-fixtures-common.gradle | 5 ++ 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle b/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle index 985fd6b07..b9897c2b0 100644 --- a/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle +++ b/buildSrc/src/main/groovy/openhouse.springboot-conventions.gradle @@ -13,40 +13,60 @@ ext { springLog4jVersion = '2.3.4.RELEASE' } -configurations { - // Excluding these libraries avoids competing implementations for LoggerFactory - // Standardizing on slf4j + log4j2 as implementation. - all*.exclude module : 'spring-boot-starter-logging' - all*.exclude module : 'logback-classic' - // Exclude Log4j 1.x and its SLF4J bridge so Hadoop transitive deps don't introduce - // a competing SLF4J binding alongside log4j-slf4j2-impl. log4j-1.2-api below provides - // the Log4j 1.x API compatibility layer that routes to Log4j2 instead. - all*.exclude group: 'org.slf4j', module: 'slf4j-log4j12' - all*.exclude group: 'log4j', module: 'log4j' - // Exclude the SLF4J 1.x binding for log4j2. log4j-1.2-api:2.25.3 transitively pulls in - // log4j-core:2.25.3 which requires SLF4J 2.x (slf4j-api:2.0.x). log4j-slf4j-impl (1.x - // binding) has no SLF4JServiceProvider and causes SLF4J 2.x to fall back to Hadoop's - // slf4j-log4j12 at runtime, routing all logging through log4j 1.x instead of log4j2. - // log4j-slf4j2-impl below provides the correct SLF4J 2.x binding. - all*.exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl' +def configureBootLoggingUnification = { + configurations.configureEach { + // Excluding these libraries avoids competing implementations for LoggerFactory + // in boot applications where we standardize on slf4j + log4j2. + exclude module: 'spring-boot-starter-logging' + exclude module: 'logback-classic' + // Exclude Log4j 1.x and its SLF4J bridge so Hadoop transitive deps don't introduce + // a competing SLF4J binding alongside log4j-slf4j2-impl. log4j-1.2-api below provides + // the Log4j 1.x API compatibility layer that routes to Log4j2 instead. + exclude group: 'org.slf4j', module: 'slf4j-log4j12' + exclude group: 'log4j', module: 'log4j' + // Exclude the SLF4J 1.x binding for log4j2. log4j-1.2-api:2.25.3 transitively pulls in + // log4j-core:2.25.3 which requires SLF4J 2.x (slf4j-api:2.0.x). log4j-slf4j-impl (1.x + // binding) has no SLF4JServiceProvider and causes SLF4J 2.x to fall back to Hadoop's + // slf4j-log4j12 at runtime, routing all logging through log4j 1.x instead of log4j2. + // log4j-slf4j2-impl below provides the correct SLF4J 2.x binding. + exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl' + } + + dependencies { + implementation 'org.springframework.boot:spring-boot-starter-log4j2:' + springLog4jVersion + // Bridge Log4j 1.x API calls (from Hadoop) to Log4j2, completing the logging unification. + // With slf4j-log4j12 and log4j:log4j excluded above, this is the sole provider of the + // Log4j 1.x API and routes all calls through Log4j2, making them visible to Spring + // Boot Actuator's /actuator/loggers endpoint. + implementation 'org.apache.logging.log4j:log4j-1.2-api:2.25.3' + // SLF4J 2.x binding for log4j2. log4j-1.2-api:2.25.3 transitively brings in + // log4j-core:2.25.3, which pulls in slf4j-api:2.0.x. The old log4j-slf4j-impl + // artifact only supports SLF4J 1.x (StaticLoggerBinder). log4j-slf4j2-impl provides + // the SLF4J 2.x ServiceProvider so SLF4J routes to log4j2 instead of falling back + // to Hadoop's slf4j-log4j12 at runtime. + implementation 'org.apache.logging.log4j:log4j-slf4j2-impl:2.25.3' + } +} + +// Libraries that consume this convention should not dictate transitive logging bindings +// for downstream consumers, so only apply logging unification when boot plugin is present. +pluginManager.withPlugin('org.springframework.boot') { + configureBootLoggingUnification() +} + +// Library modules that use this convention still run Spring-based tests and can pull +// Hadoop's legacy SLF4J binding transitively. Keep test classpaths deterministic +// without exporting logging exclusions to downstream consumers. +configurations.matching { cfg -> + ['testRuntimeClasspath', 'testCompileClasspath', 'testImplementation', 'testRuntimeOnly'].contains(cfg.name) +}.configureEach { + exclude group: 'org.slf4j', module: 'slf4j-log4j12' } dependencies { api 'io.micrometer:micrometer-registry-prometheus:1.12.3' api 'org.springframework.boot:spring-boot-starter-web:' + springVersion - implementation 'org.springframework.boot:spring-boot-starter-log4j2:' + springLog4jVersion - // Bridge Log4j 1.x API calls (from Hadoop) to Log4j2, completing the logging unification. - // With slf4j-log4j12 and log4j:log4j excluded above, this is the sole provider of the - // Log4j 1.x API and routes all calls through Log4j2, making them visible to Spring - // Boot Actuator's /actuator/loggers endpoint. - implementation 'org.apache.logging.log4j:log4j-1.2-api:2.25.3' - // SLF4J 2.x binding for log4j2. log4j-1.2-api:2.25.3 transitively brings in - // log4j-core:2.25.3, which pulls in slf4j-api:2.0.x. The old log4j-slf4j-impl - // artifact only supports SLF4J 1.x (StaticLoggerBinder). log4j-slf4j2-impl provides - // the SLF4J 2.x ServiceProvider so SLF4J routes to log4j2 instead of falling back - // to Hadoop's slf4j-log4j12 at runtime. - implementation 'org.apache.logging.log4j:log4j-slf4j2-impl:2.25.3' api 'org.springframework.boot:spring-boot-starter-actuator:2.7.8' api 'org.springframework.boot:spring-boot-starter-validation:' + springVersion annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:' + springVersion diff --git a/buildSrc/src/main/groovy/openhouse.tables-test-fixtures-common.gradle b/buildSrc/src/main/groovy/openhouse.tables-test-fixtures-common.gradle index 7979946bc..d60d34a59 100644 --- a/buildSrc/src/main/groovy/openhouse.tables-test-fixtures-common.gradle +++ b/buildSrc/src/main/groovy/openhouse.tables-test-fixtures-common.gradle @@ -21,6 +21,11 @@ dependencies { exclude group: 'org.ow2.asm' exclude group: 'org.xerial' exclude group: 'javax' + // Keep fixtures logging-neutral so consuming apps own their logging stack. + exclude group: 'org.springframework.boot', module: 'spring-boot-starter-log4j2' + exclude group: 'org.apache.logging.log4j' + exclude group: 'org.slf4j' + exclude group: 'log4j' } compileOnly 'org.springframework.boot:spring-boot-starter-tomcat:' + spring_web_version