This file contains the design from the Error Code Crawler Maven Plugin (ECM). The design fulfills the requirements we described in requirements.md.
arch~components~1
ECM consists of the following main components:
- A crawler: Components that reads extracts the error code declarations from Java code into a Java class structure
- A validator: Component that validates the declarations
- A config parser: Component that parses the
error_code_config.yml
- A report writer (missing): Component that writes the error code report
Needs: dsn
dsn~error-declaration-crawler~1
For implementing the error declaration crawler we decided to use Spoon. This library can create an Abstract Syntax Tree (AST) from Java source code. The error declaration crawler then goes over the AST and searches for invocations of the error-reporting API.
In contrast to using regular expression matching, this approach has the following advantages:
- The crawler gets the source code in a unified form. Whitespace and line breaks can't cause errors
- The crawler can handle string concatenation with constants in error messages
One could want to support string concatenation with variables or crawl error declarations like:
class Test {
void test() {
var builder = ExaError.messageBuilder("E-TEST-1");
if (x) {
builder.message("Message 1");
} else {
builder.message("Message 2");
}
throw new IllegalStateException(builder.toString());
}
}
Supporting this is, however, not desirable since it make it impossible to determine the error message using static code analysis, since the error message will only be determined at runtime.
Instead, just rewrite your code to:
class Test {
void test() {
if (x) {
throw new IllegalStateException(ExaError.messageBuilder("E-TEST-1").message("Message 1").toString());
} else {
throw new IllegalStateException(ExaError.messageBuilder("E-TEST-2").message("Message 2").toString());
}
}
}
Covers:
arch~components~1
Needs: impl, utest
dsn~validator~1
The validator consists of multiple sub-validators for the different aspects. The validator executes them.
Covers:
arch~components~1
Needs: impl, itest
dsn~identifier-validator~2
The identifier validator checks that the error identifiers have the correct format using a regular expression.
Covers:
req~verify-error-identifier-format~2
Needs: impl, utest, itest
dsn~duplication-validator~1
The duplication validator checks that each error identifier is unique.
The requirements only require that the whole identifier is unique. We decided however, to be more strict and also not allow identifiers that only differ by the number. So this implementation considers E-TEST-1
and F-TEST-1
as duplicate. This approach has two advantages:
- Developers can simply change the severity of the code without searching for a new number (For example change
E-TEST-1
toF-TEST-1
) - For generating the next free code developers only want to keep track of the highest used number. By that limitation they only need to keep track of the highest number per identifier and not per project-shorttag severity combination.
Covers:
req~verify-no-duplicate-error-codes~1
Needs: impl, utest, itest
dsn~empty-parameter-name-validator~1
Covers:
verify-no-empty-parameter-names~1
Needs: impl, utest, itest
dsn~parameters-validator~1
Covers:
req~verify-parameters-are-provided~1
Needs: impl, utest, itest
dsn~error-identifier-belongs-to-package-validator~1
Covers:
req~verify-error-codes-declared-in-correct-package~1
Needs: impl, utest, itest
dsn~config-parser~1
This component reads the error_code_config.yml
and does some basic syntax validation.
Covers:
arch~components~1
Needs: impl, utest
dsn~report-writer~1
ECM uses the report writer from error-code-model-java
to write the JSON report.
Needs: impl, itest
Covers:
feat~create-error-code-report~1
dsn~mvn-plugin~1
We decided to implement ECM as a maven plugin. By that it can be executed from the Maven build and has direct access to the Maven Project.
An alternative would be to implement ECM as standalone app and then add a Maven-plugin that invokes it. However, since we currently only use Maven as build system for Java we did not add this layer of decoupling.
Covers:
feat~mvn-integration~1
dsn~mvn-verify-goal~1
ECM adds a Maven goal called verify
. Using this goal, users can run the validation.
Covers:
feat~mvn-integration~1
Needs: impl, itest
dsn~skip-execution~1
Users can disable the execution of ECM by setting the java property error-code-crawler.skip
to true
.
Covers:
req~skip-execution~1
Needs: impl, itest, utest
dsn~create-target-directory~1
ECM error code report writer creates the project target
directory if it does not exist (see ProjectReportWriter
).
Covers:
feat~create-error-code-report~1
Needs: impl, utest
dsn~src-directories-1
By default, ECM crawls src/main/java
and src/main/test
.
Covers:
feat~src-directories
Needs: impl, itest
dsn~src-directory-override
Users can override the sources to crawl. ECM supports this by a sourcePaths
property in the plugin configuration in the pom.xml
.
Covers:
feat~src-directory-override
Needs: impl, itest
dsn~no-src-location-in-report-for-custom-source-path~1
ECM adds the source position of each error message declaration to the error-code-report. That allows the catalog to generate links for jumping to the source location.
For projects that specify a different source (typically code generated by the delombok plugin) that's not possible, since the code is just generated and not checked into the repository. For that reason we decided not to report the source location for projects that specify a sourcePath
.
An alternate solution special for deloboked code would be to replace the prefix of the generated directory with the original source directory. However then the line number would not fit, since Lombok expands the annotations. That could again be solved by searching in the original source for the error tag and by that determining the line number. However, we decided against this solution since for now the source position is not important enough.
Needs: impl, utest
dsn~mvn-plugin-thread-safe~1
In order to support parallel execution of the maven plugin and remove WARNING messages during parallel execution, maven plugin should be marked as thread-safe. The following checklist was used to make sure that plugin is thread-safe (see https://cwiki.apache.org/confluence/display/MAVEN/Parallel+builds+in+Maven+3 for more details):
- Checked that no static fields/variables in plugin/plugin code are subject to threading problems.
- Special attention was paid to find mutable static member variables of not thread-safe classes.
- No mutable static member variables of not thread-safe classes were found.
- Checked thread safety of any other third party libraries and made sure that they don't have mutable static member variables of not thread-safe classes.
- The plugin does not use singleton plexus components in
components.xml
. - The plugin does not use any known tainted libraries.
Covers:
feat~mvn-plugin-parallel-execution~1
Needs: impl