From c51ef714348c9edbd62cbf8deab51ed26adb19c1 Mon Sep 17 00:00:00 2001 From: Shahim Sharafudeen Date: Wed, 1 Apr 2026 13:13:50 +0530 Subject: [PATCH 1/2] fix(security): upgrade plexus-utils version to 4.0.3 to address CVE-2025-67030 Co-authored-by: Sayari Mukherjee --- pom.xml | 2 +- resolver/pom.xml | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 893f9f5..b44c7ca 100644 --- a/pom.xml +++ b/pom.xml @@ -126,7 +126,7 @@ org.codehaus.plexus plexus-utils - 3.5.1 + 4.0.3 diff --git a/resolver/pom.xml b/resolver/pom.xml index a81416d..d3edb8e 100644 --- a/resolver/pom.xml +++ b/resolver/pom.xml @@ -80,6 +80,19 @@ maven-compat + + org.codehaus.plexus + plexus-utils + runtime + + + + org.codehaus.plexus + plexus-xml + 4.0.4 + runtime + + org.codehaus.plexus plexus-classworlds From 293b251772d1f35f7f4348542e6b4fe1a5836b6e Mon Sep 17 00:00:00 2001 From: Shahim Sharafudeen Date: Wed, 8 Apr 2026 15:16:36 +0530 Subject: [PATCH 2/2] fix(resolver):Fix classloader issue for Spark/isolated environments --- .../airlift/resolver/ArtifactResolver.java | 107 +++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/resolver/src/main/java/com/facebook/airlift/resolver/ArtifactResolver.java b/resolver/src/main/java/com/facebook/airlift/resolver/ArtifactResolver.java index 0a0c5fe..e79a318 100644 --- a/resolver/src/main/java/com/facebook/airlift/resolver/ArtifactResolver.java +++ b/resolver/src/main/java/com/facebook/airlift/resolver/ArtifactResolver.java @@ -90,6 +90,16 @@ public class ArtifactResolver .add("http://repo.maven.apache.org/maven2/") .build(); + private static final String MAVEN_REPOSITORY_SYSTEM_CLASS = "org.apache.maven.repository.RepositorySystem"; + private static final String PLEXUS_CONTAINER_CLASS = "org.codehaus.plexus.DefaultPlexusContainer"; + private static final String AETHER_REPOSITORY_SYSTEM_CLASS = "org.eclipse.aether.RepositorySystem"; + + /** + * Cached effective ClassLoader to avoid repeated Class.forName checks on every container() call. + * Initialized lazily on first access and reused thereafter. + */ + private static volatile ClassLoader cachedEffectiveClassLoader; + private final RepositorySystem repositorySystem; private final DefaultRepositorySystemSession repositorySystemSession; private final List repositories; @@ -327,7 +337,11 @@ private static PlexusContainer container() { // TODO: move off Plexus DI, use Sisu instead try { - ClassWorld classWorld = new ClassWorld("plexus.core", Thread.currentThread().getContextClassLoader()); + // Fix for Spark and other isolated classloader environments: + // Select an effective ClassLoader by checking multiple candidates to ensure Maven Resolver/Plexus components are discoverable at runtime. + ClassLoader classLoader = getEffectiveClassLoader(); + + ClassWorld classWorld = new ClassWorld("plexus.core", classLoader); ContainerConfiguration cc = new DefaultContainerConfiguration() .setClassWorld(classWorld) @@ -350,4 +364,95 @@ private static PlexusContainer container() throw new RuntimeException("Error loading Maven system", e); } } + + /** + * Determine the most appropriate ClassLoader for initializing Maven Resolver / Plexus components. + * + * In distributed or containerized environments (e.g., Spark, Docker), the Thread Context ClassLoader + * may not have visibility into all required Maven components due to classloader isolation. This can + * lead to ServiceLoader or Plexus lookup failures (e.g., RepositorySystem initialization errors). + * + * This method attempts multiple classloaders in a deterministic order and selects the first one + * that can successfully load required Maven components: + * + * Priority order: + * 1) Thread Context ClassLoader + * - Standard mechanism in typical JVM / Maven execution environments + * - Preferred for test environments where transitive dependencies are loaded + * + * 2) ClassLoader that loaded this class + * - Most reliable in shaded, embedded, or isolated runtime environments (e.g., Spark executors) + * + * 3) System ClassLoader + * - Fallback for environments where dependencies are available globally + * + * The result is cached after the first successful determination to avoid repeated Class.forName + * checks on every container() call, which can be expensive in hot paths. + * + * If none of the candidates pass validation, the method returns the System ClassLoader as the + * most reliable fallback, ensuring a non-null ClassLoader is always returned. + * + * This defensive selection logic helps ensure consistent component discovery across different + * runtime environments without relying on a single classloader assumption. + * + * @return the classloader to use for Maven component discovery (never null) + */ + private static ClassLoader getEffectiveClassLoader() + { + // Return cached value if already determined + if (cachedEffectiveClassLoader != null) { + return cachedEffectiveClassLoader; + } + + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + if (contextClassLoader != null && canLoadMavenComponents(contextClassLoader)) { + cachedEffectiveClassLoader = contextClassLoader; + return cachedEffectiveClassLoader; + } + + ClassLoader thisClassLoader = ArtifactResolver.class.getClassLoader(); + if (thisClassLoader != null && canLoadMavenComponents(thisClassLoader)) { + cachedEffectiveClassLoader = thisClassLoader; + return cachedEffectiveClassLoader; + } + + ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); + if (systemClassLoader != null && canLoadMavenComponents(systemClassLoader)) { + cachedEffectiveClassLoader = systemClassLoader; + return cachedEffectiveClassLoader; + } + + ClassLoader fallback = systemClassLoader != null ? systemClassLoader : thisClassLoader; + if (fallback == null) { + throw new IllegalStateException("Unable to determine a valid ClassLoader for Maven component initialization. " + + "All ClassLoader candidates (context, class, system) are null or cannot load required Maven components."); + } + cachedEffectiveClassLoader = fallback; + + return cachedEffectiveClassLoader; + } + + /** + * Verify whether the provided ClassLoader has visibility into essential Maven + * and Plexus components required for resolver initialization. + * + * @param classLoader the ClassLoader to validate + * @return true if required Maven and Plexus classes are visible to the ClassLoader; + * false otherwise + */ + private static boolean canLoadMavenComponents(ClassLoader classLoader) + { + try { + // Verify visibility of a core Maven repository component + Class.forName(MAVEN_REPOSITORY_SYSTEM_CLASS, false, classLoader); + // Verify visibility of the Plexus container used for component discovery + Class.forName(PLEXUS_CONTAINER_CLASS, false, classLoader); + // Verify visibility of Maven Resolver API (critical for dependency resolution) + Class.forName(AETHER_REPOSITORY_SYSTEM_CLASS, false, classLoader); + return true; + } + catch (ClassNotFoundException e) { + return false; + } + } }