Skip to content

Commit afb2629

Browse files
author
Developer
committed
Improve AGENTS.md and fix surefire fork warning
- Condense AGENTS.md to ~150 lines for agentic coding use - Add forkCount=0 to surefire to eliminate corrupted channel warning caused by async logging writing to stdout/stderr during tests
1 parent dbd3a04 commit afb2629

2 files changed

Lines changed: 53 additions & 76 deletions

File tree

AGENTS.md

Lines changed: 50 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# AGENTS.md - elf4j-engine
22

3-
An asynchronous Java log engine implementing the ELF4J API. Java 21+, Maven build, MIT license.
3+
Asynchronous Java log engine implementing the ELF4J API. Java 21+, Maven build, MIT license.
44

55
## Build Commands
66

@@ -33,90 +33,66 @@ An asynchronous Java log engine implementing the ELF4J API. Java 21+, Maven buil
3333
## Code Style
3434

3535
- **Java 21** - uses records, pattern matching in `instanceof`, switch expressions, `String.formatted()`
36-
- **Formatter**: Spotless with Palantir Java Format 2.87.0 (Google style). Runs automatically during `process-sources`. Always run `./mvnw spotless:apply` before committing.
36+
- **Formatter**: Spotless with Palantir Java Format 2.87.0 (Google style). Always run `./mvnw spotless:apply` before committing.
3737

3838
### Imports
3939

40-
- Static imports first: `import static org.junit.jupiter.api.Assertions.*`
41-
- Then `java.*`, `javax.*`, external libs, then internal `elf4j.*`
42-
- Use static imports for test assertions and Mockito BDD methods
40+
Static imports first: `import static org.junit.jupiter.api.Assertions.*`. Then `java.*`, `javax.*`, external libs, then internal `elf4j.*`.
4341

4442
### Naming Conventions
4543

46-
| Element | Convention | Example |
47-
|----------------------|------------------|--------------------------------------|
48-
| Classes/Records | PascalCase | `NativeLogger`, `LogEvent` |
49-
| Methods/Variables | camelCase | `isEnabled()`, `logHandler` |
50-
| Constants | UPPER_SNAKE_CASE | `DEFAULT_THROWABLE_MESSAGE` |
51-
| Packages | lowercase | `elf4j.engine.logging` |
52-
| Test Classes | `*Test` suffix | `NativeLoggerTest` |
53-
| Test Methods | camelCase verb | `instanceForDifferentLevel()` |
54-
| Nested Test Classes | camelCase | `class atLevels {}`, `class render {}`|
44+
| Element | Convention | Example |
45+
|---------|------------|---------|
46+
| Classes/Records | PascalCase | `NativeLogger`, `LogEvent` |
47+
| Methods/Variables | camelCase | `isEnabled()`, `logHandler` |
48+
| Constants | UPPER_SNAKE_CASE | `DEFAULT_MESSAGE` |
49+
| Packages | lowercase | `elf4j.engine.logging` |
50+
| Test Classes | `*Test` suffix | `NativeLoggerTest` |
51+
| Test Methods | camelCase verb | `instanceForDifferentLevel()` |
5552

5653
### Null Safety
5754

58-
- Every package has `@NullMarked` (jspecify) in its `package-info.java`
59-
- Use `@Nullable` from `org.jspecify.annotations` (NOT `javax.annotation`)
60-
- All types are non-null by default; annotate nullable params/returns/fields explicitly
55+
Every package has `@NullMarked` in `package-info.java`. Use `@Nullable` from `org.jspecify.annotations` (NOT `javax.annotation`).
6156

6257
### Annotations
6358

64-
- **Lombok**: `@Value` (immutable classes), `@Getter`, `@Builder`, `@EqualsAndHashCode(onlyExplicitlyIncluded = true)`, `@ToString`
59+
- **Lombok**: `@Value`, `@Getter`, `@Builder`, `@EqualsAndHashCode(onlyExplicitlyIncluded = true)`
6560
- **jspecify**: `@NullMarked` (package-level), `@Nullable` (per-element)
6661
- **Thread safety**: `@ThreadSafe` from `javax.annotation.concurrent`
67-
- **JSON**: `@CompiledJson` from DSL-JSON for compile-time serialization
68-
- Lombok and DSL-JSON are annotation-processed at compile time
62+
- **JSON**: `@CompiledJson` from DSL-JSON
6963

70-
### Records and Immutability
64+
### Records & Immutability
7165

72-
- Use records for immutable data carriers: `LogEvent`, `ConfigurationProperties`, `LoggerThresholdLevels`, etc.
73-
- Records commonly implement interfaces (e.g., `TimestampPattern implements RenderingPattern`)
74-
- Use Lombok `@Value` for immutable classes that need more than record semantics
66+
Use records for immutable data carriers. Use Lombok `@Value` for immutable classes needing more than record semantics.
7567

7668
### Design Patterns
7769

78-
- **Interface-based design**: `LogHandler`, `LogEventWriter`, `RenderingPattern`, `PerformanceSensitive`
79-
- **Enum singletons**: `NativeLogServiceManager.INSTANCE` for lifecycle management
80-
- **Private constructors** on utility classes: `StackTraces`, `ElementPatterns`
70+
- Interface-based: `LogHandler`, `LogEventWriter`, `RenderingPattern`
71+
- Enum singletons: `NativeLogServiceManager.INSTANCE`
72+
- Private constructors on utility classes
8173

8274
### Error Handling
8375

84-
- Wrap checked exceptions in unchecked: `UncheckedIOException` for IO errors
85-
- Use `IllegalArgumentException` for invalid configuration/inputs
86-
- Use `assert` for internal invariants
87-
- Avoid checked exceptions in public APIs
88-
- Internal logging uses `elf4j.util.UtilLogger` (e.g., `UtilLogger.WARN.log(...)`)
76+
Wrap checked exceptions in unchecked (`UncheckedIOException`). Use `IllegalArgumentException` for invalid config/inputs. Use `assert` for internal invariants. Internal logging uses `elf4j.util.UtilLogger`.
8977

9078
### Thread Safety
9179

92-
- Logger instances are thread-safe (usable as static/instance/local variables)
93-
- Annotate with `@ThreadSafe` from `javax.annotation.concurrent`
94-
- Use `ReentrantLock` instead of `synchronized` (virtual-thread friendly)
95-
- Prefer immutable records and `@Value` classes
96-
97-
### Javadoc
98-
99-
- Use `/** */` for public API documentation; `/* */` for implementation details
100-
- Javadoc formatting is enforced by Spotless
80+
Logger instances are thread-safe. Use `@ThreadSafe` annotation. Use `ReentrantLock` instead of `synchronized`.
10181

10282
## Testing
10383

104-
- **JUnit 5** (Jupiter) with `@Test`, `@Nested`, `@ParameterizedTest`, `@ValueSource`
105-
- **Mockito** with BDD style: `given()`, `then()`, `willReturn()`, `should()`
106-
- **JUnit assertions** for most tests: `assertEquals`, `assertNotNull`, `assertThrows`, etc.
107-
- **AssertJ** available for fluent assertions
108-
- **Spring `ReflectionTestUtils`** for injecting mocks into Lombok `@Value` classes
84+
- **JUnit 5**: `@Test`, `@Nested`, `@ParameterizedTest`, `@ValueSource`
85+
- **Mockito**: BDD style with `given()`, `then()`, `willReturn()`, `should()`
86+
- **AssertJ**: Available for fluent assertions
87+
- **Spring `ReflectionTestUtils`**: For injecting mocks into Lombok `@Value` classes
10988

11089
### Test Conventions
11190

112-
- Test classes are **package-private** (no `public` modifier)
113-
- Use `@ExtendWith(MockitoExtension.class)` for Mockito integration
114-
- Group related tests with `@Nested` inner classes named after the method under test
115-
- Use `@Mock` for field-level mocks, `mock()` for local/inline mocks
116-
- Mockito uses `mock-maker-inline` (configured in test resources)
117-
- A custom `TestExecutionListener` adds a 2-second delay after tests for async log flushing
118-
119-
### Test Example Pattern
91+
- Test classes are **package-private** (no `public`)
92+
- Use `@ExtendWith(MockitoExtension.class)`
93+
- Group tests with `@Nested` classes named after the method under test
94+
- Use `@Mock` for field mocks, `mock()` for inline mocks
95+
- Tests have a 2-second delay after completion for async log flushing
12096

12197
```java
12298
@ExtendWith(MockitoExtension.class)
@@ -139,31 +115,29 @@ class FooTest {
139115

140116
```
141117
src/main/java/elf4j/engine/
142-
NativeLogger.java # Core Logger (implements elf4j API)
143-
NativeLoggerFactory.java # SPI LoggerFactory entry point
118+
NativeLogger.java # Core Logger (implements elf4j API)
119+
NativeLoggerFactory.java # SPI LoggerFactory entry point
144120
logging/
145-
LogEvent.java # Record: log event data
146-
EventingLogHandler.java # Async log handler
147-
NativeLogServiceManager.java # Enum singleton: lifecycle
148-
configuration/ # Config loading & logger thresholds
149-
pattern/element/ # Log output patterns (timestamp, JSON, etc.)
150-
writer/ # stdout/stderr writers
151-
util/ # Stack trace utilities
152-
src/test/java/elf4j/engine/ # Mirrors main structure
121+
LogEvent.java # Record: log event data
122+
EventingLogHandler.java # Async log handler
123+
NativeLogServiceManager.java # Enum singleton: lifecycle
124+
configuration/ # Config loading & logger thresholds
125+
pattern/element/ # Log output patterns (timestamp, JSON)
126+
writer/ # stdout/stderr writers
127+
util/ # Stack trace utilities
128+
src/test/java/elf4j/engine/ # Mirrors main structure
153129
src/test/resources/
154-
elf4j-test.properties # Test log configuration
130+
elf4j-test.properties # Test log configuration
155131
```
156132

157133
## Key Dependencies
158134

159-
| Dependency | Purpose |
160-
|-------------|----------------------------------------------|
161-
| elf4j | ELF4J logging API (this engine implements it) |
162-
| Lombok | `@Value`, `@Builder`, `@Getter`, code gen |
163-
| jspecify | `@NullMarked`, `@Nullable` null safety |
164-
| DSL-JSON | Compile-time JSON serialization (`@CompiledJson`) |
165-
| conseq4j | Sequenced concurrent async execution |
166-
| Guava | General utilities |
167-
| SLF4J | MDC adapter integration |
168-
| JUnit 5 | Test framework |
169-
| Mockito | Mocking (BDD style) |
135+
| Dependency | Purpose |
136+
|------------|---------|
137+
| elf4j | ELF4J logging API (this engine implements) |
138+
| Lombok | `@Value`, `@Builder`, `@Getter`, code gen |
139+
| jspecify | `@NullMarked`, `@Nullable` null safety |
140+
| DSL-JSON | Compile-time JSON (`@CompiledJson`) |
141+
| conseq4j | Sequenced concurrent async execution |
142+
| JUnit 5 | Test framework |
143+
| Mockito | Mocking (BDD style) |

pom.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@
171171
<groupId>org.apache.maven.plugins</groupId>
172172
<artifactId>maven-surefire-plugin</artifactId>
173173
<version>3.5.4</version>
174+
<configuration>
175+
<forkCount>0</forkCount>
176+
</configuration>
174177
</plugin>
175178
<plugin>
176179
<groupId>org.apache.maven.plugins</groupId>

0 commit comments

Comments
 (0)