PCRE4J is a Java binding for the PCRE2 (Perl Compatible Regular Expressions 2) library, providing three API layers:
- High-level:
java.util.regex-compatible API (regexmodule) - Mid-level: PCRE4J wrapper API (
libmodule) - Low-level: Direct PCRE2 API access (
apimodule)
License: LGPL-3.0 Java Version: 21 (LTS)
pcre4j/
├── api/ → IPcre2 interface (backend contract, ~290 PCRE2 constants)
├── lib/ → Core wrapper (Pcre2Code, contexts, options (`option`), exceptions (`exception`), utilities, shared test fixtures)
├── jna/ → JNA backend (Java Native Access implementation)
├── ffm/ → FFM backend (Multi-Release JAR: Java 21 preview + Java 22+ GA)
├── regex/ → java.util.regex compatibility layer (Pattern, Matcher)
Dependencies: api ← (lib | jna | ffm), (api + lib) ← regex
# Full build with tests
./gradlew build -Dpcre2.library.path=/usr/lib/x86_64-linux-gnu
# Run tests only
./gradlew test -Dpcre2.library.path=/usr/lib/x86_64-linux-gnu
# Module-specific tests
./gradlew jna:test ffm:test -Dpcre2.library.path=/usr/lib/x86_64-linux-gnu
# Code style check
./gradlew checkstyleMain checkstyleTest
# Coverage report
./gradlew build jacocoAggregatedTestReport -Dpcre2.library.path=/usr/lib/x86_64-linux-gnumacOS library path: -Dpcre2.library.path=/opt/homebrew/lib (Apple Silicon) or /usr/local/lib (Intel)
See CONTRIBUTING.md for PCRE2 installation instructions per platform.
Library discovery priority:
pcre2.library.pathsystem propertyjna.library.path(JNA) /java.library.path(FFM)- System library path
- Automatic discovery fallback (
Pcre2LibraryFinder):pcre2-config,pkg-config, well-known platform paths- Disable with
-Dpcre2.library.discovery=false
- Disable with
See CONTRIBUTING.md for the base code conventions (line length, indentation, charset, copyright header, JavaDoc).
Additional naming conventions:
- Classes:
Pcre2Code,Pcre2CompileOption - Enum values:
CASE_INSENSITIVE,DOTALL - Methods:
compile(),match(),getErrorMessage()
- Framework: JUnit 5 (Jupiter) with parameterized tests
- Backend testing: Shared base class
org.pcre4j.test.Pcre2Testsextended by backend-specific tests - Parameterization: Tests run against both JNA and FFM backends via
@MethodSource
The FFM module is a Multi-Release JAR (MRJAR):
- Java 21 (base): Uses FFM as a preview feature, requires
--enable-previewfor compiler, JVM, and Javadoc - Java 22+ (MRJAR overlay): Uses finalized FFM API, no preview flags needed
- Gradle handles
--enable-previewflags automatically for the Java 21 base compilation and tests
| Class | Module | Purpose |
|---|---|---|
IPcre2 |
api | Backend interface contract |
Pcre2Code |
lib | Compiled pattern wrapper |
Pcre2MatchData |
lib | Match result container |
Pcre4j |
lib | Bootstrap singleton for backend selection |
Pcre4jUtils |
lib | Static utility methods |
Pattern |
regex | java.util.regex-compatible pattern |
Matcher |
regex | java.util.regex-compatible matcher |
See CONTRIBUTING.md for the commit message format and type prefixes.
- Reverts use Git default:
Revert "(type) original message" - All commits must include a
Signed-off-bytrailer (DCO). Usegit commit -sto add it automatically.
Releases are created using gh release create, which creates both the git tag AND GitHub Release in one command:
gh release create <version> --title <version> --generate-notesWorkflow:
- Update
CHANGELOG.md: move Unreleased items into a new version section with the release date gh release create <version> --title <version> --generate-notescreates tag + GitHub Release (using tag as title)- Tag push triggers
.github/workflows/release.yamlfor Maven Central publish via JReleaser
Note: skipRelease: true in jreleaser.yml exists because the GitHub Release is already created by gh release create before JReleaser runs.
Dry run: release.yaml also accepts a workflow_dispatch trigger (Actions UI → "Run workflow") that exercises the full matrix build + stage + verify pipeline but skips the Maven Central deploy step. Use this to validate the release pipeline produces non-empty native JARs without committing to a public release. The Release to Maven Central step is guarded by if: github.event_name == 'push' && github.ref_type == 'tag', so only real tag pushes deploy.
Snapshots are published to Maven Central Snapshots repository (not GitHub Packages).
Version formats:
- Main branch:
main-SNAPSHOT - Pull requests:
PR-{number}-SNAPSHOT(dry-run only)
Why not GitHub Packages: GitHub Packages has a known limitation where SNAPSHOT versions don't update when republished - it always returns the first uploaded artifact. This makes it unsuitable for snapshot publishing. See GitHub Community Discussion #24658.
JReleaser configuration: Uses versionPattern: CUSTOM to allow non-semver snapshot version formats.
Release Notes Style:
- Format:
## What's Changedheader with bullet list of PRs - Content: Include only
(fix)and(feat)changes; omit(chore)and(docs) - PR format:
* (type) description by @username in <PR-URL> - Footer:
**Full Changelog**: <compare-URL>
GitHub Issues: https://github.com/alexey-pelykh/pcre4j/issues
Closing Issues: Use PR descriptions (not commit messages) since the project uses rebase-merge.
Include Fixes #<number> or Closes #<number> in the PR description to auto-close issues on merge.
IMPORTANT: When implementing new PCRE2 API bindings, update PCRE2_API.md to mark the API as implemented (add ✅).
The file tracks all PCRE2 API functions and their implementation status in PCRE4J.