Skip to content

Commit 48b3166

Browse files
xerialclaude
andauthored
Add JAR integration test for JDK compatibility (#704)
* Add Enable-Native-Access manifest attribute for JDK 24+ Add the Enable-Native-Access: ALL-UNNAMED attribute to the JAR manifest to suppress native access warnings on JDK 24+ without requiring users to add the --enable-native-access=ALL-UNNAMED command-line flag. This manifest attribute allows the library to declare its need for native access, which helps suppress the warnings introduced by JEP 472 when snappy-java loads native libraries via JNI. Benefits: - Users no longer need to add JVM flags for basic usage - Warnings are suppressed automatically when the JAR is on the classpath - Backwards compatible with all JDK versions (attribute is ignored on JDK < 24) Related to #689 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add integration test for JAR manifest and native access Add a comprehensive integration test that verifies snappy-java works in a separate JVM process. This test: 1. Builds the JAR with sbt 2. Compiles a simple test program that uses snappy-java 3. Runs the test in a fresh JVM WITHOUT --enable-native-access flag 4. Verifies the compression/decompression works correctly 5. Checks for JEP 472 warnings on JDK 24+ The test can be run two ways: - Via JUnit: testOnly org.xerial.snappy.JarManifestIntegrationTest - Via script: ./script/test-jar-integration.sh Findings: The Enable-Native-Access manifest attribute is present but does NOT suppress warnings when the JAR is used as a library on the classpath. The attribute only works for executable JARs (java -jar). Users still need to add --enable-native-access=ALL-UNNAMED for now. Related to #689 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Clean up and finalize integration test Changes: - Remove Enable-Native-Access manifest attribute (doesn't work for library JARs) - Remove unused JUnit integration test (using shell script instead) - Add JAR integration test to CI workflow for all JDK versions The integration test now runs in CI after regular tests, verifying that the built JAR works correctly in a separate JVM process on each tested JDK version (8, 11, 17, 21, 25). Related to #689 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Remove unnecessary manifest check from integration test The manifest check is no longer needed since we decided not to include the Enable-Native-Access attribute. Related to #689 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3e32cbb commit 48b3166

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,5 @@ jobs:
6363
export _JAVA_OPTIONS="--enable-native-access=ALL-UNNAMED"
6464
fi
6565
./sbt test
66+
- name: JAR Integration Test
67+
run: ./script/test-jar-integration.sh

script/test-jar-integration.sh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "=========================================="
5+
echo "Snappy-Java Integration Test"
6+
echo "=========================================="
7+
8+
# Detect Java version
9+
JAVA_VERSION=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed 's/^1\.//' | cut -d'.' -f1)
10+
echo "Java version: $JAVA_VERSION"
11+
12+
# Build the JAR
13+
echo ""
14+
echo "Building JAR..."
15+
./sbt package
16+
17+
# Find the JAR
18+
JAR_FILE=$(ls -t target/snappy-java-*.jar | grep -v sources | grep -v javadoc | head -1)
19+
if [ -z "$JAR_FILE" ]; then
20+
echo "ERROR: Could not find snappy-java JAR"
21+
exit 1
22+
fi
23+
echo "Using JAR: $JAR_FILE"
24+
25+
# Create temp directory
26+
TEMP_DIR=$(mktemp -d)
27+
echo ""
28+
echo "Using temp directory: $TEMP_DIR"
29+
30+
# Copy test source
31+
cp src/test/resources/integration/SnappyIntegrationTest.java "$TEMP_DIR/"
32+
33+
# Compile test
34+
echo ""
35+
echo "Compiling test program..."
36+
javac -cp "$JAR_FILE" -d "$TEMP_DIR" "$TEMP_DIR/SnappyIntegrationTest.java"
37+
38+
# Run test WITHOUT --enable-native-access flag
39+
echo ""
40+
echo "=========================================="
41+
echo "Running test (WITHOUT --enable-native-access flag)..."
42+
echo "=========================================="
43+
44+
cd "$TEMP_DIR"
45+
java -cp ".:$OLDPWD/$JAR_FILE" SnappyIntegrationTest 2>&1
46+
EXIT_CODE=$?
47+
cd - > /dev/null
48+
49+
echo ""
50+
echo "=========================================="
51+
if [ $EXIT_CODE -eq 0 ]; then
52+
echo "✓ Test PASSED (exit code: $EXIT_CODE)"
53+
else
54+
echo "✗ Test FAILED (exit code: $EXIT_CODE)"
55+
fi
56+
echo "=========================================="
57+
58+
# Cleanup
59+
rm -rf "$TEMP_DIR"
60+
61+
exit $EXIT_CODE
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import org.xerial.snappy.Snappy;
2+
3+
/**
4+
* Simple integration test to verify snappy-java works in a separate JVM.
5+
* This is compiled and run as a standalone program to test the JAR manifest
6+
* and native library loading on different JDK versions.
7+
*/
8+
public class SnappyIntegrationTest {
9+
public static void main(String[] args) throws Exception {
10+
String input = "Hello snappy-java! Snappy-java is a JNI-based wrapper of "
11+
+ "Snappy, a fast compresser/decompresser.";
12+
13+
// Test compression
14+
byte[] compressed = Snappy.compress(input.getBytes("UTF-8"));
15+
System.out.println("Compressed " + input.length() + " bytes to " + compressed.length + " bytes");
16+
17+
// Test decompression
18+
byte[] uncompressed = Snappy.uncompress(compressed);
19+
String result = new String(uncompressed, "UTF-8");
20+
21+
// Verify result matches input
22+
if (!result.equals(input)) {
23+
System.err.println("ERROR: Decompressed data does not match input!");
24+
System.err.println("Expected: " + input);
25+
System.err.println("Got: " + result);
26+
System.exit(1);
27+
}
28+
29+
System.out.println("SUCCESS: " + result);
30+
System.exit(0);
31+
}
32+
}

0 commit comments

Comments
 (0)