This is an automated email from the ASF dual-hosted git repository.

jongyoul pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git


The following commit(s) were added to refs/heads/master by this push:
     new 5d1ede4dad [ZEPPELIN-6416] Fix zeppelin-interpreter-shaded leak via 
zeppelin-jupyter-interpreter scope
5d1ede4dad is described below

commit 5d1ede4dad1224edac8eaa44f71a53bb5865cd84
Author: Jongyoul Lee <[email protected]>
AuthorDate: Thu May 14 09:55:36 2026 +0900

    [ZEPPELIN-6416] Fix zeppelin-interpreter-shaded leak via 
zeppelin-jupyter-interpreter scope
    
    ### What is this PR for?
    
    Fixes a regression that breaks all Selenium integration tests in 
`zeppelin-integration` (`InterpreterIT`, `AuthenticationIT`, `ZeppelinIT`, 
`InterpreterModeActionsIT`, `SparkParagraphIT`, `PersonalizeActionsIT`, 
`ParagraphActionsIT`) on master since the [ZEPPELIN-6355] zengine→server merge. 
They abort during `MiniZeppelinServer` startup with:
    
    ```
    java.lang.ClassCastException: class 
shaded.org.apache.zeppelin.org.eclipse.aether.repository.RemoteRepository
      cannot be cast to class org.eclipse.aether.repository.RemoteRepository
      (... in unnamed module of loader 'app')
        at 
org.apache.zeppelin.interpreter.InterpreterSettingManager.<init>(InterpreterSettingManager.java:186)
    ```
    
    #### Scope of impact
    
    * **CI**: `frontend.yml` selenium IT job has been red on every master push 
since 2026-05-05, blocking PR merges.
    * **Runtime**: *no production impact*. The Zeppelin distribution does not 
ship `zeppelin-interpreter-shaded.jar` on the server JVM classpath; the two-JVM 
isolation introduced by [ZEPPELIN-3689] still holds for deployed installations. 
The leak is confined to `zeppelin-integration`'s test classpath.
    
    #### Root cause
    
    `zeppelin-jupyter-interpreter/pom.xml` re-declared its dependency on 
`zeppelin-interpreter-shaded` *without scope*, silently overriding the parent's 
`<scope>provided</scope>` and downgrading it to compile. That made the shaded 
jar transitive to anyone depending on `zeppelin-jupyter-interpreter` — in 
particular `spark-interpreter` (because `IPySparkInterpreter` extends 
`IPythonInterpreter` which extends `JupyterKernelInterpreter`), and onward into 
`zeppelin-integration`'s test classpat [...]
    
    Both unshaded `zeppelin-interpreter.jar` and 
`zeppelin-interpreter-shaded.jar` end up in the same test JVM. Because the 
shade plugin keeps `org.apache.zeppelin.dep.*` class names un-relocated (per 
`<exclude>org/apache/zeppelin/**</exclude>`) but rewrites their internal 
`org.eclipse.aether.*` references to 
`shaded.org.apache.zeppelin.org.eclipse.aether.*`, both jars contain 
identically-named `Booter` / `Repository` / `DependencyResolver` classes that 
disagree on the `RemoteRepository`  [...]
    
    The scope-omission has been latent since 2019-12 ([ZEPPELIN-4497]). The 
[ZEPPELIN-6355] merge changed the dependency-resolution order in 
`zeppelin-integration`'s test classpath and exposed it.
    
    ### What type of PR is it?
    
    Bug Fix
    
    ### Todos
    
    * [x] Drop the redundant `zeppelin-interpreter-shaded` redeclaration in 
`zeppelin-jupyter-interpreter/pom.xml` so the parent's `provided` applies
    * [x] Add `maven-enforcer-plugin` `bannedDependencies` rule on 
`zeppelin-server` and `zeppelin-integration` to catch any future leak
    * [x] Verify `mvn dependency:tree` is clean for `zeppelin-server` and 
`zeppelin-integration`
    * [x] Verify the enforcer rule fails as expected when the leak is 
reintroduced (negative test)
    * [ ] Verify `frontend.yml` selenium IT goes green on this PR
    
    ### What is the Jira issue?
    
    * https://issues.apache.org/jira/browse/ZEPPELIN-6416 — this PR
    * https://issues.apache.org/jira/browse/ZEPPELIN-6417 — follow-up: extract 
`zeppelin-jupyter-kernel-client` library so interpreter modules never depend on 
the `%jupyter` magic interpreter artifact directly (structural decoupling)
    
    ### How should this be tested?
    
    ```bash
    # 1. Verify dep tree is clean (no zeppelin-interpreter-shaded)
    ./mvnw -pl zeppelin-server          dependency:tree -Pintegration 
-Pspark-scala-2.12 -Pspark-3.5 | grep zeppelin-interpreter-shaded
    ./mvnw -pl zeppelin-integration     dependency:tree -Pintegration 
-Pspark-scala-2.12 -Pspark-3.5 | grep zeppelin-interpreter-shaded
    # both should produce no matches
    
    # 2. Verify enforcer rule passes
    ./mvnw validate -pl zeppelin-server,zeppelin-integration -Pintegration 
-Pspark-scala-2.12 -Pspark-3.5
    
    # 3. Negative test: reintroduce the leak (revert the jupyter-interpreter 
pom hunk) and run #2;
    #    enforcer should fail with a BannedDependencies error pointing to 
ZEPPELIN-6416.
    
    # 4. Full CI: rely on this PR's frontend.yml run.
    ```
    
    ### Screenshots (if appropriate)
    
    N/A
    
    ### Questions
    
    * Does the license files need to update? **No** — pom-only change.
    * Is there breaking changes for older versions? **No**.
    * Does this needs documentation? **No**.
    
    Closes #5246 from jongyoul/ZEPPELIN-6416-jupyter-shaded-leak-fix.
    
    Signed-off-by: Jongyoul Lee <[email protected]>
---
 zeppelin-integration/pom.xml         | 23 +++++++++++++++++++++++
 zeppelin-jupyter-interpreter/pom.xml | 12 +++++++-----
 zeppelin-server/pom.xml              | 31 +++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/zeppelin-integration/pom.xml b/zeppelin-integration/pom.xml
index 5bdd890b83..fe665f2d01 100644
--- a/zeppelin-integration/pom.xml
+++ b/zeppelin-integration/pom.xml
@@ -185,6 +185,29 @@
             <id>enforce-dependency-convergence</id>
             <phase>none</phase>
           </execution>
+          <execution>
+            <id>enforce-no-interpreter-shaded-leak</id>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <bannedDependencies>
+                  <excludes>
+                    
<exclude>org.apache.zeppelin:zeppelin-interpreter-shaded</exclude>
+                  </excludes>
+                  <searchTransitive>true</searchTransitive>
+                  <message>
+                    zeppelin-interpreter-shaded must NOT appear on the 
zeppelin-integration test classpath.
+                    MiniZeppelinServer instantiates ZeppelinServer in-process; 
mixing shaded and unshaded
+                    org.eclipse.aether.* in the same JVM causes 
ClassCastException in
+                    InterpreterSettingManager. See ZEPPELIN-6416.
+                  </message>
+                </bannedDependencies>
+              </rules>
+              <fail>true</fail>
+            </configuration>
+          </execution>
         </executions>
       </plugin>
     </plugins>
diff --git a/zeppelin-jupyter-interpreter/pom.xml 
b/zeppelin-jupyter-interpreter/pom.xml
index adeda333b5..4651e0f473 100644
--- a/zeppelin-jupyter-interpreter/pom.xml
+++ b/zeppelin-jupyter-interpreter/pom.xml
@@ -84,11 +84,13 @@
       <artifactId>commons-codec</artifactId>
     </dependency>
 
-    <dependency>
-      <groupId>${project.groupId}</groupId>
-      <artifactId>zeppelin-interpreter-shaded</artifactId>
-      <version>${project.version}</version>
-    </dependency>
+    <!--
+      zeppelin-interpreter-shaded is inherited from 
zeppelin-interpreter-parent with <scope>provided</scope>.
+      Do NOT re-declare it here without that scope (ZEPPELIN-6416): doing so 
silently downgrades it to
+      the default compile scope and leaks the shaded jar into transitive 
consumers (e.g. spark-interpreter,
+      and onward into zeppelin-integration's test classpath), which causes 
ClassCastException between
+      shaded and unshaded org.eclipse.aether.repository.RemoteRepository 
inside InterpreterSettingManager.
+    -->
 
     <dependency>
       <groupId>${project.groupId}</groupId>
diff --git a/zeppelin-server/pom.xml b/zeppelin-server/pom.xml
index 6844c96428..6c6b9a0b26 100644
--- a/zeppelin-server/pom.xml
+++ b/zeppelin-server/pom.xml
@@ -593,6 +593,37 @@
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-dependency-plugin</artifactId>
       </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-enforcer-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>enforce-no-interpreter-shaded-leak</id>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <bannedDependencies>
+                  <excludes>
+                    
<exclude>org.apache.zeppelin:zeppelin-interpreter-shaded</exclude>
+                  </excludes>
+                  <searchTransitive>true</searchTransitive>
+                  <message>
+                    zeppelin-interpreter-shaded must NOT appear on the 
zeppelin-server classpath.
+                    The shaded jar is meant for interpreter JVMs only (loaded 
from
+                    
${ZEPPELIN_HOME}/interpreter/zeppelin-interpreter-shaded-*.jar). Mixing the 
shaded
+                    and unshaded org.eclipse.aether.* on the server classpath 
causes ClassCastException
+                    in InterpreterSettingManager. See ZEPPELIN-6416.
+                  </message>
+                </bannedDependencies>
+              </rules>
+              <fail>true</fail>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 

Reply via email to