From 4bc2b1dd1eaa459598381d53df2ef6e7a4c99e83 Mon Sep 17 00:00:00 2001 From: Milton Ortegon Date: Wed, 11 Mar 2026 16:12:41 -0500 Subject: [PATCH 1/8] Skip Spotless from eg-oss-parent on Java 21 Spotless 2.4.1 (inherited from eg-oss-parent) uses google-java-format which requires access to internal JDK compiler APIs not exported in Java 21. Override the skip property to disable it. Co-Authored-By: Claude Opus 4.6 --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 9519d40..5fdd31a 100644 --- a/pom.xml +++ b/pom.xml @@ -30,6 +30,7 @@ 21 + true 0.8.12 3.2.5 3.13.0 From ce76ce7c465881c7195ab316369db81793bb7dd0 Mon Sep 17 00:00:00 2001 From: Milton Ortegon Date: Thu, 12 Mar 2026 13:05:37 -0500 Subject: [PATCH 2/8] Upgrade SpotBugs plugin to 4.8.6 for Java 21 compatibility SpotBugs 4.0.4 (from eg-oss-parent) uses an ASM version that cannot read Java 21 class files (major version 65). Version 4.8.0+ includes an updated ASM that supports Java 21 bytecode. Co-Authored-By: Claude Opus 4.6 --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 5fdd31a..27387dc 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,7 @@ 0.8.12 3.2.5 3.13.0 + 4.8.6 3.2.12 3.2.4 From a5626a8d13899a349203f31cb8b4da197ea27efe Mon Sep 17 00:00:00 2001 From: Milton Ortegon Date: Thu, 12 Mar 2026 13:20:55 -0500 Subject: [PATCH 3/8] Fix spotbugs plugin version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 27387dc..c567bf7 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ 0.8.12 3.2.5 3.13.0 - 4.8.6 + 4.9.8.2 3.2.12 3.2.4 From df8681fcf8e8fcc240c8440c4ed8b36524237372 Mon Sep 17 00:00:00 2001 From: Milton Ortegon Date: Thu, 12 Mar 2026 14:49:33 -0500 Subject: [PATCH 4/8] Fix listener classloading: use thread context classloader instead of JavaUtils With Java 21 / Spring Boot 3.x, JavaUtils.getClassLoader() returns the JVM AppClassLoader which does not include jars from loader.path=lib/. Switching to Thread.currentThread().getContextClassLoader() ensures Spring Boot's LaunchedURLClassLoader is used, which correctly includes external listener jars placed in the lib/ directory at runtime. Fixes ClassNotFoundException for listeners like ApiaryGlueSync loaded from the lib/ directory in containerised deployments. Co-Authored-By: Claude Opus 4.6 --- .../dataplatform/dronefly/app/service/ListenerCatalog.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drone-fly-app/src/main/java/com/expediagroup/dataplatform/dronefly/app/service/ListenerCatalog.java b/drone-fly-app/src/main/java/com/expediagroup/dataplatform/dronefly/app/service/ListenerCatalog.java index 692c565..6fbe25d 100644 --- a/drone-fly-app/src/main/java/com/expediagroup/dataplatform/dronefly/app/service/ListenerCatalog.java +++ b/drone-fly-app/src/main/java/com/expediagroup/dataplatform/dronefly/app/service/ListenerCatalog.java @@ -26,7 +26,6 @@ import java.util.List; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hive.metastore.utils.JavaUtils; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.MetaStoreEventListener; @@ -62,7 +61,7 @@ private List getMetaStoreListeners(Class clazz, HiveConf conf, String for (String listenerImpl : listenerImpls) { try { T listener = (T) Class - .forName(listenerImpl.trim(), true, JavaUtils.getClassLoader()) + .forName(listenerImpl.trim(), true, Thread.currentThread().getContextClassLoader()) .getConstructor(Configuration.class) .newInstance(conf); listeners.add(listener); From d94320f12f31147d7f4d25c0b80e65edcfa7105a Mon Sep 17 00:00:00 2001 From: Milton Ortegon Date: Thu, 12 Mar 2026 15:21:39 -0500 Subject: [PATCH 5/8] Change Docker base image to Amazon Corretto on Amazon Linux 2023 Update base image tag from amazoncorretto:21 (AL2) to amazoncorretto:21-al2023 for Amazon Linux 2023 support. Co-Authored-By: Claude Opus 4.6 --- JAVA21_MIGRATION.md | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/JAVA21_MIGRATION.md b/JAVA21_MIGRATION.md index 4d81409..e3e5149 100644 --- a/JAVA21_MIGRATION.md +++ b/JAVA21_MIGRATION.md @@ -27,7 +27,7 @@ and fix the integration tests that broke as a result of the Hive 4.x upgrade. | Spotless Maven plugin | 2.4.1 | 2.43.0 (google-java-format 1.19.2, Java 21 compatible) | | JaCoCo | 0.8.6 | 0.8.12 | | Surefire | 3.0.0-M5 | 3.2.5 | -| Docker base image | `openjdk:8-jdk` | `amazoncorretto:21` | +| Docker base image | `openjdk:8-jdk` | `amazoncorretto:21-al2023` | Dropped explicit version pins for Logback, Log4j, JUnit, Mockito, AssertJ, and Dropwizard — these are now managed by the Spring Boot BOM. diff --git a/pom.xml b/pom.xml index c567bf7..00accf7 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,7 @@ 3.2.4 3.4.3 amazoncorretto - 21 + 21-al2023 ${docker.from.image}:${docker.from.tag} expediagroup ${project.artifactId} From 593b47ecccabb98b06ac0ad50d3c19bc0521c584 Mon Sep 17 00:00:00 2001 From: Milton Ortegon Date: Thu, 12 Mar 2026 16:17:49 -0500 Subject: [PATCH 6/8] Document ClassNotFoundException root cause and fix for Jib child images Adds Commit 3 section to JAVA21_MIGRATION.md explaining why external listener JARs (added by child Dockerfiles) became invisible after the Java 21 / Hive 4.x migration: Hive 4.x JavaUtils changed getClassLoader() to return AppClassLoader instead of Spring Boot's LaunchedURLClassLoader, and Jib bakes an explicit classpath at image-build time that omits JARs added by child Dockerfile RUN steps. Fix is to override ENTRYPOINT with a wildcard /app/libs/* classpath in the child Dockerfile. Co-Authored-By: Claude Sonnet 4.6 --- JAVA21_MIGRATION.md | 82 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/JAVA21_MIGRATION.md b/JAVA21_MIGRATION.md index e3e5149..d896e40 100644 --- a/JAVA21_MIGRATION.md +++ b/JAVA21_MIGRATION.md @@ -156,6 +156,88 @@ object's `isSet` flags match the deserialized object. --- +## Commit 3 — Fix `ClassNotFoundException` for external listener JARs in Jib-built images + +### Problem + +Child images that extend `drone-fly-app` (e.g. `egdp-docker-glue-sync-listener`) download a +listener JAR into `/app/libs` at Dockerfile build time: + +```dockerfile +FROM expediagroup/drone-fly-app:1.0.9-SNAPSHOT +RUN cd /app/libs && curl ... apiary-gluesync-listener-8.1.13-all.jar +``` + +After upgrading to Java 21 / Hive 4.x, the container failed on startup with: + +``` +Caused by: java.lang.ClassNotFoundException: + com.expediagroup.apiary.extensions.gluesync.listener.ApiaryGlueSync + at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(...) +``` + +### Root cause — two compounding changes + +**Change 1 — Hive 2.x → 4.x changed `JavaUtils.getClassLoader()` behavior** + +| | Hive 2.x | Hive 4.x | +|---|---|---| +| Package | `org.apache.hadoop.hive.common.JavaUtils` | `org.apache.hadoop.hive.metastore.utils.JavaUtils` | +| `getClassLoader()` returns | `Thread.currentThread().getContextClassLoader()` | JVM `AppClassLoader` | + +In a Spring Boot fat-jar launched with `PropertiesLauncher` and `loader.path=lib/`, the thread +context classloader is Spring Boot's `LaunchedURLClassLoader`, which can find JARs placed in +`loader.path`. Hive 2.x `JavaUtils` used this classloader, so external listener JARs were +visible. + +Hive 4.x `JavaUtils` returns the plain JVM `AppClassLoader`, which only sees the `-cp` +argument set at JVM startup — not dynamically placed JARs. + +**Change 2 — Jib bakes the classpath at image-build time** + +Jib generates an `ENTRYPOINT` with an **explicit list** of dependency JARs in the `-cp` +argument (determined at `mvn package` time). JARs downloaded by a child Dockerfile's `RUN` +step land on the filesystem in `/app/libs` but are **never added** to that hardcoded classpath. + +Before the migration this was masked: the Hive 2.x `JavaUtils` used `LaunchedURLClassLoader` +(via PropertiesLauncher), which resolved listener JARs through `loader.path` independently of +the Jib classpath. After the migration both defences were removed simultaneously. + +| | Before migration | After migration | +|---|---|---| +| `JavaUtils.getClassLoader()` returns | `LaunchedURLClassLoader` (sees `loader.path`) | `AppClassLoader` (sees only `-cp`) | +| Listener JAR on classpath? | ✅ Yes (via `loader.path`) | ❌ No (not in Jib `-cp`) | + +### Fix — override `ENTRYPOINT` in child Dockerfile with a wildcard classpath + +`egdp-docker-glue-sync-listener/Dockerfile` was updated to override the Jib-baked entrypoint +with one that uses `/app/libs/*`. The JVM expands the wildcard at **startup time**, picking up +every JAR present in `/app/libs/` — including those downloaded by the `RUN curl` step: + +```dockerfile +ENTRYPOINT ["java", + "--add-opens=java.base/java.lang=ALL-UNNAMED", + "--add-opens=java.base/java.lang.reflect=ALL-UNNAMED", + "--add-opens=java.base/java.io=ALL-UNNAMED", + "--add-opens=java.base/java.net=ALL-UNNAMED", + "--add-opens=java.base/java.nio=ALL-UNNAMED", + "--add-opens=java.base/java.util=ALL-UNNAMED", + "--add-opens=java.base/java.util.concurrent=ALL-UNNAMED", + "--add-opens=java.base/sun.nio.ch=ALL-UNNAMED", + "--add-opens=java.base/java.security=ALL-UNNAMED", + "-cp", "/app/resources:/app/classes:/app/libs/*", + "com.expediagroup.dataplatform.dronefly.app.DroneFly"] +``` + +The `--add-opens` flags match those in the Jib `` configuration in the parent +`pom.xml` so runtime Hadoop/Hive reflection behaviour is preserved. + +> **Note for other child images:** Any Dockerfile that extends `drone-fly-app` and adds JARs +> to `/app/libs` must include this `ENTRYPOINT` override to ensure those JARs are on the +> classpath. + +--- + ## Files changed (summary) ``` From 6e6b8f502a2ee296fdbd8ff6125adc3f5ee548bf Mon Sep 17 00:00:00 2001 From: Milton Ortegon Date: Mon, 16 Mar 2026 11:04:27 -0500 Subject: [PATCH 7/8] Fix critical vulnerabilities --- drone-fly-app/pom.xml | 71 +++++++++++++++++++ drone-fly-core/pom.xml | 18 +++-- .../dronefly/core/DroneFlyCoreTest.java | 2 +- .../core/integration/DummyListener.java | 2 +- pom.xml | 24 +++++++ 5 files changed, 109 insertions(+), 8 deletions(-) diff --git a/drone-fly-app/pom.xml b/drone-fly-app/pom.xml index a91311b..982f276 100644 --- a/drone-fly-app/pom.xml +++ b/drone-fly-app/pom.xml @@ -15,10 +15,16 @@ 1.11.532 0.2.5 4.0.1 + 1.11.4 + 2.0.1 8008 + + org.springframework.boot + spring-boot-starter-web + com.expediagroup drone-fly-core @@ -88,8 +94,30 @@ jdk.tools jdk.tools + + org.apache.logging.log4j + log4j-1.2-api + + + org.apache.avro + avro + + + org.apache.kerby + kerb-admin + + + org.apache.avro + avro + ${avro.version} + + org.apache.hive hive-standalone-metastore-server @@ -131,6 +159,14 @@ tomcat jasper-runtime + + org.apache.hadoop + hadoop-common + + + org.apache.logging.log4j + log4j-1.2-api + @@ -155,12 +191,32 @@ org.apache.hadoop hadoop-client-runtime 3.3.6 + + + org.apache.avro + avro + + + org.apache.kerby + kerb-admin + + org.apache.hadoop hadoop-mapreduce-client-core 3.3.6 test + + + org.apache.avro + avro + + + org.apache.kerby + kerb-admin + + org.springframework @@ -177,6 +233,21 @@ awaitility test + + org.apache.tomcat.embed + tomcat-embed-core + ${tomcat.embeded.version} + + + org.apache.tomcat.embed + tomcat-embed-el + ${tomcat.embeded.version} + + + org.apache.tomcat.embed + tomcat-embed-websocket + ${tomcat.embeded.version} + diff --git a/drone-fly-core/pom.xml b/drone-fly-core/pom.xml index 50aefcc..d5e51d9 100644 --- a/drone-fly-core/pom.xml +++ b/drone-fly-core/pom.xml @@ -26,12 +26,18 @@ org.springframework.boot spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-logging - - + + + org.apache.tomcat.embed + tomcat-embed-core + + + org.apache.tomcat.embed + tomcat-embed-el + + + org.apache.tomcat.embed + tomcat-embed-websocket org.springframework diff --git a/drone-fly-core/src/test/java/com/expediagroup/dataplatform/dronefly/core/DroneFlyCoreTest.java b/drone-fly-core/src/test/java/com/expediagroup/dataplatform/dronefly/core/DroneFlyCoreTest.java index a0ce34e..7355572 100644 --- a/drone-fly-core/src/test/java/com/expediagroup/dataplatform/dronefly/core/DroneFlyCoreTest.java +++ b/drone-fly-core/src/test/java/com/expediagroup/dataplatform/dronefly/core/DroneFlyCoreTest.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2020 Expedia, Inc. + * Copyright (C) 2020-2026 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/drone-fly-integration-tests/src/test/java/com/expediagroup/dataplatform/dronefly/core/integration/DummyListener.java b/drone-fly-integration-tests/src/test/java/com/expediagroup/dataplatform/dronefly/core/integration/DummyListener.java index 1ff92bd..9dfaa06 100644 --- a/drone-fly-integration-tests/src/test/java/com/expediagroup/dataplatform/dronefly/core/integration/DummyListener.java +++ b/drone-fly-integration-tests/src/test/java/com/expediagroup/dataplatform/dronefly/core/integration/DummyListener.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2020 Expedia, Inc. + * Copyright (C) 2020-2026 Expedia, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/pom.xml b/pom.xml index 00accf7..d32770b 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,7 @@ 3.2.12 3.2.4 3.4.3 + 10.1.50 amazoncorretto 21-al2023 ${docker.from.image}:${docker.from.tag} @@ -68,6 +69,29 @@ pom import + + org.springframework.boot + spring-boot-starter-web + ${springframework.boot.version} + + + org.springframework.boot + spring-boot-starter-logging + + + org.apache.tomcat.embed + tomcat-embed-core + + + org.apache.tomcat.embed + tomcat-embed-el + + + org.apache.tomcat.embed + tomcat-embed-websocket + + + From efb9c263f8123efae4a4d0ef87750ed35470ac18 Mon Sep 17 00:00:00 2001 From: Milton Ortegon Date: Mon, 16 Mar 2026 11:52:51 -0500 Subject: [PATCH 8/8] Fix Avro/Kerby vulnerabilities by upgrading Hadoop to 3.4.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upgrading hadoop-client-runtime from 3.3.6 to 3.4.2 resolves vulnerable libraries bundled inside the shaded JAR that Maven exclusions cannot reach: - Avro 1.7.7 → 1.11.3 (CVE-2023-39410, bundled via HADOOP-18880) - Kerby 1.0.1 → 2.0.3 (CVE-2023-25613, bundled via HADOOP-18956) Also removes the now-unnecessary explicit avro/kerb-admin dependency declarations and exclusions that were working around the same issue. Co-Authored-By: Claude Sonnet 4.6 --- drone-fly-app/pom.xml | 45 +++---------------------------------------- 1 file changed, 3 insertions(+), 42 deletions(-) diff --git a/drone-fly-app/pom.xml b/drone-fly-app/pom.xml index 982f276..2acac08 100644 --- a/drone-fly-app/pom.xml +++ b/drone-fly-app/pom.xml @@ -15,8 +15,7 @@ 1.11.532 0.2.5 4.0.1 - 1.11.4 - 2.0.1 + 3.4.2 8008 @@ -98,26 +97,8 @@ org.apache.logging.log4j log4j-1.2-api - - org.apache.avro - avro - - - org.apache.kerby - kerb-admin - - - org.apache.avro - avro - ${avro.version} - - org.apache.hive hive-standalone-metastore-server @@ -190,33 +171,13 @@ org.apache.hadoop hadoop-client-runtime - 3.3.6 - - - org.apache.avro - avro - - - org.apache.kerby - kerb-admin - - + ${hadoop.version} org.apache.hadoop hadoop-mapreduce-client-core - 3.3.6 + ${hadoop.version} test - - - org.apache.avro - avro - - - org.apache.kerby - kerb-admin - - org.springframework