Skip to content

[ZEPPELIN-6416] Fix zeppelin-interpreter-shaded leak via zeppelin-jupyter-interpreter scope#5246

Open
jongyoul wants to merge 1 commit intoapache:masterfrom
jongyoul:ZEPPELIN-6416-jupyter-shaded-leak-fix
Open

[ZEPPELIN-6416] Fix zeppelin-interpreter-shaded leak via zeppelin-jupyter-interpreter scope#5246
jongyoul wants to merge 1 commit intoapache:masterfrom
jongyoul:ZEPPELIN-6416-jupyter-shaded-leak-fix

Conversation

@jongyoul
Copy link
Copy Markdown
Member

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 classpath via <dependency>spark-interpreter</dependency>.

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 type. Whichever the classloader picks first wins; post-merge the shaded variant wins, so dependencyResolver.getRepos() returns shaded RemoteRepository instances which fail to cast to the unshaded type expected by InterpreterSettingManager.

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

  • Drop the redundant zeppelin-interpreter-shaded redeclaration in zeppelin-jupyter-interpreter/pom.xml so the parent's provided applies
  • Add maven-enforcer-plugin bannedDependencies rule on zeppelin-server and zeppelin-integration to catch any future leak
  • Verify mvn dependency:tree is clean for zeppelin-server and zeppelin-integration
  • 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?

How should this be tested?

# 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.

…yter-interpreter scope

zeppelin-jupyter-interpreter/pom.xml redeclared its dependency on
zeppelin-interpreter-shaded without specifying scope, defaulting it to
compile and overriding the parent (zeppelin-interpreter-parent)'s
provided scope. This made the shaded jar transitive to anything that
depends on zeppelin-jupyter-interpreter (notably spark-interpreter), and
in turn into zeppelin-integration's test classpath. Mixing the shaded
and unshaded org.eclipse.aether.* in the same JVM produced
ClassCastException at InterpreterSettingManager:186 during MiniZeppelinServer
startup, breaking all 7 selenium IT cases since the ZEPPELIN-6355 zengine
merge changed the dependency-resolution order that previously masked the
issue.

Production runtime is not affected: the Zeppelin distribution does not
ship zeppelin-interpreter-shaded on the server JVM classpath, so the
two-JVM isolation introduced by ZEPPELIN-3689 still holds for deployed
installations.

Changes:
- zeppelin-jupyter-interpreter/pom.xml: drop the local redeclaration of
  zeppelin-interpreter-shaded so the parent's <scope>provided</scope>
  applies (matching every other interpreter module). A comment documents
  why the redeclaration must not return.
- zeppelin-server/pom.xml: add a maven-enforcer-plugin bannedDependencies
  rule that fails the build if zeppelin-interpreter-shaded ever appears
  on the server classpath (compile or test, transitive).
- zeppelin-integration/pom.xml: same enforcer rule guarding the
  in-process MiniZeppelinServer test classpath.

A follow-up (ZEPPELIN-6417) tracks the structural decoupling of
JupyterKernelInterpreter into a separate kernel-client library so
interpreter modules never depend on the %jupyter magic interpreter
artifact directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jongyoul jongyoul force-pushed the ZEPPELIN-6416-jupyter-shaded-leak-fix branch from 6de5674 to 4abec5c Compare May 10, 2026 09:11
@jongyoul jongyoul marked this pull request as ready for review May 10, 2026 10:36
Copilot AI review requested due to automatic review settings May 10, 2026 10:36
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a Maven dependency-scope regression where zeppelin-interpreter-shaded leaks onto the in-process server JVM test classpath (notably zeppelin-integration Selenium ITs), causing ClassCastException due to shaded vs unshaded org.eclipse.aether.* type mismatches.

Changes:

  • Removes the redundant zeppelin-interpreter-shaded dependency re-declaration from zeppelin-jupyter-interpreter so it correctly inherits provided scope from zeppelin-interpreter-parent.
  • Adds maven-enforcer-plugin bannedDependencies checks in zeppelin-server and zeppelin-integration to prevent future shaded-jar leakage (including transitive paths).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
zeppelin-server/pom.xml Adds an enforcer rule to ban org.apache.zeppelin:zeppelin-interpreter-shaded from the server module dependency graph (including transitives).
zeppelin-jupyter-interpreter/pom.xml Drops the dependency re-declaration that was overriding inherited provided scope and leaking the shaded jar transitively.
zeppelin-integration/pom.xml Adds an enforcer rule to ban org.apache.zeppelin:zeppelin-interpreter-shaded from the integration-test classpath (including transitives).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jongyoul
Copy link
Copy Markdown
Member Author

@pan3793 @Reamer @tbonelee @ParkGyeongTae Could you please review this PR? it just fixes the CI only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants