Repository navigation
Audit third-party code bundled in published JARs #3690
Description
Activity
I checked the final binary JARs on
master. These are the third-party dependencies whose classes are physically present.Based on these results, we’ll review and update each JAR’s LICENSE and NOTICE files so they accurately reflect the third-party code bundled in that artifact.
JAR Bundled third-party dependencies parquet-avro-*.jarit.unimi.dsi:fastutil:8.5.18parquet-column-*.jarit.unimi.dsi:fastutil:8.5.18net.openhft:zero-allocation-hashing:0.27ea1parquet-format-structures-*.jarorg.apache.thrift:libthrift:0.23.0parquet-hadoop-*.jarit.unimi.dsi:fastutil:8.5.18parquet-jackson-*.jarcom.fasterxml.jackson.core:jackson-annotations:2.22com.fasterxml.jackson.core:jackson-core:2.22.1com.fasterxml.jackson.core:jackson-databind:2.22.1parquet-hadoop-bundle-*.jarit.unimi.dsi:fastutil:8.5.18net.openhft:zero-allocation-hashing:0.27ea1org.apache.thrift:libthrift:0.23.0com.fasterxml.jackson.core:jackson-annotations:2.22com.fasterxml.jackson.core:jackson-core:2.22.1com.fasterxml.jackson.core:jackson-databind:2.22.1parquet-cli-*-runtime.jarcom.beust:jcommander:1.82com.fasterxml.jackson.core:jackson-annotations:2.22com.fasterxml.jackson.core:jackson-core:2.22.1com.fasterxml.jackson.core:jackson-databind:2.22.1com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.22.1com.github.luben:zstd-jni:1.5.7-11commons-codec:commons-codec:1.11commons-pool:commons-pool:1.6io.airlift:aircompressor:2.0.3it.unimi.dsi:fastutil:8.5.18javax.annotation:javax.annotation-api:1.3.2net.openhft:zero-allocation-hashing:0.27ea1net.sf.opencsv:opencsv:2.3org.apache.avro:avro:1.11.5org.apache.commons:commons-compress:1.26.2org.apache.commons:commons-lang3:3.20.0org.apache.commons:commons-text:1.15.0org.apache.thrift:libthrift:0.23.0org.locationtech.jts:jts-core:1.20.0org.slf4j:slf4j-api:1.7.33org.tukaani:xz:1.12org.xerial.snappy:snappy-java:1.1.10.8The check removes Parquet’s own classes, matches and removes every expected dependency, and fails if any expected dependency is missing or unexplained classes remain. All seven JARs ended with zero unmatched classes.
Verification command
Run from the repository root after building the JARs:
bash <<'EOF' set -euo pipefail export LC_ALL=C tmp_dir=$(mktemp -d) trap 'rm -rf "$tmp_dir"' EXIT catalog="$tmp_dir/dependencies" failures=0 verified_jars=0 cat >"$catalog" <<'CATALOG' fastutil;it.unimi.dsi:fastutil:8.5.18;^(META-INF/versions/[0-9]+/)?(shaded/parquet/)?it/unimi/dsi/fastutil/ openhft;net.openhft:zero-allocation-hashing:0.27ea1;^(META-INF/versions/[0-9]+/)?(shaded/parquet/)?net/openhft/hashing/ thrift;org.apache.thrift:libthrift:0.23.0;^(META-INF/versions/[0-9]+/)?shaded/parquet/org/apache/thrift/ jackson-annotations;com.fasterxml.jackson.core:jackson-annotations:2.22;^(META-INF/versions/[0-9]+/)?(shaded/parquet/)?com/fasterxml/jackson/annotation/ jackson-core;com.fasterxml.jackson.core:jackson-core:2.22.1;^(META-INF/versions/[0-9]+/)?(shaded/parquet/)?com/fasterxml/jackson/core/|^META-INF/versions/9/module-info\.class$ jackson-databind;com.fasterxml.jackson.core:jackson-databind:2.22.1;^(META-INF/versions/[0-9]+/)?(shaded/parquet/)?com/fasterxml/jackson/databind/ jackson-jsr310;com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.22.1;^(META-INF/versions/[0-9]+/)?com/fasterxml/jackson/datatype/jsr310/ javax-annotation;javax.annotation:javax.annotation-api:1.3.2;^(META-INF/versions/[0-9]+/)?javax/annotation/ jts;org.locationtech.jts:jts-core:1.20.0;^(META-INF/versions/[0-9]+/)?org/locationtech/jts/ snappy;org.xerial.snappy:snappy-java:1.1.10.8;^(META-INF/versions/[0-9]+/)?org/xerial/snappy/ aircompressor;io.airlift:aircompressor:2.0.3;^(META-INF/versions/[0-9]+/)?io/airlift/compress/ commons-pool;commons-pool:commons-pool:1.6;^(META-INF/versions/[0-9]+/)?org/apache/commons/pool/ avro;org.apache.avro:avro:1.11.5;^(META-INF/versions/[0-9]+/)?shaded/parquet/org/apache/avro/ commons-compress;org.apache.commons:commons-compress:1.26.2;^(META-INF/versions/[0-9]+/)?org/apache/commons/compress/ xz;org.tukaani:xz:1.12;^(META-INF/versions/[0-9]+/)?org/tukaani/xz/ zstd;com.github.luben:zstd-jni:1.5.7-11;^(META-INF/versions/[0-9]+/)?com/github/luben/zstd/ slf4j;org.slf4j:slf4j-api:1.7.33;^(META-INF/versions/[0-9]+/)?org/slf4j/ opencsv;net.sf.opencsv:opencsv:2.3;^(META-INF/versions/[0-9]+/)?au/com/bytecode/opencsv/ commons-text;org.apache.commons:commons-text:1.15.0;^(META-INF/versions/[0-9]+/)?org/apache/commons/text/ commons-lang3;org.apache.commons:commons-lang3:3.20.0;^(META-INF/versions/[0-9]+/)?org/apache/commons/lang3/ jcommander;com.beust:jcommander:1.82;^(META-INF/versions/[0-9]+/)?com/beust/(jcommander|ah)/ commons-codec;commons-codec:commons-codec:1.11;^(META-INF/versions/[0-9]+/)?org/apache/commons/codec/ CATALOG check_jar() { local jar_file=$1 local jar_name local expected local all_classes="$tmp_dir/all-classes" local remaining="$tmp_dir/remaining" local next="$tmp_dir/next" local total_classes local project_classes local matched_classes local remaining_classes local processed_dependencies=0 local expected_dependencies jar_name=$(basename "$jar_file") case "$jar_name" in parquet-avro-*.jar) expected="fastutil" ;; parquet-column-*.jar) expected="fastutil openhft" ;; parquet-format-structures-*.jar) expected="thrift" ;; parquet-hadoop-bundle-*.jar) expected="fastutil openhft thrift jackson-annotations jackson-core jackson-databind" ;; parquet-hadoop-*.jar) expected="fastutil" ;; parquet-jackson-*.jar) expected="jackson-annotations jackson-core jackson-databind" ;; parquet-cli-*-runtime.jar) expected="fastutil openhft thrift jackson-annotations jackson-core jackson-databind jackson-jsr310 javax-annotation jts snappy aircompressor commons-pool avro commons-compress xz zstd slf4j opencsv commons-text commons-lang3 jcommander commons-codec" ;; *) return ;; esac expected=$(printf '%s' "$expected" | tr '\n' ' ' | tr -s ' ') verified_jars=$((verified_jars + 1)) if ! jar tf "$jar_file" | awk '/\.class$/ { print }' >"$all_classes"; then printf 'FAIL %s: unreadable JAR\n' "$jar_file" >&2 failures=$((failures + 1)) return fi total_classes=$(wc -l <"$all_classes" | tr -d ' ') grep -Ev \ '^(META-INF/versions/[0-9]+/)?org/apache/parquet/' \ "$all_classes" >"$remaining" || true remaining_classes=$(wc -l <"$remaining" | tr -d ' ') project_classes=$((total_classes - remaining_classes)) printf '\n%s\n' "$jar_file" printf ' %-68s %6d classes\n' \ 'Parquet project classes' "$project_classes" while IFS=';' read -r dependency_id coordinate pattern; do case " $expected " in *" $dependency_id "*) ;; *) continue ;; esac processed_dependencies=$((processed_dependencies + 1)) matched_classes=$(grep -Ec "$pattern" "$remaining" || true) printf ' %-68s %6d classes\n' "$coordinate" "$matched_classes" if [[ $matched_classes -eq 0 ]]; then printf ' FAIL: expected dependency matched no classes\n' >&2 failures=$((failures + 1)) continue fi grep -Ev "$pattern" "$remaining" >"$next" || true mv "$next" "$remaining" done <"$catalog" expected_dependencies=$(printf '%s\n' "$expected" | wc -w | tr -d ' ') if [[ $processed_dependencies -ne $expected_dependencies ]]; then printf ' FAIL: dependency catalog is incomplete\n' >&2 failures=$((failures + 1)) fi remaining_classes=$(wc -l <"$remaining" | tr -d ' ') printf ' %-68s %6d classes\n' \ 'Unmatched after filtering' "$remaining_classes" if [[ $remaining_classes -ne 0 ]]; then printf ' FAIL: unexplained classes remain:\n' >&2 sed 's/^/ /' "$remaining" >&2 failures=$((failures + 1)) fi } while IFS= read -r -d '' jar_file; do check_jar "$jar_file" done < <( find parquet-avro parquet-column parquet-format-structures \ parquet-hadoop parquet-jackson parquet-hadoop-bundle parquet-cli \ -type f -path '*/target/*.jar' \ ! -name 'original-*.jar' \ ! -name '*-tests.jar' \ ! -name '*-sources.jar' \ ! -name '*-javadoc.jar' \ -print0 ) if [[ $verified_jars -ne 7 ]]; then printf '\nFAIL: expected 7 JARs, found %d. Run a clean package build first.\n' \ "$verified_jars" >&2 failures=$((failures + 1)) fi if [[ $failures -ne 0 ]]; then printf '\nVerification failed with %d error(s).\n' "$failures" >&2 exit 1 fi printf '\nVerified %d JARs; every dependency matched and 0 classes remain.\n' \ "$verified_jars" EOF
Output
parquet-avro/target/parquet-avro-1.18.0-SNAPSHOT.jar Parquet project classes 106 classes it.unimi.dsi:fastutil:8.5.18 943 classes Unmatched after filtering 0 classes parquet-column/target/parquet-column-1.18.0-SNAPSHOT.jar Parquet project classes 653 classes it.unimi.dsi:fastutil:8.5.18 1074 classes net.openhft:zero-allocation-hashing:0.27ea1 60 classes Unmatched after filtering 0 classes parquet-format-structures/target/parquet-format-structures-1.18.0-SNAPSHOT.jar Parquet project classes 431 classes org.apache.thrift:libthrift:0.23.0 73 classes Unmatched after filtering 0 classes parquet-hadoop/target/parquet-hadoop-1.18.0-SNAPSHOT.jar Parquet project classes 304 classes it.unimi.dsi:fastutil:8.5.18 371 classes Unmatched after filtering 0 classes parquet-jackson/target/parquet-jackson-1.18.0-SNAPSHOT.jar Parquet project classes 0 classes com.fasterxml.jackson.core:jackson-annotations:2.22 77 classes com.fasterxml.jackson.core:jackson-core:2.22.1 221 classes com.fasterxml.jackson.core:jackson-databind:2.22.1 812 classes Unmatched after filtering 0 classes parquet-hadoop-bundle/target/parquet-hadoop-bundle-1.18.0-SNAPSHOT.jar Parquet project classes 1795 classes it.unimi.dsi:fastutil:8.5.18 1074 classes net.openhft:zero-allocation-hashing:0.27ea1 60 classes org.apache.thrift:libthrift:0.23.0 73 classes com.fasterxml.jackson.core:jackson-annotations:2.22 77 classes com.fasterxml.jackson.core:jackson-core:2.22.1 221 classes com.fasterxml.jackson.core:jackson-databind:2.22.1 812 classes Unmatched after filtering 0 classes parquet-cli/target/parquet-cli-1.18.0-SNAPSHOT-runtime.jar Parquet project classes 2032 classes it.unimi.dsi:fastutil:8.5.18 14280 classes net.openhft:zero-allocation-hashing:0.27ea1 120 classes org.apache.thrift:libthrift:0.23.0 73 classes com.fasterxml.jackson.core:jackson-annotations:2.22 154 classes com.fasterxml.jackson.core:jackson-core:2.22.1 441 classes com.fasterxml.jackson.core:jackson-databind:2.22.1 1624 classes com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.22.1 64 classes javax.annotation:javax.annotation-api:1.3.2 15 classes org.locationtech.jts:jts-core:1.20.0 732 classes org.xerial.snappy:snappy-java:1.1.10.8 40 classes io.airlift:aircompressor:2.0.3 124 classes commons-pool:commons-pool:1.6 55 classes org.apache.avro:avro:1.11.5 450 classes org.apache.commons:commons-compress:1.26.2 571 classes org.tukaani:xz:1.12 129 classes com.github.luben:zstd-jni:1.5.7-11 37 classes org.slf4j:slf4j-api:1.7.33 34 classes net.sf.opencsv:opencsv:2.3 10 classes org.apache.commons:commons-text:1.15.0 168 classes org.apache.commons:commons-lang3:3.20.0 421 classes com.beust:jcommander:1.82 73 classes commons-codec:commons-codec:1.11 96 classes Unmatched after filtering 0 classes Verified 7 JARs; every dependency matched and 0 classes remain.Thanks for generating the list. I just checked, and all the included binaries are ASF compatible 👍.
- added a commit that references this issue
on Jul 27, 2026 Thanks for checking! Compatibility looks good. We still need to review each bundled dependency for any required
LICENSEorNOTICEupdates. ASF release policy requires those files to account for the exact contents of each artifact, including non-Apache license terms and relevant upstream notices.For example, we were pretty meticulous about this in iceberg: apache/iceberg#16196
Good news is, we only need to check the 3rd party dependencies listed above for each jar.
EDIT: i see #3694, thanks! i'll take a look
Reacted by Fokko Driesprong- added a commit that references this issue
on Aug 11, 2026
Background
We need to identify which published JARs bundle third-party code. ASF release policy requires JARs to place LICENSE and NOTICE in
META-INFand requires the LICENSE file to cover every bundled non-Apache component. Any required third-party notices also need to be included.This issue documents the findings and provides a script to verify them.
Findings
Cross-checking the final JAR contents against the Maven Shade configuration found:
parquet-avro-*.jarparquet-column-*.jarparquet-format-structures-*.jarlibthriftparquet-hadoop-*.jarparquet-jackson-*.jarparquet-hadoop-bundle-*.jarorg.apache.parquet:parquet-*JARsparquet-cli-*-runtime.jarshadedArtifactAttached=true, classifierruntime, includes all dependenciesA few edge cases:
parquet-variant,parquet-protobuf, andparquet-thriftrun Shade, but filtering and minimization leave no third-party classes in the final JARs.parquet-benchmarks.jarbundles the full dependency tree, but it is a local-only uber-JAR. The published versionedparquet-benchmarks-*.jarcontains only project classes.Setup and verification commands
Setup
Run the setup commands from the repository root with Java 17. Maven output is left visible so build progress and failures are easy to follow.
Verification
After setup completes, run the verification separately:
The Java 17 build completed successfully, and the legal-file check verified all 59 JARs.