This file provides guidance for AI coding agents working with the Apache Fesod (Incubating) codebase.
Apache Fesod (Incubating) is a Java library for processing spreadsheets (XLS/XLSX/CSV) without OOM, derived from Alibaba EasyExcel. It uses Apache POI under the hood with streaming SAX-based reading. The project is an Apache incubator project and must follow ASF conventions.
- Language: Java 8+ (source/target = 1.8; CI builds on JDK 8, 11, 17, 21, 25 — JDK 17+ is recommended for local development)
- Build: Maven 3.6.3 via
./mvnwwrapper (project docs require 3.9+, but wrapper currently pins 3.6.3; both work) - CI matrix: JDK 8, 11, 17, 21, 25
# Build (runs tests by default, per Maven/Apache convention)
./mvnw clean install
# Fast build without running tests
./mvnw clean install -DskipTests
# Run tests for the library modules only
./mvnw clean package -pl fesod-common,fesod-shaded,fesod-sheet
# Format check / auto-format
./mvnw spotless:check
./mvnw spotless:apply
# Run tests by tag
./mvnw test -Dtest.groups=unit # fast unit tests only
./mvnw test -Dtest.excludedGroups=fuzz # exclude slow fuzz tests
# Full install with javadoc (CI validation)
./mvnw install -B -V
./mvnw javadoc:javadoc- Formatter: Palantir Java Format (enforced by Spotless); Checkstyle checks import restrictions during Maven's
validatephase - Imports: Static imports first, then regular imports; no unused imports (enforced by Spotless
importOrderwith\#|separator) - Import restrictions: Checkstyle allows named static imports from JUnit
Assertions/Assumptions, MockitoMockito/ArgumentMatchers, and AssertJAssertionsthroughAvoidStaticImport.excludes. These libraries have Maventestscope and are unavailable to production compilation. Other static imports and all wildcard imports remain forbidden by Checkstyle. - Indent: 4 spaces
- License header: ASF Apache 2.0 header required on all
.java,.xml,.yml,.tomlfiles. Header template attools/spotless/license-header.txt; enforced by the Hawkeye workflow (.github/workflows/license-check.yml), not Spotless - Lombok: Allowed; config in
lombok.config(toString.callSuper = CALL,equalsAndHashCode.callSuper = CALL) - Commits: English, format
type: description(types:fix,feat,refactor,test,docs,chore,style,dependency)
(root) # Root POM (artifactId: fesod-parent), dependency & plugin management
├── fesod-common/ # Zero-dependency utilities (org.apache.fesod.common.util)
├── fesod-shaded/ # Relocated Spring ASM/cglib (org.apache.fesod.shaded)
├── fesod-bom/ # BOM for downstream consumers
└── fesod-sheet/ # Core library: read/write XLS/XLSX/CSV via POI
├── src/main/java/org/apache/fesod/sheet/
│ ├── FesodSheet.java # Main entry: FesodSheet.read() / FesodSheet.write()
│ ├── analysis/ # Read pipeline (v03=XLS BIFF, v07=XLSX SAX, csv)
│ ├── write/ # Write pipeline (builder, executor, handler chains)
│ ├── metadata/ # Data models, builders, csv/ property/
│ ├── converters/ # Type conversion framework (by Java type)
│ └── util/ # DateUtils, NumberUtils, WorkBookUtil, etc.
└── src/test/java/org/apache/fesod/sheet/
└── testkit/ # Test infrastructure (NOT a separate module)
├── Tags.java # @Tag constants: unit, round-trip, read, write, format, fuzz
├── base/ # AbstractExcelTest (round-trip base)
├── assertions/ # ExcelAssertions fluent API
└── builders/ # TestDataBuilder
- JUnit 5 with
PER_CLASSlifecycle andReplaceUnderscoresdisplay name generator (configured globally infesod-sheet/src/test/resources/junit-platform.properties, not via per-class annotations) - Tags (use
@Tag(Tags.XXX)):unit— pure logic, no file I/Oround-trip— write-then-read viaAbstractExcelTestread/write— single-direction testsformat— CSV/charset/date format testsfuzz— Jazzer property-based (slow, excluded in PR CI)
- Real-file tests: Prefer
AbstractExcelTest.createTempFile()+ExcelAssertionsfor integration tests - Test data: Use
TestDataBuilder.simpleData(n)or model classes intestkit/models/
spotless:check— format- License header (hawkeye)
- Multi-JDK test matrix (8/11/17/21/25)
mvn install+mvn javadoc:javadoc- CodeQL security scan