https://github.com/gravitee-io/gravitee-archrules-maven-plugin
https://github.com/gravitee-io/gravitee-archrules-maven-plugin
product-am security-scan
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/gravitee-io/gravitee-archrules-maven-plugin
- Owner: gravitee-io
- License: apache-2.0
- Created: 2026-01-27T15:29:52.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-05-26T14:14:57.000Z (about 1 month ago)
- Last Synced: 2026-05-26T16:20:48.998Z (about 1 month ago)
- Topics: product-am, security-scan
- Language: Java
- Size: 79.1 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.adoc
- License: LICENSE.txt
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# Gravitee Architecture Rules Maven Plugin
[](https://download.gravitee.io/#graviteeio-apim/plugins/policies/gravitee-archrules-maven-plugin/)
[](https://github.com/gravitee-io/gravitee-archrules-maven-plugin/blob/master/LICENSE.txt)
[](https://github.com/gravitee-io/gravitee-archrules-maven-plugin/releases)
[](https://circleci.com/gh/gravitee-io/gravitee-archrules-maven-plugin)
A Maven plugin that enforces architectural rules and logging best practices across Gravitee projects using [ArchUnit](https://www.archunit.org/).
## Overview
The Gravitee Architecture Rules Maven Plugin helps maintain code quality and consistency by automatically checking compliance with architectural rules during the build process. It focuses on enforcing logging best practices to ensure proper observability and traceability in distributed systems.
**Key benefits:**
- Catches architectural violations early in the development cycle
- Enforces consistent logging patterns across the codebase
- Improves observability by ensuring proper request context propagation
- Reduces technical debt by preventing anti-patterns
## Architecture Rules
The plugin provides two main rule checks:
### 1. Global Logging Check (`global-logging-check`)
**Purpose:** Prevents direct usage of SLF4J's `LoggerFactory` to enforce standardized logging patterns.
**Rationale:** Direct usage of `LoggerFactory.getLogger()` can lead to inconsistent logger initialization and makes it harder to enforce organization-wide logging standards.
**What it checks:**
- No classes should depend on `org.slf4j.LoggerFactory`
- Exceptions can be configured via allow-lists
**Example violation:**
```java
// ❌ Violation
import org.slf4j.LoggerFactory;
public class MyService {
private static final Logger log = LoggerFactory.getLogger(MyService.class);
}
```
### 2. Execution Context Logging Check (`execution-context-logging-check`)
**Purpose:** Ensures that when an `ExecutionContext` is available as a method parameter, logging is done through the context-aware logger (`ctx.withLogger(log)`) instead of calling the logger directly.
**Rationale:** In request-scoped operations, using context-aware logging automatically includes correlation IDs, API keys, and other contextual information in log entries, significantly improving traceability and debugging capabilities.
**What it checks:**
- Methods that receive an `ExecutionContext` parameter should use `ctx.withLogger(log)` for logging
- Direct calls to `Logger.info()`, `Logger.debug()`, `Logger.error()`, `Logger.warn()`, or `Logger.trace()` are flagged as violations
- **Internal methods (private/protected) called from a method with `ExecutionContext` are also checked** (call graph traversal)
- Legacy `io.gravitee.gateway.api.ExecutionContext` is excluded from checks
- Additional context classes can be configured to extend the rule beyond `ExecutionContext` types (e.g., `KafkaConnectionContext`)
**Example violations:**
```java
// ❌ Violation - Direct call
public void processRequest(ExecutionContext ctx, Request request) {
log.info("Processing request"); // Missing context information
}
//----------------------------------//
// ❌ Violation - Via internal method
public void processRequest(ExecutionContext ctx, Request request) {
processInternal(request); // Calls private method
}
private void processInternal(Request request) {
log.info("Processing"); // VIOLATION detected - parent has ExecutionContext
}
//----------------------------------//
// ✅ Correct - Using withLogger
public void processRequest(ExecutionContext ctx, Request request) {
ctx.withLogger(log).info("Processing request"); // Includes correlation ID, API key, etc.
}
//----------------------------------//
// ✅ Correct - Passing ExecutionContext to internal methods
public void processRequest(ExecutionContext ctx, Request request) {
processInternal(ctx, request);
}
private void processInternal(ExecutionContext ctx, Request request) {
ctx.withLogger(log).info("Processing"); // Uses contextual logger
}
//----------------------------------//
// ❌ Violation - With additional context type (KafkaConnectionContext)
public void processKafkaMessage(KafkaConnectionContext ctx, Message msg) {
log.info("Processing message"); // Missing Kafka context information
}
// ✅ Correct - Using withLogger with additional context type
public void processKafkaMessage(KafkaConnectionContext ctx, Message msg) {
ctx.withLogger(log).info("Processing message"); // Includes Kafka connection details
}
```
**Note:** To scan additional context types like `KafkaConnectionContext`, you must configure the `additionalContextClasses` parameter (see [Advanced Configuration](#advanced-xml-configuration)).
## Configuration
### Basic XML Configuration
Add the plugin to your `pom.xml`:
```xml
io.gravitee.maven
gravitee-archrules-maven-plugin
1.0.0-SNAPSHOT
check-global-logging
global-logging-check
check-execution-context-logging
execution-context-logging-check
```
### Advanced XML Configuration
Customize rule checks with allow-lists and exclusions:
```xml
io.gravitee.maven
gravitee-archrules-maven-plugin
1.0.0-SNAPSHOT
check-global-logging
global-logging-check
com.example.LegacyService
com.example.ThirdPartyAdapter
Test
TestHelper
com.example.legacy..
com.example.generated..
check-execution-context-logging
execution-context-logging-check
com.example.SpecialHandler
ConfigurationEvaluator
com.example.tests..
com.example.FakeExecutionContext
com.example.MockExecutionContext
io.gravitee.node.api.kafka.KafkaConnectionContext
com.example.CustomContext
```
### CLI Configuration with `-D` Properties
All plugin parameters can be configured via command-line properties using the `gravitee.archrules.*` prefix:
```bash
# Skip architecture checks entirely
mvn verify -Dgravitee.archrules.skip=true
# Continue build even if violations are found (warnings only)
mvn verify -Dgravitee.archrules.failOnError=false
# Global logging check with allow-lists
mvn verify \
-Dgravitee.archrules.allowList=com.example.LegacyService,com.example.ThirdPartyAdapter \
-Dgravitee.archrules.allowListSuffixes=Test,TestHelper,ConfigurationEvaluator \
-Dgravitee.archrules.packagesToExclude=com.example.legacy..,com.example.generated..
# Execution context logging check with specific configuration
mvn gioArchRules:execution-context-logging-check \
-Dgravitee.archrules.allowList=com.example.SpecialHandler \
-Dgravitee.archrules.packagesToExclude=com.example.tests.. \
-Dgravitee.archrules.ignoreExecutionContextClasses=com.example.FakeExecutionContext,com.example.MockExecutionContext \
-Dgravitee.archrules.additionalContextClasses=io.gravitee.node.api.kafka.KafkaConnectionContext
# Run only specific goal
mvn gioArchRules:global-logging-check
mvn gioArchRules:execution-context-logging-check
# Combine multiple parameters
mvn verify \
-Dgravitee.archrules.allowList=com.example.LegacyClass \
-Dgravitee.archrules.allowListSuffixes=Test \
-Dgravitee.archrules.failOnError=false
```
**Note:** When configuring lists via CLI, use comma-separated values (e.g., `class1,class2,class3`). Maven will automatically parse them into the appropriate list format.
## Configuration Parameters
### Common Parameters (All Goals)
| Parameter | Type | Default | CLI Property | Description |
|-----------|------|---------|--------------|-------------|
| `skip` | `boolean` | `false` | `gravitee.archrules.skip` | Skip all architecture rule checks |
| `failOnError` | `boolean` | `true` | `gravitee.archrules.failOnError` | Fail the build when violations are found (if false, only warnings are logged) |
| `allowList` | `List` | `[]` | `gravitee.archrules.allowList` | Fully qualified class names exempt from rule checks (comma-separated in CLI) |
| `allowListSuffixes` | `List` | `[]` | `gravitee.archrules.allowListSuffixes` | Class name suffixes exempt from rule checks (e.g., "Test", "ConfigurationEvaluator"; comma-separated in CLI) |
| `packagesToExclude` | `List` | `[]` | `gravitee.archrules.packagesToExclude` | Package patterns to exclude from scanning (supports ArchUnit syntax like "com.example.."; comma-separated in CLI) |
### Execution Context Logging Check Only
| Parameter | Type | Default | CLI Property | Description |
|-----------|------|---------|--------------|-------------|
| `ignoreExecutionContextClasses` | `List` | `[]` | `gravitee.archrules.ignoreExecutionContextClasses` | Fully qualified class names of ExecutionContext implementations to ignore (e.g., test doubles; comma-separated in CLI) |
| `additionalContextClasses` | `List` | `[]` | `gravitee.archrules.additionalContextClasses` | Fully qualified class names of additional context types to scan (e.g., `io.gravitee.node.api.kafka.KafkaConnectionContext`; comma-separated in CLI) |
## Execution Phase
Both goals run by default during the **`verify`** phase of the Maven lifecycle. This ensures architectural compliance is checked before integration tests and deployment.
## Tips and Best Practices
- **Start small:** Begin by running the checks on new modules or packages, then gradually expand coverage
- **Use allow-lists wisely:** Allow-lists are useful for legacy code, but avoid overusing them—they can hide technical debt
- **Leverage suffixes:** Use `allowListSuffixes` for patterns like test classes, generated code, or configuration evaluators
- **Package exclusions:** Use ArchUnit's `..` notation (e.g., `com.example.legacy..`) to exclude entire package trees
- **CI/CD integration:** These checks run automatically during `mvn verify` or `mvn install`, ensuring violations are caught before merge
- **Incremental adoption:** If you have a large legacy codebase, consider creating separate executions with different configurations for new vs. legacy code
## Troubleshooting
**Q: The plugin fails but I don't see any violation details**
A: Check the Maven output carefully—ArchUnit prints detailed violation reports including file locations and line numbers.
**Q: Can I run the checks on test code?**
A: By default, the plugin scans `target/classes` (main code). To scan test classes, you would need to configure `outputDirectory` to point to `target/test-classes`.
**Q: How do I temporarily disable the checks?**
A: Use `-Dgravitee.archrules.skip=true` or add `true` to the plugin configuration.
**Q: What's the difference between `allowList` and `ignoreExecutionContextClasses`?**
A: `allowList` exempts classes from **all** rule checks in that goal, while `ignoreExecutionContextClasses` specifically excludes certain types from being considered as "ExecutionContext" (useful for test doubles).
## Requirements
- **Java:** 21+
- **Maven:** 3.9.6+
- **ArchUnit:** 1.2.1
## License
Copyright © 2015 The Gravitee team (http://gravitee.io)
Licensed under the Apache License, Version 2.0