Skip to content

Add AnalysisPlugin interface for tracking analysis decisions#3

Draft
Copilot wants to merge 3 commits intomasterfrom
copilot/fix-b557e6d0-f9ba-4e80-b858-62aea0092bf6
Draft

Add AnalysisPlugin interface for tracking analysis decisions#3
Copilot wants to merge 3 commits intomasterfrom
copilot/fix-b557e6d0-f9ba-4e80-b858-62aea0092bf6

Conversation

Copy link

Copilot AI commented Oct 6, 2025

Implements support for AnalysisPlugin as described in bndtools#6772, providing a way to observe and track analysis decisions made by the Analyzer during bundle creation.

Problem

When building OSGi bundles, bnd analyzes code and determines version ranges for imported packages based on various factors (provider types, explicit directives, version policies). However, there was no way to observe these decisions or understand why a particular version range was chosen, making debugging and auditing difficult.

Solution

This PR introduces a new AnalysisPlugin interface that receives callbacks during the analysis phase with detailed information about version decisions:

public interface AnalysisPlugin extends OrderedPlugin {
    void reportImportVersion(Analyzer analyzer, PackageRef packageRef, 
                           String version, String reason) throws Exception;
    
    default void reportAnalysis(Analyzer analyzer, String category, 
                               String details) throws Exception {}
}

The plugin is called during Analyzer.augmentImports() and provides:

  • The package being imported
  • The calculated version range
  • A human-readable reason (e.g., "provider type detected", "consumer type (default)", "explicit provide directive")

Example Usage

public class LoggingAnalysisPlugin implements AnalysisPlugin {
    @Override
    public void reportImportVersion(Analyzer analyzer, PackageRef packageRef, 
                                   String version, String reason) {
        System.out.printf("Import: %s -> %s (%s)%n", 
                         packageRef.getFQN(), version, reason);
    }
}

In a bnd.bnd file:

-plugin: com.example.LoggingAnalysisPlugin

Changes

  • New interface: aQute.bnd.service.AnalysisPlugin following the existing plugin architecture pattern
  • Analyzer modifications: Added callback invocation in augmentImports() with helper methods buildVersionReason() and reportImportVersion()
  • Comprehensive tests: 3 test scenarios covering plugin invocation, provider/consumer reporting, and ordering
  • Documentation: Complete guide with examples in docs/_plugins/analysisplugin.md

Testing

All tests pass with no regressions:

  • New AnalysisPluginTest: 3 tests ✅
  • Existing Analyzer tests: all passing ✅
  • Existing Plugin tests: all passing ✅
  • Total: 1565 tests, 6 pre-existing unrelated failures

Use Cases

  • Debugging: Understand why bnd chose a particular version range
  • Compliance: Log analysis decisions for audit purposes
  • Optimization: Identify opportunities to optimize version policies
  • Documentation: Generate reports about bundle dependencies

Closes bndtools#6772

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • bndtools.jfrog.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -Xms1024m -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.14-bin/38aieal9i53h9rfe7vjup95b9/gradle-8.14/lib/gradle-daemon-main-8.14.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.14-bin/38aieal9i53h9rfe7vjup95b9/gradle-8.14/lib/agents/gradle-instrumentation-agent-8.14.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.14 (dns block)
  • scans-in.gradle.com
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -Xms1024m -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.14-bin/38aieal9i53h9rfe7vjup95b9/gradle-8.14/lib/gradle-daemon-main-8.14.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.14-bin/38aieal9i53h9rfe7vjup95b9/gradle-8.14/lib/agents/gradle-instrumentation-agent-8.14.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.14 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Suggest to add support for analysis plugins as described in @bndtools/bndbndtools/issues/6772


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits October 6, 2025 08:30
Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com>
Co-authored-by: laeubi <1331477+laeubi@users.noreply.github.com>
Copilot AI changed the title [WIP] Suggest to add support for analysis plugins as described in @bndtools/bnd/issues/6772 Add AnalysisPlugin interface for tracking analysis decisions Oct 6, 2025
Copilot AI requested a review from laeubi October 6, 2025 08:39
* @param details detailed information about the decision
* @throws Exception if an error occurs during processing
*/
default void reportAnalysis(Analyzer analyzer, String category, String details) throws Exception {

Choose a reason for hiding this comment

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

This method is not called anywhere. Is it really needed?

@chrisrueger
Copy link

@laeubi If you want , we can give this a try again e.g. for bnd 7.3.0
One thought on void reportImportVersion(Analyzer analyzer, PackageRef packageRef, String version, String reason)

What do you think about making String reason somehow lazy (e.g. using Memoize) so that the reason is only calculated when there really is a plugin interested in. Might be performance relevant in case the "reason calculation" might get more complex in the future. But maybe that is premature optimization :)

@laeubi
Copy link
Owner

laeubi commented Feb 2, 2026

I think having it as a plugin is already enough as the I can decide if I need the info or not. I also don't think that much complex computations (that not already where taken) are needed here so don't let us over-engineer it here :-)

@chrisrueger
Copy link

Ok. Can you set the PR to ready for review and point it to upstream master, so i can merge?

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.

Add a way for collecting analysis results in the Analyzer

4 participants