Refactor the rule loading mechanism to use ServiceLoader Pattern#69
Refactor the rule loading mechanism to use ServiceLoader Pattern#69nureka-rodrigo wants to merge 3 commits intoballerina-platform:mainfrom nureka-rodrigo:test
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR refactors the rule loading mechanism to remove the deprecated JSON‑based approach and switch to Java’s ServiceLoader pattern for discovering rule providers. Key changes include the removal of rules.json files and associated JSON parsing code, a new loadRulesFromEnum method that uses ServiceLoader to load rules, and cleanup of obsolete compiler plugin files.
Reviewed Changes
Copilot reviewed 72 out of 73 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| test-compiler-plugins/* | Removal of several plugin files (rules.json, analyzer implementations, README, etc.) related to the JSON‑based rule loading mechanism |
| scan-command/src/main/java/io/ballerina/scan/internal/ProjectAnalyzer.java | Refactored external analyzer loading to use ServiceLoader, replacing old JSON parsing logic |
| Other files (e.g. IssueImpl, ReporterImpl, module-info.java, etc.) | Adjustments to align with the new ServiceLoader pattern and removal of obsolete imports |
| externalAnalyzers.put(pkgDependency.manifest().compilerPluginDescriptor().toString(), | ||
| new ArrayList<>()); |
There was a problem hiding this comment.
When pluginDesc is null, the current code uses pkgDependency.manifest().compilerPluginDescriptor().toString() as the key for externalAnalyzers. This key may be ambiguous or lead to unexpected behavior; consider using a more explicit fallback or skip adding an entry for dependencies without a valid descriptor.
| externalAnalyzers.put(pkgDependency.manifest().compilerPluginDescriptor().toString(), | |
| new ArrayList<>()); | |
| // Skip adding an entry for dependencies without a valid descriptor |
|
|
||
| try (URLClassLoader ucl = URLClassLoader.newInstance(jarUrls.toArray(URL[]::new), | ||
| this.getClass().getClassLoader())) { | ||
| ServiceLoader<RuleProvider> loader = ServiceLoader.load(RuleProvider.class, ucl); |
There was a problem hiding this comment.
It may be useful to log or handle the case where no RuleProvider implementations are found, so that the absence of external rules does not go unnoticed during runtime.
| @@ -0,0 +1,45 @@ | |||
| package io.ballerina.examplestaticcodeanalyzer; | |||
There was a problem hiding this comment.
Usually we have multiple levels for package name like this io.ballerina.runtime.observability.metrics
better to rename this
There was a problem hiding this comment.
These are test-related files that have existed since version 0.1.0. Should I still proceed with the renaming?
|
Co-authored-by: Tharik Kanaka <tharik.kanaka@gmail.com>
|



Purpose
Fixes #66
Approach
Replaced the
JSON-based rule loading mechanism with Java'sServiceLoaderpattern. Before the rules were loaded by parsing arules.jsonfile from the pluginJARusingGson. Rules are now loaded usingServiceLoader<RuleProvider>, where external plugins implement theRuleProviderinterface.Caution
The scan tool is no longer backward compatible with old compiler plugins. Existing plugins will need to be updated to work with this new approach.
Migration Guide for Compiler Plugin Authors
With this change, external compiler plugins need to be updated to use the new
ServiceLoader-based approach:Enumclasses that implement theRuleinterface (see an example implementation):RuleProviderinterface should be created (see an example implementation):META-INF/services/io.ballerina.scan.RuleProviderin the compiler plugin JAR (see an example implementation):rules.jsonfile is no longer needed and can be removed from the plugin resources.Check List