Skip to content

Conversation

@karenyrx
Copy link
Contributor

@karenyrx karenyrx commented Nov 26, 2025

…odule/plugin

Description

Currently, k-nn -> extends transport-grpc and neural-search -> extends knn, but when neural-search tries to extend transport-grpc (which is already in knn) it gives jar hell when trying to build

Test Plan

Tested with opensearch-project/neural-search#1665

  • Before: neural-search fails to build with following error:

| Caused by: java.lang.IllegalStateException: jar hell! extended plugins [opensearch-knn, transport-grpc] have duplicate codebases with each other: [file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/error_prone_annotations-2.24.1.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/protobufs-0.24.0.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/grpc-protobuf-lite-1.75.0.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/failureaccess-1.0.2.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/grpc-stub-1.75.0.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/perfmark-api-0.27.0.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/guava-33.2.1-jre.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/grpc-netty-shaded-1.75.0.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/grpc-api-1.75.0.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/grpc-core-1.75.0.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/transport-grpc-spi-3.4.0-SNAPSHOT.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/grpc-protobuf-1.75.0.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/grpc-util-1.75.0.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/grpc-services-1.75.0.jar, file:/home/runner/work/neural-search/neural-search/build/testclusters/integTest-0/distro/3.4.0-ARCHIVE/modules/transport-grpc/transport-grpc-3.4.0-SNAPSHOT.jar]
  • After:
    Newly emitted log shows the the intersection of all shared ancestor dependencies between opensearch-knn and transport-grpc:
{"level":"INFO","timestamp":"2025-11-26T08:11:04,080","thread":"main","file":"PluginsService.java", "line":"734","message":"Plugin [opensearch-neural-search] extends multiple plugins/modules that share common dependencies: [file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/transport-grpc-spi-3.3.1.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/failureaccess-1.0.2.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/guava-33.2.1-jre.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/protobufs-0.24.0.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/grpc-api-1.75.0.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/transport-grpc-3.3.1.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/grpc-services-1.75.0.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/grpc-protobuf-1.75.0.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/grpc-netty-shaded-1.75.0.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/perfmark-api-0.27.0.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/grpc-core-1.75.0.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/grpc-util-1.75.0.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/grpc-protobuf-lite-1.75.0.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/error_prone_annotations-2.24.1.jar, file:/usr/share/opensearch-all/opensearch-v3.x/modules/transport-grpc/grpc-stub-1.75.0.jar]. This is expected when extended plugins share common ancestors."}

Hybrid queries are successfully discovered via transport-grpc-spi

{"level":"INFO","timestamp":"2025-11-26T08:11:04,496","thread":"main","file":"GrpcPlugin.java", "line":"101","message":"Discovered QueryBuilderProtoConverter extension: org.opensearch.knn.grpc.proto.request.search.query.KNNQueryBuilderProtoConverter (handles: KNN)"}
{"level":"INFO","timestamp":"2025-11-26T08:11:04,496","thread":"main","file":"GrpcPlugin.java", "line":"101","message":"Discovered QueryBuilderProtoConverter extension: org.opensearch.neuralsearch.grpc.proto.request.search.query.HybridQueryBuilderProtoConverter (handles: HYBRID)"}
{"level":"INFO","timestamp":"2025-11-26T08:11:04,496","thread":"main","file":"GrpcPlugin.java", "line":"108","message":"Successfully loaded 2 QueryBuilderProtoConverter extensions"}

Hybrid queries are successfully registered with transport-grpc:

{"level":"INFO","timestamp":"2025-11-26T08:11:07,760","thread":"main","file":"GrpcPlugin.java", "line":"318","message":"Processing external converter: org.opensearch.neuralsearch.grpc.proto.request.search.query.HybridQueryBuilderProtoConverter (handles: HYBRID)"}
{"level":"INFO","timestamp":"2025-11-26T08:11:07,761","thread":"main","file":"GrpcPlugin.java", "line":"326","message":"Injected registry into converter: org.opensearch.neuralsearch.grpc.proto.request.search.query.HybridQueryBuilderProtoConverter"}
{"level":"INFO","timestamp":"2025-11-26T08:11:07,761","thread":"main","file":"QueryBuilderProtoConverterSpiRegistry.java", "line":"121","message":"Registered query converter for HYBRID: org.opensearch.neuralsearch.grpc.proto.request.search.query.HybridQueryBuilderProtoConverter"}
{"level":"INFO","timestamp":"2025-11-26T08:11:07,761","thread":"main","file":"GrpcPlugin.java", "line":"331","message":"Successfully injected registry and registered all 2 external converters"}
{"level":"INFO","timestamp":"2025-11-26T08:11:07,761","thread":"main","file":"QueryBuilderProtoConverterSpiRegistry.java", "line":"85","message":"Set registry on 26 converters"}

Related Issues

Resolves #20100

Check List

  • Functionality includes testing.
  • API changes companion pull request created, if applicable.
  • Public documentation issue/PR created, if applicable.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Summary by CodeRabbit

  • Bug Fixes
    • Relaxed jar hell validation for extended plugins with shared transitive dependencies. The system now logs informational messages with plugin names and overlap details instead of blocking deployment. This allows extended plugins to share common dependencies while maintaining validation checks for conflicts with core libraries and other plugins.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions github-actions bot added bug Something isn't working Plugins labels Nov 26, 2025
@karenyrx karenyrx changed the title plugin service allow multiple extended plugins both extend the same m… [Plugins] Relax jar hell check when extended plugins share transitive dependencies Nov 26, 2025
@github-actions
Copy link
Contributor

❌ Gradle check result for d4e646b: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@peterzhuamazon
Copy link
Member

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 26, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Nov 26, 2025

Walkthrough

The pull request relaxes the jar hell check in OpenSearch's plugin loader to permit extended plugins sharing transitive dependencies. Instead of throwing an IllegalStateException when multiple extended plugins have overlapping classpaths, the code now logs an informational message with the plugin name and overlapping URLs, allowing plugin loading to continue.

Changes

Cohort / File(s) Summary
Changelog entry
CHANGELOG.md
Added unreleased note documenting the relaxation of jar hell checks for extended plugins sharing transitive dependencies.
Plugin jar hell check
server/src/main/java/org/opensearch/plugins/PluginsService.java
Modified checkBundleJarHell method: changed behavior when extended plugins have overlapping classpaths from throwing IllegalStateException to logging informational message with plugin name and intersection details; control flow continues without exception.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Straightforward logic change from exception-throwing to logging in a single conditional block
  • Changelog update is routine documentation
  • Change scope is narrow and isolated to one method
  • No public API changes or method signature modifications

Poem

🐰 Plugins once clashed in jar hell's deep night,
Now extended friends share codebases right!
With shared dependencies, no more the fright—
Just info logs whisper, all's cozy and bright!

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: relaxing jar hell checks for extended plugins sharing transitive dependencies.
Description check ✅ Passed The description covers the problem, test plan with concrete examples, before/after behavior, related issue, and checklist compliance.
Linked Issues check ✅ Passed The changes in PluginsService.java directly address issue #20100 by replacing the IllegalStateException with logging when extended plugins share transitive dependencies, allowing the code to continue and rely on JarHell.checkJarHell for real conflicts.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objectives: CHANGELOG.md documents the fix, and PluginsService.java implements the jar hell relaxation for extended plugins sharing transitive dependencies.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@peterzhuamazon
Copy link
Member

This PR raised before coderabbitai is online on the repo, so I manually trigger it here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
server/src/main/java/org/opensearch/plugins/PluginsService.java (1)

728-735: Relaxed transitive-overlap check matches intended semantics; logging looks correct

The new info log on Lines [731-735] for intersection between accumulated urls and pluginUrls correctly turns what used to be a fatal “duplicate codebases among extended plugins” error into diagnostic output, while:

  • Still throwing when the candidate plugin’s own bundle.urls intersect any extended plugin’s URLs (real duplicate codebase for the plugin itself).
  • Still running JarHell.checkJarHell on:
    • The growing union of extended-plugins’ URLs, and
    • The union of those URLs plus the bundle’s own URLs, and
    • The plugin+core union later in the method.

This cleanly solves the “multiple plugins extend the same ancestor/module” diamond case without weakening actual jar-hell protection.

If you expect many such configurations in production, you might consider downgrading this to debug once the behavior is well validated to avoid noisy logs, but info is reasonable initially for visibility.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 468f944 and d4e646b.

📒 Files selected for processing (2)
  • CHANGELOG.md (1 hunks)
  • server/src/main/java/org/opensearch/plugins/PluginsService.java (1 hunks)
🔇 Additional comments (1)
CHANGELOG.md (1)

36-36: Changelog entry accurately documents the behavioral change

The new “Relax jar hell check…” bullet on Line [36] is clear, correctly scoped to extended plugins sharing transitive dependencies, and links to the right PR. No further edits needed.

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

Labels

bug Something isn't working Plugins

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Jar Hell Error When Multiple Plugins Extend the Same Module/Plugin

2 participants