diff --git a/README.md b/README.md
index 7c3157ea..c50fbbc3 100644
--- a/README.md
+++ b/README.md
@@ -199,10 +199,12 @@ Download the self-contained fat JAR for your Elasticsearch version:
| Elasticsearch Version | Artifact |
|-----------------------|----------------------------------------|
-| ES 6.x | `softclient4es6-jdbc-driver-0.2.0.jar` |
-| ES 7.x | `softclient4es7-jdbc-driver-0.2.0.jar` |
-| ES 8.x | `softclient4es8-jdbc-driver-0.2.0.jar` |
-| ES 9.x | `softclient4es9-jdbc-driver-0.2.0.jar` |
+| ES 6.x | `softclient4es6-jdbc-driver-0.2.1.jar` |
+| ES 7.x | `softclient4es7-jdbc-driver-0.2.1.jar` |
+| ES 8.x | `softclient4es8-jdbc-driver-0.2.1.jar` |
+| ES 9.x | `softclient4es9-jdbc-driver-0.2.1.jar` |
+
+> **Java 11+ recommended** (17+ for ES 9.x): **cross-index JOINs require Java 11+** — the embedded JOIN engine is built on Apache Arrow 18.x, which ships Java-11 bytecode.
```text
JDBC URL: jdbc:elastic://localhost:9200
@@ -217,20 +219,20 @@ Driver class: app.softnetwork.elastic.jdbc.ElasticDriver
app.softnetwork.elastic
softclient4es8-jdbc-driver
- 0.2.0
+ 0.2.1
```
**Gradle:**
```groovy
-implementation 'app.softnetwork.elastic:softclient4es8-jdbc-driver:0.2.0'
+implementation 'app.softnetwork.elastic:softclient4es8-jdbc-driver:0.2.1'
```
**sbt:**
```scala
-libraryDependencies += "app.softnetwork.elastic" % "softclient4es8-jdbc-driver" % "0.2.0"
+libraryDependencies += "app.softnetwork.elastic" % "softclient4es8-jdbc-driver" % "0.2.1"
```
The JDBC driver JARs are Scala-version-independent (no `_2.12` or `_2.13` suffix) and include all required dependencies.
@@ -309,6 +311,8 @@ For programmatic access, add SoftClient4ES to your project.
| 8.x | `softclient4es8-java-client` | 2.12, 2.13 | 8+ |
| 9.x | `softclient4es9-java-client` | 2.13 only | 17+ |
+> JDK versions above apply to the client libraries themselves. **Cross-index JOINs (via the arrow extensions, the JDBC/ADBC drivers) require Java 11+** — see [Cross-Index JOIN](documentation/sql/joins.md).
+
### sbt Setup
```scala
@@ -320,7 +324,7 @@ libraryDependencies += "app.softnetwork.elastic" %% "softclient4es8-java-client"
// Add the community extensions for materialized views (optional)
libraryDependencies += "app.softnetwork.elastic" %% "softclient4es-community-extensions" % "0.2.0"
// Add the JDBC driver if you want to use it from Scala (optional)
-libraryDependencies += "app.softnetwork.elastic" %% "softclient4es-jdbc-driver" % "0.2.0"
+libraryDependencies += "app.softnetwork.elastic" %% "softclient4es-jdbc-driver" % "0.2.1"
```
```scala
diff --git a/documentation/client/adbc_driver.md b/documentation/client/adbc_driver.md
index fd94abcf..f7466716 100644
--- a/documentation/client/adbc_driver.md
+++ b/documentation/client/adbc_driver.md
@@ -23,10 +23,10 @@ Download the self-contained fat JAR for your Elasticsearch version:
| Elasticsearch | Artifact |
|----------------|-----------------------------------------------------|
-| ES 6.x | `softclient4es6-adbc-driver-0.2.0.jar` |
-| ES 7.x | `softclient4es7-adbc-driver-0.2.0.jar` |
-| ES 8.x | `softclient4es8-adbc-driver-0.2.0.jar` |
-| ES 9.x | `softclient4es9-adbc-driver-0.2.0.jar` |
+| ES 6.x | `softclient4es6-adbc-driver-0.2.1.jar` |
+| ES 7.x | `softclient4es7-adbc-driver-0.2.1.jar` |
+| ES 8.x | `softclient4es8-adbc-driver-0.2.1.jar` |
+| ES 9.x | `softclient4es9-adbc-driver-0.2.1.jar` |
### Maven / Gradle / sbt
@@ -36,20 +36,20 @@ Download the self-contained fat JAR for your Elasticsearch version:
app.softnetwork.elastic
softclient4es8-adbc-driver
- 0.2.0
+ 0.2.1
```
**Gradle:**
```groovy
-implementation 'app.softnetwork.elastic:softclient4es8-adbc-driver:0.2.0'
+implementation 'app.softnetwork.elastic:softclient4es8-adbc-driver:0.2.1'
```
**sbt:**
```scala
-libraryDependencies += "app.softnetwork.elastic" % "softclient4es8-adbc-driver" % "0.2.0"
+libraryDependencies += "app.softnetwork.elastic" % "softclient4es8-adbc-driver" % "0.2.1"
```
---
diff --git a/documentation/client/arrow_flight_sql.md b/documentation/client/arrow_flight_sql.md
index 0edded62..b90d8dfb 100644
--- a/documentation/client/arrow_flight_sql.md
+++ b/documentation/client/arrow_flight_sql.md
@@ -49,15 +49,15 @@ Available images per ES version:
### Fat JAR
```bash
-java -jar softclient4es8-arrow-flight-sql-0.2.0.jar
+java -jar softclient4es8-arrow-flight-sql-0.2.1.jar
```
| Elasticsearch | Artifact |
|---------------|----------|
-| ES 6.x | `softclient4es6-arrow-flight-sql-0.2.0.jar` |
-| ES 7.x | `softclient4es7-arrow-flight-sql-0.2.0.jar` |
-| ES 8.x | `softclient4es8-arrow-flight-sql-0.2.0.jar` |
-| ES 9.x | `softclient4es9-arrow-flight-sql-0.2.0.jar` |
+| ES 6.x | `softclient4es6-arrow-flight-sql-0.2.1.jar` |
+| ES 7.x | `softclient4es7-arrow-flight-sql-0.2.1.jar` |
+| ES 8.x | `softclient4es8-arrow-flight-sql-0.2.1.jar` |
+| ES 9.x | `softclient4es9-arrow-flight-sql-0.2.1.jar` |
---
diff --git a/documentation/client/download_analytics.md b/documentation/client/download_analytics.md
index 8b20bb08..37e7eaa8 100644
--- a/documentation/client/download_analytics.md
+++ b/documentation/client/download_analytics.md
@@ -15,7 +15,7 @@ beacon to a public endpoint with exactly these fields:
|---------------|----------|-----------------------------------------------|
| `source` | `portal` | Where the count came from (the docs button) |
| `driver` | `jdbc` | Which driver family (`jdbc` or `adbc`) |
-| `version` | `0.2.0` | The published artifact version |
+| `version` | `0.2.1` | The published artifact version |
| `count_delta` | `1` | One download |
A timestamp is added on the server. That is the **entire** record.
diff --git a/documentation/client/jdbc.md b/documentation/client/jdbc.md
index 6599aaba..a6504385 100644
--- a/documentation/client/jdbc.md
+++ b/documentation/client/jdbc.md
@@ -20,10 +20,10 @@ Download the self-contained fat JAR for your Elasticsearch version. The JARs are
| Elasticsearch | Artifact |
|---------------|----------|
-| ES 6.x | `softclient4es6-jdbc-driver-0.2.0.jar` |
-| ES 7.x | `softclient4es7-jdbc-driver-0.2.0.jar` |
-| ES 8.x | `softclient4es8-jdbc-driver-0.2.0.jar` |
-| ES 9.x | `softclient4es9-jdbc-driver-0.2.0.jar` |
+| ES 6.x | `softclient4es6-jdbc-driver-0.2.1.jar` |
+| ES 7.x | `softclient4es7-jdbc-driver-0.2.1.jar` |
+| ES 8.x | `softclient4es8-jdbc-driver-0.2.1.jar` |
+| ES 9.x | `softclient4es9-jdbc-driver-0.2.1.jar` |
### Build Tool Integration
@@ -33,20 +33,20 @@ Download the self-contained fat JAR for your Elasticsearch version. The JARs are
app.softnetwork.elastic
softclient4es8-jdbc-driver
- 0.2.0
+ 0.2.1
```
**Gradle:**
```groovy
-implementation 'app.softnetwork.elastic:softclient4es8-jdbc-driver:0.2.0'
+implementation 'app.softnetwork.elastic:softclient4es8-jdbc-driver:0.2.1'
```
**sbt:**
```scala
-libraryDependencies += "app.softnetwork.elastic" % "softclient4es8-jdbc-driver" % "0.2.0"
+libraryDependencies += "app.softnetwork.elastic" % "softclient4es8-jdbc-driver" % "0.2.1"
```
---
diff --git a/documentation/client/repl.md b/documentation/client/repl.md
index 53439b87..c90e2383 100644
--- a/documentation/client/repl.md
+++ b/documentation/client/repl.md
@@ -42,11 +42,15 @@ It provides:
| Elasticsearch Version | Minimum Java Version |
|-----------------------|----------------------|
-| ES 6 | Java 8+ |
-| ES 7 | Java 8+ |
-| ES 8 | Java 8+ |
+| ES 6 | Java 11+ |
+| ES 7 | Java 11+ |
+| ES 8 | Java 11+ |
| ES 9 | Java 17+ |
+> The 0.20+ REPL requires **Java 11+** on every ES version: the CLI bundles logback
+> 1.5.x and the JOIN engine is built on Apache Arrow 18.x — both ship Java-11
+> bytecode. See [Extensions](#extensions-cross-index-joins-materialized-views).
+
### Network Requirements
- Network access to JFrog repository (`softnetwork.jfrog.io`)
@@ -60,13 +64,13 @@ It provides:
#### Linux / macOS
```bash
-curl -fsSL https://raw.githubusercontent.com/SOFTNETWORK-APP/softclient4es/main/install.sh | bash
+curl -fsSL https://raw.githubusercontent.com/SOFTNETWORK-APP/SoftClient4ES/main/install.sh | bash
```
Or download and run manually:
```bash
-curl -O https://raw.githubusercontent.com/SOFTNETWORK-APP/softclient4es/main/install.sh
+curl -O https://raw.githubusercontent.com/SOFTNETWORK-APP/SoftClient4ES/main/install.sh
chmod +x install.sh
./install.sh
```
@@ -74,13 +78,13 @@ chmod +x install.sh
#### Windows (PowerShell)
```powershell
-irm https://raw.githubusercontent.com/SOFTNETWORK-APP/softclient4es/main/install.ps1 | iex
+irm https://raw.githubusercontent.com/SOFTNETWORK-APP/SoftClient4ES/main/install.ps1 | iex
```
Or download and run manually:
```powershell
-Invoke-WebRequest -Uri https://raw.githubusercontent.com/SOFTNETWORK-APP/softclient4es/main/install.ps1 -OutFile install.ps1
+Invoke-WebRequest -Uri https://raw.githubusercontent.com/SOFTNETWORK-APP/SoftClient4ES/main/install.ps1 -OutFile install.ps1
.\install.ps1
```
@@ -193,7 +197,8 @@ softclient4es/
│ ├── application.conf # Application configuration
│ └── logback.xml # Logging configuration
├── lib/
-│ └── softclient4es8-cli_2.13-x.y.z-assembly.jar
+│ ├── softclient4es8-cli_2.13-x.y.z-assembly.jar
+│ └── ... # extension jars + their dependencies (see Extensions)
├── logs/ # Log files directory
│ └── softclient4es.log # (created at runtime)
├── LICENSE
@@ -202,6 +207,51 @@ softclient4es/
└── uninstall.sh
```
+### Extensions (cross-index JOINs, materialized views)
+
+Cross-index `JOIN`s and materialized views are delivered as **extensions** — separate
+jars discovered on the classpath through the `ExtensionSpi` ServiceLoader mechanism:
+
+- `softclient4es-arrow-extensions` — the cross-index JOIN engine (**required for
+ `SELECT … JOIN` across indices** — the same engine the JDBC driver embeds)
+- `softclient4es-community-extensions` — materialized views and quota enforcement
+
+**The installer sets these up by default** — no manual step:
+
+- **community extensions**: always installed — any engine version (matching 0.1.x line
+ for engines < 0.20)
+- **arrow extensions**: installed for engines ≥ 0.20 (requires Java 11+, like the
+ 0.20+ CLI itself — Apache Arrow 18.x ships Java-11 bytecode)
+
+Each extension is resolved **with its full dependency closure** (Apache Arrow, DuckDB,
+…; ~250 jars) via a bundled [coursier](https://get-coursier.io) resolver into `lib/`.
+The launcher runs the REPL with `java -cp ":lib/*"`, so every jar in `lib/`
+is visible.
+
+To skip them:
+
+```bash
+./install.sh --no-extensions # minimal install — JOINs and MVs unavailable
+```
+
+**Manual installation on an existing install** (or air-gapped preparation):
+
+```bash
+# Resolve each extension with all its dependencies into lib/
+cs fetch --repository https://softnetwork.jfrog.io/artifactory/releases \
+ "app.softnetwork.elastic:softclient4es-arrow-extensions_2.13:" \
+ "app.softnetwork.elastic:softclient4es-community-extensions_2.13:" \
+ | xargs -I{} cp {} ~/softclient4es/lib/
+```
+
+> ⚠️ **Copying only the two extension jars into `lib/` is NOT enough** — they are thin
+> jars whose engine (Arrow memory, DuckDB, Flight) arrives transitively. Always resolve
+> the full dependency closure as above. Installations made with an installer older than
+> the 0.20 line launched the REPL with `java -jar`, which ignores `lib/` entirely —
+> re-run the installer to get the classpath-based launcher.
+
+The launcher adds the required Arrow `--add-opens` flags automatically on Java 9+.
+
### Add to PATH
#### Linux / macOS
diff --git a/documentation/sql/joins.md b/documentation/sql/joins.md
index fbca93b7..08bd8f9a 100644
--- a/documentation/sql/joins.md
+++ b/documentation/sql/joins.md
@@ -7,6 +7,8 @@ Elasticsearch has no native cross-index JOIN — and a stock JDBC driver on top
1. **Query-time cross-index JOIN** — `INNER` / `LEFT` / `RIGHT` / `FULL OUTER` joins across indices (and across clusters), at query time, on **every** surface: the REPL, the JDBC driver, the ADBC driver, the Arrow Flight SQL sidecar, and Federation. The drivers are the **free delivery channel**; the JOIN *depth* is metered.
2. **Persisted [Materialized Views](materialized_views.md)** — the other superpower: denormalize cross-index data once into a queryable view. (That has its own page; this page is about query-time JOINs.)
+> **Runtime requirement — Java 11+.** The JOIN engine is built on Apache Arrow 18.x, which ships Java-11 bytecode, and the 0.20+ REPL/driver line also bundles logback 1.5.x (Java-11 as well). Every JVM-side surface (the REPL, the JDBC/ADBC drivers) requires **Java 11 or newer** at runtime (17+ for ES 9); the Flight SQL and Federation Docker images bundle their own Java 17. In the REPL, the installer sets the extensions up for you (see the [REPL Extensions section](../client/repl.md#extensions-cross-index-joins-materialized-views)).
+
## The JOIN ladder
Three meters gate how far a JOIN can reach. Think of them as rungs:
diff --git a/install.ps1 b/install.ps1
index 9046dd21..d5a7f3ae 100644
--- a/install.ps1
+++ b/install.ps1
@@ -50,7 +50,7 @@ Examples:
.\install.ps1
.\install.ps1 -ListVersions -EsVersion 8
.\install.ps1 -Target "C:\tools\softclient4es" -EsVersion 8 -Version 1.0.0
- .\install.ps1 -EsVersion 7 -Version 0.2.0
+ .\install.ps1 -EsVersion 7 -Version 0.20.0
"@
exit 0
diff --git a/install.sh b/install.sh
index 8b25ee18..2ba51005 100755
--- a/install.sh
+++ b/install.sh
@@ -142,17 +142,24 @@ Options:
-v, --version SoftClient4ES version (default: latest)
-s, --scala Scala version (default: $DEFAULT_SCALA_VERSION)
-l, --list-versions List available versions for the specified ES version
+ --no-extensions Skip the extensions (cross-index JOINs, materialized views)
-h, --help Show this help message
+Extensions (installed by default, with all their dependencies):
+ - community extensions (materialized views): always — any engine version, Java 8+
+ - arrow extensions (cross-index JOINs): engine >= 0.20; requires Java 11+
+ (Apache Arrow constraint)
+ Use --no-extensions for a minimal install.
+
Java Requirements:
- ES 6, 7, 8 → Java 8 or higher
+ ES 6, 7, 8 → Java 11 or higher (the 0.20+ CLI bundles logback 1.5.x = Java-11 bytecode)
ES 9 → Java 17 or higher
Examples:
$0
$0 --list-versions --es-version 8
$0 --target /opt/softclient4es --es-version 8 --version 0.16-SNAPSHOT
- $0 -t ~/tools/softclient4es -e 7 -v 0.2.0
+ $0 -t ~/tools/softclient4es -e 7 -v 0.20.0
Detected OS: $OS_TYPE
@@ -169,6 +176,7 @@ ES_VERSION="$DEFAULT_ES_VERSION"
SOFT_VERSION="$DEFAULT_SOFT_VERSION"
SCALA_VERSION="$DEFAULT_SCALA_VERSION"
LIST_VERSIONS=false
+WITH_EXTENSIONS=true
while [[ $# -gt 0 ]]; do
case $1 in
@@ -192,6 +200,14 @@ while [[ $# -gt 0 ]]; do
LIST_VERSIONS=true
shift
;;
+ --no-extensions)
+ WITH_EXTENSIONS=false
+ shift
+ ;;
+ --extensions)
+ WITH_EXTENSIONS=true
+ shift
+ ;;
-h|--help)
show_help
;;
@@ -226,7 +242,10 @@ get_required_java_version() {
if [[ "$es_ver" == "9" ]]; then
echo 17
else
- echo 8
+ # The 0.20+ CLI bundles logback 1.5.x (Java-11 bytecode): the REPL
+ # does not start on Java 8 — verified empirically (--help crashes
+ # with UnsupportedClassVersionError on Zulu 8).
+ echo 11
fi
}
@@ -237,7 +256,8 @@ REQUIRED_JAVA_VERSION=$(get_required_java_version "$ES_VERSION")
# =============================================================================
fetch_versions() {
- local api_url="${JFROG_API_URL}/${ARTIFACT_NAME}"
+ local artifact="${1:-$ARTIFACT_NAME}"
+ local api_url="${JFROG_API_URL}/${artifact}"
local response=""
if command -v curl &> /dev/null; then
@@ -481,6 +501,118 @@ download_jar() {
success "Downloaded to $dest"
}
+# =============================================================================
+# Install Extensions (cross-index JOINs, materialized views)
+# =============================================================================
+
+# The engine assembly is launched via classpath (bin/softclient4es uses -cp
+# "lib/*"), so extension jars dropped into lib/ are discovered through the
+# ServiceLoader SPI. The extensions are thin jars: their full dependency
+# closure (Apache Arrow, DuckDB, ...) must be resolved too — a couple of jars
+# is NOT enough. We bootstrap the coursier launcher (a single portable jar
+# that runs with the already-required java) to resolve everything.
+
+COURSIER_URL="https://github.com/coursier/launchers/raw/master/coursier"
+JFROG_ROOT_URL="https://softnetwork.jfrog.io/artifactory/releases"
+EXTENSIONS_INSTALLED="none"
+
+# version_ge A B — true if version A >= version B
+version_ge() {
+ [[ "$(printf '%s\n%s\n' "$2" "$1" | sort_versions | head -1)" == "$2" ]]
+}
+
+# Resolve one extension (with its full dependency closure) into lib/.
+# $1 = artifact base name (without scala suffix), $2 = version
+install_one_extension() {
+ local ext="$1"
+ local ver="$2"
+ local artifact="${ext}_${SCALA_VERSION}"
+ local cs="$TARGET_DIR/bin/.coursier"
+ local jars jar base_jar count
+
+ info "Resolving ${artifact}:${ver} with all dependencies..."
+ if ! jars=$("$cs" fetch --repository "$JFROG_ROOT_URL" "app.softnetwork.elastic:${artifact}:${ver}" 2>/dev/null); then
+ warn "Dependency resolution failed for $artifact — skipping"
+ return 1
+ fi
+
+ count=0
+ while IFS= read -r jar; do
+ [[ -f "$jar" ]] || continue
+ base_jar=$(basename "$jar")
+ if [[ ! -f "$TARGET_DIR/lib/$base_jar" ]]; then
+ cp "$jar" "$TARGET_DIR/lib/$base_jar"
+ (( ++count )) || true
+ fi
+ done <<< "$jars"
+
+ success "Installed ${artifact}:${ver} ($count jar(s) added to lib/)"
+ if [[ "$EXTENSIONS_INSTALLED" == "none" ]]; then
+ EXTENSIONS_INSTALLED="${ext}:${ver}"
+ else
+ EXTENSIONS_INSTALLED="$EXTENSIONS_INSTALLED ${ext}:${ver}"
+ fi
+ return 0
+}
+
+install_extensions() {
+ if [[ "$WITH_EXTENSIONS" != true ]]; then
+ info "Skipping extensions (--no-extensions)"
+ return 0
+ fi
+
+ info "Installing extensions (materialized views + cross-index JOINs)..."
+
+ local cs="$TARGET_DIR/bin/.coursier"
+ if [[ ! -x "$cs" ]]; then
+ if ! download_file "$COURSIER_URL" "$cs" "coursier resolver"; then
+ warn "Could not download the coursier resolver — extensions skipped."
+ warn "Manual install: https://github.com/SOFTNETWORK-APP/SoftClient4ES/blob/main/documentation/client/repl.md"
+ return 0
+ fi
+ chmod +x "$cs"
+ fi
+
+ local java_version
+ java_version=$(get_java_version)
+
+ # ── Community extensions (materialized views) — ALWAYS installed by default.
+ # No Arrow dependency, runs on Java 8+. For engines < 0.20 the matching
+ # 0.1.x line is selected; for >= 0.20 the latest release.
+ local community_ver
+ if version_ge "$SOFT_VERSION" "0.20"; then
+ community_ver=$(fetch_versions "softclient4es-community-extensions_${SCALA_VERSION}" | grep -v 'SNAPSHOT' | tail -1)
+ else
+ community_ver=$(fetch_versions "softclient4es-community-extensions_${SCALA_VERSION}" | grep -v 'SNAPSHOT' | grep '^0\.1\.' | tail -1)
+ fi
+ if [[ -n "$community_ver" ]]; then
+ install_one_extension "softclient4es-community-extensions" "$community_ver" || true
+ else
+ warn "Could not resolve a community-extensions release for engine $SOFT_VERSION — skipping"
+ fi
+
+ # ── Arrow extensions (cross-index JOINs) — default for engines >= 0.20.
+ # Hard runtime constraint: Apache Arrow 18.x ships Java-11 bytecode
+ # (class file major 55) — on Java 8 the JOIN engine cannot load.
+ if ! version_ge "$SOFT_VERSION" "0.20"; then
+ info "Cross-index JOIN extension requires SoftClient4ES >= 0.20 (installing $SOFT_VERSION) — skipping"
+ return 0
+ fi
+ if [[ -n "$java_version" ]] && [[ "$java_version" -lt 11 ]]; then
+ warn "Cross-index JOINs require Java 11+ (Apache Arrow constraint) — found Java $java_version."
+ warn "Materialized views remain available; re-run the installer on Java 11+ to enable JOINs."
+ return 0
+ fi
+
+ local arrow_ver
+ arrow_ver=$(fetch_versions "softclient4es-arrow-extensions_${SCALA_VERSION}" | grep -v 'SNAPSHOT' | tail -1)
+ if [[ -n "$arrow_ver" ]]; then
+ install_one_extension "softclient4es-arrow-extensions" "$arrow_ver" || true
+ else
+ warn "Could not resolve an arrow-extensions release — skipping"
+ fi
+}
+
# =============================================================================
# Download Documentation and License
# =============================================================================
@@ -645,6 +777,8 @@ check_java() {
echo "Error: Java \$REQUIRED_JAVA+ is required. Found: Java \$java_version" >&2
exit 1
fi
+
+ JAVA_MAJOR="\$java_version"
}
check_java
@@ -652,17 +786,27 @@ check_java
# Default JVM options
JAVA_OPTS="\${JAVA_OPTS:--Xmx512m}"
+# The extensions (Apache Arrow / DuckDB) need reflective access on Java 9+
+EXTRA_OPTS=""
+if [[ -n "\$JAVA_MAJOR" ]] && [[ "\$JAVA_MAJOR" -ge 9 ]]; then
+ EXTRA_OPTS="--add-opens=java.base/java.nio=ALL-UNNAMED -Dio.netty.tryReflectionSetAccessible=true"
+fi
+
# Logback configuration
LOGBACK_OPTS=""
if [[ -f "\$LOGBACK_FILE" ]]; then
LOGBACK_OPTS="-Dlogback.configurationFile=\$LOGBACK_FILE"
fi
-exec java \$JAVA_OPTS \\
+# The engine assembly comes first on the classpath so it wins any conflict;
+# lib/* brings the extension jars, discovered via the ServiceLoader SPI.
+# (java -jar would ignore the classpath entirely — do not switch back.)
+exec java \$JAVA_OPTS \$EXTRA_OPTS \\
-Dconfig.file="\$CONFIG_FILE" \\
-Dlog.dir="\$LOG_DIR" \\
\$LOGBACK_OPTS \\
- -jar "\$JAR_FILE" \\
+ -cp "\$JAR_FILE:\$BASE_DIR/lib/*" \\
+ app.softnetwork.elastic.client.Cli \\
"\$@"
LAUNCHER_EOF
@@ -770,6 +914,7 @@ Version: $SOFT_VERSION
Scala: $SCALA_VERSION
Java Required: $REQUIRED_JAVA_VERSION+
Artifact: $ARTIFACT_NAME
+Extensions: $EXTENSIONS_INSTALLED
OS: $OS_TYPE
EOF
@@ -800,7 +945,12 @@ print_summary() {
echo " │ ├── application.conf"
echo " │ └── logback.xml"
echo " ├── lib/"
- echo " │ └── $JAR_NAME"
+ echo " │ ├── $JAR_NAME"
+ if [[ "$EXTENSIONS_INSTALLED" != "none" ]]; then
+ echo " │ └── (+ extension jars: $EXTENSIONS_INSTALLED)"
+ else
+ echo " │ └── (no extensions installed)"
+ fi
echo " ├── logs/"
echo " │ └── softclient4es.log (created at runtime)"
echo " ├── LICENSE"
@@ -876,6 +1026,7 @@ main() {
echo ""
create_directories
download_jar
+ install_extensions
download_docs
create_config
create_logback_config