Reporting and receiving problems via the Problems API Sample
You can open this sample in an IDE that supports Gradle. |
This sample shows how problems can be emitted via the Problems API and how those reports are consumed on the IDE-side. Visit the user manual to learn more about the Problems API.
Running the sample
To run the sample, execute the ./gradlew :sample-ide:importBuild
command.
Project structure
The sample consists of multiple, individual builds composed into a composite build with the following layout
-
sample-project
: A Gradle build with plugins that report problems -
sample-ide
: a project that simulates the IDE functionality. In other words, it uses the Gradle Tooling API to configure and run thesample-project
build and prints the received problem reports received during the process. -
reporters/standard-plugin
shows the usage of the Problems API in a standard Gradle plugin. -
reporters/model-builder-plugin
shows how to use the Problems API to report problems when reading project configuration via the Tooling API. -
reporters/script-plugin
shows how to use the Problems API in a precompiled script plugin.
Emitting a problem
Problems can be emitted via an injected Problems
service.
Here’s an example on how to report a problem from a plugin, including adding custom additional data:
ProblemId problemId = ProblemId.create("adhoc-plugin-deprecation", "Plugin is deprecated", PROBLEM_GROUP);
problems.getReporter().report(problemId, problem -> problem
.contextualLabel("The 'standard-plugin' is deprecated")
.documentedAt("https://github.com/gradle/gradle/README.md")
.severity(Severity.WARNING)
.solution("Please use a more recent plugin version")
.additionalData(SomeAdditionalData.class, additionalData -> {
additionalData.setName("Some name");
additionalData.setNames(java.util.Arrays.asList("name1", "name2"));
})
);
Receiving a problem report
Problems are emitted as Tooling API progress events. They can be processed by registering a ProgressListener
:
@Override
public void statusChanged(ProgressEvent progressEvent) {
if (progressEvent instanceof SingleProblemEvent) {
prettyPrint((SingleProblemEvent) progressEvent);
} else if (progressEvent instanceof ProblemSummariesEvent) {
prettyPrint((ProblemSummariesEvent) progressEvent);
}
}
Receiving custom additional data
To read custom additional data on the Tooling API side, you need a view type.
A view type represents interface or class through which you want to access the underlying data. The API will return an implementation of this type that provides a specific "view" of the data, allowing for type-safe access to underlying data. The view type must be compatible with the actual data structure.
Your view type can include various properties based on the following rules:
-
Simple types (
String
,Integer
,Boolean
, etc.) -
Collections (
List
,Set
,Map
) -
Composite types made up of the above
-
Gradle Provider API types, which are automatically mapped to their corresponding types
Also see the CustomAdditionalData for more information.
This view type can be used to retrieve the additional data stored in the problem instance:
interface SomeDataView {
String getName();
List<String> getNames();
}
This view type can be used to retrieve the additional data stored in the problem instance:
AdditionalData data = problem.getAdditionalData();
if (data instanceof CustomAdditionalData) {
System.out.println(" - additional data: " + ((CustomAdditionalData) data).get(SomeDataView.class).getName());
}