name: Java 9+ Module Support on: push: branches: [ 'master', 'main', 'release/**' ] pull_request: branches: [ '*' ] # Cancel superseded in-progress runs for the same PR. In-progress # push runs are never cancelled, though a still-queued push run may # be superseded by a newer queued one. concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: # Test Java 9+ module support (JPMS) # Verifies that module-info.java is properly compiled and the resulting # JAR can be used with jlink to create custom Java runtimes. module-test: strategy: matrix: os: [ 'ubuntu-latest' ] jdk_version: [ '11', '17', '21' ] runs-on: ${{ matrix.os }} name: Module Test (JDK ${{ matrix.jdk_version }}) steps: - uses: actions/checkout@v4 - name: Setup JUnit uses: ./.github/actions/setup-junit # Cache the installed wolfSSL build. The key matches the one built # in linux-common.yml for the same configure flags, so this job # shares the cache with the main CI matrix. - name: Build native wolfSSL (cached) uses: ./.github/actions/build-wolfssl-cached with: configure: '--enable-jni' - name: Setup Java uses: actions/setup-java@v4 with: distribution: 'zulu' java-version: ${{ matrix.jdk_version }} - name: Set LD_LIBRARY_PATH run: | echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GITHUB_WORKSPACE/build-dir/lib" >> "$GITHUB_ENV" - name: Copy makefile run: cp makefile.linux makefile - name: Build JNI library run: PREFIX=$GITHUB_WORKSPACE/build-dir make - name: Build JAR with module support (ant) run: ant build-jce-release - name: Verify module-info.class exists in JAR run: | echo "Checking for module-info.class in wolfcrypt-jni.jar..." if jar tf lib/wolfcrypt-jni.jar | grep -q "module-info.class"; then echo "SUCCESS: module-info.class found in JAR" else echo "FAILURE: module-info.class not found in JAR" echo "JAR contents:" jar tf lib/wolfcrypt-jni.jar | head -20 exit 1 fi - name: Verify module descriptor with jar --describe-module run: | echo "Describing module in wolfcrypt-jni.jar..." jar --describe-module --file=lib/wolfcrypt-jni.jar echo "" echo "Verifying module name is 'com.wolfssl.wolfcrypt'..." MODULE_NAME=$(jar --describe-module --file=lib/wolfcrypt-jni.jar 2>&1 | head -1 | cut -d' ' -f1) if [ "$MODULE_NAME" = "com.wolfssl.wolfcrypt" ]; then echo "SUCCESS: Module name is correct: $MODULE_NAME" else echo "FAILURE: Expected module name 'com.wolfssl.wolfcrypt', got '$MODULE_NAME'" exit 1 fi - name: Verify module exports correct packages run: | echo "Verifying module exports..." EXPORTS=$(jar --describe-module --file=lib/wolfcrypt-jni.jar 2>&1) echo "$EXPORTS" echo "" if echo "$EXPORTS" | grep -q "exports com.wolfssl.wolfcrypt"; then echo "SUCCESS: exports com.wolfssl.wolfcrypt" else echo "FAILURE: missing 'exports com.wolfssl.wolfcrypt'" exit 1 fi if echo "$EXPORTS" | grep -q "exports com.wolfssl.provider.jce"; then echo "SUCCESS: exports com.wolfssl.provider.jce" else echo "FAILURE: missing 'exports com.wolfssl.provider.jce'" exit 1 fi - name: Test jlink can create runtime with module run: | echo "Testing jlink integration..." jlink \ --module-path lib/wolfcrypt-jni.jar:$JAVA_HOME/jmods \ --add-modules com.wolfssl.wolfcrypt \ --output test-jlink-runtime \ --no-header-files \ --no-man-pages echo "" echo "SUCCESS: jlink created custom runtime" echo "Runtime modules:" ./test-jlink-runtime/bin/java --list-modules echo "" echo "Verifying com.wolfssl.wolfcrypt module is present..." if ./test-jlink-runtime/bin/java --list-modules | grep -q "com.wolfssl.wolfcrypt"; then echo "SUCCESS: com.wolfssl.wolfcrypt module found in custom runtime" else echo "FAILURE: com.wolfssl.wolfcrypt module not found in custom runtime" exit 1 fi - name: Clean up jlink test runtime run: rm -rf test-jlink-runtime - name: Run standard tests to verify module doesn't break functionality run: ant test - name: Clean ant build for Maven test run: ant clean - name: Maven build and verify module-info in JAR run: | echo "Building with Maven..." mvn package -DskipTests -q echo "" # Exclude the filtered-providers classified jar, also built by # 'mvn package' on JDK 9+ MAVEN_JAR=$(ls target/wolfcrypt-jni-*.jar | grep -v filtered-providers) echo "Maven JAR: $MAVEN_JAR" echo "" echo "Checking for module-info.class in Maven-built JAR..." if jar tf "$MAVEN_JAR" | grep -q "module-info.class"; then echo "SUCCESS: module-info.class found in Maven JAR" else echo "FAILURE: module-info.class not found in Maven JAR" jar tf "$MAVEN_JAR" | head -20 exit 1 fi echo "" echo "Verifying Maven JAR module descriptor..." jar --describe-module --file="$MAVEN_JAR" - name: Clean Maven build run: mvn clean -q - name: Show logs on failure if: failure() || cancelled() run: | cat build/reports/*.txt 2>/dev/null || echo "No test reports found" # Verify Java 8 builds do NOT include module-info.class # This ensures the conditional compilation works correctly for Java 8 users java8-no-module-test: runs-on: ubuntu-latest name: Java 8 No Module Test steps: - uses: actions/checkout@v4 - name: Setup JUnit uses: ./.github/actions/setup-junit # Cache the installed wolfSSL build. The key matches the one built # in linux-common.yml for the same configure flags, so this job # shares the cache with the main CI matrix. - name: Build native wolfSSL (cached) uses: ./.github/actions/build-wolfssl-cached with: configure: '--enable-jni' - name: Setup Java 8 uses: actions/setup-java@v4 with: distribution: 'zulu' java-version: '8' - name: Set LD_LIBRARY_PATH run: | echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GITHUB_WORKSPACE/build-dir/lib" >> "$GITHUB_ENV" - name: Copy makefile run: cp makefile.linux makefile - name: Build JNI library run: PREFIX=$GITHUB_WORKSPACE/build-dir make - name: Build JAR with Java 8 (ant) run: ant build-jce-release - name: Verify module-info.class is NOT in JAR (Java 8) run: | echo "Checking that module-info.class is NOT in wolfcrypt-jni.jar (Java 8 build)..." if jar tf lib/wolfcrypt-jni.jar | grep -q "module-info.class"; then echo "FAILURE: module-info.class should NOT be in Java 8 JAR" exit 1 else echo "SUCCESS: module-info.class correctly absent from Java 8 JAR" fi - name: Run standard tests to verify Java 8 compatibility run: ant test - name: Show logs on failure if: failure() || cancelled() run: | cat build/reports/*.txt 2>/dev/null || echo "No test reports found"