From 7bac92e07e265447192c3feeb780a3b24d98d2ea Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Mon, 7 Jul 2025 16:11:59 -0500 Subject: [PATCH 01/20] Added graal vm plugin to pom.xml and classes to reflection-config.json --- ice/pom.xml | 37 +++++ ice/src/main/resources/reflection-config.json | 134 ++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 ice/src/main/resources/reflection-config.json diff --git a/ice/pom.xml b/ice/pom.xml index b200694b..f7dd3d0d 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -667,5 +667,42 @@ + + native + + + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + true + + + build-native + + compile-no-fork + + package + + + + ice + com.altinity.ice.cli.Main + + --initialize-at-build-time=ch.qos.logback + -H:ReflectionConfigurationFiles=src/main/resources/reflection-config.json + --trace-class-initialization=ch.qos.logback.classic.Logger + --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker + --trace-object-instantiation=ch.qos.logback.classic.Logger + --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-build-time=ch.qos.logback.classic.Logger + --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout + + + + + + + diff --git a/ice/src/main/resources/reflection-config.json b/ice/src/main/resources/reflection-config.json new file mode 100644 index 00000000..1d9866a5 --- /dev/null +++ b/ice/src/main/resources/reflection-config.json @@ -0,0 +1,134 @@ +[ + { + "name": "ch.qos.logback.classic.AsyncAppender", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.Logger.effectiveLevelInt", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.Logger.loggerContext", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.encoder.PatternLayoutEncoder", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.DateConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.LevelConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.LineSeparatorConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.LoggerConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.MessageConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.classic.pattern.ThreadConverter", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.core.ConsoleAppender", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "ch.qos.logback.core.FileAppender", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredFields": true, + "allPublicFields": true, + "allDeclaredClasses": true, + "allPublicClasses": true + } +] From 27d6cfa24e440c211b21cb7b0e2b8959a462ca42 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Wed, 19 Nov 2025 19:20:07 -0600 Subject: [PATCH 02/20] Fixed steps to build ice native image --- .github/workflows/verify.yaml | 16 ++++++ README.md | 32 +++++++++++- build-native.sh | 95 +++++++++++++++++++++++++++++++++++ ice/pom.xml | 85 ++++++++++++++++++++++++++++++- 4 files changed, 225 insertions(+), 3 deletions(-) create mode 100755 build-native.sh diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 053511ae..a48026c9 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -57,3 +57,19 @@ jobs: ./mvnw -pl ice-rest-catalog failsafe:integration-test failsafe:verify -Dit.test=DockerScenarioBasedIT -Ddocker.image=altinity/ice-rest-catalog:debug-with-ice-latest-master-amd64 + native-build: + name: Build and test native image + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'graalvm' + cache: maven + - name: Install musl for static linking + run: sudo apt-get update && sudo apt-get install -y musl-tools + - name: Build native image (amd64 static with musl) + run: ./build-native.sh + env: + ARCH: amd64 diff --git a/README.md b/README.md index f308e5fc..e83f3fdf 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,14 @@ Create/delete tables, insert data with `ice insert -p ns1.table1 file://example. ## Installation -Pre-built binaries\* (+ links to Docker images for [ice](https://hub.docker.com/r/altinity/ice) and [ice-rest-catalog](https://hub.docker.com/r/altinity/ice-rest-catalog)) are available from [GitHub Releases](https://github.com/Altinity/ice/releases) page. -> \* currently require `java` 21+ to run (available [here](https://adoptium.net/installation/)). +Pre-built binaries (+ links to Docker images for [ice](https://hub.docker.com/r/altinity/ice) and [ice-rest-catalog](https://hub.docker.com/r/altinity/ice-rest-catalog)) are available from [GitHub Releases](https://github.com/Altinity/ice/releases) page. + +**Two types of binaries are available:** + +1. **Java-based binaries** - Require Java 21+ to run (available [here](https://adoptium.net/installation/)) +2. **Native binaries** - Standalone executables with no Java dependency + - `ice-native-amd64` - Static binary (musl) for x86_64 Linux (no dependencies) + - `ice-native-arm64` - Dynamic binary for ARM64 Linux (requires glibc) ## Usage @@ -19,6 +25,8 @@ See [examples/](examples/). ## Development +### Standard Build (Java-based) + Install [sdkman](https://sdkman.io/install), then ```shell @@ -35,6 +43,26 @@ sdk env ./mvnw ``` +### Native Image Build (Standalone) + +Build standalone native binaries with no Java dependency: + +```shell +# Install prerequisites +sdk env # or ensure Java 21+ and GraalVM are available + +# For amd64 (static with musl - no dependencies) +./build-native.sh +# Produces: ice/target/ice (static binary) + +# Or use Maven directly +mvn -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true + +# For ARM64 (dynamic with glibc) +ARCH=arm64 ./build-native.sh +# Or: mvn -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true + + ## License Copyright (c) 2025, Altinity Inc and/or its affiliates. All rights reserved. diff --git a/build-native.sh b/build-native.sh new file mode 100755 index 00000000..891d534f --- /dev/null +++ b/build-native.sh @@ -0,0 +1,95 @@ +#!/bin/bash +# Build native images for ice CLI +# Supports: amd64 (static with musl), arm64 (dynamic) + +set -e + +VERSION="${VERSION:-0.0.0-SNAPSHOT}" +ARCH="${ARCH:-$(uname -m)}" + +# Convert architecture names +case "$ARCH" in + x86_64) + ARCH="amd64" + PROFILE="native-amd64-static" + ;; + aarch64|arm64) + ARCH="arm64" + PROFILE="native-arm64" + ;; + *) + echo "Unsupported architecture: $ARCH" + echo "Supported: x86_64/amd64, aarch64/arm64" + exit 1 + ;; +esac + +echo "============================================" +echo "Building native ice binary" +echo "Architecture: $ARCH" +echo "Profile: $PROFILE" +echo "Version: $VERSION" +echo "============================================" +echo "" + +# Check for musl-gcc on amd64 builds +if [ "$ARCH" = "amd64" ]; then + if ! command -v x86_64-linux-musl-gcc &> /dev/null && ! command -v musl-gcc &> /dev/null; then + echo " WARNING: musl compiler not found!" + echo "" + echo "For static builds on amd64, you need musl-tools installed." + echo "" + echo "Install it with:" + echo " Ubuntu/Debian: sudo apt-get install musl-tools" + echo " Fedora/RHEL: sudo dnf install musl-gcc musl-libc-static" + echo " Alpine: apk add musl-dev gcc" + echo "" + echo "Or build without static linking using the 'native' profile:" + echo " mvn -Pnative -pl ice clean package -Dmaven.test.skip=true" + echo "" + read -p "Continue anyway? (y/N) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + else + echo "✓ musl compiler found" + fi +fi +echo "" + +# Set version +./mvnw -am -pl ice versions:set -DnewVersion=${VERSION} + +# Build native image +echo "Building native image..." +./mvnw -Pno-check -P${PROFILE} -pl ice clean package -Dmaven.test.skip=true + +echo "" +echo "============================================" +echo "✓ Native binary built successfully!" +echo "============================================" +echo "" +echo "Binary location: ice/target/ice" +echo "" +echo "Test the binary:" +echo " ./ice/target/ice --version" +echo " ./ice/target/ice check" +echo "" + +# Show binary info +if [ -f "ice/target/ice" ]; then + ls -lh ice/target/ice + file ice/target/ice || true + + if [ "$ARCH" = "amd64" ]; then + echo "" + echo "Static binary (no dependencies):" + ldd ice/target/ice 2>&1 || echo " ✓ Statically linked (expected for amd64)" + else + echo "" + echo "Dynamic binary dependencies:" + ldd ice/target/ice || true + fi +fi + diff --git a/ice/pom.xml b/ice/pom.xml index f7dd3d0d..098bfff0 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -690,7 +690,7 @@ com.altinity.ice.cli.Main --initialize-at-build-time=ch.qos.logback - -H:ReflectionConfigurationFiles=src/main/resources/reflection-config.json + -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json --trace-class-initialization=ch.qos.logback.classic.Logger --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker --trace-object-instantiation=ch.qos.logback.classic.Logger @@ -704,5 +704,88 @@ + + native-amd64-static + + + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + true + + + build-native + + compile-no-fork + + package + + + + ice + com.altinity.ice.cli.Main + + + --initialize-at-build-time=ch.qos.logback + -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json + --trace-class-initialization=ch.qos.logback.classic.Logger + --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker + --trace-object-instantiation=ch.qos.logback.classic.Logger + --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-build-time=ch.qos.logback.classic.Logger + --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout + + --static + --libc=musl + + -H:+RemoveUnusedSymbols + -H:+ReportExceptionStackTraces + + + + + + + + native-arm64 + + + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + true + + + build-native + + compile-no-fork + + package + + + + ice + com.altinity.ice.cli.Main + + + --initialize-at-build-time=ch.qos.logback + -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json + --trace-class-initialization=ch.qos.logback.classic.Logger + --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker + --trace-object-instantiation=ch.qos.logback.classic.Logger + --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-build-time=ch.qos.logback.classic.Logger + --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout + + -H:+RemoveUnusedSymbols + -H:+ReportExceptionStackTraces + + + + + + From b1bef04b1e3ab21bf9f9db0f8393f03522721191 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Wed, 19 Nov 2025 19:23:18 -0600 Subject: [PATCH 03/20] include amd64 in supported architecture --- build-native.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-native.sh b/build-native.sh index 891d534f..1b6c26c0 100755 --- a/build-native.sh +++ b/build-native.sh @@ -9,7 +9,7 @@ ARCH="${ARCH:-$(uname -m)}" # Convert architecture names case "$ARCH" in - x86_64) + x86_64|amd64) ARCH="amd64" PROFILE="native-amd64-static" ;; From a2f6743c474faff2dcdf9d7e61493a7f00d46753 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Wed, 19 Nov 2025 19:28:49 -0600 Subject: [PATCH 04/20] Added runtime depedencies for native image. --- ice/pom.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ice/pom.xml b/ice/pom.xml index 098bfff0..35c59eee 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -695,6 +695,9 @@ --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=org.slf4j.LoggerFactory + --initialize-at-run-time=org.slf4j.helpers.Reporter + --initialize-at-run-time=picocli.CommandLine$Help$Ansi --initialize-at-build-time=ch.qos.logback.classic.Logger --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout @@ -733,6 +736,9 @@ --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=org.slf4j.LoggerFactory + --initialize-at-run-time=org.slf4j.helpers.Reporter + --initialize-at-run-time=picocli.CommandLine$Help$Ansi --initialize-at-build-time=ch.qos.logback.classic.Logger --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout @@ -776,6 +782,9 @@ --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=org.slf4j.LoggerFactory + --initialize-at-run-time=org.slf4j.helpers.Reporter + --initialize-at-run-time=picocli.CommandLine$Help$Ansi --initialize-at-build-time=ch.qos.logback.classic.Logger --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout From fc1d23a5e55a35758cca7347d9b15e5edcec44f4 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Wed, 19 Nov 2025 19:35:12 -0600 Subject: [PATCH 05/20] Added runtime depedencies for native image. --- ice/pom.xml | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/ice/pom.xml b/ice/pom.xml index 35c59eee..367dde56 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -689,17 +689,9 @@ ice com.altinity.ice.cli.Main - --initialize-at-build-time=ch.qos.logback -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --trace-class-initialization=ch.qos.logback.classic.Logger - --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker - --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask - --initialize-at-run-time=org.slf4j.LoggerFactory - --initialize-at-run-time=org.slf4j.helpers.Reporter - --initialize-at-run-time=picocli.CommandLine$Help$Ansi - --initialize-at-build-time=ch.qos.logback.classic.Logger - --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout + -H:+ReportExceptionStackTraces @@ -730,17 +722,8 @@ com.altinity.ice.cli.Main - --initialize-at-build-time=ch.qos.logback -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --trace-class-initialization=ch.qos.logback.classic.Logger - --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker - --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask - --initialize-at-run-time=org.slf4j.LoggerFactory - --initialize-at-run-time=org.slf4j.helpers.Reporter - --initialize-at-run-time=picocli.CommandLine$Help$Ansi - --initialize-at-build-time=ch.qos.logback.classic.Logger - --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout --static --libc=musl @@ -776,17 +759,8 @@ com.altinity.ice.cli.Main - --initialize-at-build-time=ch.qos.logback -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --trace-class-initialization=ch.qos.logback.classic.Logger - --trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker - --trace-object-instantiation=ch.qos.logback.classic.Logger --initialize-at-run-time=io.netty.channel.ChannelHandlerMask - --initialize-at-run-time=org.slf4j.LoggerFactory - --initialize-at-run-time=org.slf4j.helpers.Reporter - --initialize-at-run-time=picocli.CommandLine$Help$Ansi - --initialize-at-build-time=ch.qos.logback.classic.Logger - --initialize-at-build-time=com.altinity.ice.internal.logback.ColorAwarePatternLayout -H:+RemoveUnusedSymbols -H:+ReportExceptionStackTraces From 371c0f8bcee579f23e2fac49129a8d163de06702 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Fri, 21 Nov 2025 07:50:21 -0600 Subject: [PATCH 06/20] Fixed reflection-config.json --- .github/workflows/verify.yaml | 16 +++++++++----- ice/pom.xml | 9 +++++--- ice/src/main/resources/reflection-config.json | 22 ------------------- 3 files changed, 16 insertions(+), 31 deletions(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index a48026c9..85bad765 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -67,9 +67,13 @@ jobs: java-version: '21' distribution: 'graalvm' cache: maven - - name: Install musl for static linking - run: sudo apt-get update && sudo apt-get install -y musl-tools - - name: Build native image (amd64 static with musl) - run: ./build-native.sh - env: - ARCH: amd64 + - name: Build native image (dynamic linking - no musl required) + run: ./mvnw -Pnative -pl ice clean package -Dmaven.test.skip=true + - name: Test native binary + run: ./test-native-binary.sh + - name: Upload native binary as artifact + uses: actions/upload-artifact@v4 + with: + name: ice-native-amd64-dynamic + path: ice/target/ice + if-no-files-found: error diff --git a/ice/pom.xml b/ice/pom.xml index 367dde56..3b1db9bf 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -690,7 +690,8 @@ com.altinity.ice.cli.Main -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=io.netty + --initialize-at-run-time=ch.qos.logback -H:+ReportExceptionStackTraces @@ -723,7 +724,8 @@ -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=io.netty + --initialize-at-run-time=ch.qos.logback --static --libc=musl @@ -760,7 +762,8 @@ -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=io.netty + --initialize-at-run-time=ch.qos.logback -H:+RemoveUnusedSymbols -H:+ReportExceptionStackTraces diff --git a/ice/src/main/resources/reflection-config.json b/ice/src/main/resources/reflection-config.json index 1d9866a5..15a1a7b5 100644 --- a/ice/src/main/resources/reflection-config.json +++ b/ice/src/main/resources/reflection-config.json @@ -10,28 +10,6 @@ "allDeclaredClasses": true, "allPublicClasses": true }, - { - "name": "ch.qos.logback.classic.Logger.effectiveLevelInt", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.Logger.loggerContext", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, { "name": "ch.qos.logback.classic.encoder.PatternLayoutEncoder", "allDeclaredConstructors": true, From ddbcf9fcdc4243814f0a4066fbe416a00b6cabfb Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Fri, 21 Nov 2025 08:57:32 -0600 Subject: [PATCH 07/20] remove verify binary step. --- .github/workflows/verify.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 85bad765..50736f6a 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -69,8 +69,6 @@ jobs: cache: maven - name: Build native image (dynamic linking - no musl required) run: ./mvnw -Pnative -pl ice clean package -Dmaven.test.skip=true - - name: Test native binary - run: ./test-native-binary.sh - name: Upload native binary as artifact uses: actions/upload-artifact@v4 with: From 303357d83c6728c9045b33ed7e99c62a18b5af93 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Fri, 21 Nov 2025 09:23:46 -0600 Subject: [PATCH 08/20] Add support for ARM. --- .github/workflows/verify.yaml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 50736f6a..099facc5 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -58,8 +58,19 @@ jobs: -Dit.test=DockerScenarioBasedIT -Ddocker.image=altinity/ice-rest-catalog:debug-with-ice-latest-master-amd64 native-build: - name: Build and test native image - runs-on: ubuntu-24.04 + name: Build and test native image (${{ matrix.arch }}) + runs-on: ${{ matrix.runner }} + strategy: + matrix: + include: + - arch: amd64 + runner: ubuntu-24.04 + profile: native + artifact: ice-native-amd64-dynamic + - arch: arm64 + runner: ubuntu-24.04-arm + profile: native-arm64 + artifact: ice-native-arm64-dynamic steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 @@ -68,10 +79,10 @@ jobs: distribution: 'graalvm' cache: maven - name: Build native image (dynamic linking - no musl required) - run: ./mvnw -Pnative -pl ice clean package -Dmaven.test.skip=true + run: ./mvnw -P${{ matrix.profile }} -pl ice clean package -Dmaven.test.skip=true - name: Upload native binary as artifact uses: actions/upload-artifact@v4 with: - name: ice-native-amd64-dynamic + name: ${{ matrix.artifact }} path: ice/target/ice if-no-files-found: error From 12ef6b0cbef62e7d6705cbc4f846b9c99554da82 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Sat, 22 Nov 2025 08:55:09 -0600 Subject: [PATCH 09/20] Added Dockerfile. --- docker-build-native.sh | 55 ++++++++++++++++++ ice/Dockerfile.native | 52 +++++++++++++++++ ice/Dockerfile.native-amd64-static | 33 +++++++++++ ice/Dockerfile.native-arm64 | 33 +++++++++++ ice/Dockerfile.native-builder | 91 ++++++++++++++++++++++++++++++ 5 files changed, 264 insertions(+) create mode 100755 docker-build-native.sh create mode 100644 ice/Dockerfile.native create mode 100644 ice/Dockerfile.native-amd64-static create mode 100644 ice/Dockerfile.native-arm64 create mode 100644 ice/Dockerfile.native-builder diff --git a/docker-build-native.sh b/docker-build-native.sh new file mode 100755 index 00000000..f300e81c --- /dev/null +++ b/docker-build-native.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# Build ICE native images using Docker +# Usage: ./docker-build-native.sh [amd64|arm64|both] + +set -euo pipefail + +ARCH="${1:-$(uname -m)}" + +# Normalize architecture names +case "$ARCH" in + x86_64|amd64) + BUILD_ARCH="amd64" + PLATFORM="linux/amd64" + ;; + aarch64|arm64) + BUILD_ARCH="arm64" + PLATFORM="linux/arm64" + ;; + both) + echo "Building for both architectures..." + $0 amd64 + $0 arm64 + exit 0 + ;; + *) + echo "Unsupported architecture: $ARCH" + echo "Usage: $0 [amd64|arm64|both]" + exit 1 + ;; +esac + +echo "========================================" +echo "Building ICE native image for $BUILD_ARCH" +echo "Platform: $PLATFORM" +echo "========================================" + +# Build the Docker image +docker build \ + --platform="$PLATFORM" \ + --build-arg ARCH="$BUILD_ARCH" \ + -f ice/Dockerfile.native-builder \ + -t ice-native-builder:"$BUILD_ARCH" \ + . + +# Extract the binary +CONTAINER_ID=$(docker create ice-native-builder:"$BUILD_ARCH") +docker cp "$CONTAINER_ID":/ice "./ice-$BUILD_ARCH" +docker rm "$CONTAINER_ID" + +echo "" +echo "✓ Native binary created: ./ice-$BUILD_ARCH" +echo "" +echo "Test it with:" +echo " ./ice-$BUILD_ARCH --help" + diff --git a/ice/Dockerfile.native b/ice/Dockerfile.native new file mode 100644 index 00000000..52caa1e3 --- /dev/null +++ b/ice/Dockerfile.native @@ -0,0 +1,52 @@ +# Multi-arch native image build for ice +# Supports: amd64 (with static musl), arm64 (dynamic) +ARG BASE_IMAGE_TAG="nonroot" +ARG VERSION="0.0.0-SNAPSHOT" +ARG TARGETARCH + +FROM --platform=$BUILDPLATFORM ghcr.io/graalvm/native-image-community:21.0.2 AS build + +WORKDIR /app + +# Install musl for static linking (amd64) +RUN microdnf install -y musl-devel || true + +# Cache maven dependencies for faster re-builds +COPY .mvn/ .mvn/ +COPY mvnw . +COPY pom.xml . +COPY ice/pom.xml ice/pom.xml +COPY ice-rest-catalog/pom.xml ice-rest-catalog/pom.xml +RUN ./mvnw -am -pl ice dependency:go-offline + +ARG VERSION +ARG TARGETARCH + +COPY . . + +RUN ./mvnw -am -pl ice versions:set -DnewVersion=${VERSION} + +# Build with appropriate profile based on architecture +RUN if [ "$TARGETARCH" = "amd64" ]; then \ + echo "Building static native image for amd64 with musl..."; \ + ./mvnw -Pno-check -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true; \ + elif [ "$TARGETARCH" = "arm64" ]; then \ + echo "Building native image for arm64..."; \ + ./mvnw -Pno-check -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true; \ + else \ + echo "Building native image for $TARGETARCH..."; \ + ./mvnw -Pno-check -Pnative -pl ice clean package -Dmaven.test.skip=true; \ + fi + +# Use scratch for amd64 (static), distroless for arm64 (dynamic) +FROM scratch AS final-amd64 +COPY --from=build /app/ice/target/ice /usr/local/bin/ice +ENTRYPOINT ["/usr/local/bin/ice"] + +FROM gcr.io/distroless/base-debian12:${BASE_IMAGE_TAG} AS final-arm64 +COPY --from=build /app/ice/target/ice /usr/local/bin/ice +ENTRYPOINT ["/usr/local/bin/ice"] + +# Select appropriate final stage based on architecture +FROM final-${TARGETARCH} AS final + diff --git a/ice/Dockerfile.native-amd64-static b/ice/Dockerfile.native-amd64-static new file mode 100644 index 00000000..dd0c2587 --- /dev/null +++ b/ice/Dockerfile.native-amd64-static @@ -0,0 +1,33 @@ +# Dockerfile for building ICE native image (amd64, static with musl) +# Usage: docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64-static . + +FROM ghcr.io/graalvm/native-image-community:21-muslib AS builder + +WORKDIR /workspace + +# Copy license header file (required by license-maven-plugin) +COPY apache-header.txt . + +# Copy Maven files for dependency resolution +COPY mvnw . +COPY .mvn .mvn +COPY pom.xml . +COPY ice/pom.xml ice/ +COPY ice-rest-catalog/pom.xml ice-rest-catalog/ + +# Download dependencies (cached layer) +RUN ./mvnw dependency:go-offline -pl ice || true + +# Copy source code +COPY ice/src ice/src + +# Build static native image with musl +RUN ./mvnw -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true + +# ============================================================================ +# Final stage: minimal scratch image (truly standalone binary) +# ============================================================================ +FROM scratch +COPY --from=builder /workspace/ice/target/ice /ice +ENTRYPOINT ["/ice"] + diff --git a/ice/Dockerfile.native-arm64 b/ice/Dockerfile.native-arm64 new file mode 100644 index 00000000..4d997ec1 --- /dev/null +++ b/ice/Dockerfile.native-arm64 @@ -0,0 +1,33 @@ +# Dockerfile for building ICE native image (arm64, dynamic linking) +# Usage: docker build -f ice/Dockerfile.native-arm64 -t ice-native:arm64 . + +FROM ghcr.io/graalvm/native-image-community:21 AS builder + +WORKDIR /workspace + +# Copy license header file (required by license-maven-plugin) +COPY apache-header.txt . + +# Copy Maven files for dependency resolution +COPY mvnw . +COPY .mvn .mvn +COPY pom.xml . +COPY ice/pom.xml ice/ +COPY ice-rest-catalog/pom.xml ice-rest-catalog/ + +# Download dependencies (cached layer) +RUN ./mvnw dependency:go-offline -pl ice || true + +# Copy source code +COPY ice/src ice/src + +# Build dynamic native image +RUN ./mvnw -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true + +# ============================================================================ +# Final stage: distroless base (includes minimal glibc runtime) +# ============================================================================ +FROM gcr.io/distroless/base-debian12:nonroot +COPY --from=builder /workspace/ice/target/ice /ice +ENTRYPOINT ["/ice"] + diff --git a/ice/Dockerfile.native-builder b/ice/Dockerfile.native-builder new file mode 100644 index 00000000..0a044e6d --- /dev/null +++ b/ice/Dockerfile.native-builder @@ -0,0 +1,91 @@ +# Multi-stage Dockerfile for building ICE native images +# Supports both amd64 (with static musl) and arm64 (dynamic) + +ARG ARCH=amd64 + +# ============================================================================ +# Stage 1: Build stage with all dependencies +# ============================================================================ +FROM ghcr.io/graalvm/native-image-community:21 AS builder + +# Install build dependencies +RUN microdnf install -y \ + findutils \ + tar \ + gzip \ + wget \ + && microdnf clean all + +# Detect architecture and install appropriate dependencies +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "x86_64" ]; then \ + echo "Installing musl toolchain and zlib for amd64 static builds..."; \ + # Download and install musl-gcc + wget -q https://musl.libc.org/releases/musl-1.2.5.tar.gz && \ + tar -xzf musl-1.2.5.tar.gz && \ + cd musl-1.2.5 && \ + ./configure --prefix=/usr/local/musl --disable-shared && \ + make -j$(nproc) && \ + make install && \ + cd .. && \ + rm -rf musl-1.2.5 musl-1.2.5.tar.gz && \ + # Download and install zlib for musl + wget -q https://zlib.net/zlib-1.3.1.tar.gz && \ + tar -xzf zlib-1.3.1.tar.gz && \ + cd zlib-1.3.1 && \ + CC=/usr/local/musl/bin/musl-gcc ./configure --prefix=/usr/local/musl --static && \ + make -j$(nproc) && \ + make install && \ + cd .. && \ + rm -rf zlib-1.3.1 zlib-1.3.1.tar.gz && \ + # Create symlink for native-image to find musl-gcc + ln -sf /usr/local/musl/bin/musl-gcc /usr/local/bin/x86_64-linux-musl-gcc; \ + else \ + echo "ARM64 detected - using dynamic linking (no musl required)"; \ + fi + +WORKDIR /workspace + +# Copy license header file (required by license-maven-plugin) +COPY apache-header.txt . + +# Copy Maven wrapper and pom files first (for better caching) +COPY mvnw . +COPY .mvn .mvn +COPY pom.xml . +COPY ice/pom.xml ice/ +COPY ice-rest-catalog/pom.xml ice-rest-catalog/ + +# Download dependencies (cached layer) +RUN ./mvnw dependency:go-offline -pl ice || true + +# Copy source code +COPY ice/src ice/src + +# Build native image based on architecture +RUN ARCH=$(uname -m) && \ + if [ "$ARCH" = "x86_64" ]; then \ + echo "Building static native image for amd64 with musl..."; \ + export PATH="/usr/local/musl/bin:$PATH" && \ + ./mvnw -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true; \ + else \ + echo "Building dynamic native image for arm64..."; \ + ./mvnw -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true; \ + fi + +# ============================================================================ +# Stage 2: Runtime image (minimal) +# ============================================================================ +FROM scratch AS runtime-amd64 +COPY --from=builder /workspace/ice/target/ice /ice +ENTRYPOINT ["/ice"] + +FROM gcr.io/distroless/base-debian12:nonroot AS runtime-arm64 +COPY --from=builder /workspace/ice/target/ice /ice +ENTRYPOINT ["/ice"] + +# ============================================================================ +# Stage 3: Final stage (architecture-dependent) +# ============================================================================ +FROM runtime-${ARCH} AS final + From d0b8aafba2661fe7562c2a4c080106fd2e61af58 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Sun, 23 Nov 2025 10:22:59 -0600 Subject: [PATCH 10/20] Remove autogenerated files. --- GITHUB_RELEASE_TEMPLATE.md | 34 -- build-native.sh | 95 ----- docker-build-native.sh | 55 --- .../docker-compose/test-ssl-verification.md | 186 ++++++++++ examples/scratch/output.json | 0 ice-rest-catalog/SCENARIO_TESTING.md | 344 ++++++++++++++++++ ice/Dockerfile.native | 52 --- ice/Dockerfile.native-amd64-static | 2 +- ice/Dockerfile.native-builder | 91 ----- 9 files changed, 531 insertions(+), 328 deletions(-) delete mode 100644 GITHUB_RELEASE_TEMPLATE.md delete mode 100755 build-native.sh delete mode 100755 docker-build-native.sh create mode 100644 examples/docker-compose/test-ssl-verification.md create mode 100644 examples/scratch/output.json create mode 100644 ice-rest-catalog/SCENARIO_TESTING.md delete mode 100644 ice/Dockerfile.native delete mode 100644 ice/Dockerfile.native-builder diff --git a/GITHUB_RELEASE_TEMPLATE.md b/GITHUB_RELEASE_TEMPLATE.md deleted file mode 100644 index fe7ff576..00000000 --- a/GITHUB_RELEASE_TEMPLATE.md +++ /dev/null @@ -1,34 +0,0 @@ -## Installation - -### ice - -```sh -curl -sSL https://github.com/altinity/ice/releases/download/REPLACE_WITH_TAG/ice-REPLACE_WITH_VER \ - -o ice && chmod a+x ice && sudo mv ice /usr/local/bin/ -``` - -#### Docker - - - -- `altinity/ice:REPLACE_WITH_VER` -- `altinity/ice:debug-REPLACE_WITH_VER` - -> `debug-*` images contain busybox shell. - -### ice-rest-catalog - -```sh -curl -sSL https://github.com/altinity/ice/releases/download/REPLACE_WITH_TAG/ice-rest-catalog-REPLACE_WITH_VER \ - -o ice-rest-catalog && chmod a+x ice-rest-catalog && sudo mv ice-rest-catalog /usr/local/bin/ -``` - -#### Docker - - - -- `altinity/ice-rest-catalog:REPLACE_WITH_VER` -- `altinity/ice-rest-catalog:debug-REPLACE_WITH_VER` -- `altinity/ice-rest-catalog:debug-with-ice-REPLACE_WITH_VER` - -> `debug-*` images contain busybox shell. diff --git a/build-native.sh b/build-native.sh deleted file mode 100755 index 1b6c26c0..00000000 --- a/build-native.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash -# Build native images for ice CLI -# Supports: amd64 (static with musl), arm64 (dynamic) - -set -e - -VERSION="${VERSION:-0.0.0-SNAPSHOT}" -ARCH="${ARCH:-$(uname -m)}" - -# Convert architecture names -case "$ARCH" in - x86_64|amd64) - ARCH="amd64" - PROFILE="native-amd64-static" - ;; - aarch64|arm64) - ARCH="arm64" - PROFILE="native-arm64" - ;; - *) - echo "Unsupported architecture: $ARCH" - echo "Supported: x86_64/amd64, aarch64/arm64" - exit 1 - ;; -esac - -echo "============================================" -echo "Building native ice binary" -echo "Architecture: $ARCH" -echo "Profile: $PROFILE" -echo "Version: $VERSION" -echo "============================================" -echo "" - -# Check for musl-gcc on amd64 builds -if [ "$ARCH" = "amd64" ]; then - if ! command -v x86_64-linux-musl-gcc &> /dev/null && ! command -v musl-gcc &> /dev/null; then - echo " WARNING: musl compiler not found!" - echo "" - echo "For static builds on amd64, you need musl-tools installed." - echo "" - echo "Install it with:" - echo " Ubuntu/Debian: sudo apt-get install musl-tools" - echo " Fedora/RHEL: sudo dnf install musl-gcc musl-libc-static" - echo " Alpine: apk add musl-dev gcc" - echo "" - echo "Or build without static linking using the 'native' profile:" - echo " mvn -Pnative -pl ice clean package -Dmaven.test.skip=true" - echo "" - read -p "Continue anyway? (y/N) " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - exit 1 - fi - else - echo "✓ musl compiler found" - fi -fi -echo "" - -# Set version -./mvnw -am -pl ice versions:set -DnewVersion=${VERSION} - -# Build native image -echo "Building native image..." -./mvnw -Pno-check -P${PROFILE} -pl ice clean package -Dmaven.test.skip=true - -echo "" -echo "============================================" -echo "✓ Native binary built successfully!" -echo "============================================" -echo "" -echo "Binary location: ice/target/ice" -echo "" -echo "Test the binary:" -echo " ./ice/target/ice --version" -echo " ./ice/target/ice check" -echo "" - -# Show binary info -if [ -f "ice/target/ice" ]; then - ls -lh ice/target/ice - file ice/target/ice || true - - if [ "$ARCH" = "amd64" ]; then - echo "" - echo "Static binary (no dependencies):" - ldd ice/target/ice 2>&1 || echo " ✓ Statically linked (expected for amd64)" - else - echo "" - echo "Dynamic binary dependencies:" - ldd ice/target/ice || true - fi -fi - diff --git a/docker-build-native.sh b/docker-build-native.sh deleted file mode 100755 index f300e81c..00000000 --- a/docker-build-native.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash -# Build ICE native images using Docker -# Usage: ./docker-build-native.sh [amd64|arm64|both] - -set -euo pipefail - -ARCH="${1:-$(uname -m)}" - -# Normalize architecture names -case "$ARCH" in - x86_64|amd64) - BUILD_ARCH="amd64" - PLATFORM="linux/amd64" - ;; - aarch64|arm64) - BUILD_ARCH="arm64" - PLATFORM="linux/arm64" - ;; - both) - echo "Building for both architectures..." - $0 amd64 - $0 arm64 - exit 0 - ;; - *) - echo "Unsupported architecture: $ARCH" - echo "Usage: $0 [amd64|arm64|both]" - exit 1 - ;; -esac - -echo "========================================" -echo "Building ICE native image for $BUILD_ARCH" -echo "Platform: $PLATFORM" -echo "========================================" - -# Build the Docker image -docker build \ - --platform="$PLATFORM" \ - --build-arg ARCH="$BUILD_ARCH" \ - -f ice/Dockerfile.native-builder \ - -t ice-native-builder:"$BUILD_ARCH" \ - . - -# Extract the binary -CONTAINER_ID=$(docker create ice-native-builder:"$BUILD_ARCH") -docker cp "$CONTAINER_ID":/ice "./ice-$BUILD_ARCH" -docker rm "$CONTAINER_ID" - -echo "" -echo "✓ Native binary created: ./ice-$BUILD_ARCH" -echo "" -echo "Test it with:" -echo " ./ice-$BUILD_ARCH --help" - diff --git a/examples/docker-compose/test-ssl-verification.md b/examples/docker-compose/test-ssl-verification.md new file mode 100644 index 00000000..72ca27ea --- /dev/null +++ b/examples/docker-compose/test-ssl-verification.md @@ -0,0 +1,186 @@ +# Testing SSL Certificate Verification Skip + +This guide shows how to test the `--insecure` / `--ssl-no-verify` flag with self-signed certificates. + +## Option 1: Quick Test with a Self-Signed HTTPS Server + +### 1. Generate a self-signed certificate + +```bash +# Generate a self-signed certificate for testing +openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes \ + -subj "/CN=localhost" \ + -addext "subjectAltName=DNS:localhost,IP:127.0.0.1" +``` + +### 2. Set up an HTTPS proxy to ice-rest-catalog + +Create a simple nginx config to add SSL in front of the catalog: + +**nginx-ssl.conf**: +```nginx +events { + worker_connections 1024; +} + +http { + server { + listen 5443 ssl; + server_name localhost; + + ssl_certificate /etc/nginx/cert.pem; + ssl_certificate_key /etc/nginx/key.pem; + + location / { + proxy_pass http://ice-rest-catalog:5000; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } +} +``` + +**docker-compose.ssl-test.yaml**: +```yaml +services: + nginx-ssl: + image: nginx:alpine + ports: + - "5443:5443" + volumes: + - ./cert.pem:/etc/nginx/cert.pem:ro + - ./key.pem:/etc/nginx/key.pem:ro + - ./nginx-ssl.conf:/etc/nginx/nginx.conf:ro + depends_on: + - ice-rest-catalog +``` + +### 3. Start the services + +```bash +# Start the regular docker-compose setup +docker-compose up -d + +# Start the SSL proxy +docker-compose -f docker-compose.ssl-test.yaml up -d +``` + +### 4. Test the ice CLI + +First, format and build the code: +```bash +cd /home/kanthi/Documents/GITHUB/ALTINITY/ice +mvn com.spotify.fmt:fmt-maven-plugin:format -pl ice +mvn clean install -pl ice -am -DskipTests +``` + +Create a test config file `.ice-ssl-test.yaml`: +```yaml +uri: https://localhost:5443 +bearerToken: foo +warehouse: s3://bucket1 +sslVerify: false # Config file option +s3: + endpoint: http://localhost:8999 + pathStyleAccess: true + accessKeyID: miniouser + secretAccessKey: miniopassword + region: minio +``` + +**Test 1: Without --insecure flag (should fail with SSL error)**: +```bash +./ice/target/ice-jar -c .ice-ssl-test.yaml check +# Expected: SSL certificate verification error +``` + +**Test 2: With --insecure flag (should succeed)**: +```bash +./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure check +# Expected: OK +``` + +**Test 3: Using config file sslVerify option**: +With `sslVerify: false` in the config file: +```bash +./ice/target/ice-jar -c .ice-ssl-test.yaml check +# Expected: OK (with warning about disabled SSL verification) +``` + +**Test 4: Test other commands**: +```bash +# List namespaces +./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure describe + +# Create a namespace +./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure create-namespace test_ns + +# Create a table +./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure create-table test_ns.test_table \ + --schema '[{"name":"id","type":"int"},{"name":"name","type":"string"}]' +``` + +## Option 2: Test with Public Self-Signed Certificate Server + +You can also test against a public service with a self-signed certificate: + +```bash +# This will fail due to self-signed certificate +./ice/target/ice-jar -c config.yaml check + +# This will work with --insecure +./ice/target/ice-jar -c config.yaml --insecure check +``` + +## Option 3: Test with Internal CA Certificate + +If you have an internal CA, you can test the custom CA bundle feature: + +```yaml +uri: https://internal-catalog.company.local:5443 +caCrt: | + -----BEGIN CERTIFICATE----- + MIIDXTCCAkWgAwIBAgIJAKJ... + -----END CERTIFICATE----- +bearerToken: foo +``` + +This should work without `--insecure` because the CA certificate is provided. + +## Expected Behavior + +### Without SSL verification skip: +- ❌ Fails with certificate verification errors for self-signed certificates +- ✅ Works with valid certificates from trusted CAs +- ✅ Works when custom CA certificate is provided via `caCrt` + +### With SSL verification skip (`--insecure` or `sslVerify: false`): +- ⚠️ Displays warning: "SSL certificate verification is DISABLED. This is insecure and should only be used for development." +- ✅ Works with any certificate (self-signed, expired, wrong hostname, etc.) +- ⚠️ **INSECURE**: Should only be used for development/testing + +## Command-line Flags + +Two equivalent options: +- `--insecure` - Shorter, commonly used in tools like curl +- `--ssl-no-verify` - More explicit about what it does + +Both flags: +- Override the config file `sslVerify` setting +- Apply to all subcommands (check, describe, scan, insert, etc.) +- Display a warning message when SSL verification is disabled + +## Config File Option + +```yaml +sslVerify: false # Skip SSL certificate verification +``` + +Note: The command-line flag takes precedence over the config file option. + + + + + + diff --git a/examples/scratch/output.json b/examples/scratch/output.json new file mode 100644 index 00000000..e69de29b diff --git a/ice-rest-catalog/SCENARIO_TESTING.md b/ice-rest-catalog/SCENARIO_TESTING.md new file mode 100644 index 00000000..af54e58e --- /dev/null +++ b/ice-rest-catalog/SCENARIO_TESTING.md @@ -0,0 +1,344 @@ +# Scenario-Based Testing Framework + +This document describes the new scenario-based testing framework for ICE REST Catalog integration tests. + +## Overview + +The scenario-based testing framework provides a scalable, data-driven approach to integration testing. Instead of hardcoding test scenarios in Java test methods, each scenario is defined in its own directory with: + +- Configuration files (scenario.yaml) +- Input data (parquet files) +- Executable test scripts (run.sh.tmpl, verify.sh.tmpl) + +This approach makes it much easier to: +- Add new test scenarios without writing Java code +- Share test scenarios across teams +- Test complex workflows with multiple steps +- Provision cloud resources dynamically (future feature) + +## Directory Structure + +``` +ice-rest-catalog/src/test/resources/scenarios/ +├── README.md # Documentation for scenario structure +├── basic-operations/ # Example scenario +│ ├── scenario.yaml # Scenario configuration +│ ├── run.sh.tmpl # Main test script (templated) +│ └── verify.sh.tmpl # Optional verification script +├── insert-scan/ +│ ├── scenario.yaml +│ ├── run.sh.tmpl +│ ├── verify.sh.tmpl +│ └── input.parquet # Test data +└── insert-partitioned/ + ├── scenario.yaml + ├── run.sh.tmpl + ├── verify.sh.tmpl + └── input.parquet +``` + +## Key Components + +### 1. ScenarioConfig.java +Java class that represents the scenario.yaml configuration file. Supports: +- Scenario metadata (name, description) +- Catalog configuration overrides +- Environment variables for scripts +- Cloud resource specifications (for future provisioning) +- Test phases + +### 2. ScenarioTestRunner.java +Core test execution engine that: +- Discovers scenario directories +- Loads scenario configurations +- Processes template variables in scripts +- Executes scripts and captures output +- Reports results + +### 3. ScenarioBasedIT.java +TestNG parameterized test class that: +- Automatically discovers all scenarios +- Runs each scenario as a separate test case +- Provides test infrastructure (MinIO, REST catalog) +- Injects template variables (CLI config, endpoints, etc.) + +### 4. RESTCatalogTestBase.java (Updated) +Base test class that provides: +- MinIO container setup/teardown +- REST catalog server setup/teardown +- Helper methods for scenarios (getMinioEndpoint, getCatalogUri, etc.) + +## How It Works + +### 1. Test Discovery +When you run `mvn test -Dtest=ScenarioBasedIT`, the test framework: + +1. Scans `src/test/resources/scenarios/` for directories +2. Each directory is considered a scenario +3. Creates a parameterized test for each scenario + +### 2. Test Execution +For each scenario: + +1. **Setup Phase**: + - Start MinIO container + - Start ICE REST catalog server + - Create temporary CLI config file + - Build template variables + +2. **Execution Phase**: + - Load scenario.yaml configuration + - Process run.sh.tmpl with template variables + - Execute the processed script + - Capture stdout, stderr, and exit code + +3. **Verification Phase** (optional): + - Process verify.sh.tmpl with template variables + - Execute verification script + - Capture results + +4. **Teardown Phase**: + - Stop REST catalog server + - Stop MinIO container + - Clean up temporary files + +### 3. Template Processing +Scripts can use template variables in the format `{{VARIABLE_NAME}}`: + +```bash +# Available template variables: +# {{ICE_CLI}} - Path to ice CLI executable +# {{CLI_CONFIG}} - Path to temporary CLI config file +# {{MINIO_ENDPOINT}} - MinIO endpoint URL (e.g., http://localhost:9000) +# {{CATALOG_URI}} - REST catalog URI (e.g., http://localhost:8080) +# {{SCENARIO_DIR}} - Absolute path to scenario directory + +# Environment variables from scenario.yaml are also available +{{ICE_CLI}} --config {{CLI_CONFIG}} create-namespace ${NAMESPACE_NAME} +``` + +## Creating a New Scenario + +1. **Create scenario directory**: + ```bash + mkdir ice-rest-catalog/src/test/resources/scenarios/my-new-test + ``` + +2. **Create scenario.yaml**: + ```yaml + name: "My New Test" + description: "Description of what this test does" + + env: + NAMESPACE_NAME: "my_test_ns" + TABLE_NAME: "my_test_ns.my_table" + + cloudResources: + s3: + buckets: + - "test-bucket" + ``` + +3. **Create run.sh.tmpl**: + ```bash + #!/bin/bash + set -e + + echo "Running my test..." + + # Create namespace + {{ICE_CLI}} --config {{CLI_CONFIG}} create-namespace ${NAMESPACE_NAME} + + # ... more test steps ... + + # Cleanup + {{ICE_CLI}} --config {{CLI_CONFIG}} delete-namespace ${NAMESPACE_NAME} + + echo "Test completed successfully" + ``` + +4. **Add test data** (optional): + ```bash + cp example-data.parquet ice-rest-catalog/src/test/resources/scenarios/my-new-test/input.parquet + ``` + +5. **Run the test**: + ```bash + mvn test -Dtest=ScenarioBasedIT#testScenario[my-new-test] + ``` + +## Running Tests + +### Run all scenarios: +```bash +cd ice-rest-catalog +mvn test -Dtest=ScenarioBasedIT +``` + +### Run a specific scenario: +```bash +mvn test -Dtest=ScenarioBasedIT#testScenario[basic-operations] +``` + +### Run scenarios matching a pattern: +```bash +mvn test -Dtest=ScenarioBasedIT#testScenario[insert*] +``` + +## Benefits Over Previous Approach + +### Before (Hardcoded Java Tests): +```java +@Test +public void testScenario1() throws Exception { + File config = createTempCliConfig(); + new CommandLine(Main.class).execute("--config", config.getAbsolutePath(), + "create-namespace", "test_ns"); + new CommandLine(Main.class).execute("--config", config.getAbsolutePath(), + "delete-namespace", "test_ns"); + // ... repeat for each scenario +} + +@Test +public void testScenario2() throws Exception { + // ... duplicate setup code ... +} +``` + +**Problems**: +- Lots of duplicated code +- Hard to add new scenarios +- Difficult to test complex workflows +- No separation of test data and test logic +- Hard to share tests with non-Java developers + +### After (Scenario-Based Tests): +``` +scenarios/ + scenario1/ + scenario.yaml + run.sh.tmpl + scenario2/ + scenario.yaml + run.sh.tmpl + input.parquet +``` + +**Benefits**: +- ✅ No code duplication +- ✅ Easy to add new scenarios (just add a directory) +- ✅ Can test complex workflows with multiple steps +- ✅ Clear separation of test data and logic +- ✅ Scripts can be shared and run independently +- ✅ Can be used by QA engineers without Java knowledge +- ✅ Future: automatic cloud resource provisioning + +## Example Scenarios + +### 1. basic-operations +Tests fundamental catalog operations: +- Create namespace +- List namespaces +- Delete namespace + +### 2. insert-scan +Tests data insertion and retrieval: +- Create namespace +- Insert data from parquet file +- Scan table +- Verify data contents +- Cleanup + +### 3. insert-partitioned +Tests partitioned table creation: +- Create namespace +- Insert data with partition specification +- Verify table was created +- Cleanup + +## Future Enhancements + +1. **Cloud Resource Provisioning**: + - Automatically create S3 buckets, SQS queues, etc. based on scenario.yaml + - Use AWS CloudFormation or Terraform templates + - Clean up resources after test completion + +2. **Parallel Execution**: + - Run independent scenarios in parallel + - Speed up test suite execution + +3. **Test Data Generation**: + - Generate synthetic test data based on schema specifications + - Support for various data formats (Avro, ORC, etc.) + +4. **Scenario Composition**: + - Reuse common scenario steps + - Create scenario libraries + +5. **Performance Testing**: + - Add performance benchmarks to scenarios + - Track performance over time + +## Migration Guide + +To migrate existing hardcoded tests to scenarios: + +1. Identify the test scenario (e.g., "insert with partitioning") +2. Create a scenario directory +3. Extract configuration into scenario.yaml +4. Convert Java test code to bash script in run.sh.tmpl +5. Add test data files if needed +6. Delete the old Java test method + +Example migration: + +**Before** (RESTCatalogInsertIT.java): +```java +@Test +public void testInsertCommand() throws Exception { + File config = createTempCliConfig(); + String namespace = "test_insert"; + new CommandLine(Main.class).execute("--config", config, + "create-namespace", namespace); + // ... more code ... +} +``` + +**After** (scenarios/insert-scan/): +``` +scenario.yaml # Configuration +run.sh.tmpl # Test logic +input.parquet # Test data +``` + +## Troubleshooting + +### Scenario not discovered +- Ensure scenario directory is in `src/test/resources/scenarios/` +- Check that `scenario.yaml` exists in the directory +- Directory name should not start with `.` + +### Script execution fails +- Check script has correct shebang (`#!/bin/bash`) +- Verify template variables are correctly specified +- Check file paths are relative to {{SCENARIO_DIR}} +- Review script output in test logs + +### ICE CLI not found +- Ensure `ice/target/ice-jar` is built: `mvn -am -pl ice package` +- Or ensure `.bin/local-ice` script exists +- Check that ICE_CLI template variable is correctly set + +## Additional Resources + +- [Scenarios README](src/test/resources/scenarios/README.md) - Detailed scenario structure documentation +- [ICE CLI Documentation](../ice/README.md) - CLI command reference +- [TestNG Documentation](https://testng.org/doc/) - TestNG testing framework + + + + + + + + diff --git a/ice/Dockerfile.native b/ice/Dockerfile.native deleted file mode 100644 index 52caa1e3..00000000 --- a/ice/Dockerfile.native +++ /dev/null @@ -1,52 +0,0 @@ -# Multi-arch native image build for ice -# Supports: amd64 (with static musl), arm64 (dynamic) -ARG BASE_IMAGE_TAG="nonroot" -ARG VERSION="0.0.0-SNAPSHOT" -ARG TARGETARCH - -FROM --platform=$BUILDPLATFORM ghcr.io/graalvm/native-image-community:21.0.2 AS build - -WORKDIR /app - -# Install musl for static linking (amd64) -RUN microdnf install -y musl-devel || true - -# Cache maven dependencies for faster re-builds -COPY .mvn/ .mvn/ -COPY mvnw . -COPY pom.xml . -COPY ice/pom.xml ice/pom.xml -COPY ice-rest-catalog/pom.xml ice-rest-catalog/pom.xml -RUN ./mvnw -am -pl ice dependency:go-offline - -ARG VERSION -ARG TARGETARCH - -COPY . . - -RUN ./mvnw -am -pl ice versions:set -DnewVersion=${VERSION} - -# Build with appropriate profile based on architecture -RUN if [ "$TARGETARCH" = "amd64" ]; then \ - echo "Building static native image for amd64 with musl..."; \ - ./mvnw -Pno-check -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true; \ - elif [ "$TARGETARCH" = "arm64" ]; then \ - echo "Building native image for arm64..."; \ - ./mvnw -Pno-check -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true; \ - else \ - echo "Building native image for $TARGETARCH..."; \ - ./mvnw -Pno-check -Pnative -pl ice clean package -Dmaven.test.skip=true; \ - fi - -# Use scratch for amd64 (static), distroless for arm64 (dynamic) -FROM scratch AS final-amd64 -COPY --from=build /app/ice/target/ice /usr/local/bin/ice -ENTRYPOINT ["/usr/local/bin/ice"] - -FROM gcr.io/distroless/base-debian12:${BASE_IMAGE_TAG} AS final-arm64 -COPY --from=build /app/ice/target/ice /usr/local/bin/ice -ENTRYPOINT ["/usr/local/bin/ice"] - -# Select appropriate final stage based on architecture -FROM final-${TARGETARCH} AS final - diff --git a/ice/Dockerfile.native-amd64-static b/ice/Dockerfile.native-amd64-static index dd0c2587..e8b4f271 100644 --- a/ice/Dockerfile.native-amd64-static +++ b/ice/Dockerfile.native-amd64-static @@ -1,5 +1,5 @@ # Dockerfile for building ICE native image (amd64, static with musl) -# Usage: docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64-static . +# Usage: docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64 . FROM ghcr.io/graalvm/native-image-community:21-muslib AS builder diff --git a/ice/Dockerfile.native-builder b/ice/Dockerfile.native-builder deleted file mode 100644 index 0a044e6d..00000000 --- a/ice/Dockerfile.native-builder +++ /dev/null @@ -1,91 +0,0 @@ -# Multi-stage Dockerfile for building ICE native images -# Supports both amd64 (with static musl) and arm64 (dynamic) - -ARG ARCH=amd64 - -# ============================================================================ -# Stage 1: Build stage with all dependencies -# ============================================================================ -FROM ghcr.io/graalvm/native-image-community:21 AS builder - -# Install build dependencies -RUN microdnf install -y \ - findutils \ - tar \ - gzip \ - wget \ - && microdnf clean all - -# Detect architecture and install appropriate dependencies -RUN ARCH=$(uname -m) && \ - if [ "$ARCH" = "x86_64" ]; then \ - echo "Installing musl toolchain and zlib for amd64 static builds..."; \ - # Download and install musl-gcc - wget -q https://musl.libc.org/releases/musl-1.2.5.tar.gz && \ - tar -xzf musl-1.2.5.tar.gz && \ - cd musl-1.2.5 && \ - ./configure --prefix=/usr/local/musl --disable-shared && \ - make -j$(nproc) && \ - make install && \ - cd .. && \ - rm -rf musl-1.2.5 musl-1.2.5.tar.gz && \ - # Download and install zlib for musl - wget -q https://zlib.net/zlib-1.3.1.tar.gz && \ - tar -xzf zlib-1.3.1.tar.gz && \ - cd zlib-1.3.1 && \ - CC=/usr/local/musl/bin/musl-gcc ./configure --prefix=/usr/local/musl --static && \ - make -j$(nproc) && \ - make install && \ - cd .. && \ - rm -rf zlib-1.3.1 zlib-1.3.1.tar.gz && \ - # Create symlink for native-image to find musl-gcc - ln -sf /usr/local/musl/bin/musl-gcc /usr/local/bin/x86_64-linux-musl-gcc; \ - else \ - echo "ARM64 detected - using dynamic linking (no musl required)"; \ - fi - -WORKDIR /workspace - -# Copy license header file (required by license-maven-plugin) -COPY apache-header.txt . - -# Copy Maven wrapper and pom files first (for better caching) -COPY mvnw . -COPY .mvn .mvn -COPY pom.xml . -COPY ice/pom.xml ice/ -COPY ice-rest-catalog/pom.xml ice-rest-catalog/ - -# Download dependencies (cached layer) -RUN ./mvnw dependency:go-offline -pl ice || true - -# Copy source code -COPY ice/src ice/src - -# Build native image based on architecture -RUN ARCH=$(uname -m) && \ - if [ "$ARCH" = "x86_64" ]; then \ - echo "Building static native image for amd64 with musl..."; \ - export PATH="/usr/local/musl/bin:$PATH" && \ - ./mvnw -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true; \ - else \ - echo "Building dynamic native image for arm64..."; \ - ./mvnw -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true; \ - fi - -# ============================================================================ -# Stage 2: Runtime image (minimal) -# ============================================================================ -FROM scratch AS runtime-amd64 -COPY --from=builder /workspace/ice/target/ice /ice -ENTRYPOINT ["/ice"] - -FROM gcr.io/distroless/base-debian12:nonroot AS runtime-arm64 -COPY --from=builder /workspace/ice/target/ice /ice -ENTRYPOINT ["/ice"] - -# ============================================================================ -# Stage 3: Final stage (architecture-dependent) -# ============================================================================ -FROM runtime-${ARCH} AS final - From 48e0a04c467cae8c0141bd388eda8bc1945c54e6 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Sun, 23 Nov 2025 10:27:48 -0600 Subject: [PATCH 11/20] Removed accidentally committed files. --- .../docker-compose/test-ssl-verification.md | 186 ---------- examples/scratch/output.json | 0 ice-rest-catalog/SCENARIO_TESTING.md | 344 ------------------ 3 files changed, 530 deletions(-) delete mode 100644 examples/docker-compose/test-ssl-verification.md delete mode 100644 examples/scratch/output.json delete mode 100644 ice-rest-catalog/SCENARIO_TESTING.md diff --git a/examples/docker-compose/test-ssl-verification.md b/examples/docker-compose/test-ssl-verification.md deleted file mode 100644 index 72ca27ea..00000000 --- a/examples/docker-compose/test-ssl-verification.md +++ /dev/null @@ -1,186 +0,0 @@ -# Testing SSL Certificate Verification Skip - -This guide shows how to test the `--insecure` / `--ssl-no-verify` flag with self-signed certificates. - -## Option 1: Quick Test with a Self-Signed HTTPS Server - -### 1. Generate a self-signed certificate - -```bash -# Generate a self-signed certificate for testing -openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes \ - -subj "/CN=localhost" \ - -addext "subjectAltName=DNS:localhost,IP:127.0.0.1" -``` - -### 2. Set up an HTTPS proxy to ice-rest-catalog - -Create a simple nginx config to add SSL in front of the catalog: - -**nginx-ssl.conf**: -```nginx -events { - worker_connections 1024; -} - -http { - server { - listen 5443 ssl; - server_name localhost; - - ssl_certificate /etc/nginx/cert.pem; - ssl_certificate_key /etc/nginx/key.pem; - - location / { - proxy_pass http://ice-rest-catalog:5000; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } - } -} -``` - -**docker-compose.ssl-test.yaml**: -```yaml -services: - nginx-ssl: - image: nginx:alpine - ports: - - "5443:5443" - volumes: - - ./cert.pem:/etc/nginx/cert.pem:ro - - ./key.pem:/etc/nginx/key.pem:ro - - ./nginx-ssl.conf:/etc/nginx/nginx.conf:ro - depends_on: - - ice-rest-catalog -``` - -### 3. Start the services - -```bash -# Start the regular docker-compose setup -docker-compose up -d - -# Start the SSL proxy -docker-compose -f docker-compose.ssl-test.yaml up -d -``` - -### 4. Test the ice CLI - -First, format and build the code: -```bash -cd /home/kanthi/Documents/GITHUB/ALTINITY/ice -mvn com.spotify.fmt:fmt-maven-plugin:format -pl ice -mvn clean install -pl ice -am -DskipTests -``` - -Create a test config file `.ice-ssl-test.yaml`: -```yaml -uri: https://localhost:5443 -bearerToken: foo -warehouse: s3://bucket1 -sslVerify: false # Config file option -s3: - endpoint: http://localhost:8999 - pathStyleAccess: true - accessKeyID: miniouser - secretAccessKey: miniopassword - region: minio -``` - -**Test 1: Without --insecure flag (should fail with SSL error)**: -```bash -./ice/target/ice-jar -c .ice-ssl-test.yaml check -# Expected: SSL certificate verification error -``` - -**Test 2: With --insecure flag (should succeed)**: -```bash -./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure check -# Expected: OK -``` - -**Test 3: Using config file sslVerify option**: -With `sslVerify: false` in the config file: -```bash -./ice/target/ice-jar -c .ice-ssl-test.yaml check -# Expected: OK (with warning about disabled SSL verification) -``` - -**Test 4: Test other commands**: -```bash -# List namespaces -./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure describe - -# Create a namespace -./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure create-namespace test_ns - -# Create a table -./ice/target/ice-jar -c .ice-ssl-test.yaml --insecure create-table test_ns.test_table \ - --schema '[{"name":"id","type":"int"},{"name":"name","type":"string"}]' -``` - -## Option 2: Test with Public Self-Signed Certificate Server - -You can also test against a public service with a self-signed certificate: - -```bash -# This will fail due to self-signed certificate -./ice/target/ice-jar -c config.yaml check - -# This will work with --insecure -./ice/target/ice-jar -c config.yaml --insecure check -``` - -## Option 3: Test with Internal CA Certificate - -If you have an internal CA, you can test the custom CA bundle feature: - -```yaml -uri: https://internal-catalog.company.local:5443 -caCrt: | - -----BEGIN CERTIFICATE----- - MIIDXTCCAkWgAwIBAgIJAKJ... - -----END CERTIFICATE----- -bearerToken: foo -``` - -This should work without `--insecure` because the CA certificate is provided. - -## Expected Behavior - -### Without SSL verification skip: -- ❌ Fails with certificate verification errors for self-signed certificates -- ✅ Works with valid certificates from trusted CAs -- ✅ Works when custom CA certificate is provided via `caCrt` - -### With SSL verification skip (`--insecure` or `sslVerify: false`): -- ⚠️ Displays warning: "SSL certificate verification is DISABLED. This is insecure and should only be used for development." -- ✅ Works with any certificate (self-signed, expired, wrong hostname, etc.) -- ⚠️ **INSECURE**: Should only be used for development/testing - -## Command-line Flags - -Two equivalent options: -- `--insecure` - Shorter, commonly used in tools like curl -- `--ssl-no-verify` - More explicit about what it does - -Both flags: -- Override the config file `sslVerify` setting -- Apply to all subcommands (check, describe, scan, insert, etc.) -- Display a warning message when SSL verification is disabled - -## Config File Option - -```yaml -sslVerify: false # Skip SSL certificate verification -``` - -Note: The command-line flag takes precedence over the config file option. - - - - - - diff --git a/examples/scratch/output.json b/examples/scratch/output.json deleted file mode 100644 index e69de29b..00000000 diff --git a/ice-rest-catalog/SCENARIO_TESTING.md b/ice-rest-catalog/SCENARIO_TESTING.md deleted file mode 100644 index af54e58e..00000000 --- a/ice-rest-catalog/SCENARIO_TESTING.md +++ /dev/null @@ -1,344 +0,0 @@ -# Scenario-Based Testing Framework - -This document describes the new scenario-based testing framework for ICE REST Catalog integration tests. - -## Overview - -The scenario-based testing framework provides a scalable, data-driven approach to integration testing. Instead of hardcoding test scenarios in Java test methods, each scenario is defined in its own directory with: - -- Configuration files (scenario.yaml) -- Input data (parquet files) -- Executable test scripts (run.sh.tmpl, verify.sh.tmpl) - -This approach makes it much easier to: -- Add new test scenarios without writing Java code -- Share test scenarios across teams -- Test complex workflows with multiple steps -- Provision cloud resources dynamically (future feature) - -## Directory Structure - -``` -ice-rest-catalog/src/test/resources/scenarios/ -├── README.md # Documentation for scenario structure -├── basic-operations/ # Example scenario -│ ├── scenario.yaml # Scenario configuration -│ ├── run.sh.tmpl # Main test script (templated) -│ └── verify.sh.tmpl # Optional verification script -├── insert-scan/ -│ ├── scenario.yaml -│ ├── run.sh.tmpl -│ ├── verify.sh.tmpl -│ └── input.parquet # Test data -└── insert-partitioned/ - ├── scenario.yaml - ├── run.sh.tmpl - ├── verify.sh.tmpl - └── input.parquet -``` - -## Key Components - -### 1. ScenarioConfig.java -Java class that represents the scenario.yaml configuration file. Supports: -- Scenario metadata (name, description) -- Catalog configuration overrides -- Environment variables for scripts -- Cloud resource specifications (for future provisioning) -- Test phases - -### 2. ScenarioTestRunner.java -Core test execution engine that: -- Discovers scenario directories -- Loads scenario configurations -- Processes template variables in scripts -- Executes scripts and captures output -- Reports results - -### 3. ScenarioBasedIT.java -TestNG parameterized test class that: -- Automatically discovers all scenarios -- Runs each scenario as a separate test case -- Provides test infrastructure (MinIO, REST catalog) -- Injects template variables (CLI config, endpoints, etc.) - -### 4. RESTCatalogTestBase.java (Updated) -Base test class that provides: -- MinIO container setup/teardown -- REST catalog server setup/teardown -- Helper methods for scenarios (getMinioEndpoint, getCatalogUri, etc.) - -## How It Works - -### 1. Test Discovery -When you run `mvn test -Dtest=ScenarioBasedIT`, the test framework: - -1. Scans `src/test/resources/scenarios/` for directories -2. Each directory is considered a scenario -3. Creates a parameterized test for each scenario - -### 2. Test Execution -For each scenario: - -1. **Setup Phase**: - - Start MinIO container - - Start ICE REST catalog server - - Create temporary CLI config file - - Build template variables - -2. **Execution Phase**: - - Load scenario.yaml configuration - - Process run.sh.tmpl with template variables - - Execute the processed script - - Capture stdout, stderr, and exit code - -3. **Verification Phase** (optional): - - Process verify.sh.tmpl with template variables - - Execute verification script - - Capture results - -4. **Teardown Phase**: - - Stop REST catalog server - - Stop MinIO container - - Clean up temporary files - -### 3. Template Processing -Scripts can use template variables in the format `{{VARIABLE_NAME}}`: - -```bash -# Available template variables: -# {{ICE_CLI}} - Path to ice CLI executable -# {{CLI_CONFIG}} - Path to temporary CLI config file -# {{MINIO_ENDPOINT}} - MinIO endpoint URL (e.g., http://localhost:9000) -# {{CATALOG_URI}} - REST catalog URI (e.g., http://localhost:8080) -# {{SCENARIO_DIR}} - Absolute path to scenario directory - -# Environment variables from scenario.yaml are also available -{{ICE_CLI}} --config {{CLI_CONFIG}} create-namespace ${NAMESPACE_NAME} -``` - -## Creating a New Scenario - -1. **Create scenario directory**: - ```bash - mkdir ice-rest-catalog/src/test/resources/scenarios/my-new-test - ``` - -2. **Create scenario.yaml**: - ```yaml - name: "My New Test" - description: "Description of what this test does" - - env: - NAMESPACE_NAME: "my_test_ns" - TABLE_NAME: "my_test_ns.my_table" - - cloudResources: - s3: - buckets: - - "test-bucket" - ``` - -3. **Create run.sh.tmpl**: - ```bash - #!/bin/bash - set -e - - echo "Running my test..." - - # Create namespace - {{ICE_CLI}} --config {{CLI_CONFIG}} create-namespace ${NAMESPACE_NAME} - - # ... more test steps ... - - # Cleanup - {{ICE_CLI}} --config {{CLI_CONFIG}} delete-namespace ${NAMESPACE_NAME} - - echo "Test completed successfully" - ``` - -4. **Add test data** (optional): - ```bash - cp example-data.parquet ice-rest-catalog/src/test/resources/scenarios/my-new-test/input.parquet - ``` - -5. **Run the test**: - ```bash - mvn test -Dtest=ScenarioBasedIT#testScenario[my-new-test] - ``` - -## Running Tests - -### Run all scenarios: -```bash -cd ice-rest-catalog -mvn test -Dtest=ScenarioBasedIT -``` - -### Run a specific scenario: -```bash -mvn test -Dtest=ScenarioBasedIT#testScenario[basic-operations] -``` - -### Run scenarios matching a pattern: -```bash -mvn test -Dtest=ScenarioBasedIT#testScenario[insert*] -``` - -## Benefits Over Previous Approach - -### Before (Hardcoded Java Tests): -```java -@Test -public void testScenario1() throws Exception { - File config = createTempCliConfig(); - new CommandLine(Main.class).execute("--config", config.getAbsolutePath(), - "create-namespace", "test_ns"); - new CommandLine(Main.class).execute("--config", config.getAbsolutePath(), - "delete-namespace", "test_ns"); - // ... repeat for each scenario -} - -@Test -public void testScenario2() throws Exception { - // ... duplicate setup code ... -} -``` - -**Problems**: -- Lots of duplicated code -- Hard to add new scenarios -- Difficult to test complex workflows -- No separation of test data and test logic -- Hard to share tests with non-Java developers - -### After (Scenario-Based Tests): -``` -scenarios/ - scenario1/ - scenario.yaml - run.sh.tmpl - scenario2/ - scenario.yaml - run.sh.tmpl - input.parquet -``` - -**Benefits**: -- ✅ No code duplication -- ✅ Easy to add new scenarios (just add a directory) -- ✅ Can test complex workflows with multiple steps -- ✅ Clear separation of test data and logic -- ✅ Scripts can be shared and run independently -- ✅ Can be used by QA engineers without Java knowledge -- ✅ Future: automatic cloud resource provisioning - -## Example Scenarios - -### 1. basic-operations -Tests fundamental catalog operations: -- Create namespace -- List namespaces -- Delete namespace - -### 2. insert-scan -Tests data insertion and retrieval: -- Create namespace -- Insert data from parquet file -- Scan table -- Verify data contents -- Cleanup - -### 3. insert-partitioned -Tests partitioned table creation: -- Create namespace -- Insert data with partition specification -- Verify table was created -- Cleanup - -## Future Enhancements - -1. **Cloud Resource Provisioning**: - - Automatically create S3 buckets, SQS queues, etc. based on scenario.yaml - - Use AWS CloudFormation or Terraform templates - - Clean up resources after test completion - -2. **Parallel Execution**: - - Run independent scenarios in parallel - - Speed up test suite execution - -3. **Test Data Generation**: - - Generate synthetic test data based on schema specifications - - Support for various data formats (Avro, ORC, etc.) - -4. **Scenario Composition**: - - Reuse common scenario steps - - Create scenario libraries - -5. **Performance Testing**: - - Add performance benchmarks to scenarios - - Track performance over time - -## Migration Guide - -To migrate existing hardcoded tests to scenarios: - -1. Identify the test scenario (e.g., "insert with partitioning") -2. Create a scenario directory -3. Extract configuration into scenario.yaml -4. Convert Java test code to bash script in run.sh.tmpl -5. Add test data files if needed -6. Delete the old Java test method - -Example migration: - -**Before** (RESTCatalogInsertIT.java): -```java -@Test -public void testInsertCommand() throws Exception { - File config = createTempCliConfig(); - String namespace = "test_insert"; - new CommandLine(Main.class).execute("--config", config, - "create-namespace", namespace); - // ... more code ... -} -``` - -**After** (scenarios/insert-scan/): -``` -scenario.yaml # Configuration -run.sh.tmpl # Test logic -input.parquet # Test data -``` - -## Troubleshooting - -### Scenario not discovered -- Ensure scenario directory is in `src/test/resources/scenarios/` -- Check that `scenario.yaml` exists in the directory -- Directory name should not start with `.` - -### Script execution fails -- Check script has correct shebang (`#!/bin/bash`) -- Verify template variables are correctly specified -- Check file paths are relative to {{SCENARIO_DIR}} -- Review script output in test logs - -### ICE CLI not found -- Ensure `ice/target/ice-jar` is built: `mvn -am -pl ice package` -- Or ensure `.bin/local-ice` script exists -- Check that ICE_CLI template variable is correctly set - -## Additional Resources - -- [Scenarios README](src/test/resources/scenarios/README.md) - Detailed scenario structure documentation -- [ICE CLI Documentation](../ice/README.md) - CLI command reference -- [TestNG Documentation](https://testng.org/doc/) - TestNG testing framework - - - - - - - - From 3b3ddbb64cdabc5182c5d63ac9d1688c9c325cd2 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Sun, 23 Nov 2025 10:29:25 -0600 Subject: [PATCH 12/20] Added GITHUB_RELEASE_TEMPLATE.md --- GITHUB_RELEASE_TEMPLATE.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 GITHUB_RELEASE_TEMPLATE.md diff --git a/GITHUB_RELEASE_TEMPLATE.md b/GITHUB_RELEASE_TEMPLATE.md new file mode 100644 index 00000000..fe7ff576 --- /dev/null +++ b/GITHUB_RELEASE_TEMPLATE.md @@ -0,0 +1,34 @@ +## Installation + +### ice + +```sh +curl -sSL https://github.com/altinity/ice/releases/download/REPLACE_WITH_TAG/ice-REPLACE_WITH_VER \ + -o ice && chmod a+x ice && sudo mv ice /usr/local/bin/ +``` + +#### Docker + + + +- `altinity/ice:REPLACE_WITH_VER` +- `altinity/ice:debug-REPLACE_WITH_VER` + +> `debug-*` images contain busybox shell. + +### ice-rest-catalog + +```sh +curl -sSL https://github.com/altinity/ice/releases/download/REPLACE_WITH_TAG/ice-rest-catalog-REPLACE_WITH_VER \ + -o ice-rest-catalog && chmod a+x ice-rest-catalog && sudo mv ice-rest-catalog /usr/local/bin/ +``` + +#### Docker + + + +- `altinity/ice-rest-catalog:REPLACE_WITH_VER` +- `altinity/ice-rest-catalog:debug-REPLACE_WITH_VER` +- `altinity/ice-rest-catalog:debug-with-ice-REPLACE_WITH_VER` + +> `debug-*` images contain busybox shell. From 3bbcf76980d4c5640375357e3f029fd206c7d4e8 Mon Sep 17 00:00:00 2001 From: Kanthi Subramanian Date: Sun, 23 Nov 2025 10:39:06 -0600 Subject: [PATCH 13/20] Updated README.md with instructions to build native image. --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e83f3fdf..d9f7f459 100644 --- a/README.md +++ b/README.md @@ -52,16 +52,14 @@ Build standalone native binaries with no Java dependency: sdk env # or ensure Java 21+ and GraalVM are available # For amd64 (static with musl - no dependencies) -./build-native.sh -# Produces: ice/target/ice (static binary) - -# Or use Maven directly mvn -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true +For arm64 +mvn -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true -# For ARM64 (dynamic with glibc) -ARCH=arm64 ./build-native.sh -# Or: mvn -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true +# Docker builds +docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64 . +docker build -f ice/Dockerfile.native-arm64 -t ice-native:arm64 . ## License From 50ac8e36c1d6bf436f1aaa049da5d080effc03ff Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Mon, 27 Apr 2026 17:32:18 -0400 Subject: [PATCH 14/20] Merge x86 and arm native builds into the same profile - Binary is static besides libc due to some libraries like zstd that require JNI - Use graalvm tracing agent to generate reachability metadata files - Update workflow to test native binaries --- .bin/agent-ice | 17 + .github/workflows/verify.yaml | 8 +- README.md | 13 +- ice-rest-catalog/pom.xml | 4 + .../ice/rest/catalog/ScenarioBasedIT.java | 26 +- ...kerfile.native-arm64 => Dockerfile.native} | 10 +- ice/Dockerfile.native-amd64-static | 33 - ice/pom.xml | 74 +- .../com.altinity/ice/jni-config.json | 30 + .../ice/predefined-classes-config.json | 8 + .../com.altinity/ice/proxy-config.json | 5 + .../com.altinity/ice/reflect-config.json | 980 ++++++++++++++++++ .../com.altinity/ice/resource-config.json | 109 ++ .../ice/serialization-config.json | 8 + ice/src/main/resources/reflection-config.json | 112 -- 15 files changed, 1195 insertions(+), 242 deletions(-) create mode 100755 .bin/agent-ice rename ice/{Dockerfile.native-arm64 => Dockerfile.native} (68%) delete mode 100644 ice/Dockerfile.native-amd64-static create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/jni-config.json create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/predefined-classes-config.json create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/proxy-config.json create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json create mode 100644 ice/src/main/resources/META-INF/native-image/com.altinity/ice/serialization-config.json delete mode 100644 ice/src/main/resources/reflection-config.json diff --git a/.bin/agent-ice b/.bin/agent-ice new file mode 100755 index 00000000..e8d44971 --- /dev/null +++ b/.bin/agent-ice @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -euo pipefail +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) +PROJECT_ROOT=$(cd -- "$SCRIPT_DIR/.." && pwd) + +shopt -s nullglob +jars=("$PROJECT_ROOT"/ice/target/ice-*-shaded.jar) +shopt -u nullglob +if (( ${#jars[@]} == 0 )); then + echo "agent-ice: no ice-*-shaded.jar in $PROJECT_ROOT/ice/target/." >&2 + exit 1 +fi +jar=$(ls -t "${jars[@]}" | head -n1) + +exec "${JAVA_HOME:?JAVA_HOME not set — run inside direnv shell}/bin/java" \ +-agentlib:native-image-agent=config-merge-dir=$PROJECT_ROOT/ice/src/main/resources/META-INF/native-image/com.altinity/ice,experimental-class-loader-support \ +-jar "$jar" "$@" diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 099facc5..973c64d9 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -17,7 +17,6 @@ jobs: - run: ./mvnw clean verify - name: Install run: ./mvnw install - # TODO: check native-image can build ice - name: Run Scenario-Based Integration Tests run: ../mvnw test -Dtest=ScenarioBasedIT working-directory: ice-rest-catalog @@ -65,11 +64,9 @@ jobs: include: - arch: amd64 runner: ubuntu-24.04 - profile: native artifact: ice-native-amd64-dynamic - arch: arm64 runner: ubuntu-24.04-arm - profile: native-arm64 artifact: ice-native-arm64-dynamic steps: - uses: actions/checkout@v4 @@ -79,7 +76,10 @@ jobs: distribution: 'graalvm' cache: maven - name: Build native image (dynamic linking - no musl required) - run: ./mvnw -P${{ matrix.profile }} -pl ice clean package -Dmaven.test.skip=true + run: ./mvnw -Pnative -pl ice clean package + - name: Run Scenario-Based Integration Tests + run: ../mvnw test -Dtest=ScenarioBasedIT -Dice.native=true + working-directory: ice-rest-catalog - name: Upload native binary as artifact uses: actions/upload-artifact@v4 with: diff --git a/README.md b/README.md index d9f7f459..05b1860e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Pre-built binaries (+ links to Docker images for [ice](https://hub.docker.com/r/ 1. **Java-based binaries** - Require Java 21+ to run (available [here](https://adoptium.net/installation/)) 2. **Native binaries** - Standalone executables with no Java dependency - - `ice-native-amd64` - Static binary (musl) for x86_64 Linux (no dependencies) + - `ice-native-amd64` - Dynamic binary for x86_64 Linux (requires glibc) - `ice-native-arm64` - Dynamic binary for ARM64 Linux (requires glibc) ## Usage @@ -51,15 +51,14 @@ Build standalone native binaries with no Java dependency: # Install prerequisites sdk env # or ensure Java 21+ and GraalVM are available -# For amd64 (static with musl - no dependencies) -mvn -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true -For arm64 -mvn -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true +# Build ice binary (both amd64 and arm64) +mvn -Pnative -pl ice clean package -Dmaven.test.skip=true # Docker builds -docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64 . +docker build -f ice/Dockerfile.native -t ice-native:amd64 . -docker build -f ice/Dockerfile.native-arm64 -t ice-native:arm64 . +docker build -f ice/Dockerfile.native -t ice-native:arm64 . +``` ## License diff --git a/ice-rest-catalog/pom.xml b/ice-rest-catalog/pom.xml index 38053fdb..f861254e 100644 --- a/ice-rest-catalog/pom.xml +++ b/ice-rest-catalog/pom.xml @@ -17,6 +17,7 @@ 0.8.5 1.70.0 1.21.4 + false @@ -562,6 +563,9 @@ org.apache.maven.plugins maven-failsafe-plugin + + ${ice.native} + **/DockerScenarioBasedIT.java diff --git a/ice-rest-catalog/src/test/java/com/altinity/ice/rest/catalog/ScenarioBasedIT.java b/ice-rest-catalog/src/test/java/com/altinity/ice/rest/catalog/ScenarioBasedIT.java index 24b098e7..c54a692d 100644 --- a/ice-rest-catalog/src/test/java/com/altinity/ice/rest/catalog/ScenarioBasedIT.java +++ b/ice-rest-catalog/src/test/java/com/altinity/ice/rest/catalog/ScenarioBasedIT.java @@ -23,6 +23,8 @@ */ public class ScenarioBasedIT extends RESTCatalogTestBase { + private static final boolean USE_NATIVE = Boolean.getBoolean("ice.native"); + @Override protected ScenarioTestRunner createScenarioRunner(String scenarioName) throws Exception { Path scenariosDir = getScenariosDirectory(); @@ -38,18 +40,24 @@ protected ScenarioTestRunner createScenarioRunner(String scenarioName) throws Ex // Try to find ice-jar in the build String projectRoot = Paths.get("").toAbsolutePath().getParent().toString(); - String iceJar = projectRoot + "/ice/target/ice-jar"; + String iceJar = + USE_NATIVE ? projectRoot + "/ice/target/ice" : projectRoot + "/ice/target/ice-jar"; File iceJarFile = new File(iceJar); - if (iceJarFile.exists() && iceJarFile.canExecute()) { - // Use pre-built ice-jar if available - templateVars.put("ICE_CLI", iceJar); - logger.info("Using ice-jar from: {}", iceJar); + String override = System.getenv("ICE_CLI_OVERRIDE"); + if (override != null) { + templateVars.put("ICE_CLI", override); } else { - // Fall back to using local-ice wrapper script - String localIce = projectRoot + "/.bin/local-ice"; - templateVars.put("ICE_CLI", localIce); - logger.info("Using local-ice script from: {}", localIce); + if (iceJarFile.exists() && iceJarFile.canExecute()) { + // Use pre-built ice-jar if available + templateVars.put("ICE_CLI", iceJar); + logger.info("Using ice-jar from: {}", iceJar); + } else { + // Fall back to using local-ice wrapper script + String localIce = projectRoot + "/.bin/local-ice"; + templateVars.put("ICE_CLI", localIce); + logger.info("Using local-ice script from: {}", localIce); + } } return new ScenarioTestRunner(scenariosDir, templateVars); diff --git a/ice/Dockerfile.native-arm64 b/ice/Dockerfile.native similarity index 68% rename from ice/Dockerfile.native-arm64 rename to ice/Dockerfile.native index 4d997ec1..10961656 100644 --- a/ice/Dockerfile.native-arm64 +++ b/ice/Dockerfile.native @@ -1,5 +1,6 @@ -# Dockerfile for building ICE native image (arm64, dynamic linking) -# Usage: docker build -f ice/Dockerfile.native-arm64 -t ice-native:arm64 . +# Dockerfile for building ICE native image (mostly-static with dynamic libc) +# Usage (amd64): docker build -f ice/Dockerfile.native -t ice-native:amd64 . +# Usage (arm64): docker build -f ice/Dockerfile.native -t ice-native:arm64 . FROM ghcr.io/graalvm/native-image-community:21 AS builder @@ -21,8 +22,8 @@ RUN ./mvnw dependency:go-offline -pl ice || true # Copy source code COPY ice/src ice/src -# Build dynamic native image -RUN ./mvnw -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true +# Build mostly-static native image (everything statically linked except libc) +RUN ./mvnw -Pnative -pl ice clean package -Dmaven.test.skip=true # ============================================================================ # Final stage: distroless base (includes minimal glibc runtime) @@ -30,4 +31,3 @@ RUN ./mvnw -Pnative-arm64 -pl ice clean package -Dmaven.test.skip=true FROM gcr.io/distroless/base-debian12:nonroot COPY --from=builder /workspace/ice/target/ice /ice ENTRYPOINT ["/ice"] - diff --git a/ice/Dockerfile.native-amd64-static b/ice/Dockerfile.native-amd64-static deleted file mode 100644 index e8b4f271..00000000 --- a/ice/Dockerfile.native-amd64-static +++ /dev/null @@ -1,33 +0,0 @@ -# Dockerfile for building ICE native image (amd64, static with musl) -# Usage: docker build -f ice/Dockerfile.native-amd64-static -t ice-native:amd64 . - -FROM ghcr.io/graalvm/native-image-community:21-muslib AS builder - -WORKDIR /workspace - -# Copy license header file (required by license-maven-plugin) -COPY apache-header.txt . - -# Copy Maven files for dependency resolution -COPY mvnw . -COPY .mvn .mvn -COPY pom.xml . -COPY ice/pom.xml ice/ -COPY ice-rest-catalog/pom.xml ice-rest-catalog/ - -# Download dependencies (cached layer) -RUN ./mvnw dependency:go-offline -pl ice || true - -# Copy source code -COPY ice/src ice/src - -# Build static native image with musl -RUN ./mvnw -Pnative-amd64-static -pl ice clean package -Dmaven.test.skip=true - -# ============================================================================ -# Final stage: minimal scratch image (truly standalone binary) -# ============================================================================ -FROM scratch -COPY --from=builder /workspace/ice/target/ice /ice -ENTRYPOINT ["/ice"] - diff --git a/ice/pom.xml b/ice/pom.xml index 3b1db9bf..61c5d41f 100644 --- a/ice/pom.xml +++ b/ice/pom.xml @@ -669,39 +669,6 @@ native - - - - org.graalvm.buildtools - native-maven-plugin - ${native.maven.plugin.version} - true - - - build-native - - compile-no-fork - - package - - - - ice - com.altinity.ice.cli.Main - - -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --initialize-at-run-time=io.netty - --initialize-at-run-time=ch.qos.logback - -H:+ReportExceptionStackTraces - - - - - - - - - native-amd64-static @@ -723,12 +690,10 @@ com.altinity.ice.cli.Main - -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json --initialize-at-run-time=io.netty --initialize-at-run-time=ch.qos.logback - - --static - --libc=musl + + -H:+StaticExecutableWithDynamicLibC -H:+RemoveUnusedSymbols -H:+ReportExceptionStackTraces @@ -738,40 +703,5 @@ - - native-arm64 - - - - org.graalvm.buildtools - native-maven-plugin - ${native.maven.plugin.version} - true - - - build-native - - compile-no-fork - - package - - - - ice - com.altinity.ice.cli.Main - - - -H:ReflectionConfigurationFiles=${project.basedir}/src/main/resources/reflection-config.json - --initialize-at-run-time=io.netty - --initialize-at-run-time=ch.qos.logback - - -H:+RemoveUnusedSymbols - -H:+ReportExceptionStackTraces - - - - - - diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/jni-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/jni-config.json new file mode 100644 index 00000000..c681d3ef --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/jni-config.json @@ -0,0 +1,30 @@ +[ +{ + "name":"com.github.luben.zstd.ZstdInputStreamNoFinalizer", + "fields":[{"name":"dstPos"}, {"name":"srcPos"}] +}, +{ + "name":"com.github.luben.zstd.ZstdOutputStreamNoFinalizer", + "fields":[{"name":"dstPos"}, {"name":"srcPos"}] +}, +{ + "name":"java.lang.Boolean", + "methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"org.jline.nativ.CLibrary", + "fields":[{"name":"TCSADRAIN"}, {"name":"TCSAFLUSH"}, {"name":"TCSANOW"}, {"name":"TIOCGWINSZ"}, {"name":"TIOCSWINSZ"}] +}, +{ + "name":"org.jline.nativ.CLibrary$Termios", + "fields":[{"name":"SIZEOF"}, {"name":"c_cc"}, {"name":"c_cflag"}, {"name":"c_iflag"}, {"name":"c_ispeed"}, {"name":"c_lflag"}, {"name":"c_oflag"}, {"name":"c_ospeed"}] +}, +{ + "name":"org.jline.nativ.CLibrary$WinSize", + "fields":[{"name":"SIZEOF"}, {"name":"ws_col"}, {"name":"ws_row"}, {"name":"ws_xpixel"}, {"name":"ws_ypixel"}] +}, +{ + "name":"sun.management.VMManagementImpl", + "fields":[{"name":"compTimeMonitoringSupport"}, {"name":"currentThreadCpuTimeSupport"}, {"name":"objectMonitorUsageSupport"}, {"name":"otherThreadCpuTimeSupport"}, {"name":"remoteDiagnosticCommandsSupport"}, {"name":"synchronizerUsageSupport"}, {"name":"threadAllocatedMemorySupport"}, {"name":"threadContentionMonitoringSupport"}] +} +] diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/predefined-classes-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/predefined-classes-config.json new file mode 100644 index 00000000..0e79b2c5 --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/predefined-classes-config.json @@ -0,0 +1,8 @@ +[ + { + "type":"agent-extracted", + "classes":[ + ] + } +] + diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/proxy-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/proxy-config.json new file mode 100644 index 00000000..4a9716c1 --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/proxy-config.json @@ -0,0 +1,5 @@ +[ + { + "interfaces":["sun.misc.SignalHandler"] + } +] diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json new file mode 100644 index 00000000..7b350ca9 --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -0,0 +1,980 @@ +[ +{ + "name":"[B" +}, +{ + "name":"[Lcom.altinity.ice.cli.Main$IcePartition;" +}, +{ + "name":"[Lcom.altinity.ice.cli.Main$IceSortOrder;" +}, +{ + "name":"[Lcom.altinity.ice.cli.Main$PartitionFilter;" +}, +{ + "name":"[Lcom.altinity.ice.cli.internal.cmd.AlterTable$Update;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.deser.BeanDeserializerModifier;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.deser.Deserializers;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.deser.KeyDeserializers;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.deser.ValueInstantiators;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.ser.BeanSerializerModifier;" +}, +{ + "name":"[Lcom.fasterxml.jackson.databind.ser.Serializers;" +}, +{ + "name":"[Ljava.lang.String;" +}, +{ + "name":"[Ljava.util.List;" +}, +{ + "name":"[Ljava.util.Map$Entry;" +}, +{ + "name":"[Lorg.apache.avro.util.springframework.ConcurrentReferenceHashMap$Segment;" +}, +{ + "name":"[Lorg.apache.iceberg.Accessor;" +}, +{ + "name":"[Lorg.apache.iceberg.avro.ValueWriter;" +}, +{ + "name":"[Lorg.apache.iceberg.parquet.ParquetValueReader;" +}, +{ + "name":"[Lorg.apache.iceberg.parquet.ParquetValueWriter;" +}, +{ + "name":"[Lorg.apache.iceberg.parquet.TripleIterator;" +}, +{ + "name":"[Lorg.apache.iceberg.relocated.com.google.common.collect.ImmutableMapEntry;" +}, +{ + "name":"[Lsun.security.pkcs.SignerInfo;" +}, +{ + "name":"ch.qos.logback.classic.joran.SerializedModelConfigurator", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.classic.util.DefaultJoranConfigurator", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"ch.qos.logback.core.ConsoleAppender", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setTarget","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.Layout", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.OutputStreamAppender", + "methods":[{"name":"setEncoder","parameterTypes":["ch.qos.logback.core.encoder.Encoder"] }] +}, +{ + "name":"ch.qos.logback.core.encoder.Encoder", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.encoder.LayoutWrappingEncoder", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setLayout","parameterTypes":["ch.qos.logback.core.Layout"] }, {"name":"setParent","parameterTypes":["ch.qos.logback.core.spi.ContextAware"] }] +}, +{ + "name":"ch.qos.logback.core.pattern.PatternLayoutBase", + "methods":[{"name":"setPattern","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"ch.qos.logback.core.spi.ContextAware", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.Main", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.Main$IcePartition", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.Main$IceSortOrder", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","boolean","boolean"] }] +}, +{ + "name":"com.altinity.ice.cli.Main$PartitionFilter", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.util.List"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$AddColumn", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$Update", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"data","parameterTypes":[] }, {"name":"error","parameterTypes":[] }, {"name":"kind","parameterTypes":[] }, {"name":"metadata","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Data", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"currentSnapshot","parameterTypes":[] }, {"name":"location","parameterTypes":[] }, {"name":"metrics","parameterTypes":[] }, {"name":"partitionSpecRaw","parameterTypes":[] }, {"name":"properties","parameterTypes":[] }, {"name":"schemaRaw","parameterTypes":[] }, {"name":"sortOrderRaw","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Error", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Metadata", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"id","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.Describe$Table$Snapshot", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"id","parameterTypes":[] }, {"name":"location","parameterTypes":[] }, {"name":"operation","parameterTypes":[] }, {"name":"parentID","parameterTypes":[] }, {"name":"sequenceNumber","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampISO","parameterTypes":[] }, {"name":"timestampISOLocal","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.ListNamespaces$Result", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"namespaces","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.ListPartitions$PartitionFieldInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"name","parameterTypes":[] }, {"name":"sourceColumn","parameterTypes":[] }, {"name":"transform","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.ListPartitions$Result", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"partitionSpec","parameterTypes":[] }, {"name":"partitions","parameterTypes":[] }, {"name":"table","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.config.Config", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.Boolean","java.lang.String","java.lang.String","java.lang.String","java.lang.String[]","com.altinity.ice.cli.internal.config.Config$S3","java.util.Map"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.config.Config$S3", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.altinity.ice.internal.iceberg.io.SchemeFileIO", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.internal.logback.ColorAwarePatternLayout", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.internal.logback.ColorAwarePatternLayout$NoColorConverter", + "queryAllPublicMethods":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.internal.picocli.VersionProvider", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.fasterxml.jackson.databind.ext.Java7SupportImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BBHeader$ReadAndWriteCounterRef", + "fields":[{"name":"writeCounter"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BBHeader$ReadCounterRef", + "fields":[{"name":"readCounter"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BLCHeader$DrainStatusRef", + "fields":[{"name":"drainStatus"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueColdProducerFields", + "fields":[{"name":"producerLimit"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueConsumerFields", + "fields":[{"name":"consumerIndex"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BaseMpscLinkedArrayQueueProducerFields", + "fields":[{"name":"producerIndex"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.BoundedLocalCache", + "fields":[{"name":"refreshes"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.CacheLoader", + "methods":[{"name":"loadAll","parameterTypes":["java.util.Set"] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.FD", + "fields":[{"name":"value"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.FDMS", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.FS", + "fields":[{"name":"key"}, {"name":"value"}], + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.PS", + "fields":[{"name":"key"}, {"name":"value"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.PSA", + "fields":[{"name":"accessTime"}], + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.PW", + "fields":[{"name":"value"}], + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.github.benmanes.caffeine.cache.SI", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.SSA", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.SSLA", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.StripedBuffer", + "fields":[{"name":"tableBusy"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.UnboundedLocalCache", + "fields":[{"name":"refreshes"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.WILSMS", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.WS", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.github.benmanes.caffeine.cache.WSL", + "fields":[{"name":"FACTORY"}] +}, +{ + "name":"com.sun.crypto.provider.AESCipher$General", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.ARCFOURCipher", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.DESCipher", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.DESedeCipher", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.DHParameters", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.GaloisCounterMode$AESGCM", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.HmacCore$HmacSHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.TlsMasterSecretGenerator", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"groovy.lang.Closure" +}, +{ + "name":"java.io.Console", + "methods":[{"name":"isTerminal","parameterTypes":[] }] +}, +{ + "name":"java.io.Serializable", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.Class", + "methods":[{"name":"getRecordComponents","parameterTypes":[] }] +}, +{ + "name":"java.lang.Comparable", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.Double", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"java.lang.Number", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.Object", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.Record", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.String" +}, +{ + "name":"java.lang.System", + "methods":[{"name":"console","parameterTypes":[] }] +}, +{ + "name":"java.lang.Thread", + "fields":[{"name":"threadLocalRandomProbe"}] +}, +{ + "name":"java.lang.constant.Constable", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.constant.ConstantDesc", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.reflect.Executable", + "methods":[{"name":"getParameters","parameterTypes":[] }] +}, +{ + "name":"java.lang.reflect.Method" +}, +{ + "name":"java.lang.reflect.Parameter", + "methods":[{"name":"getName","parameterTypes":[] }] +}, +{ + "name":"java.lang.reflect.RecordComponent", + "methods":[{"name":"getName","parameterTypes":[] }, {"name":"getType","parameterTypes":[] }] +}, +{ + "name":"java.nio.file.Path" +}, +{ + "name":"java.nio.file.Paths", + "methods":[{"name":"get","parameterTypes":["java.lang.String","java.lang.String[]"] }] +}, +{ + "name":"java.security.AlgorithmParametersSpi" +}, +{ + "name":"java.security.KeyStoreSpi" +}, +{ + "name":"java.security.SecureRandomParameters" +}, +{ + "name":"java.security.interfaces.ECPrivateKey" +}, +{ + "name":"java.security.interfaces.ECPublicKey" +}, +{ + "name":"java.security.interfaces.RSAPrivateKey" +}, +{ + "name":"java.security.interfaces.RSAPublicKey" +}, +{ + "name":"java.sql.Connection" +}, +{ + "name":"java.sql.Date" +}, +{ + "name":"java.sql.Driver" +}, +{ + "name":"java.sql.DriverManager", + "methods":[{"name":"getConnection","parameterTypes":["java.lang.String"] }, {"name":"getDriver","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.sql.Time", + "methods":[{"name":"","parameterTypes":["long"] }] +}, +{ + "name":"java.sql.Timestamp", + "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.time.Duration", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.Instant", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.LocalDate", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.LocalDateTime", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.LocalTime", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.MonthDay", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.OffsetDateTime", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.OffsetTime", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.Period", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.Year", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.YearMonth", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.time.ZoneId", + "methods":[{"name":"of","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.time.ZoneOffset", + "methods":[{"name":"of","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.time.ZonedDateTime", + "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] +}, +{ + "name":"java.util.Date" +}, +{ + "name":"java.util.Map", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.util.concurrent.ForkJoinTask", + "fields":[{"name":"aux"}, {"name":"status"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicBoolean", + "fields":[{"name":"value"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicMarkableReference", + "fields":[{"name":"pair"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicReference", + "fields":[{"name":"value"}] +}, +{ + "name":"java.util.concurrent.atomic.Striped64", + "fields":[{"name":"base"}, {"name":"cellsBusy"}] +}, +{ + "name":"java.util.concurrent.atomic.Striped64$Cell", + "fields":[{"name":"value"}] +}, +{ + "name":"javax.security.auth.x500.X500Principal", + "fields":[{"name":"thisX500Name"}], + "methods":[{"name":"","parameterTypes":["sun.security.x509.X500Name"] }] +}, +{ + "name":"jdk.internal.misc.Unsafe" +}, +{ + "name":"kotlin.Unit" +}, +{ + "name":"manifest_entry" +}, +{ + "name":"org.apache.commons.logging.LogFactory" +}, +{ + "name":"org.apache.commons.logging.impl.Log4JLogger", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }, {"name":"setLogFactory","parameterTypes":["org.apache.commons.logging.LogFactory"] }] +}, +{ + "name":"org.apache.commons.logging.impl.LogFactoryImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.commons.logging.impl.WeakHashtable", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.hadoop.fs.FSDataInputStream" +}, +{ + "name":"org.apache.hadoop.mapred.JobConf" +}, +{ + "name":"org.apache.hadoop.mapred.JobConfigurable" +}, +{ + "name":"org.apache.hadoop.thirdparty.com.google.common.util.concurrent.AbstractFuture", + "fields":[{"name":"listeners"}, {"name":"value"}, {"name":"waiters"}] +}, +{ + "name":"org.apache.hadoop.thirdparty.com.google.common.util.concurrent.AbstractFuture$Waiter", + "fields":[{"name":"next"}, {"name":"thread"}] +}, +{ + "name":"org.apache.http.client.config.RequestConfig$Builder", + "methods":[{"name":"setNormalizeUri","parameterTypes":["boolean"] }] +}, +{ + "name":"org.apache.iceberg.GenericDataFile", + "methods":[{"name":"","parameterTypes":["org.apache.iceberg.types.Types$StructType"] }] +}, +{ + "name":"org.apache.iceberg.GenericManifestEntry", + "methods":[{"name":"","parameterTypes":["org.apache.iceberg.types.Types$StructType"] }] +}, +{ + "name":"org.apache.iceberg.GenericManifestFile", + "methods":[{"name":"","parameterTypes":["org.apache.avro.Schema"] }] +}, +{ + "name":"org.apache.iceberg.GenericPartitionFieldSummary", + "methods":[{"name":"","parameterTypes":["org.apache.avro.Schema"] }] +}, +{ + "name":"org.apache.iceberg.PartitionData", + "methods":[{"name":"","parameterTypes":["org.apache.iceberg.types.Types$StructType"] }] +}, +{ + "name":"org.apache.iceberg.aws.ApacheHttpClientConfigurations", + "methods":[{"name":"create","parameterTypes":["java.util.Map"] }] +}, +{ + "name":"org.apache.iceberg.aws.AwsClientFactories$DefaultAwsClientFactory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.iceberg.aws.s3.S3FileIO", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.iceberg.hadoop.HadoopMetricsContext", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"org.apache.iceberg.relocated.com.google.common.collect.BiMap", + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.relocated.com.google.common.collect.ImmutableBiMap", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.relocated.com.google.common.collect.RegularImmutableMap", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"org.apache.iceberg.relocated.com.google.common.collect.SingletonImmutableBiMap", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"org.apache.iceberg.rest.RESTMessage", + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.rest.RESTRequest", + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.rest.RESTResponse", + "queryAllDeclaredMethods":true +}, +{ + "name":"org.apache.iceberg.rest.requests.CreateNamespaceRequest", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"org.apache.iceberg.rest.requests.CreateTableRequest", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"org.apache.iceberg.rest.responses.CreateNamespaceResponse", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.iceberg.rest.responses.ListNamespacesResponse", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.iceberg.rest.responses.ListTablesResponse", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.iceberg.util.Pair$1" +}, +{ + "name":"org.apache.log4j.Level", + "fields":[{"name":"TRACE"}] +}, +{ + "name":"org.apache.log4j.Priority" +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.ByteBitPackingBE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.ByteBitPackingForLongBE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.ByteBitPackingForLongLE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.ByteBitPackingLE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.LemireBitPackingBE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.column.values.bitpacking.LemireBitPackingLE", + "fields":[{"name":"factory"}] +}, +{ + "name":"org.apache.parquet.hadoop.codec.SnappyCodec", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.apache.parquet.hadoop.codec.ZstandardCodec", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.brotli.dec.BrotliInputStream" +}, +{ + "name":"org.jline.terminal.impl.exec.ExecTerminalProvider", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.jline.terminal.impl.ffm.FfmTerminalProvider" +}, +{ + "name":"org.jline.terminal.impl.jansi.JansiTerminalProvider", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.jline.terminal.impl.jna.JnaTerminalProvider", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.jline.terminal.impl.jni.JniTerminalProvider", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"org.osgi.framework.BundleEvent" +}, +{ + "name":"picocli.AutoComplete$GenerateCompletion", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"picocli.CommandLine$AutoHelpMixin", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"scala.util.Properties" +}, +{ + "name":"shaded.parquet.com.fasterxml.jackson.databind.ext.Java7SupportImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.misc.Signal", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }, {"name":"handle","parameterTypes":["sun.misc.Signal","sun.misc.SignalHandler"] }] +}, +{ + "name":"sun.misc.SignalHandler", + "fields":[{"name":"SIG_DFL"}] +}, +{ + "name":"sun.misc.Unsafe", + "allDeclaredFields":true, + "methods":[{"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }] +}, +{ + "name":"sun.security.pkcs12.PKCS12KeyStore", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.DSA$SHA224withDSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.DSA$SHA256withDSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.JavaKeyStore$DualFormatJKS", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.JavaKeyStore$JKS", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.NativePRNG", + "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] +}, +{ + "name":"sun.security.provider.SHA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA2$SHA224", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA2$SHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA5$SHA384", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA5$SHA512", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.X509Factory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.certpath.PKIXCertPathValidator", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.PSSParameters", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSAKeyFactory$Legacy", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSAPSSSignature", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSASignature$SHA224withRSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.rsa.RSASignature$SHA256withRSA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.ssl.KeyManagerFactoryImpl$SunX509", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.ssl.SSLContextImpl$DefaultSSLContext", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.ssl.SSLContextImpl$TLSContext", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.util.ObjectIdentifier" +}, +{ + "name":"sun.security.x509.AuthorityInfoAccessExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.AuthorityKeyIdentifierExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.BasicConstraintsExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.CRLDistributionPointsExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.CertificateExtensions" +}, +{ + "name":"sun.security.x509.CertificatePoliciesExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.ExtendedKeyUsageExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.IssuerAlternativeNameExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.KeyUsageExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.NetscapeCertTypeExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.PrivateKeyUsageExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.SubjectAlternativeNameExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +}, +{ + "name":"sun.security.x509.SubjectKeyIdentifierExtension", + "methods":[{"name":"","parameterTypes":["java.lang.Boolean","java.lang.Object"] }] +} +] diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json new file mode 100644 index 00000000..1912bec8 --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json @@ -0,0 +1,109 @@ +{ + "resources":{ + "includes":[{ + "pattern":"\\QMETA-INF/maven/org.jline/jline-native/pom.properties\\E" + }, { + "pattern":"\\QMETA-INF/maven/org.xerial.snappy/snappy-java/pom.properties\\E" + }, { + "pattern":"\\QMETA-INF/services/ch.qos.logback.classic.spi.Configurator\\E" + }, { + "pattern":"\\QMETA-INF/services/java.lang.System$LoggerFinder\\E" + }, { + "pattern":"\\QMETA-INF/services/java.net.spi.InetAddressResolverProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/java.net.spi.URLStreamHandlerProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/java.nio.channels.spi.SelectorProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/java.nio.charset.spi.CharsetProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/java.time.zone.ZoneRulesProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/javax.xml.parsers.SAXParserFactory\\E" + }, { + "pattern":"\\QMETA-INF/services/javax.xml.stream.XMLInputFactory\\E" + }, { + "pattern":"\\QMETA-INF/services/org.apache.avro.Conversion\\E" + }, { + "pattern":"\\QMETA-INF/services/org.apache.avro.LogicalTypes$LogicalTypeFactory\\E" + }, { + "pattern":"\\QMETA-INF/services/org.apache.commons.logging.LogFactory\\E" + }, { + "pattern":"\\QMETA-INF/services/org.slf4j.spi.SLF4JServiceProvider\\E" + }, { + "pattern":"\\QMETA-INF/services/org/jline/terminal/provider/exec\\E" + }, { + "pattern":"\\QMETA-INF/services/org/jline/terminal/provider/ffm\\E" + }, { + "pattern":"\\QMETA-INF/services/org/jline/terminal/provider/jansi\\E" + }, { + "pattern":"\\QMETA-INF/services/org/jline/terminal/provider/jna\\E" + }, { + "pattern":"\\QMETA-INF/services/org/jline/terminal/provider/jni\\E" + }, { + "pattern":"\\QMETA-INF/services/software.amazon.awssdk.http.SdkHttpService\\E" + }, { + "pattern":"\\Qcommons-logging.properties\\E" + }, { + "pattern":"\\Qcore-default.xml\\E" + }, { + "pattern":"\\Qcore-site.xml\\E" + }, { + "pattern":"\\Qhadoop-site.xml\\E" + }, { + "pattern":"\\Qiceberg-build.properties\\E" + }, { + "pattern":"\\Qlinux/amd64/libzstd-jni-1.5.6-6.so\\E" + }, { + "pattern":"\\Qlogback-test.scmo\\E" + }, { + "pattern":"\\Qlogback-test.xml\\E" + }, { + "pattern":"\\Qlogback.scmo\\E" + }, { + "pattern":"\\Qlogback.xml\\E" + }, { + "pattern":"\\Qmapred-default.xml\\E" + }, { + "pattern":"\\Qmapred-site.xml\\E" + }, { + "pattern":"\\Qmozilla/public-suffix-list.txt\\E" + }, { + "pattern":"\\Qorg-xerial-snappy.properties\\E" + }, { + "pattern":"\\Qorg/apache/hc/client5/version.properties\\E" + }, { + "pattern":"\\Qorg/jline/nativ/Linux/x86_64/libjlinenative.so\\E" + }, { + "pattern":"\\Qorg/jline/utils/capabilities.txt\\E" + }, { + "pattern":"\\Qorg/jline/utils/xterm-256color.caps\\E" + }, { + "pattern":"\\Qorg/publicsuffix/list/effective_tld_names.dat\\E" + }, { + "pattern":"\\Qorg/xerial/snappy/VERSION\\E" + }, { + "pattern":"\\Qorg/xerial/snappy/native/Linux/x86_64/libsnappyjava.so\\E" + }, { + "pattern":"\\Qsoftware/amazon/awssdk/core/util/mime.types\\E" + }, { + "pattern":"\\Qsoftware/amazon/awssdk/global/handlers/execution.interceptors\\E" + }, { + "pattern":"\\Qsoftware/amazon/awssdk/global/partitions.json\\E" + }, { + "pattern":"\\Qsoftware/amazon/awssdk/services/s3/execution.interceptors\\E" + }, { + "pattern":"\\Qyarn-default.xml\\E" + }, { + "pattern":"\\Qyarn-site.xml\\E" + }, { + "pattern":"java.base:\\Qjdk/internal/icu/impl/data/icudt72b/nfkc.nrm\\E" + }, { + "pattern":"java.base:\\Qjdk/internal/icu/impl/data/icudt72b/uprops.icu\\E" + }, { + "pattern":"java.base:\\Qsun/net/idn/uidna.spp\\E" + }, { + "pattern":"java.base:\\Qsun/text/resources/LineBreakIteratorData\\E" + }]}, + "bundles":[] +} diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/serialization-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/serialization-config.json new file mode 100644 index 00000000..f3d7e06e --- /dev/null +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/serialization-config.json @@ -0,0 +1,8 @@ +{ + "types":[ + ], + "lambdaCapturingTypes":[ + ], + "proxies":[ + ] +} diff --git a/ice/src/main/resources/reflection-config.json b/ice/src/main/resources/reflection-config.json deleted file mode 100644 index 15a1a7b5..00000000 --- a/ice/src/main/resources/reflection-config.json +++ /dev/null @@ -1,112 +0,0 @@ -[ - { - "name": "ch.qos.logback.classic.AsyncAppender", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.encoder.PatternLayoutEncoder", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.DateConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.LevelConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.LineSeparatorConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.LoggerConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.MessageConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.classic.pattern.ThreadConverter", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.core.ConsoleAppender", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - }, - { - "name": "ch.qos.logback.core.FileAppender", - "allDeclaredConstructors": true, - "allPublicConstructors": true, - "allDeclaredMethods": true, - "allPublicMethods": true, - "allDeclaredFields": true, - "allPublicFields": true, - "allDeclaredClasses": true, - "allPublicClasses": true - } -] From 96405eebb19cb4d36c699853b97134fd020562d0 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Mon, 27 Apr 2026 17:50:11 -0400 Subject: [PATCH 15/20] Fix verify workflow --- .github/workflows/verify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 973c64d9..ce998778 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -76,7 +76,7 @@ jobs: distribution: 'graalvm' cache: maven - name: Build native image (dynamic linking - no musl required) - run: ./mvnw -Pnative -pl ice clean package + run: ./mvnw -Pnative -pl ice clean install -Dmaven.test.skip=true - name: Run Scenario-Based Integration Tests run: ../mvnw test -Dtest=ScenarioBasedIT -Dice.native=true working-directory: ice-rest-catalog From ed93d9081f3b3e79700ed668c3ca3e24350519f7 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Thu, 30 Apr 2026 11:55:25 -0400 Subject: [PATCH 16/20] Try fix workflow --- .github/workflows/verify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index ce998778..1cae0e24 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -76,7 +76,7 @@ jobs: distribution: 'graalvm' cache: maven - name: Build native image (dynamic linking - no musl required) - run: ./mvnw -Pnative -pl ice clean install -Dmaven.test.skip=true + run: ./mvnw -Pnative clean install -Dmaven.test.skip=true - name: Run Scenario-Based Integration Tests run: ../mvnw test -Dtest=ScenarioBasedIT -Dice.native=true working-directory: ice-rest-catalog From 4dd6346b41a4d72e33e4cdb97d8fe9ba24813eba Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Thu, 30 Apr 2026 12:24:35 -0400 Subject: [PATCH 17/20] Update reflect-config.json --- .../com.altinity/ice/reflect-config.json | 59 ++++++++++++++++++- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json index 7b350ca9..707ca319 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -107,7 +107,7 @@ "name":"com.altinity.ice.cli.Main", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] + "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeMetadata","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"listTables","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.Main$IcePartition", @@ -135,7 +135,7 @@ "allDeclaredFields":true, "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true, - "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }] + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }, {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.Boolean"] }] }, { "name":"com.altinity.ice.cli.internal.cmd.AlterTable$Update", @@ -177,6 +177,45 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"id","parameterTypes":[] }, {"name":"location","parameterTypes":[] }, {"name":"operation","parameterTypes":[] }, {"name":"parentID","parameterTypes":[] }, {"name":"sequenceNumber","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampISO","parameterTypes":[] }, {"name":"timestampISOLocal","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$DataFileInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"columnSizes","parameterTypes":[] }, {"name":"fileSizeInBytes","parameterTypes":[] }, {"name":"format","parameterTypes":[] }, {"name":"lowerBounds","parameterTypes":[] }, {"name":"nullValueCounts","parameterTypes":[] }, {"name":"partition","parameterTypes":[] }, {"name":"path","parameterTypes":[] }, {"name":"recordCount","parameterTypes":[] }, {"name":"upperBounds","parameterTypes":[] }, {"name":"valueCounts","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$HistoryInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$ManifestInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"addedFilesCount","parameterTypes":[] }, {"name":"dataFiles","parameterTypes":[] }, {"name":"deletedFilesCount","parameterTypes":[] }, {"name":"existingFilesCount","parameterTypes":[] }, {"name":"partitionSpecId","parameterTypes":[] }, {"name":"path","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$MetadataInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"history","parameterTypes":[] }, {"name":"manifests","parameterTypes":[] }, {"name":"schema","parameterTypes":[] }, {"name":"snapshots","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$SchemaInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$Summary", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, { "name":"com.altinity.ice.cli.internal.cmd.ListNamespaces$Result", "allDeclaredFields":true, @@ -198,6 +237,13 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"partitionSpec","parameterTypes":[] }, {"name":"partitions","parameterTypes":[] }, {"name":"table","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.ListTables$Result", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"namespace","parameterTypes":[] }, {"name":"tables","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.config.Config", "allDeclaredFields":true, @@ -209,7 +255,8 @@ "name":"com.altinity.ice.cli.internal.config.Config$S3", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }] }, { "name":"com.altinity.ice.internal.iceberg.io.SchemeFileIO", @@ -545,6 +592,12 @@ "name":"java.time.ZonedDateTime", "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] }, +{ + "name":"java.util.Collections$UnmodifiableMap", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, { "name":"java.util.Date" }, From b98ee644239bc67841ebcbb1bbb15d2760a45a92 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Thu, 30 Apr 2026 13:14:38 -0400 Subject: [PATCH 18/20] Add aarch64 paths to resource-config.json --- .../native-image/com.altinity/ice/resource-config.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json index 1912bec8..9b4619fb 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json @@ -54,6 +54,8 @@ "pattern":"\\Qiceberg-build.properties\\E" }, { "pattern":"\\Qlinux/amd64/libzstd-jni-1.5.6-6.so\\E" + }, { + "pattern":"\\Qlinux/aarch64/libzstd-jni-1.5.6-6.so\\E" }, { "pattern":"\\Qlogback-test.scmo\\E" }, { @@ -74,6 +76,8 @@ "pattern":"\\Qorg/apache/hc/client5/version.properties\\E" }, { "pattern":"\\Qorg/jline/nativ/Linux/x86_64/libjlinenative.so\\E" + }, { + "pattern":"\\Qorg/jline/nativ/Linux/aarch64/libjlinenative.so\\E" }, { "pattern":"\\Qorg/jline/utils/capabilities.txt\\E" }, { @@ -84,6 +88,8 @@ "pattern":"\\Qorg/xerial/snappy/VERSION\\E" }, { "pattern":"\\Qorg/xerial/snappy/native/Linux/x86_64/libsnappyjava.so\\E" + }, { + "pattern":"\\Qorg/xerial/snappy/native/Linux/aarch64/libsnappyjava.so\\E" }, { "pattern":"\\Qsoftware/amazon/awssdk/core/util/mime.types\\E" }, { From 1348f73c8521ade5d007f7423bc58dad27436839 Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Thu, 7 May 2026 13:17:48 -0400 Subject: [PATCH 19/20] Add describe-parquet test --- examples/scratch/README.md | 2 +- .../scenarios/basic-operations/run.sh.tmpl | 4 + .../scenarios/describe-parquet/input.parquet | Bin 0 -> 2446 bytes .../scenarios/describe-parquet/run.sh.tmpl | 151 ++++++++++++++++++ .../scenarios/describe-parquet/scenario.yaml | 10 ++ .../com.altinity/ice/reflect-config.json | 44 ++++- .../com.altinity/ice/resource-config.json | 12 +- 7 files changed, 215 insertions(+), 8 deletions(-) create mode 100644 ice-rest-catalog/src/test/resources/scenarios/describe-parquet/input.parquet create mode 100644 ice-rest-catalog/src/test/resources/scenarios/describe-parquet/run.sh.tmpl create mode 100644 ice-rest-catalog/src/test/resources/scenarios/describe-parquet/scenario.yaml diff --git a/examples/scratch/README.md b/examples/scratch/README.md index 011fd715..179eba38 100644 --- a/examples/scratch/README.md +++ b/examples/scratch/README.md @@ -37,7 +37,7 @@ ice insert nyc.taxis_p_by_day -p \ # delete partition ice delete nyc.taxis_p_by_day \ - --partition '[{"name": "tpep_pickup_datetime", "values": ["2024-12-31T23:51:20"]}]' --dry-run=false + --partition '[{"name": "tpep_pickup_datetime_day", "values": ["2024-12-31"]}]' --dry-run=false # insert data ordered by tpep_pickup_datetime column ice insert nyc.taxis_s_by_day -p \ diff --git a/ice-rest-catalog/src/test/resources/scenarios/basic-operations/run.sh.tmpl b/ice-rest-catalog/src/test/resources/scenarios/basic-operations/run.sh.tmpl index de9184a2..178d17fa 100644 --- a/ice-rest-catalog/src/test/resources/scenarios/basic-operations/run.sh.tmpl +++ b/ice-rest-catalog/src/test/resources/scenarios/basic-operations/run.sh.tmpl @@ -30,6 +30,10 @@ echo "OK list-namespaces listed ${NAMESPACE_NAME}" {{ICE_CLI}} --config {{CLI_CONFIG}} describe echo "OK Listed namespaces" +# Check configuration +{{ICE_CLI}} --config {{CLI_CONFIG}} check +echo "OK checked configuration" + # Insert from file (like README: ice insert flowers.iris -p file://...) {{ICE_CLI}} --config {{CLI_CONFIG}} insert ${TABLE_IRIS} -p "file://${INPUT_PATH}" echo "Inserted from file into ${TABLE_IRIS}" diff --git a/ice-rest-catalog/src/test/resources/scenarios/describe-parquet/input.parquet b/ice-rest-catalog/src/test/resources/scenarios/describe-parquet/input.parquet new file mode 100644 index 0000000000000000000000000000000000000000..028c64cf9f7d9ea46bfeeaf940482aaee90a1b54 GIT binary patch literal 2446 zcmZ`*L1-Ii7JgDj^8efVlXj z+h~)tReRFWhaP+iY7a$+Qgkq^*-PEa;-d=<2zpU(g6+Yl#l^)qB!vBb$#tBx9gt_{ z{qO(gz4v|Z{Vu=u=TMXW->5#yzNoj-c+To9(buwYj)=C>skKZhHy(ZdSt^wqi|&7y zN?D^(=3;JbG@?w3J<{(uM64qj3mr{oQZ#l|z@TipsH&9LfvnNEcG%`J+fs0g##Ncd zbUX7exWy$nkLrLEd4Po?Zml3GL2Z)^amx`evS2yK8Lb3r>3ybuE+Fm-Q=hc3= zNd<)4#fLqv(M9da4o6rocpN%8X>h^1rgkZHk(+Rj{l-b2p`%XBV1fC_E;2_-tzKG(RB zxnWH|)LsdNuF!!t4fhz?K0wudcULwRJSzEwmaEg@e2aLSeYTC_Yuo}$M_1AGM>@{zU?#KLo&SQ`ZEz>>IwEsSoA>Df=};m6B7Ba zYPh`*Hwha|&mO5BWFjo18v1$OCRwHj$n`+`nLnXJ50r-ichGNo)XJZ@VbL)d_zA^& zgo(2W(^`t(p^AoQy!rplOZJpnJOxz=gF0Hp^ypT|-Ly+QQoK(kQ1y)Z&I9Jjbf985Lr!D=ae)}z)e`vso zO&o&sm({zs?ko@E>94D|@2p?Hb@SG3Y2Mav-&lWt{rWOyZ9#kegVP=yoag^|!e@Gg zR#Gczopx`&49To~aQ*Kq?_Ildy}J63Wj#!Kcp~lO?yT09Z@zSM_5B-ns{_->!1U4j z$}g5&ZT0T6P6N}4Qw~T&A1>csU%mVB1W|q~?H1g>P2%Vob~O&ur@o@oSkK=Z%YQL6 zDPDEN;MBMrIbynhag-}9|3F6rxPXRw2n*3_$6p?|5J?1)tc-D%QCx}lac?$W} z(B!|*pF&9H>%5SA6e=JPiD-;}gstG4MkWHTQ+21e&5i48iNkM-0b*SR?d74NQmGPh0{{e!n B/dev/null 2>&1; then + echo "FAIL describe-parquet should fail on missing file" + exit 1 +fi +echo "OK Missing file rejected" + +echo "Describe-parquet test completed successfully" diff --git a/ice-rest-catalog/src/test/resources/scenarios/describe-parquet/scenario.yaml b/ice-rest-catalog/src/test/resources/scenarios/describe-parquet/scenario.yaml new file mode 100644 index 00000000..8e878c9c --- /dev/null +++ b/ice-rest-catalog/src/test/resources/scenarios/describe-parquet/scenario.yaml @@ -0,0 +1,10 @@ +name: "Describe parquet metadata" +description: "Tests describe-parquet against a local iris parquet file across all option flags and both YAML and JSON output formats" + +catalogConfig: + warehouse: "s3://test-bucket/warehouse" + +env: + INPUT_FILE: "input.parquet" + EXPECTED_ROWS: "150" + EXPECTED_COLUMN_COUNT: "5" diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json index 707ca319..094000f9 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -107,7 +107,7 @@ "name":"com.altinity.ice.cli.Main", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeMetadata","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"listTables","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] + "methods":[{"name":"alterTable","parameterTypes":["java.lang.String","java.lang.String"] }, {"name":"check","parameterTypes":[] }, {"name":"createNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"createTable","parameterTypes":["java.lang.String","java.lang.String","boolean","boolean","java.lang.String","boolean","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"delete","parameterTypes":["java.lang.String","java.lang.String","java.lang.Boolean"] }, {"name":"deleteNamespace","parameterTypes":["java.lang.String","boolean"] }, {"name":"deleteTable","parameterTypes":["java.lang.String","boolean","boolean"] }, {"name":"describe","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeMetadata","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","boolean"] }, {"name":"describeParquet","parameterTypes":["java.lang.String","boolean","boolean","boolean","boolean","boolean","boolean","java.lang.String","boolean"] }, {"name":"files","parameterTypes":["java.lang.String"] }, {"name":"insert","parameterTypes":["java.lang.String","boolean","java.lang.String[]","java.lang.String","boolean","boolean","boolean","java.lang.String","boolean","boolean","int","boolean","com.altinity.ice.cli.internal.cmd.Insert$DataFileNamingStrategy$Name","boolean","boolean","java.lang.String","int","java.lang.String","java.lang.String","boolean","int","java.lang.String","java.lang.String","java.lang.String","boolean","java.lang.String"] }, {"name":"listNamespaces","parameterTypes":["java.lang.String","boolean"] }, {"name":"listPartitions","parameterTypes":["java.lang.String","boolean"] }, {"name":"listTables","parameterTypes":["java.lang.String","boolean"] }, {"name":"scanTable","parameterTypes":["java.lang.String","int","boolean"] }, {"name":"shell","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.Main$IcePartition", @@ -216,6 +216,48 @@ "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true }, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$Column", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"logicalType","parameterTypes":[] }, {"name":"name","parameterTypes":[] }, {"name":"repetition","parameterTypes":[] }, {"name":"type","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$ColumnChunk", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"codec","parameterTypes":[] }, {"name":"encodings","parameterTypes":[] }, {"name":"path","parameterTypes":[] }, {"name":"stats","parameterTypes":[] }, {"name":"totalSize","parameterTypes":[] }, {"name":"type","parameterTypes":[] }, {"name":"uncompressedSize","parameterTypes":[] }, {"name":"valueCount","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$ColumnStats", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"max","parameterTypes":[] }, {"name":"min","parameterTypes":[] }, {"name":"nulls","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$ParquetInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"columns","parameterTypes":[] }, {"name":"rowGroups","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$RowGroup", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"columns","parameterTypes":[] }, {"name":"compressedSize","parameterTypes":[] }, {"name":"index","parameterTypes":[] }, {"name":"rowCount","parameterTypes":[] }, {"name":"startingPos","parameterTypes":[] }, {"name":"totalSize","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$Summary", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"columnCount","parameterTypes":[] }, {"name":"compressedSize","parameterTypes":[] }, {"name":"createdBy","parameterTypes":[] }, {"name":"rowGroups","parameterTypes":[] }, {"name":"rows","parameterTypes":[] }, {"name":"uncompressedSize","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.ListNamespaces$Result", "allDeclaredFields":true, diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json index 9b4619fb..ad082462 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/resource-config.json @@ -52,10 +52,10 @@ "pattern":"\\Qhadoop-site.xml\\E" }, { "pattern":"\\Qiceberg-build.properties\\E" - }, { - "pattern":"\\Qlinux/amd64/libzstd-jni-1.5.6-6.so\\E" }, { "pattern":"\\Qlinux/aarch64/libzstd-jni-1.5.6-6.so\\E" + }, { + "pattern":"\\Qlinux/amd64/libzstd-jni-1.5.6-6.so\\E" }, { "pattern":"\\Qlogback-test.scmo\\E" }, { @@ -74,10 +74,10 @@ "pattern":"\\Qorg-xerial-snappy.properties\\E" }, { "pattern":"\\Qorg/apache/hc/client5/version.properties\\E" - }, { - "pattern":"\\Qorg/jline/nativ/Linux/x86_64/libjlinenative.so\\E" }, { "pattern":"\\Qorg/jline/nativ/Linux/aarch64/libjlinenative.so\\E" + }, { + "pattern":"\\Qorg/jline/nativ/Linux/x86_64/libjlinenative.so\\E" }, { "pattern":"\\Qorg/jline/utils/capabilities.txt\\E" }, { @@ -86,10 +86,10 @@ "pattern":"\\Qorg/publicsuffix/list/effective_tld_names.dat\\E" }, { "pattern":"\\Qorg/xerial/snappy/VERSION\\E" - }, { - "pattern":"\\Qorg/xerial/snappy/native/Linux/x86_64/libsnappyjava.so\\E" }, { "pattern":"\\Qorg/xerial/snappy/native/Linux/aarch64/libsnappyjava.so\\E" + }, { + "pattern":"\\Qorg/xerial/snappy/native/Linux/x86_64/libsnappyjava.so\\E" }, { "pattern":"\\Qsoftware/amazon/awssdk/core/util/mime.types\\E" }, { From 321c38aef676ed8b50ebf56aa5f99df24ed8c8ef Mon Sep 17 00:00:00 2001 From: Andrew Xie Date: Fri, 8 May 2026 13:55:35 -0400 Subject: [PATCH 20/20] Add more cases to schema-evolution scenario --- .../scenarios/schema-evolution/run.sh.tmpl | 105 ++++++++++++++ .../scenarios/schema-evolution/scenario.yaml | 4 +- .../com.altinity/ice/reflect-config.json | 132 +++++++++++++++++- 3 files changed, 237 insertions(+), 4 deletions(-) diff --git a/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/run.sh.tmpl b/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/run.sh.tmpl index 4a076deb..e4fde013 100644 --- a/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/run.sh.tmpl +++ b/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/run.sh.tmpl @@ -45,9 +45,114 @@ if [ "${SECOND_LINES}" -le "${FIRST_LINES}" ]; then fi echo "OK Second scan: ${SECOND_LINES} lines (rows inserted)" +# alter_column: add an int column then widen to long +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"add_column","name":"an_int","type":"int"}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_NAME} > /tmp/schema_ev_int.txt +if ! grep -qF 'an_int: optional int' /tmp/schema_ev_int.txt; then + echo "FAIL add_column an_int as int not visible" + cat /tmp/schema_ev_int.txt + exit 1 +fi +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"alter_column","name":"an_int","type":"long"}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_NAME} > /tmp/schema_ev_long.txt +if ! grep -qF 'an_int: optional long' /tmp/schema_ev_long.txt; then + echo "FAIL alter_column int->long not applied" + cat /tmp/schema_ev_long.txt + exit 1 +fi +echo "OK alter_column promoted int to long" + +# rename_column an_int -> a_long +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"rename_column","name":"an_int","new_name":"a_long"}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_NAME} > /tmp/schema_ev_rename.txt +if grep -qF ' an_int:' /tmp/schema_ev_rename.txt; then + echo "FAIL rename_column: old name 'an_int' still present" + cat /tmp/schema_ev_rename.txt + exit 1 +fi +if ! grep -qF 'a_long: optional long' /tmp/schema_ev_rename.txt; then + echo "FAIL rename_column: new name 'a_long' not visible" + cat /tmp/schema_ev_rename.txt + exit 1 +fi +echo "OK rename_column an_int -> a_long" + +# drop_column 'extra' +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"drop_column","name":"extra"}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_NAME} > /tmp/schema_ev_drop.txt +if grep -qF ' extra:' /tmp/schema_ev_drop.txt; then + echo "FAIL drop_column: 'extra' still present" + cat /tmp/schema_ev_drop.txt + exit 1 +fi +echo "OK drop_column 'extra' removed" + +# set_tblproperty: set then remove (value=null) +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"set_tblproperty","key":"owner","value":"qa"}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -p ${TABLE_NAME} > /tmp/schema_ev_props_set.txt +if ! grep -qF 'owner: qa' /tmp/schema_ev_props_set.txt; then + echo "FAIL set_tblproperty owner=qa not visible in describe -p" + cat /tmp/schema_ev_props_set.txt + exit 1 +fi +echo "OK set_tblproperty owner=qa" + +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} $'[{"op":"set_tblproperty","key":"owner","value":null}]' +{{ICE_CLI}} --config {{CLI_CONFIG}} describe -p ${TABLE_NAME} > /tmp/schema_ev_props_unset.txt +if grep -qF 'owner: qa' /tmp/schema_ev_props_unset.txt; then + echo "FAIL set_tblproperty value=null did not remove 'owner'" + cat /tmp/schema_ev_props_unset.txt + exit 1 +fi +echo "OK set_tblproperty value=null removed 'owner'" + +# rename_to: ensure new name appears and old name disappears +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_NAME} "[{\"op\":\"rename_to\",\"new_name\":\"${TABLE_RENAMED}\"}]" +{{ICE_CLI}} --config {{CLI_CONFIG}} list-tables ${NAMESPACE_NAME} > /tmp/schema_ev_rename_to.txt +LISTED_NAMES=$(awk '/^- /{sub(/^- */,""); print}' /tmp/schema_ev_rename_to.txt) +if grep -qFx "${TABLE_NAME}" <<<"${LISTED_NAMES}"; then + echo "FAIL rename_to: original table ${TABLE_NAME} still listed" + cat /tmp/schema_ev_rename_to.txt + exit 1 +fi +if ! grep -qFx "${TABLE_RENAMED}" <<<"${LISTED_NAMES}"; then + echo "FAIL rename_to: renamed table ${TABLE_RENAMED} not listed" + cat /tmp/schema_ev_rename_to.txt + exit 1 +fi +echo "OK rename_to ${TABLE_RENAMED}" + +# Rename back so the existing cleanup path still works +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_RENAMED} "[{\"op\":\"rename_to\",\"new_name\":\"${TABLE_NAME}\"}]" + +# drop_partition_field: needs a partitioned table +{{ICE_CLI}} --config {{CLI_CONFIG}} insert --create-table ${TABLE_PARTITIONED} "file://${INPUT_PATH}" \ + --partition='[{"column":"variety","transform":"identity"}]' +PART_BEFORE=$({{ICE_CLI}} --config {{CLI_CONFIG}} list-partitions ${TABLE_PARTITIONED}) +if ! grep -q "variety=" <<<"${PART_BEFORE}"; then + echo "FAIL partitioned table missing 'variety=' partition entries before drop" + printf '%s\n' "${PART_BEFORE}" + exit 1 +fi +{{ICE_CLI}} --config {{CLI_CONFIG}} alter-table ${TABLE_PARTITIONED} $'[{"op":"drop_partition_field","name":"variety"}]' +DESCRIBE_PART=$({{ICE_CLI}} --config {{CLI_CONFIG}} describe -s ${TABLE_PARTITIONED}) +# After dropping, the partition spec should no longer reference 'variety' as an active field. +# Iceberg renders dropped fields as "void()" in the spec; an active identity partition shows as "identity(variety)". +if grep -qE "identity\(variety\)" <<<"${DESCRIBE_PART}"; then + echo "FAIL drop_partition_field: identity(variety) still active in spec" + printf '%s\n' "${DESCRIBE_PART}" + exit 1 +fi +echo "OK drop_partition_field 'variety'" + # Cleanup {{ICE_CLI}} --config {{CLI_CONFIG}} delete-table ${TABLE_NAME} +{{ICE_CLI}} --config {{CLI_CONFIG}} delete-table ${TABLE_PARTITIONED} {{ICE_CLI}} --config {{CLI_CONFIG}} delete-namespace ${NAMESPACE_NAME} +rm -f /tmp/schema_ev_describe.txt /tmp/schema_ev_scan1.txt /tmp/schema_ev_scan2.txt \ + /tmp/schema_ev_int.txt /tmp/schema_ev_long.txt /tmp/schema_ev_rename.txt \ + /tmp/schema_ev_drop.txt /tmp/schema_ev_props_set.txt /tmp/schema_ev_props_unset.txt \ + /tmp/schema_ev_rename_to.txt echo "OK Cleanup done" echo "Schema evolution test completed successfully" diff --git a/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/scenario.yaml b/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/scenario.yaml index 8a753b63..684274be 100644 --- a/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/scenario.yaml +++ b/ice-rest-catalog/src/test/resources/scenarios/schema-evolution/scenario.yaml @@ -1,5 +1,5 @@ name: "Schema evolution (add, drop, rename)" -description: "Tests alter-table: add column, drop column, rename column" +description: "Tests alter-table: add_column, alter_column, rename_column, drop_column, set_tblproperty, rename_to, drop_partition_field" catalogConfig: warehouse: "s3://test-bucket/warehouse" @@ -7,3 +7,5 @@ catalogConfig: env: NAMESPACE_NAME: "test_schema_ev" TABLE_NAME: "test_schema_ev.t1" + TABLE_RENAMED: "test_schema_ev.t1_renamed" + TABLE_PARTITIONED: "test_schema_ev.t_part" diff --git a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json index 094000f9..70a02591 100644 --- a/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json +++ b/ice/src/main/resources/META-INF/native-image/com.altinity/ice/reflect-config.json @@ -14,6 +14,9 @@ { "name":"[Lcom.altinity.ice.cli.internal.cmd.AlterTable$Update;" }, +{ + "name":"[Lcom.altinity.ice.cli.internal.cmd.DescribeMetadata$ManifestInfo;" +}, { "name":"[Lcom.fasterxml.jackson.databind.deser.BeanDeserializerModifier;" }, @@ -32,6 +35,9 @@ { "name":"[Lcom.fasterxml.jackson.databind.ser.Serializers;" }, +{ + "name":"[Ljava.lang.Object;" +}, { "name":"[Ljava.lang.String;" }, @@ -137,6 +143,48 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }, {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.String","java.lang.Boolean"] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$AlterColumn", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$DropColumn", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$DropPartitionField", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$RenameColumn", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$RenameTo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.AlterTable$SetTblProperty", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.AlterTable$Update", "allDeclaredFields":true, @@ -184,11 +232,19 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"columnSizes","parameterTypes":[] }, {"name":"fileSizeInBytes","parameterTypes":[] }, {"name":"format","parameterTypes":[] }, {"name":"lowerBounds","parameterTypes":[] }, {"name":"nullValueCounts","parameterTypes":[] }, {"name":"partition","parameterTypes":[] }, {"name":"path","parameterTypes":[] }, {"name":"recordCount","parameterTypes":[] }, {"name":"upperBounds","parameterTypes":[] }, {"name":"valueCounts","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$FieldInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"fieldId","parameterTypes":[] }, {"name":"name","parameterTypes":[] }, {"name":"required","parameterTypes":[] }, {"name":"type","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$HistoryInfo", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true + "queryAllDeclaredConstructors":true, + "methods":[{"name":"metadataLog","parameterTypes":[] }, {"name":"snapshotLog","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$ManifestInfo", @@ -204,17 +260,40 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"history","parameterTypes":[] }, {"name":"manifests","parameterTypes":[] }, {"name":"schema","parameterTypes":[] }, {"name":"snapshots","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }] }, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$MetadataLogEntry", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"file","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampMillis","parameterTypes":[] }] +}, { "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$SchemaInfo", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true + "queryAllDeclaredConstructors":true, + "methods":[{"name":"fields","parameterTypes":[] }, {"name":"schemaId","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$SnapshotInfo", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"manifestListLocation","parameterTypes":[] }, {"name":"operation","parameterTypes":[] }, {"name":"parentId","parameterTypes":[] }, {"name":"sequenceNumber","parameterTypes":[] }, {"name":"snapshotId","parameterTypes":[] }, {"name":"summary","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampMillis","parameterTypes":[] }] +}, +{ + "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$SnapshotLogEntry", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"snapshotId","parameterTypes":[] }, {"name":"timestamp","parameterTypes":[] }, {"name":"timestampMillis","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.internal.cmd.DescribeMetadata$Summary", "allDeclaredFields":true, "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true + "queryAllDeclaredConstructors":true, + "methods":[{"name":"currentSnapshotId","parameterTypes":[] }, {"name":"formatVersion","parameterTypes":[] }, {"name":"lastUpdated","parameterTypes":[] }, {"name":"lastUpdatedMillis","parameterTypes":[] }, {"name":"location","parameterTypes":[] }, {"name":"numSnapshots","parameterTypes":[] }, {"name":"partitionSpec","parameterTypes":[] }, {"name":"properties","parameterTypes":[] }, {"name":"sortOrder","parameterTypes":[] }, {"name":"uuid","parameterTypes":[] }] }, { "name":"com.altinity.ice.cli.internal.cmd.DescribeParquet$Column", @@ -480,6 +559,10 @@ "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true }, +{ + "name":"java.lang.Iterable", + "queryAllDeclaredMethods":true +}, { "name":"java.lang.Number", "allDeclaredFields":true, @@ -634,6 +717,15 @@ "name":"java.time.ZonedDateTime", "methods":[{"name":"parse","parameterTypes":["java.lang.CharSequence"] }] }, +{ + "name":"java.util.AbstractCollection", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.util.Collection", + "queryAllDeclaredMethods":true +}, { "name":"java.util.Collections$UnmodifiableMap", "allDeclaredFields":true, @@ -643,10 +735,34 @@ { "name":"java.util.Date" }, +{ + "name":"java.util.ImmutableCollections$AbstractImmutableCollection", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.util.ImmutableCollections$AbstractImmutableList", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"java.util.ImmutableCollections$ListN", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"java.util.List", + "queryAllDeclaredMethods":true +}, { "name":"java.util.Map", "queryAllDeclaredMethods":true }, +{ + "name":"java.util.RandomAccess", + "queryAllDeclaredMethods":true +}, { "name":"java.util.concurrent.ForkJoinTask", "fields":[{"name":"aux"}, {"name":"status"}] @@ -807,6 +923,12 @@ "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true }, +{ + "name":"org.apache.iceberg.rest.requests.RenameTableRequest", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, { "name":"org.apache.iceberg.rest.responses.CreateNamespaceResponse", "allDeclaredFields":true, @@ -950,6 +1072,10 @@ "name":"sun.security.provider.JavaKeyStore$JKS", "methods":[{"name":"","parameterTypes":[] }] }, +{ + "name":"sun.security.provider.MD5", + "methods":[{"name":"","parameterTypes":[] }] +}, { "name":"sun.security.provider.NativePRNG", "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }]