From c850b79bd84d07397e25d1e831d3f1acef7ebe33 Mon Sep 17 00:00:00 2001 From: Jonas Konrad Date: Fri, 25 Sep 2026 18:47:01 +0200 Subject: [PATCH 1/5] Rework README Describe the fork as the maintained continuation of lz4/lz4-java, add Gradle coordinates and supported native platforms, recommend the safe decompressor and frame streams, modernize the examples, and add security, build and license sections. The version is omitted in favor of a Maven Central badge so it doesn't go stale. Co-Authored-By: Claude Opus 5.5 --- README.md | 293 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 168 insertions(+), 125 deletions(-) diff --git a/README.md b/README.md index b2497ecd..0e0865f9 100644 --- a/README.md +++ b/README.md @@ -1,174 +1,217 @@ # LZ4 Java -*Community-maintained fork of https://github.com/lz4/lz4-java to patch [CVE‐2025‐12183](https://sites.google.com/sonatype.com/vulnerabilities/cve-2025-12183). Maven coordinates:* +[![Maven Central](https://img.shields.io/maven-central/v/at.yawk.lz4/lz4-java)](https://central.sonatype.com/artifact/at.yawk.lz4/lz4-java) + +Fast [LZ4](https://github.com/lz4/lz4) compression and [xxHash](https://github.com/Cyan4973/xxHash) hashing for Java, +with JNI bindings to the reference C implementation and a pure Java fallback. + +This is the community-maintained continuation of [lz4/lz4-java](https://github.com/lz4/lz4-java), which is no longer +maintained. The fork was originally created to fix +[CVE‐2025‐12183](https://sites.google.com/sonatype.com/vulnerabilities/cve-2025-12183) and has since received further +security fixes, an updated lz4 library, new native platforms and a modernized build. It is a drop-in replacement: the +Java package names (`net.jpountz.*`) and API are unchanged, only the Maven coordinates are different. + +## Installation + +Replace `VERSION` with the latest version shown on +[Maven Central](https://central.sonatype.com/artifact/at.yawk.lz4/lz4-java) or the +[releases page](https://github.com/yawkat/lz4-java/releases). + +Maven: ```xml at.yawk.lz4 lz4-java + VERSION ``` -LZ4 compression for Java, based on Yann Collet's work available at -https://github.com/lz4/lz4. - -This library provides access to two compression methods that both generate a -valid LZ4 stream: - - fast scan (LZ4): - - low memory footprint (~ 16 KB), - - very fast (fast scan with skipping heuristics in case the input looks - incompressible), - - reasonable compression ratio (depending on the redundancy of the input). - - high compression (LZ4 HC): - - medium memory footprint (~ 256 KB), - - rather slow (~ 10 times slower than LZ4), - - good compression ratio (depending on the size and the redundancy of the - input). - - interoperable (LZ4 Frame): - - overlay on top of lz4, that makes it system and library independent - - this is the version to employ in order to share lz4 compressed data - with other systems using different lz4 frameworks. - -The streams produced by LZ4 and LZ4 HC use the same compression format, -are very fast to decompress and can be decompressed by the same lz4-java decompressor instance. - -The streams produced by LZ4 Frame can be read by other independent implementations of LZ4 Frame in any other language, including the `lz4` CLI tool. - -## Implementations - -For LZ4 compressors, LZ4 HC compressors and decompressors, 3 implementations are -available: - - JNI bindings to the original C implementation by Yann Collet, - - a pure Java port of the compression and decompression algorithms, - - a Java port that uses the `sun.misc.Unsafe` API in order to achieve compression - and decompression speeds close to the C implementation. - -Have a look at [LZ4Factory](https://lz4-java.yawk.at/current/javadoc/net/jpountz/lz4/LZ4Factory) for more information. +Gradle: -## Compatibility notes +```kotlin +implementation("at.yawk.lz4:lz4-java:VERSION") +``` + +If another library pulls in `org.lz4:lz4-java`, exclude it (or use Gradle's dependency substitution) and add this +artifact instead. Both contain the same classes, so make sure only one of them ends up on the classpath. + +Requirements: + +- Java 7 or newer. The JAR has the `Automatic-Module-Name` `org.lz4.java` and OSGi metadata. +- The JAR bundles native libraries for Linux (amd64, i386, aarch64, ppc64le, s390x, riscv64), macOS (x86_64, + aarch64) and Windows (amd64). On other platforms, the pure Java implementation is used automatically. +- On Java 24 and newer, the JVM prints a warning when the native library is loaded. Pass + `--enable-native-access=ALL-UNNAMED` (or the name of your module) to silence it. + +> **Note:** Before 1.8.1, there was also an `lz4-pure-java` artifact without the native libraries. It has been +> discontinued and its latest version is still vulnerable to CVE‐2025‐12183. Please open an issue if you have a use +> case that requires it. + +## Choosing an API + +| You want to… | Use | +|-----------------------------------------------------------------|------------------------------------------------------------------------| +| Exchange data with other tools or languages (e.g. the `lz4` CLI) | `LZ4FrameOutputStream` / `LZ4FrameInputStream` (LZ4 frame format) | +| Compress a single `byte[]` or `ByteBuffer` and get it back | `LZ4CompressorWithLength` / `LZ4DecompressorWithLength` | +| Full control over raw LZ4 blocks | `LZ4Compressor` / `LZ4SafeDecompressor` | +| Hash data | `XXHash32`, `XXHash64` and their streaming variants | + +`LZ4BlockOutputStream` / `LZ4BlockInputStream` use a format specific to lz4-java. Prefer the frame streams for new +code, unless you need compatibility with data that was already written in the block stream format. + +### Compressors + +- **Fast compressor** (`fastCompressor()`): low memory footprint (~16 KB), very fast, reasonable compression ratio. +- **High compressor** (`highCompressor()`): LZ4 HC, higher memory footprint (~256 KB) and roughly 10× slower than the + fast compressor, but a better compression ratio. The compression level can be tuned; higher levels cost + significantly more CPU. + +Both produce the same block format, and their output can be read by the same decompressor. + +### Decompressors + +**Use `safeDecompressor()`.** It takes the compressed length as input, is safe for untrusted data, and is the fastest +decompressor with the native implementation. + +`fastDecompressor()` takes the *decompressed* length instead. It is kept for compatibility, but for security reasons it +now always uses the (slower) safe Java implementation, regardless of which factory it came from. The +`nativeInsecureInstance()` and `unsafeInsecureInstance()` factories return the old, faster fast decompressors, but +**must never be used with untrusted input**. + +### Implementations - - Compressors and decompressors are interchangeable: it is perfectly correct - to compress with the JNI bindings and to decompress with a Java port, or the - other way around. +`LZ4Factory` and `XXHashFactory` provide the following implementations, which all produce compatible output: - - Compressors might not generate the same compressed streams on all platforms, - especially if CPU endianness differs, but the compressed streams can be - safely decompressed by any decompressor implementation on any platform. +- `nativeInstance()`: JNI bindings to the reference C implementation. +- `safeInstance()`: A pure Java port. +- `unsafeInstance()`: A Java port using `sun.misc.Unsafe`. For LZ4, this is currently an alias for the safe instance + out of caution. + +In most cases, just use `fastestInstance()`, which picks the native implementation if it can be loaded and falls back +to Java otherwise. Obtaining a factory is expensive, so store it in a static field and reuse it. See the +[LZ4Factory javadoc](https://lz4-java.yawk.at/current/javadoc/net/jpountz/lz4/LZ4Factory) for caveats of the native +implementation (temporary files, class loaders). ## Examples -```java -LZ4Factory factory = LZ4Factory.fastestInstance(); +### LZ4 frame streams -byte[] data = "12345345234572".getBytes("UTF-8"); -final int decompressedLength = data.length; +Files written this way can be read by the `lz4` command line tool and any other LZ4 frame implementation, and vice +versa. -// compress data -LZ4Compressor compressor = factory.fastCompressor(); -int maxCompressedLength = compressor.maxCompressedLength(decompressedLength); -byte[] compressed = new byte[maxCompressedLength]; -int compressedLength = compressor.compress(data, 0, decompressedLength, compressed, 0, maxCompressedLength); - -// decompress data -// - method 1: when the decompressed length is known -LZ4FastDecompressor decompressor = factory.fastDecompressor(); -byte[] restored = new byte[decompressedLength]; -int compressedLength2 = decompressor.decompress(compressed, 0, restored, 0, decompressedLength); -// compressedLength == compressedLength2 - -// - method 2: when the compressed length is known (a little slower) -// the destination buffer needs to be over-sized -LZ4SafeDecompressor decompressor2 = factory.safeDecompressor(); -int decompressedLength2 = decompressor2.decompress(compressed, 0, compressedLength, restored, 0); -// decompressedLength == decompressedLength2 +```java +try (OutputStream out = new LZ4FrameOutputStream(new FileOutputStream("data.lz4"))) { + out.write(data); +} + +try (InputStream in = new LZ4FrameInputStream(new FileInputStream("data.lz4"))) { + byte[] restored = in.readAllBytes(); +} ``` +### Compressing a byte array + +`LZ4CompressorWithLength` prepends the original length to the compressed data, so you don't have to track it yourself. + ```java -byte[] data = "12345345234572".getBytes("UTF-8"); -final int decompressedLength = data.length; +LZ4Factory factory = LZ4Factory.fastestInstance(); -LZ4FrameOutputStream outStream = new LZ4FrameOutputStream(new FileOutputStream(new File("test.lz4"))); -outStream.write(data); -outStream.close(); +LZ4CompressorWithLength compressor = new LZ4CompressorWithLength(factory.fastCompressor()); +byte[] compressed = compressor.compress(data); -byte[] restored = new byte[decompressedLength]; -LZ4FrameInputStream inStream = new LZ4FrameInputStream(new FileInputStream(new File("test.lz4"))); -inStream.read(restored); -inStream.close(); +LZ4DecompressorWithLength decompressor = new LZ4DecompressorWithLength(factory.safeDecompressor()); +byte[] restored = decompressor.decompress(compressed); ``` -# xxhash Java +To protect against decompression bombs, `LZ4DecompressorWithLength` refuses to allocate output buffers larger than +64 MiB by default. Pass a different maximum to the constructor, or set the +`net.jpountz.lz4.LZ4DecompressorWithLength.maxDecompressedLength` system property. For large data, use the frame +streams instead. -xxhash hashing for Java, based on Yann Collet's work available at https://github.com/Cyan4973/xxHash (old version -http://code.google.com/p/xxhash/). xxhash is a non-cryptographic, extremly fast -and high-quality ([SMHasher](http://code.google.com/p/smhasher/wiki/SMHasher) -score of 10) hash function. +### Raw LZ4 blocks -## Implementations +With the low-level API, you are responsible for storing the original length alongside the compressed data. -Similarly to LZ4, 3 implementations are available: JNI bindings, pure Java port -and pure Java port that uses `sun.misc.Unsafe`. - -Have a look at [XXHashFactory](https://lz4-java.yawk.at/current/javadoc/net/jpountz/xxhash/XXHashFactory) for more information. +```java +LZ4Factory factory = LZ4Factory.fastestInstance(); -## Compatibility notes +// compress +LZ4Compressor compressor = factory.fastCompressor(); +byte[] compressed = new byte[compressor.maxCompressedLength(data.length)]; +int compressedLength = compressor.compress(data, 0, data.length, compressed, 0, compressed.length); - - All implementation return the same hash for the same input bytes: - - on any JVM, - - on any platform (even if the endianness or integer size differs). +// decompress +LZ4SafeDecompressor decompressor = factory.safeDecompressor(); +byte[] restored = new byte[data.length]; +int decompressedLength = decompressor.decompress(compressed, 0, compressedLength, restored, 0); +``` -## Example +### xxHash ```java XXHashFactory factory = XXHashFactory.fastestInstance(); - -byte[] data = "12345345234572".getBytes("UTF-8"); -ByteArrayInputStream in = new ByteArrayInputStream(data); - -int seed = 0x9747b28c; // used to initialize the hash value, use whatever - // value you want, but always the same -StreamingXXHash32 hash32 = factory.newStreamingHash32(seed); -byte[] buf = new byte[8]; // for real-world usage, use a larger buffer, like 8192 bytes -for (;;) { - int read = in.read(buf); - if (read == -1) { - break; - } - hash32.update(buf, 0, read); +long seed = 0; // any value, but use the same one for all hashes you want to compare + +// one-shot +long hash = factory.hash64().hash(data, 0, data.length, seed); + +// streaming +try (StreamingXXHash64 streamingHash = factory.newStreamingHash64(seed)) { + byte[] buf = new byte[8192]; + int read; + while ((read = in.read(buf)) != -1) { + streamingHash.update(buf, 0, read); + } + long streamedHash = streamingHash.getValue(); } -int hash = hash32.getValue(); ``` -# Download +xxHash is a very fast, non-cryptographic hash function. All implementations return the same hash for the same input, +on every JVM and platform. -You can download released artifacts from [Maven Central](https://central.sonatype.com/artifact/at.yawk.lz4/lz4-java). +## Compatibility notes -Prior to 1.8.1, there was also a lz4-pure-java artifact that excluded the JNI binary. This artifact has been discontinued because it is difficult to build and doesn't make a lot of sense from a design standpoint. The latest version of this artifact is still vulnerable to CVE‐2025‐12183. Please open an issue if you have a use case that requires this version. +- Implementations are interchangeable: data compressed with the native implementation can be decompressed with the + Java one, and vice versa. +- Compressed output is not guaranteed to be byte-for-byte identical across implementations, versions or platforms, but + it can always be decompressed by any of them. -# Documentation +## Security - - [lz4](https://lz4-java.yawk.at/current/javadoc/net/jpountz/lz4/package-summary.html) - - [xxhash](https://lz4-java.yawk.at/current/javadoc/net/jpountz/xxhash/package-summary.html) - - [changelog (versions <= 1.8.0)](https://github.com/yawkat/lz4-java/blob/main/CHANGES.md) - - [changelog / GitHub releases (versions >= 1.8.1)](https://github.com/yawkat/lz4-java/releases) +Security fixes are published as [GitHub security advisories](https://github.com/yawkat/lz4-java/security/advisories) +and noted in the [release notes](https://github.com/yawkat/lz4-java/releases). Please report vulnerabilities privately +through GitHub's [vulnerability reporting](https://github.com/yawkat/lz4-java/security/advisories/new). -# Performance +## Documentation -Both lz4 and xxhash focus on speed. Although compression, decompression and -hashing performance can depend a lot on the input (there are lies, damn lies -and benchmarks), here are some benchmarks that try to give a sense of the -speed at which they compress/decompress/hash bytes. +- Javadoc: [lz4](https://lz4-java.yawk.at/current/javadoc/net/jpountz/lz4/package-summary.html), + [xxhash](https://lz4-java.yawk.at/current/javadoc/net/jpountz/xxhash/package-summary.html) +- [Release notes](https://github.com/yawkat/lz4-java/releases) (1.8.1 and later) +- [Changelog](https://github.com/yawkat/lz4-java/blob/main/CHANGES.md) (1.8.0 and earlier) +- Benchmarks of the original project (1.8.0): + [compression](https://lz4.github.io/lz4-java/1.8.0/lz4-compression-benchmark/), + [decompression](https://lz4.github.io/lz4-java/1.8.0/lz4-decompression-benchmark/), + [xxhash](https://lz4.github.io/lz4-java/1.3.0/xxhash-benchmark/) - - [lz4 compression](https://lz4.github.io/lz4-java/1.8.0/lz4-compression-benchmark/) - - [lz4 decompression](https://lz4.github.io/lz4-java/1.8.0/lz4-decompression-benchmark/) - - [xxhash hashing](https://lz4.github.io/lz4-java/1.3.0/xxhash-benchmark/) +## Building -# Build +You need: -Make sure you have a Java 7 installation in your [Maven toolchains.xml](https://maven.apache.org/guides/mini/guide-using-toolchains.html). You may also need a C compiler. +- A JDK 25 to run Maven. +- A JDK 7 registered in your [Maven toolchains.xml](https://maven.apache.org/guides/mini/guide-using-toolchains.html), + used to compile the library. Alternatively, pass `-Dmaven.compiler.source=8 -Dmaven.compiler.target=8` to build + with the default JDK. +- A C compiler, to build the native library for your platform. + +```bash +git submodule update --init +./mvnw verify +``` -First run `git submodule init` and then `git submodule update` to initialize the lz4 submodule in `src/lz4`. +The released JAR contains native libraries for all supported platforms. These are built in GitHub Actions, see +[`build-all-and-publish.yml`](https://github.com/yawkat/lz4-java/blob/main/.github/workflows/build-all-and-publish.yml). -Then, run `./mvnw verify`. +## License -Building a full artifact with native libraries for all supported platforms is more complex. We do this through GitHub Actions. +[Apache License 2.0](https://github.com/yawkat/lz4-java/blob/main/LICENSE.txt) From 65545a52bb1a058f94c45c2edd7996c842412bfd Mon Sep 17 00:00:00 2001 From: Jonas Konrad Date: Fri, 25 Sep 2026 18:52:21 +0200 Subject: [PATCH 2/5] Add contribution guidelines Document how to report bugs, request features and contribute, including the requirements for acceptable contributions, as required by the OpenSSF Best Practices criteria. Co-Authored-By: Claude Opus 5.5 --- CONTRIBUTING.md | 39 +++++++++++++++++++++++++++++++++++++++ README.md | 8 ++++++++ 2 files changed, 47 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..99bfea0a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,39 @@ +# Contributing to lz4-java + +Thanks for your interest in contributing! + +## Reporting bugs and requesting features + +- **Bugs and feature requests:** open a [GitHub issue](https://github.com/yawkat/lz4-java/issues). For bugs, include + the lz4-java version, Java version, OS and architecture, which `LZ4Factory`/`XXHashFactory` instance you use, and + ideally a minimal reproducer. +- **Questions:** use [GitHub Discussions](https://github.com/yawkat/lz4-java/discussions). +- **Security vulnerabilities:** do **not** open a public issue. Report them privately through + [GitHub's vulnerability reporting](https://github.com/yawkat/lz4-java/security/advisories/new). + +## Pull requests + +Pull requests are welcome. For larger changes, please open an issue first to discuss the approach. + +To be accepted, a contribution must meet these requirements: + +- **The build passes.** `./mvnw verify` must succeed, and CI must be green on all platforms. See the + [README](README.md#building) for build prerequisites. +- **Java 7 compatibility.** The library is compiled with Java 7 and must not use newer language features or APIs. + Tests may use the newer Java version configured in `pom.xml`. +- **No breaking API changes.** Public API must stay source and binary compatible. Deprecate instead of removing, and + keep new non-user-facing members as private as possible. +- **Tests.** Bug fixes should come with a regression test, and new features with tests. New tests use JUnit 5 or + newer (existing JUnit 4 tests run through the vintage engine). Code that parses input (decompressors, streams) + should also be covered by a [Jazzer](https://github.com/CodeIntelligenceTesting/jazzer) fuzz test, run with the + `fuzz` Maven profile. Each fuzz test needs its own execution in that profile. +- **Code style.** There is no automated formatter. Follow the style of the surrounding code and + [`.editorconfig`](.editorconfig) (2-space indentation), and keep diffs minimal: no unrelated reformatting. +- **Generated code.** Most of the Java and Unsafe implementations are generated from the MVEL templates in + `src/build/source_templates`. Edit the templates, not the generated files under `target/`. +- **Implementations stay consistent.** A change to one implementation (JNI, Java safe, Java unsafe) usually needs a + matching change in the others. +- **License.** Contributions are accepted under the [Apache License 2.0](LICENSE.txt), the project's license. New + source files need the Apache license header used by existing files. + +Keep pull requests focused on a single change and describe what changed and why. diff --git a/README.md b/README.md index 0e0865f9..1d87b745 100644 --- a/README.md +++ b/README.md @@ -183,6 +183,14 @@ Security fixes are published as [GitHub security advisories](https://github.com/ and noted in the [release notes](https://github.com/yawkat/lz4-java/releases). Please report vulnerabilities privately through GitHub's [vulnerability reporting](https://github.com/yawkat/lz4-java/security/advisories/new). +## Feedback and contributing + +- Report bugs and request features through [GitHub issues](https://github.com/yawkat/lz4-java/issues). +- Ask questions in [GitHub Discussions](https://github.com/yawkat/lz4-java/discussions). +- Pull requests are welcome. See + [CONTRIBUTING.md](https://github.com/yawkat/lz4-java/blob/main/CONTRIBUTING.md) for the requirements for + contributions. + ## Documentation - Javadoc: [lz4](https://lz4-java.yawk.at/current/javadoc/net/jpountz/lz4/package-summary.html), From f6f716ef6b73af10c220f51afd1d23df396b21ec Mon Sep 17 00:00:00 2001 From: Jonas Konrad Date: Fri, 25 Sep 2026 19:08:37 +0200 Subject: [PATCH 3/5] Add OpenSSF Scorecard and coverage reporting Run OpenSSF Scorecard weekly and on pushes to main, publishing results for the README badge. Record JaCoCo coverage in a new coverage profile on the Linux amd64 test job and upload it to Codecov via OIDC. Add the Codecov, OpenSSF Best Practices and Scorecard badges to the README. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/scorecard.yml | 46 +++++++++++++++++++++++++++++++++ .github/workflows/test.yml | 17 ++++++++++++ README.md | 3 +++ pom.xml | 28 ++++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 .github/workflows/scorecard.yml diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 00000000..2a5b7f71 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,46 @@ +# OpenSSF Scorecard supply-chain security analysis, published to https://scorecard.dev for the README badge +name: Scorecard + +on: + push: + branches: [main] + schedule: + - cron: '17 4 * * 1' + # For the Branch-Protection check to pick up changes to branch protection rules + branch_protection_rule: + workflow_dispatch: + +permissions: {} + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Upload results to the code scanning dashboard + security-events: write + # Publish results to the OpenSSF REST API + id-token: write + contents: read + actions: read + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + - name: Run analysis + uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4 + with: + results_file: results.sarif + results_format: sarif + publish_results: true + - name: Upload artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: scorecard-results + path: results.sarif + retention-days: 5 + - name: Upload to code scanning + uses: github/codeql-action/upload-sarif@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2 + with: + sarif_file: results.sarif diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0a7f30bc..51333482 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,15 +6,24 @@ on: pull_request: workflow_dispatch: +permissions: + contents: read + jobs: linux: name: Linux test runs-on: ${{ matrix.runs-on }} + permissions: + contents: read + # Codecov upload via OIDC + id-token: write strategy: fail-fast: false matrix: include: - runs-on: ubuntu-24.04 + coverage: true + maven-flags: -Pcoverage - runs-on: ubuntu-24.04-arm # Azul Zulu 7 not available on Aarch64 maven-flags: >- @@ -57,3 +66,11 @@ jobs: -Dsurefire.reportFormat=plain \ ${{ matrix.maven-flags }} \ verify + - name: Upload coverage to Codecov + if: matrix.coverage + uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 + with: + files: target/site/jacoco/jacoco.xml + # OIDC tokens are not available to pull requests from forks, which use tokenless upload instead + use_oidc: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork) }} + fail_ci_if_error: false diff --git a/README.md b/README.md index 1d87b745..d234a929 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # LZ4 Java [![Maven Central](https://img.shields.io/maven-central/v/at.yawk.lz4/lz4-java)](https://central.sonatype.com/artifact/at.yawk.lz4/lz4-java) +[![codecov](https://codecov.io/gh/yawkat/lz4-java/graph/badge.svg)](https://codecov.io/gh/yawkat/lz4-java) +[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/14930/badge)](https://www.bestpractices.dev/projects/14930) +[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/yawkat/lz4-java/badge)](https://scorecard.dev/viewer/?uri=github.com/yawkat/lz4-java) Fast [LZ4](https://github.com/lz4/lz4) compression and [xxHash](https://github.com/Cyan4973/xxHash) hashing for Java, with JNI bindings to the reference C implementation and a pure Java fallback. diff --git a/pom.xml b/pom.xml index de9783c2..bac1faaf 100644 --- a/pom.xml +++ b/pom.xml @@ -341,6 +341,34 @@ + + + coverage + + + + org.jacoco + jacoco-maven-plugin + 0.8.15 + + + prepare-agent + + prepare-agent + + + + report + verify + + report + + + + + + + deploy From 1a1670e959d9a0c4d62307686ff2585cb1aa26ac Mon Sep 17 00:00:00 2001 From: Jonas Konrad Date: Fri, 25 Sep 2026 19:13:25 +0200 Subject: [PATCH 4/5] Fix Codecov OIDC detection for this repository This repository is itself a GitHub fork, so head.repo.fork is always true and OIDC was never used. Compare the head repository instead, and only upload the JaCoCo report. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/test.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 51333482..ec021c17 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -71,6 +71,8 @@ jobs: uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1 with: files: target/site/jacoco/jacoco.xml - # OIDC tokens are not available to pull requests from forks, which use tokenless upload instead - use_oidc: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork) }} + disable_search: true + # OIDC tokens are not available to pull requests from other repositories, which use tokenless upload instead. + # Don't use head.repo.fork here: this repository is itself a fork, so that is always true. + use_oidc: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }} fail_ci_if_error: false From e51e721bebdd101af45bb0ae23b8e722cb6ced95 Mon Sep 17 00:00:00 2001 From: Jonas Konrad Date: Fri, 25 Sep 2026 19:16:32 +0200 Subject: [PATCH 5/5] Mark CHANGES.md as covering 1.8.0 and earlier only Co-Authored-By: Claude Opus 5.5 --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index c2ddb3bf..74f4936c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,8 @@ # Change log +*This changelog covers lz4-java 1.8.0 and earlier. For newer versions, see +[GitHub Releases](https://github.com/yawkat/lz4-java/releases).* + ## 1.8.0 - Upgraded LZ4 to 1.9.3. Updated the JNI bindings. Minimum glibc version in GNU/Linux platforms: 2.17 on aarch64, 2.2.5 on amd64, 2.17 on ppc64le, 2.2 on s390x.