Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,63 @@ implementation("org.xerial.snappy:snappy-java:(version)")
libraryDependencies += "org.xerial.snappy" % "snappy-java" % "(version)"
```

## JDK 24+ Native Access Requirements

Starting with JDK 24, Java has introduced restrictions on native method access through [JEP 472: Prepare to Restrict the Use of JNI](https://openjdk.org/jeps/472). Since snappy-java uses JNI to load native libraries for high-performance compression, applications running on **JDK 24 or later** must enable native access.

### Required JVM Flag

When running on JDK 24+, add the following JVM flag to your application:

```bash
--enable-native-access=ALL-UNNAMED
```

### Examples

**Running a JAR:**
```bash
java --enable-native-access=ALL-UNNAMED -jar your-application.jar
```

**Maven:**
```xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--enable-native-access=ALL-UNNAMED</argLine>
</configuration>
</plugin>
```
Comment on lines +85 to +94
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The provided Maven example only covers the maven-surefire-plugin, which is used for running unit tests. This is a very common use case, but it would be beneficial to also mention that a similar configuration is needed for other execution scenarios, such as:

  • Integration tests with maven-failsafe-plugin.
  • Running the application with exec-maven-plugin.

This would help users configure their projects more completely. You could add a short note to clarify this.


**Gradle:**
```gradle
tasks.withType(Test) {
jvmArgs '--enable-native-access=ALL-UNNAMED'
}
```
Comment on lines +96 to +101
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The Gradle example configures the JVM arguments for all tasks of type Test. This is great for testing, but users might also run their application using other tasks (e.g., the run task from the application plugin, or custom JavaExec tasks).

It would be helpful to either mention this or provide an example for configuring application execution as well. For instance, for the application plugin:

application {
    applicationDefaultJvmArgs = ['--enable-native-access=ALL-UNNAMED']
}

This would provide more comprehensive guidance for Gradle users.


**sbt:**
```scala
javaOptions += "--enable-native-access=ALL-UNNAMED"
```

### Why is this needed?

Per JEP 472's policy of "integrity by default," it is the application developer's responsibility (not the library's) to explicitly enable native access. This change improves security by making native operations visible and controlled at the application level.

Without this flag on JDK 24+, you will see warnings like:
```
WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::load has been called by org.xerial.snappy.SnappyLoader
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
```

These warnings will become errors in future JDK releases.

**Note:** This requirement only applies to JDK 24 and later. Earlier JDK versions (8-23) do not require this flag.


## Usage
First, import `org.xerial.snapy.Snappy` in your Java code:
Expand Down
Loading