diff --git a/hackathon-CoC2026/Dockerfile b/hackathon-CoC2026/Dockerfile new file mode 100644 index 000000000..2897bb7d1 --- /dev/null +++ b/hackathon-CoC2026/Dockerfile @@ -0,0 +1,72 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Hackathon developer environment (Community over Code 2026, Glasgow). +# +# This is a JDK-based development container, not a slim runtime image: +# participants are expected to edit Wayang source and rebuild Wayang during +# the hackathon, so we keep Maven Wrapper + git + the full source tree +# available inside it. +# +# Build context is the REPO ROOT (see compose.yaml: `context: ..`), because +# the whole source tree needs to be present to build Wayang. + +FROM eclipse-temurin:17-jdk + +LABEL org.opencontainers.image.source="https://github.com/apache/wayang" + +# git -> some mvnw/plugin steps and contributor workflows expect it +# bash -> mvnw and our entrypoint are bash scripts +# postgresql-client -> lets participants run `psql` from inside the +# container to poke at the hackathon Postgres service +RUN apt-get update \ + && apt-get install -y --no-install-recommends git bash postgresql-client \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /workspace/wayang + +# The source tree is normally supplied at runtime via the bind mount in +# compose.yaml (so local edits show up immediately). We still COPY it here +# so `docker build` works standalone, without compose, e.g. in CI. +COPY . /workspace/wayang + +# The repo's Maven Wrapper is frequently checked out with CRLF line endings +# on Windows, which breaks execution inside the Linux container. +RUN sed -i 's/\r$//' mvnw \ + && chmod +x mvnw + +COPY hackathon-CoC2026/docker/entrypoint.sh /usr/local/bin/wayang-entrypoint +RUN chmod +x /usr/local/bin/wayang-entrypoint + +# Pre-warm the Maven local repo (~/.m2) at image build time, so a PUSHED, +# PULLED image already has every dependency downloaded — this is what +# actually gets participants under the 10-15 minute target, vs. a +# from-source build which takes much longer on a cold cache (see +# README.md "Timing"). This step builds against whatever source was +# checked out when this image was built. +# +# ~/.m2 lives outside /workspace/wayang, so it is NOT overwritten by the +# bind mount in compose.yaml. The first time the wayang-maven-cache named +# volume is created, Docker seeds it from this image layer automatically +# (standard behavior for a volume mounted over a non-empty image +# directory), so the warm cache survives into the running container. +RUN ./mvnw -B -q clean package -pl :wayang-assembly -Pdistribution -DskipTests \ + && ./mvnw -B -q dependency:build-classpath -pl :wayang-assembly \ + -Dmdep.outputFile=/tmp/wayang-classpath.txt \ + && rm -rf /workspace/wayang/wayang-assembly/target + +ENTRYPOINT ["wayang-entrypoint"] +CMD ["bash"] diff --git a/hackathon-CoC2026/Dockerfile.dockerignore b/hackathon-CoC2026/Dockerfile.dockerignore new file mode 100644 index 000000000..c30f9533f --- /dev/null +++ b/hackathon-CoC2026/Dockerfile.dockerignore @@ -0,0 +1,30 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +.git +.gitignore +**/target/ + +.idea/ +.vscode/ +*.iml + +*.log + +.DS_Store +Thumbs.db + +.m2/ diff --git a/hackathon-CoC2026/README.md b/hackathon-CoC2026/README.md new file mode 100644 index 000000000..2c080d066 --- /dev/null +++ b/hackathon-CoC2026/README.md @@ -0,0 +1,204 @@ +# Wayang Hackathon Development Environment — Community over Code 2026, Glasgow + +This folder is a self-contained Docker development environment for the Wayang +hackathon. It gets a contributor from a fresh checkout to a working build of +Wayang with the **Java**, **Spark**, and **PostgreSQL** platforms all +runnable inside the container. + +This is a *developer* environment, not just a runtime: the full source tree +is bind-mounted into the container, so you edit code on your host machine +with your usual editor/IDE, and build/run it inside the container. Nothing +beyond Git and Docker Desktop is required on the host. + +**Timing**: building the Wayang distribution from source on a cold Maven +cache takes 30-50+ minutes depending on network speed and machine specs — +that's just how long compiling Wayang and its dependency tree (including +Spark) genuinely takes the first time. That is NOT what hackathon +participants are expected to do. Instead, a multi-architecture image +supporting both linux/amd64 and linux/arm64 is built and pushed to +GitHub Container Registry ahead of the event, with its Maven cache +already warmed at build time. Participants just pull the image: + +```bash +docker compose pull +docker compose up -d +``` + +This is the intended 10-15 minute setup path — it's a Docker image pull +plus container startup, not a build. `docker compose up -d --build` +(building from source locally) is still available and is what this README +documents step by step below, for contributors actively working on the +Dockerfile/build itself — participants on hackathon day shouldn't need it. + +## What's here + +``` +hackathon-CoC2026/ +├── Dockerfile # JDK 17 + git + Maven Wrapper + psql client +├── compose.yaml # the "wayang" dev container + a real "postgres" service +├── verify.sh # one-command build + cross-platform verification +├── docker/ +│ ├── entrypoint.sh # normalizes mvnw line endings on every start +│ └── postgres/ +│ └── init.sql # seeds a small table used by the Postgres smoke test +├── examples/ +│ └── PostgresSmokeTest.java # a Wayang plan spanning Java, Spark, and Postgres +└── README.md # this file +``` + +## Prerequisites + +Install on your host machine: + +- [Git](https://git-scm.com/) +- [Docker Desktop](https://www.docker.com/products/docker-desktop/) (includes + Docker Compose) + +Verify: + +```bash +docker --version +docker compose version +``` + +## 1. Get the source + +```bash +git clone https://github.com/apache/wayang.git +cd wayang +``` + +(If you're working from a fork/branch, clone that instead.) + +## 2. Start the environment + +From this folder: + +```bash +cd hackathon-CoC2026 +docker compose pull # gets the pre-built, cache-warmed image (fast) +docker compose up -d +``` + +If you're actively changing the Dockerfile or want a from-source build +instead, use `docker compose up -d --build` (see Timing above — this is +slow on a cold cache). + +Either way, this starts two services: + +- `wayang` — the container you'll work in (Java 17 JDK, Maven Wrapper, git) +- `postgres` — a real PostgreSQL 16 instance, seeded with a small sample + table (`word_counts_seed`) + +Check both containers are up: + +```bash +docker compose ps +``` + +`postgres` should show as `healthy` before moving on (it has a healthcheck +that waits for it to accept connections). + +## 3. Run the verification script + +```bash +docker compose exec wayang bash hackathon-CoC2026/verify.sh +``` +**Note:** `verify.sh` performs a full Wayang distribution build to validate +the development environment end-to-end. This build can take 30-50+ minutes +on a cold Maven cache. It is not required to start the pre-built hackathon +environment and is not part of the 10-15 minute participant setup target. + +This single command: builds `wayang-assembly`, extracts the distribution, +runs the bundled WordCount app on the Java platform, resolves the full +Maven runtime classpath, and compiles + runs `PostgresSmokeTest.java` — a +Wayang plan that reads from Postgres, filters on Java, and maps on Spark. + +The distribution's extracted layout is `bin/`, `conf/`, `jars/`, and +`libs/`. Both `jars/*` and `libs/*` are needed on the classpath to compile +and run against Wayang's own modules — `jars/` alone is not enough. Neither +directory contains Spark's own transitive runtime dependencies (e.g. +`spark-sql`), though — those are only resolved through Maven's local +repository, via `./mvnw -pl wayang-assembly dependency:build-classpath`, +which is why `verify.sh` builds the classpath from both sources combined. + +You do not need to hand-edit `bin/wayang-submit` or add `--add-opens`/ +`--add-exports` flags yourself — the script uses `wayang-submit` as-is for +the Java check, and pulls the same flags straight out of that script for its +own direct `java` invocation of the smoke test. + +Confirmed working output looks like this: + +``` +Wayang plan executed across Postgres, Java, and Spark. Results: +WAYANG -> 42 +SPARK -> 17 +POSTGRES -> 9 +Total rows: 3 +``` + +If it fails, see Troubleshooting below. + +You can also poke at the database directly from inside the container: + +```bash +psql -h postgres -U wayang -d wayang_hackathon -c "select * from word_counts_seed;" +# password: wayang +``` + +## Troubleshooting + +- **`mvnw: command not found` / permission denied** — the entrypoint fixes + line endings and permissions on `mvnw` on every container start, but if + you edited/replaced it from the host afterward, re-run + `sed -i 's/\r$//' mvnw && chmod +x mvnw` inside the container. +- **Postgres connection refused** — wait for `docker compose ps` to show + `postgres` as `healthy`; the `wayang` service is configured to start after + that, but a manual `docker compose exec` shell you opened earlier may have + started before it. Just retry. +- **Slow first build** — this is the Maven dependency download, not a bug + (see Timing above). It's cached in the `wayang-maven-cache` volume; + `docker compose down` (without `-v`) keeps it, `docker compose down -v` + deletes it. +- **Out of memory during the build** — increase Docker Desktop's memory + limit (Settings → Resources). +- **`ClassNotFoundException`/`NoClassDefFoundError` for a Spark class** — + confirm `/tmp/wayang-classpath.txt` from `verify.sh` actually contains + `spark-sql` and `spark-sql-api` jars; if not, re-run the `dependency: + build-classpath` step and check for Maven resolution errors above it. +- **`no matching manifest for linux/arm64/v8`** — the published image may + not include an ARM64 variant. Ensure the image supports both + `linux/amd64` and `linux/arm64` platforms, then run + `docker compose pull` again. +- **`tar: ... Function not implemented` on Apple Silicon** — this can occur + when an AMD64-only image is forced to run on an ARM64 host through + emulation. Do not force `linux/amd64`; use the multi-architecture image + so Docker pulls the native ARM64 variant. + +## Resetting everything + +```bash +docker compose down -v +``` + +This removes both containers and both named volumes (Maven cache and +Postgres data), so the next `docker compose up -d --build` starts completely +fresh. + +## For maintainers: publishing the image + +The hackathon image is published to GitHub Container Registry (GHCR). +To publish an updated image, build and push images for both `linux/amd64` +and `linux/arm64`, then create a multi-architecture manifest for the shared +tag. Ensure the published package is public so participants can pull it +without authenticating. + +After publishing an update, verify that both architectures are present and +that the image passes the end-to-end smoke test. + +## Later platforms + +This environment currently exercises Java, Spark, and PostgreSQL, per the +initial hackathon scope. Adding another platform (e.g. SQLite, GraphChi) +only requires seeding/service changes here in `hackathon-CoC2026/` — the +`Dockerfile` and `compose.yaml` at the repository root are untouched. diff --git a/hackathon-CoC2026/compose.yaml b/hackathon-CoC2026/compose.yaml new file mode 100644 index 000000000..06fcdb625 --- /dev/null +++ b/hackathon-CoC2026/compose.yaml @@ -0,0 +1,82 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Run from this folder with: docker compose up -d --build +# +# Paths below (context, volumes) are relative to THIS file, so `..` means +# the repository root. + +services: + wayang: + # `docker compose up -d` (no --build) pulls this pre-built image, which + # already has its Maven cache warmed — this is what gets participants + # to a working setup in minutes on hackathon day. `docker compose up -d + # --build` ignores this and builds locally from the Dockerfile instead, + # which is slower (see README.md "Timing") but always matches your + # exact checkout — useful for contributors actively changing the + # Dockerfile/build itself, not needed for hackathon participants. + image: ghcr.io/mohit-devlogs/wayang-hackathon:latest + build: + context: .. + dockerfile: hackathon-CoC2026/Dockerfile + container_name: wayang-hackathon + security_opt: + - seccomp=unconfined + working_dir: /workspace/wayang + volumes: + # Full repo, read-write, so edits made on the host (or inside the + # container) are shared both ways. + - ..:/workspace/wayang + # Named volume for the Maven local repo: keeps ~/.m2 between + # `docker compose down` / `up` cycles so dependencies aren't + # re-downloaded every time. + - wayang-maven-cache:/root/.m2 + environment: + # Picked up by hackathon-CoC2026/examples/PostgresSmokeTest.java and + # can be used from any app via System.getenv(...) or by writing them + # into a wayang.properties file (see README.md). + WAYANG_POSTGRES_JDBC_URL: jdbc:postgresql://postgres:5432/wayang_hackathon + WAYANG_POSTGRES_USER: wayang + WAYANG_POSTGRES_PASSWORD: wayang + depends_on: + postgres: + condition: service_healthy + stdin_open: true + tty: true + + postgres: + image: postgres:16-alpine + container_name: wayang-hackathon-postgres + environment: + POSTGRES_DB: wayang_hackathon + POSTGRES_USER: wayang + POSTGRES_PASSWORD: wayang + volumes: + - ./docker/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:ro + - wayang-postgres-data:/var/lib/postgresql/data + ports: + # Exposed on the host too, so participants can point a local SQL + # client at it if they want (e.g. `psql -h localhost -p 55432`). + - "55432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U wayang -d wayang_hackathon"] + interval: 5s + timeout: 5s + retries: 20 + +volumes: + wayang-maven-cache: + wayang-postgres-data: diff --git a/hackathon-CoC2026/docker/entrypoint.sh b/hackathon-CoC2026/docker/entrypoint.sh new file mode 100644 index 000000000..0d1651c4c --- /dev/null +++ b/hackathon-CoC2026/docker/entrypoint.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +# The source tree is bind-mounted from the host (see compose.yaml), so mvnw's +# line endings depend on how the host checked it out. Re-normalize on every +# start rather than only at image build time. +if [ -f /workspace/wayang/mvnw ]; then + sed -i 's/\r$//' /workspace/wayang/mvnw + chmod +x /workspace/wayang/mvnw +fi + +exec "$@" diff --git a/hackathon-CoC2026/docker/postgres/init.sql b/hackathon-CoC2026/docker/postgres/init.sql new file mode 100644 index 000000000..9af655462 --- /dev/null +++ b/hackathon-CoC2026/docker/postgres/init.sql @@ -0,0 +1,32 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +-- Seed table used by examples/PostgresSmokeTest.java to prove the Postgres +-- platform is reachable and queryable from inside the hackathon container. +-- Runs automatically the first time the postgres data volume is created +-- (standard postgres image behavior for /docker-entrypoint-initdb.d). + +CREATE TABLE IF NOT EXISTS word_counts_seed ( + word VARCHAR(64) NOT NULL, + count INTEGER NOT NULL +); + +INSERT INTO word_counts_seed (word, count) VALUES + ('wayang', 42), + ('spark', 17), + ('postgres', 9), + ('hackathon',5), + ('glasgow', 3); diff --git a/hackathon-CoC2026/examples/PostgresSmokeTest.java b/hackathon-CoC2026/examples/PostgresSmokeTest.java new file mode 100644 index 000000000..118a8ca9a --- /dev/null +++ b/hackathon-CoC2026/examples/PostgresSmokeTest.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.wayang.api.JavaPlanBuilder; +import org.apache.wayang.basic.data.Record; +import org.apache.wayang.core.api.Configuration; +import org.apache.wayang.core.api.WayangContext; +import org.apache.wayang.java.Java; +import org.apache.wayang.postgres.Postgres; +import org.apache.wayang.postgres.operators.PostgresTableSource; +import org.apache.wayang.spark.Spark; + +import java.util.Collection; + +/** + * Hackathon smoke test: builds a single Wayang plan that reads from the + * seeded Postgres table, forces the filter step onto the Java platform, + * and forces the map step onto the Spark platform, proving all three + * platforms work together inside the container. + * + * Run via hackathon-CoC2026/verify.sh, which sets up the classpath needed + * for the Postgres and Spark platforms and compiles/runs this class. + */ +public class PostgresSmokeTest { + + public static void main(String[] args) { + Configuration configuration = new Configuration(); + configuration.setProperty( + "wayang.postgres.jdbc.url", + envOrDefault("WAYANG_POSTGRES_JDBC_URL", "jdbc:postgresql://postgres:5432/wayang_hackathon")); + configuration.setProperty( + "wayang.postgres.jdbc.user", + envOrDefault("WAYANG_POSTGRES_USER", "wayang")); + configuration.setProperty( + "wayang.postgres.jdbc.password", + envOrDefault("WAYANG_POSTGRES_PASSWORD", "wayang")); + + WayangContext wayangContext = new WayangContext(configuration) + .withPlugin(Java.basicPlugin()) + .withPlugin(Spark.basicPlugin()) + .withPlugin(Postgres.plugin()); + + JavaPlanBuilder planBuilder = new JavaPlanBuilder(wayangContext) + .withJobName("Hackathon smoke test (Postgres + Java + Spark)") + .withUdfJarOf(PostgresSmokeTest.class); + + Collection result = planBuilder + .readTable(new PostgresTableSource("word_counts_seed", "word", "count")) + .filter(record -> record.getInt(1) > 5) + .withTargetPlatform(Java.platform()) + .map(record -> record.getString(0).toUpperCase() + " -> " + record.getInt(1)) + .withTargetPlatform(Spark.platform()) + .collect(); + + System.out.println("Wayang plan executed across Postgres, Java, and Spark. Results:"); + result.forEach(System.out::println); + System.out.println("Total rows: " + result.size()); + + if (result.isEmpty()) { + throw new IllegalStateException( + "Connected and ran fine, but got zero rows back — check that init.sql actually ran " + + "(docker compose down -v to reset the postgres volume and retry)."); + } + } + + private static String envOrDefault(String key, String fallback) { + String value = System.getenv(key); + return (value == null || value.isEmpty()) ? fallback : value; + } +} diff --git a/hackathon-CoC2026/verify.sh b/hackathon-CoC2026/verify.sh new file mode 100644 index 000000000..578683206 --- /dev/null +++ b/hackathon-CoC2026/verify.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Run this from inside the wayang dev container: +# docker compose exec wayang bash hackathon-CoC2026/verify.sh +# +# Builds Wayang, extracts the distribution (which has both a jars/ and a +# libs/ directory), resolves the full Maven runtime classpath (needed +# because Spark's own runtime jars are NOT copied into the assembled +# distribution — only wayang-spark's own jar is), and compiles + runs +# PostgresSmokeTest.java against the combined classpath. + +set -euo pipefail +cd "$(dirname "$0")/.." # repo root +REPO_ROOT="$(pwd)" + +DIST_TARBALL="$(find wayang-assembly/target -maxdepth 1 -name 'apache-wayang-assembly-*.tar.gz' | head -n 1)" + +if [ -z "$DIST_TARBALL" ]; then + echo "==> Building wayang-assembly (first run can take significantly longer than" + echo " 15 minutes on a cold Maven cache — this is expected, see README.md)" + ./mvnw -q clean package -pl :wayang-assembly -Pdistribution -DskipTests -B + + DIST_TARBALL="$(find wayang-assembly/target -maxdepth 1 -name 'apache-wayang-assembly-*.tar.gz' | head -n 1)" +fi + +if [ -z "$DIST_TARBALL" ]; then + echo "Could not find apache-wayang-assembly-*.tar.gz under wayang-assembly/target/" >&2 + exit 1 +fi + +echo "==> Extracting $DIST_TARBALL" +tar -xzf "$DIST_TARBALL" -C wayang-assembly/target +DIST_DIR="$(find wayang-assembly/target -maxdepth 1 -type d -name 'wayang-*' | head -n 1)" +export WAYANG_HOME="$(cd "$DIST_DIR" && pwd)" +export PATH="$PATH:$WAYANG_HOME/bin" +echo "WAYANG_HOME=$WAYANG_HOME" +# Confirmed layout: $WAYANG_HOME/{bin,conf,jars,libs} + +echo "==> Verifying Java platform (bundled WordCount app)" +( cd "$WAYANG_HOME" && bin/wayang-submit org.apache.wayang.apps.wordcount.Main java "file://$REPO_ROOT/README.md" | tail -n 20 ) || true +# Uses bin/wayang-submit as-is: it already carries the Java 17 --add-opens/ +# --add-exports flags Spark needs, so this script does not duplicate that +# logic for this check — only for the direct `java` call below, which +# doesn't go through wayang-submit. + +if [ -s /tmp/wayang-classpath.txt ]; then + echo "==> Reusing the Maven classpath baked into this image at build time" +else + echo "==> Resolving the full Maven runtime classpath (covers Spark's transitive" + echo " dependencies, which live in the local Maven repo, not the distribution)" + ./mvnw -q -pl wayang-assembly dependency:build-classpath \ + -Dmdep.outputFile=/tmp/wayang-classpath.txt -B +fi +MAVEN_CP="$(cat /tmp/wayang-classpath.txt)" + +DIST_CP="$WAYANG_HOME/libs/*:$WAYANG_HOME/jars/*" +FULL_CP="${DIST_CP}:${MAVEN_CP}" + +echo "==> Reusing the Java 17 module flags already defined in wayang-submit" +JAVA17_FLAGS="$(grep -o -- '--add-\(opens\|exports\)=[^ "'"'"']*' "$WAYANG_HOME/bin/wayang-submit" | tr '\n' ' ')" + +echo "==> Compiling and running PostgresSmokeTest.java" +mkdir -p /tmp/hackathon-classes +javac -cp "$FULL_CP" -d /tmp/hackathon-classes "$REPO_ROOT/hackathon-CoC2026/examples/PostgresSmokeTest.java" +java $JAVA17_FLAGS -cp "$FULL_CP:/tmp/hackathon-classes" PostgresSmokeTest