This is an automated email from the ASF dual-hosted git repository.
Cole-Greer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/master by this push:
new 982ee6e65d Support Java 21/25 and Spark 4.1, raise minimum to Java 17
(#3489)
982ee6e65d is described below
commit 982ee6e65df9d6e5e699d784261286791181e0c2
Author: Oleksandr Porunov <[email protected]>
AuthorDate: Thu Jul 9 05:52:51 2026 +0100
Support Java 21/25 and Spark 4.1, raise minimum to Java 17 (#3489)
Modernizes TinkerPop 4.0 to build and run on Java 21 and Java 25 and
upgrades
the Spark OLAP integration to Spark 4.1. Because Spark 4 requires Java 17
as a
minimum, the project-wide minimum Java version is raised from 11 to 17.
Every
LTS release from the new minimum upward (17, 21, 25) is covered by CI.
Java 21/25 support:
- Groovy 4.0.25 -> 4.0.32 (bundled ASM parses Java 25 bytecode)
- StringFactory: detect the Java 21+ lambda class name format ($$Lambda/)
- LambdaRestrictionStrategy: match "lambda" case-insensitively
- ImportGremlinPluginTest: account for Math.TAU added in Java 19
- gremlin-groovy: declare annotationProcessorPaths explicitly (JDK 23+ no
longer runs classpath-discovered processors) and widen the javadoc
groovy-stubs profile to all supported JDKs
- gremlin-console: apply the neo4j-gremlin --add-opens flags for JDK 17+
Dependency upgrades:
- Hadoop 3.4.2 -> 3.4.3 (uses the Subject.current()/callAs() replacement
APIs)
- Spark 3.5.4 -> 4.1.2, which is Scala 2.13 only, the first Spark line to
support Java 25, and the second to support Java 21 (SPARK-43831 landed in
4.0): spark-core_2.12 -> _2.13, Scala 2.13 source migration
(JavaConversions -> CollectionConverters, WrappedArray -> immutable
ArraySeq), and aligned Netty, jackson (via jackson-bom) and other
transitive
versions that Spark 4 requires
- Netty 4.1.125 -> 4.2.7 (required by Spark 4)
Java 17 baseline (breaking):
- enforcer requireJavaVersion [11,18) -> [17,26); compiler release 11 -> 17
(and gremlin-groovy/gremlin-annotations release 8 -> 17)
- build-test.yml: all jobs run on Java 17, plus new Java 21 and Java 25
jobs;
the Java 11 job is removed and coverage runs on the Java 17 job
- Dockerfiles updated to Java 17; developer, reference, and upgrade docs
list
Java 17 as the minimum with Java 21 and 25 supported
Integration-test fixes for the Java 17 baseline (deep reflection into
java.base
is denied by default on Java 17, and TLS 1.3 is the default):
- gremlin-server.sh: append the jdk17 --add-opens/--add-exports set to
JAVA_OPTIONS so the standalone/Docker server can perform the deep
reflection
Kryo/Gryo needs
- GremlinServerSslIntegrateTest: accept the alerts Java 17's TLS 1.3 raises
for
a missing/untrusted client certificate
- gremlin-socket-server and gremlin-console test Docker images use Java 17
Assisted-by: claude-opus-4.8
---
.github/workflows/build-test.yml | 80 +++++++++++++---------
CHANGELOG.asciidoc | 3 +
docker/Dockerfile | 4 +-
.../dev/developer/development-environment.asciidoc | 9 +--
docs/src/reference/gremlin-variants.asciidoc | 1 +
docs/src/upgrade/release-4.x.x.asciidoc | 14 ++++
gremlin-annotations/pom.xml | 6 +-
gremlin-console/Dockerfile | 2 +-
gremlin-console/pom.xml | 4 +-
gremlin-console/src/main/bin/gremlin.sh | 5 +-
gremlin-console/src/test/python/docker/Dockerfile | 2 +-
.../verification/LambdaRestrictionStrategy.java | 2 +-
.../gremlin/structure/util/StringFactory.java | 3 +-
.../gremlin/jsr223/ImportGremlinPluginTest.java | 11 ++-
gremlin-groovy/pom.xml | 46 +++++++++++--
gremlin-server/Dockerfile | 2 +-
gremlin-server/src/main/bin/gremlin-server.sh | 19 +++++
.../server/GremlinServerSslIntegrateTest.java | 18 +++--
gremlin-tools/gremlin-socket-server/Dockerfile | 2 +-
pom.xml | 24 +++----
spark-gremlin/pom.xml | 49 ++++++++++---
.../tinkerpop/gremlin/spark/structure/Spark.java | 4 +-
.../spark/structure/io/gryo/GryoRegistrator.java | 4 +-
.../spark/structure/io/gryo/GryoSerializer.java | 4 +-
.../structure/io/gryo/WrappedArraySerializer.java | 21 +++---
.../gremlin/spark/structure/SparkTest.java | 6 +-
26 files changed, 242 insertions(+), 103 deletions(-)
diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml
index 0f8f7aecad..30ffc51ac3 100644
--- a/.github/workflows/build-test.yml
+++ b/.github/workflows/build-test.yml
@@ -20,10 +20,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Build with Maven
run: mvn clean install -DskipTests -Dci --batch-mode
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
@@ -40,25 +40,39 @@ jobs:
java-version: '17'
distribution: 'temurin'
- name: Build with Maven
- run: mvn clean install -pl $EXCLUDE_MODULES -Dci --batch-mode
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
- java-jdk11:
- name: mvn clean install - jdk11
+ run: mvn clean install -pl $EXCLUDE_MODULES -Dci --batch-mode
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
-Dcoverage
+ - name: Upload to Codecov
+ uses: codecov/codecov-action@v7
+ with:
+ directory: ./gremlin-tools/gremlin-coverage/target/site
+ java-jdk21:
+ name: mvn clean install - jdk21
timeout-minutes: 45
needs: smoke
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 21
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '21'
distribution: 'temurin'
- name: Build with Maven
- run: mvn clean install -pl $EXCLUDE_MODULES -Dci --batch-mode
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
-Dcoverage
- - name: Upload to Codecov
- uses: codecov/codecov-action@v7
+ run: mvn clean install -pl $EXCLUDE_MODULES -Dci --batch-mode
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
+ java-jdk25:
+ name: mvn clean install - jdk25
+ timeout-minutes: 45
+ needs: smoke
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v7
+ - name: Set up JDK 25
+ uses: actions/setup-java@v5
with:
- directory: ./gremlin-tools/gremlin-coverage/target/site
+ java-version: '25'
+ distribution: 'temurin'
+ - name: Build with Maven
+ run: mvn clean install -pl $EXCLUDE_MODULES -Dci --batch-mode
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
gremlin-server-default:
name: gremlin-server default
timeout-minutes: 45
@@ -66,10 +80,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Build with Maven
run: |
@@ -82,10 +96,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Generate Gremlin Server Base
working-directory: .
@@ -118,10 +132,10 @@ jobs:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v7
-# - name: Set up JDK 11
+# - name: Set up JDK 17
# uses: actions/setup-java@v5
# with:
-# java-version: '11'
+# java-version: '17'
# distribution: 'temurin'
# - name: Build with Maven
# run: |
@@ -134,10 +148,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Build with Maven
run: |
@@ -153,10 +167,10 @@ jobs:
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Build with Maven Windows
if: runner.os == 'Windows'
@@ -177,10 +191,10 @@ jobs:
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Build with Maven Windows
if: runner.os == 'Windows'
@@ -198,10 +212,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Build with Maven
run: |
@@ -215,10 +229,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Build with Maven
run: |
@@ -235,10 +249,10 @@ jobs:
node-version: [ '22', '24', '26' ]
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Get Cached Server Base Image
uses: actions/cache@v6
@@ -269,10 +283,10 @@ jobs:
PYTHON_VERSION: ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
@@ -291,10 +305,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- - name: Set up JDK11
+ - name: Set up JDK17
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: '17'
distribution: 'temurin'
- name: Set up .NET 8.0.x
uses: actions/setup-dotnet@v5
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 9632d16aee..8bb8aacf59 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,6 +25,9 @@
image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
[[release-4-0-0]]
=== TinkerPop 4.0.0 (Release Date: NOT OFFICIALLY RELEASED YET)
+* Raised the minimum Java version to 17 for building and running *(breaking)*.
+* Enabled building and running with Java 21 and Java 25.
+* Bumped Groovy to 4.0.32, Hadoop to 3.4.3, Spark to 4.1.2 (Scala 2.13), and
Netty to 4.2.7 to support Java 25.
* Standardized connection options across all GLVs (Java, Python, .NET, Go,
JavaScript) per the TinkerPop 4.x GLV proposal; see the upgrade docs for the
full per-driver table. *(breaking)*
** Aligned option names across drivers: `maxConnections` (128),
`connectTimeoutMillis` (5000), `readTimeoutMillis` (off), `idleTimeoutMillis`
(180000), `keepAliveTimeMillis` (30000), `compression` (on/`deflate`),
`batchSize` (64), `bulkResults` (false), `maxResponseHeaderBytes`, `proxy`, and
`ssl`. Timeouts use a millisecond-suffixed canonical name with an idiomatic
duration companion (Java `Duration`, Go `time.Duration`, .NET `TimeSpan`,
Python seconds); JavaScript uses milliseconds only.
** Java: renamed
`maxConnectionPoolSize`/`connectionSetupTimeoutMillis`/`idleConnectionTimeoutMillis`/`resultIterationBatchSize`
and `RequestOptions.addG`->`traversalSource`; removed
`maxResponseContentLength` (responses now stream); added `readTimeoutMillis`,
`keepAliveTimeMillis`, `maxResponseHeaderBytes`, `proxy`, `url(String)`,
`ssl(SslContext)`. *(breaking)*
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 66a375384b..921c80ee68 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -29,7 +29,7 @@ RUN apt-get install apt-transport-https gnupg ca-certificates
RUN sh -c 'echo "deb https://download.mono-project.com/repo/ubuntu
stable-focal main" | tee /etc/apt/sources.list.d/mono-official-stable.list'
RUN apt-get update
-RUN apt-get install -y openjdk-11-jdk gawk git maven openssh-server subversion
zip
+RUN apt-get install -y openjdk-17-jdk gawk git maven openssh-server subversion
zip
RUN apt-get install -y --force-yes dotnet-sdk-8.0 mono-devel
ENV DEBIAN_FRONTEND=noninteractive
@@ -43,7 +43,7 @@ RUN python3 -m pip install --upgrade pip
RUN pip install virtualenv
RUN pip install virtualenvwrapper --no-deps
-RUN rm -rf /var/lib/apt/lists/* /var/cache/openjdk-11-jdk
+RUN rm -rf /var/lib/apt/lists/* /var/cache/openjdk-17-jdk
RUN sed -i 's@PermitRootLogin without-password@PermitRootLogin yes@'
/etc/ssh/sshd_config
RUN sed -i 's@session\s*required\s*pam_loginuid.so@session optional
pam_loginuuid.so@g' /etc/pam.d/sshd
diff --git a/docs/src/dev/developer/development-environment.asciidoc
b/docs/src/dev/developer/development-environment.asciidoc
index e0a9559218..c7748ac728 100644
--- a/docs/src/dev/developer/development-environment.asciidoc
+++ b/docs/src/dev/developer/development-environment.asciidoc
@@ -28,8 +28,9 @@ image:conspiracy.png[]
[[system-configuration]]
== System Configuration
-At a minimum, development of TinkerPop requires
link:https://openjdk.java.net/projects/jdk/11/[Java 11] or
-link:https://openjdk.org/projects/jdk/17/[Java 17]. Note, however, that there
are some issues with deep reflection
+At a minimum, development of TinkerPop requires
link:https://openjdk.org/projects/jdk/17/[Java 17]; builds and tests
+also run on link:https://openjdk.org/projects/jdk/21/[Java 21] and
link:https://openjdk.org/projects/jdk/25/[Java 25].
+Note, however, that there are some issues with deep reflection
so there are `--add-opens` JVM options included in the pom files to enable
this to work. Maven (requiring a minimum of
link:https://maven.apache.org/download.cgi[Maven 3.5.3+]) is used as the
common build system, which even
controls the builds of non-JVM
link:https://tinkerpop.apache.org/docs/x.y.z/reference/#gremlin-drivers-variants[GLVs]
@@ -47,7 +48,7 @@ system. You will need to install both
link:https://docs.docker.com/engine/instal
link:https://docs.docker.com/compose/install/[Docker Compose], which are
included in
link:https://docs.docker.com/desktop/[Docker Desktop].
-IMPORTANT: Use Java 11 for documentation generation with `bin/process-docs.sh`
and for other build features outside
+IMPORTANT: Use Java 17 for documentation generation with `bin/process-docs.sh`
and for other build features outside
of the basic `mvn clean install` sort of function.
IMPORTANT: For those who intend to offer a contribution, building with a
minimal configuration may not be sufficient
@@ -124,7 +125,7 @@ The core of the documentation generation process is an
link:https://asciidoctor.
Gremlin Console subprocess, and renders the console output as tabbed HTML. The
orchestration script
`bin/process-docs.sh` wraps this and acts as the entrypoint: it validates the
Gremlin Console and Gremlin Server
distributions, installs the required plugins into the console, starts a
Gremlin Server (for the `:remote` examples) and
-a Gephi mock, then invokes Maven to run the extension. Javadocs should be
built using Java 11.
+a Gephi mock, then invokes Maven to run the extension. Javadocs should be
built using Java 17.
Before generating documentation, build the build all of the dependencies that
the process consumes:
diff --git a/docs/src/reference/gremlin-variants.asciidoc
b/docs/src/reference/gremlin-variants.asciidoc
index 4e90afdcf6..22e21adabc 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -902,6 +902,7 @@ The following table outlines recommended runtime versions
by the release in whic
|3.6.0 | Java 8, 11
|3.7.0 | Java 8, 11, 17
|3.8.0 | Java 11, 17
+|4.0.0 | Java 17, 21, 25
|===
[[gremlin-java-connecting]]
diff --git a/docs/src/upgrade/release-4.x.x.asciidoc
b/docs/src/upgrade/release-4.x.x.asciidoc
index 1118cf3fc9..96ded966ba 100644
--- a/docs/src/upgrade/release-4.x.x.asciidoc
+++ b/docs/src/upgrade/release-4.x.x.asciidoc
@@ -106,6 +106,20 @@ These change runtime behavior on upgrade even if you do
not change your configur
See:
link:https://lists.apache.org/thread/yqtr2wnb1kq2pqqq4002cz511q5o0bkg[[DISCUSS]
Standardizing GLV connection options in TinkerPop 4].
+==== Java 17 Required; Java 21 and 25 Supported
+
+TinkerPop 4.0 raises the minimum Java version from 11 to 17 for both building
and running, and adds support for running
+on Java 21 and Java 25, so that every LTS release from the new minimum upward
is covered by TinkerPop's automated
+tests. *(breaking)* Supporting Java 25 required upgrading Groovy to 4.0.32
(whose bundled ASM can parse Java 25
+bytecode) and Hadoop to 3.4.3 (which moved off the `Subject.getSubject()` API
that was removed along with the Security
+Manager). Spark was upgraded to 4.1.x, built on Scala 2.13 — the first Spark
line that supports Java 25. Because Spark 4
+requires Java 17 as its minimum, and `spark-gremlin` is part of the build, the
project-wide minimum is now Java 17.
+Netty was upgraded to 4.2.x as required by Spark 4.
+
+As with the earlier JDK 17 support, some libraries still rely on deep
reflection (most notably the Kryo serialization
+library used with OLAP), so it may be necessary to `--add-opens` or
`--add-exports` certain modules at runtime. The set
+of options used by TinkerPop's own tests is unchanged.
+
==== Declarative Pattern Matching
Gremlin has always offered both imperative and declarative styles to writing
graph queries. While the imperative style
diff --git a/gremlin-annotations/pom.xml b/gremlin-annotations/pom.xml
index 8a1a83299a..15214dbd24 100644
--- a/gremlin-annotations/pom.xml
+++ b/gremlin-annotations/pom.xml
@@ -95,9 +95,9 @@ limitations under the License.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <release>8</release>
- <source>8</source>
- <target>8</target>
+ <release>17</release>
+ <source>17</source>
+ <target>17</target>
<compilerArgs>
<arg>-parameters</arg>
<arg>-proc:none</arg>
diff --git a/gremlin-console/Dockerfile b/gremlin-console/Dockerfile
index 44c995ae66..5752709997 100644
--- a/gremlin-console/Dockerfile
+++ b/gremlin-console/Dockerfile
@@ -23,7 +23,7 @@ ARG GREMLIN_CONSOLE_DIR
RUN apk add --no-cache --update \
bash \
- openjdk11-jdk
+ openjdk17-jdk
COPY src/main/docker/docker-entrypoint.sh /
COPY ${GREMLIN_CONSOLE_DIR} /opt/gremlin-console
diff --git a/gremlin-console/pom.xml b/gremlin-console/pom.xml
index c167c08f79..0c96d16aa7 100644
--- a/gremlin-console/pom.xml
+++ b/gremlin-console/pom.xml
@@ -384,12 +384,12 @@ limitations under the License.
<target>
<exec executable="docker"
failonerror="true">
<!-- This build command relies on
Docker's caching mechanism to reduce the amount of times it is run. -->
- <arg line="build -t
gremlin-console-test:py3.10jre11 ./src/test/python/docker"/>
+ <arg line="build -t
gremlin-console-test:py3.10jre17 ./src/test/python/docker"/>
</exec>
<exec executable="docker"
failonerror="true">
<arg line="run --rm --mount
type=bind,src=${project.basedir}/src/test/python,dst=/console_app
--mount
type=bind,src=${project.basedir}/target/apache-tinkerpop-gremlin-console-${project.version}-standalone,dst=/console_app/gremlin-console
- gremlin-console-test:py3.10jre11"/>
+ gremlin-console-test:py3.10jre17"/>
</exec>
</target>
</configuration>
diff --git a/gremlin-console/src/main/bin/gremlin.sh
b/gremlin-console/src/main/bin/gremlin.sh
index 2cd33cbc04..8a245f80ef 100755
--- a/gremlin-console/src/main/bin/gremlin.sh
+++ b/gremlin-console/src/main/bin/gremlin.sh
@@ -108,9 +108,10 @@ if [ -n "$SCRIPT_DEBUG" ]; then
set -x
fi
-# Detect JDK version and add specific flags for JDK 17
+# Detect the JDK major version and add specific flags for JDK 17 and newer
JAVA_VERSION=$($JAVA -version 2>&1 | awk -F '"' '/version/ {print $2}')
-if [[ "$JAVA_VERSION" == 17* ]]; then
+JAVA_MAJOR_VERSION=$(echo "$JAVA_VERSION" | awk -F. '{if ($1 == 1) print $2;
else print $1}')
+if [[ "$JAVA_MAJOR_VERSION" -ge 17 ]]; then
JVM_OPTS+=( "--add-opens=java.base/sun.nio.ch=ALL-UNNAMED" )
JVM_OPTS+=(
"--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED" )
fi
diff --git a/gremlin-console/src/test/python/docker/Dockerfile
b/gremlin-console/src/test/python/docker/Dockerfile
index e20de5991b..f4dec1f694 100644
--- a/gremlin-console/src/test/python/docker/Dockerfile
+++ b/gremlin-console/src/test/python/docker/Dockerfile
@@ -20,7 +20,7 @@ FROM python:3.10-bullseye
LABEL maintainer="[email protected]"
-RUN apt-get update && apt-get install -y --no-install-recommends
openjdk-11-jre && apt-get install dos2unix
+RUN apt-get update && apt-get install -y --no-install-recommends
openjdk-17-jre && apt-get install dos2unix
WORKDIR /console_app
CMD dos2unix ./gremlin-console/bin/gremlin.sh && python3 setup.py build &&
python3 setup.py test; \
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/LambdaRestrictionStrategy.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/LambdaRestrictionStrategy.java
index d26141e632..5dc0c25f4c 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/LambdaRestrictionStrategy.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/verification/LambdaRestrictionStrategy.java
@@ -51,7 +51,7 @@ public final class LambdaRestrictionStrategy extends
AbstractTraversalStrategy<T
@Override
public void apply(final Traversal.Admin<?, ?> traversal) {
for (final Step<?, ?> step : traversal.getSteps()) {
- if ((step instanceof LambdaHolder || step instanceof
ComparatorHolder) && step.toString().contains("lambda"))
+ if ((step instanceof LambdaHolder || step instanceof
ComparatorHolder) && step.toString().toLowerCase().contains("lambda"))
throw new VerificationException("The provided traversal
contains a lambda step: " + step, traversal);
}
}
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
index 74ba38437e..f84d83357b 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/StringFactory.java
@@ -237,7 +237,8 @@ public final class StringFactory {
}
private static boolean hasLambda(final String objectString) {
- return objectString.contains("$Lambda$") || // JAVA
(org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraphPlayTest$$Lambda$1/1711574013@61a52fb)
+ return objectString.contains("$Lambda$") || // JAVA <21
(org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraphPlayTest$$Lambda$1/1711574013@61a52fb)
+ objectString.contains("$$Lambda/") || // JAVA 21+
(org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraphPlayTest$$Lambda/0x00007fc001151000@61a52fb)
objectString.contains("$_run_closure") || // GROOVY
(groovysh_evaluate$_run_closure1@db44aa2)
objectString.contains("<lambda>"); // PYTHON (<function
<lambda> at 0x10dfaec80>)
}
diff --git
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/ImportGremlinPluginTest.java
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/ImportGremlinPluginTest.java
index 0a1868da74..c628f48578 100644
---
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/ImportGremlinPluginTest.java
+++
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/jsr223/ImportGremlinPluginTest.java
@@ -148,8 +148,15 @@ public class ImportGremlinPluginTest {
.fieldsImports(Collections.singletonList(Math.class.getCanonicalName() +
"#*")).create();
final DefaultImportCustomizer customizer = (DefaultImportCustomizer)
module.getCustomizers().get()[0];
- assertThat(customizer.getFieldImports(), is(new HashSet<>(
- Arrays.asList(Math.class.getField("PI"),
Math.class.getField("E")))));
+ // Math.TAU was added in Java 19
+ final HashSet<Field> expectedFields = new HashSet<>(Arrays.asList(
+ Math.class.getField("PI"), Math.class.getField("E")));
+ try {
+ expectedFields.add(Math.class.getField("TAU"));
+ } catch (NoSuchFieldException ignored) {
+ // TAU not available in Java < 19
+ }
+ assertThat(customizer.getFieldImports(), is(expectedFields));
}
@Test
diff --git a/gremlin-groovy/pom.xml b/gremlin-groovy/pom.xml
index 5b7af40287..aaafa65750 100644
--- a/gremlin-groovy/pom.xml
+++ b/gremlin-groovy/pom.xml
@@ -142,12 +142,44 @@ limitations under the License.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <release>8</release>
- <source>8</source>
- <target>8</target>
+ <release>17</release>
+ <source>17</source>
+ <target>17</target>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-annotations</artifactId>
+ <version>${project.version}</version>
+ </path>
+ <path>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-core</artifactId>
+ <version>${project.version}</version>
+ </path>
+ <path>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-shaded</artifactId>
+ <version>${project.version}</version>
+ </path>
+ <path>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-language</artifactId>
+ <version>${project.version}</version>
+ </path>
+ <path>
+ <groupId>com.squareup</groupId>
+ <artifactId>javapoet</artifactId>
+ <version>${javapoet.version}</version>
+ </path>
+ <path>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4-runtime</artifactId>
+ <version>${antlr4.version}</version>
+ </path>
+ </annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
@@ -155,9 +187,9 @@ limitations under the License.
<profiles>
<profile>
- <id>jdk11</id>
+ <id>jdk11-and-newer</id>
<activation>
- <jdk>[11,18)</jdk>
+ <jdk>[11,)</jdk>
</activation>
<build>
<plugins>
@@ -167,8 +199,8 @@ limitations under the License.
<configuration>
<!--
need to override source path as we don't seem to
get the groovy-stubs automatically. this worked
- under java 8 but errors under java 11 due to
missing files on the path. i guess java 8 was more
- forgiving.
+ under java 8 but errors under java 11 and newer
due to missing files on the path. i guess java 8
+ was more forgiving.
-->
<sourcepath>${pom.basedir}/src/main/java:${project.build.directory}/generated-sources/annotations:${project.build.directory}/generated-sources/groovy-stubs/main</sourcepath>
</configuration>
diff --git a/gremlin-server/Dockerfile b/gremlin-server/Dockerfile
index 63a494d63b..7eb7a58003 100644
--- a/gremlin-server/Dockerfile
+++ b/gremlin-server/Dockerfile
@@ -24,7 +24,7 @@ ARG GREMLIN_SERVER_DIR
RUN apk add --no-cache --update \
bash \
perl \
- openjdk11-jdk
+ openjdk17-jdk
COPY src/main/docker/docker-entrypoint.sh /
COPY ${GREMLIN_SERVER_DIR} /opt/gremlin-server
diff --git a/gremlin-server/src/main/bin/gremlin-server.sh
b/gremlin-server/src/main/bin/gremlin-server.sh
index 430a18c398..438daf1ca6 100755
--- a/gremlin-server/src/main/bin/gremlin-server.sh
+++ b/gremlin-server/src/main/bin/gremlin-server.sh
@@ -94,6 +94,25 @@ if [[ "$JAVA_OPTIONS" = "" ]] ; then
JAVA_OPTIONS="-Xms512m -Xmx4096m"
fi
+# These options are required for libraries that still rely on deep reflection
(notably Kryo, used by Gryo) to work on
+# Java 17 and newer, where such access into java.base is denied by default.
They mirror the jdk17JvmArgs used by the
+# build (see the root pom.xml) and are always appended so they apply even when
JAVA_OPTIONS is overridden.
+JAVA_OPTIONS="$JAVA_OPTIONS \
+-XX:+IgnoreUnrecognizedVMOptions \
+--add-exports=java.base/sun.nio.ch=ALL-UNNAMED \
+--add-exports=java.base/sun.security.x509=ALL-UNNAMED \
+--add-exports=java.base/sun.security.action=ALL-UNNAMED \
+--add-opens=java.base/java.io=ALL-UNNAMED \
+--add-opens=java.base/java.nio=ALL-UNNAMED \
+--add-opens=java.base/sun.nio.cs=ALL-UNNAMED \
+--add-opens=java.base/java.lang=ALL-UNNAMED \
+--add-opens=java.base/java.lang.invoke=ALL-UNNAMED \
+--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
+--add-opens=java.base/java.util=ALL-UNNAMED \
+--add-opens=java.base/java.util.concurrent=ALL-UNNAMED \
+--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED \
+--add-opens=java.base/java.net=ALL-UNNAMED"
+
# Build Java CLASSPATH
CP="$GREMLIN_HOME/conf/"
CP="$CP":$( find "$GREMLIN_HOME/lib" -name "*.jar" -print | tr '\n' ':' ).
diff --git
a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSslIntegrateTest.java
b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSslIntegrateTest.java
index a8ae0b860f..2e73cca38e 100644
---
a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSslIntegrateTest.java
+++
b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/GremlinServerSslIntegrateTest.java
@@ -261,7 +261,9 @@ public class GremlinServerSslIntegrateTest extends
AbstractGremlinServerIntegrat
client.submit("g.inject('test')").one();
fail("Should throw exception because ssl client auth is enabled on
the server but client does not have a cert");
} catch (Exception x) {
- assertSslException(x, "bad_certificate");
+ // Under TLS 1.3 (default on Java 17+) a client-certificate
rejection may reach the client as the specific
+ // alert or, depending on handshake timing, as a generic
engine-closed error.
+ assertSslException(x, "bad_certificate", "certificate_required",
"SSLEngine closed already");
} finally {
cluster.close();
}
@@ -277,7 +279,9 @@ public class GremlinServerSslIntegrateTest extends
AbstractGremlinServerIntegrat
client.submit("g.inject('test')").one();
fail("Should throw exception because ssl client auth is enabled on
the server but does not trust client's cert");
} catch (Exception x) {
- assertSslException(x, "bad_certificate");
+ // Under TLS 1.3 (default on Java 17+) a client-certificate
rejection may reach the client as the specific
+ // alert or, depending on handshake timing, as a generic
engine-closed error.
+ assertSslException(x, "bad_certificate", "certificate_required",
"SSLEngine closed already");
} finally {
cluster.close();
}
@@ -343,10 +347,16 @@ public class GremlinServerSslIntegrateTest extends
AbstractGremlinServerIntegrat
}
}
- private static void assertSslException(Exception x, String
expectedSubstring) {
+ private static void assertSslException(final Exception x, final String...
acceptableSubstrings) {
logger.warn("Exception caught: {}", x.getMessage(), x);
final Throwable root = ExceptionHelper.getRootCause(x);
assertThat(root, instanceOf(SSLException.class));
- assertThat(root.getMessage(), containsString(expectedSubstring));
+ final String message = root.getMessage();
+ // The exact TLS alert can vary by JDK/TLS version (for example a
missing client certificate is reported as
+ // "bad_certificate" under TLS 1.2 but "certificate_required" under
the TLS 1.3 that is default on Java 17+),
+ // so accept any of the provided substrings.
+ final boolean matched = message != null &&
Arrays.stream(acceptableSubstrings).anyMatch(message::contains);
+ assertThat("Expected SSL exception message <" + message + "> to
contain one of " +
+ Arrays.toString(acceptableSubstrings), matched, is(true));
}
}
diff --git a/gremlin-tools/gremlin-socket-server/Dockerfile
b/gremlin-tools/gremlin-socket-server/Dockerfile
index 3010f33cd6..f40c91a66d 100644
--- a/gremlin-tools/gremlin-socket-server/Dockerfile
+++ b/gremlin-tools/gremlin-socket-server/Dockerfile
@@ -24,7 +24,7 @@ ARG SOCKET_SERVER_VERSION
RUN apk add --no-cache --update \
bash \
- openjdk11-jdk
+ openjdk17-jdk
COPY ${SOCKET_SERVER_DIR}/gremlin-socket-server-${SOCKET_SERVER_VERSION}.jar
/opt/gremlin-socket-server/gremlin-socket-server.jar
COPY ${SOCKET_SERVER_DIR}/libs/ /opt/gremlin-socket-server/libs/
diff --git a/pom.xml b/pom.xml
index 9f4b908127..8f426fc504 100644
--- a/pom.xml
+++ b/pom.xml
@@ -159,7 +159,7 @@ limitations under the License.
<commons.text.version>1.15.0</commons.text.version>
<cucumber.version>7.21.1</cucumber.version>
<exp4j.version>0.4.8</exp4j.version>
- <groovy.version>4.0.25</groovy.version>
+ <groovy.version>4.0.32</groovy.version>
<!--
don't really use guava directly, but there are a lot of jar
conflicts around it,
so centralizing that dependency version here
@@ -170,7 +170,7 @@ limitations under the License.
it supports the jakarta.inject namespace which tinkerpop doesn't
fuss with
-->
<guice.version>6.0.0</guice.version>
- <hadoop.version>3.4.2</hadoop.version>
+ <hadoop.version>3.4.3</hadoop.version>
<hamcrest.version>3.0</hamcrest.version>
<java.tuples.version>1.2</java.tuples.version>
<javadoc-plugin.version>3.3.1</javadoc-plugin.version>
@@ -180,10 +180,10 @@ limitations under the License.
<logback.version>1.3.15</logback.version>
<metrics.version>3.0.2</metrics.version>
<mockito.version>5.19.0</mockito.version>
- <netty.version>4.1.125.Final</netty.version>
+ <netty.version>4.2.7.Final</netty.version>
<slf4j.version>2.0.16</slf4j.version>
<snakeyaml.version>2.0</snakeyaml.version>
- <spark.version>3.5.4</spark.version>
+ <spark.version>4.1.2</spark.version>
<awssdk.version>2.29.3</awssdk.version>
<!-- Version aligned with Netty's optional bcpkix dependency used for
SelfSignedCertificate -->
<bouncycastle.version>1.69</bouncycastle.version>
@@ -259,7 +259,7 @@ limitations under the License.
<rules>
<DependencyConvergence/>
<requireJavaVersion>
- <version>[11,18)</version>
+ <version>[17,26)</version>
</requireJavaVersion>
<requireMavenVersion>
<version>[3.5.3,)</version>
@@ -624,9 +624,9 @@ limitations under the License.
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
<configuration>
- <release>11</release>
- <source>11</source>
- <target>11</target>
+ <release>17</release>
+ <source>17</source>
+ <target>17</target>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
@@ -733,7 +733,7 @@ limitations under the License.
<artifactId>maven-javadoc-plugin</artifactId>
<version>${javadoc-plugin.version}</version>
<configuration>
- <source>11</source>
+ <source>17</source>
</configuration>
</plugin>
<plugin>
@@ -741,7 +741,7 @@ limitations under the License.
<artifactId>gmavenplus-plugin</artifactId>
<version>4.1.1</version>
<configuration>
- <targetBytecode>11</targetBytecode>
+ <targetBytecode>17</targetBytecode>
</configuration>
</plugin>
<plugin>
@@ -2203,7 +2203,7 @@ limitations under the License.
-Dlog4j.configuration=${log4j-test.properties}
-Dslf4j.provider=ch.qos.logback.classic.spi.LogbackServiceProvider
-Dbuild.dir=${project.build.directory}
-Dis.testing=true ${suresafeArgs}
- -Djava.net.preferIPv4Stack=true
+ -Djava.net.preferIPv4Stack=true ${jdk17JvmArgs}
</argLine>
</configuration>
</plugin>
@@ -2215,7 +2215,7 @@ limitations under the License.
-Dlog4j.configuration=${log4j-test.properties}
-Dhost=localhost -Dport=8182
-Dslf4j.provider=ch.qos.logback.classic.spi.LogbackServiceProvider
-Dbuild.dir=${project.build.directory}
-Dis.testing=true ${suresafeArgs}
- -Djava.net.preferIPv4Stack=true
+ -Djava.net.preferIPv4Stack=true ${jdk17JvmArgs}
</argLine>
</configuration>
</plugin>
diff --git a/spark-gremlin/pom.xml b/spark-gremlin/pom.xml
index ce0eff687e..0b2917997d 100644
--- a/spark-gremlin/pom.xml
+++ b/spark-gremlin/pom.xml
@@ -25,6 +25,42 @@ limitations under the License.
</parent>
<artifactId>spark-gremlin</artifactId>
<name>Apache TinkerPop :: Spark Gremlin</name>
+ <dependencyManagement>
+ <dependencies>
+ <!-- Align every jackson artifact with the version Spark 4.x is
built against; its bundled
+ jackson-module-scala requires a matching jackson-databind.
The BOM also resolves the version skew
+ between jackson-databind/core and jackson-annotations. -->
+ <dependency>
+ <groupId>com.fasterxml.jackson</groupId>
+ <artifactId>jackson-bom</artifactId>
+ <version>2.21.2</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <!-- Spark 4.1.x and Hadoop pull in conflicting versions of these
transitive dependencies; pin each to a
+ single version so that dependency convergence is satisfied -->
+ <dependency>
+ <groupId>com.thoughtworks.paranamer</groupId>
+ <artifactId>paranamer</artifactId>
+ <version>2.8.3</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>4.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk18on</artifactId>
+ <version>1.82</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.xml.bind</groupId>
+ <artifactId>jaxb-api</artifactId>
+ <version>2.2.12</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.tinkerpop</groupId>
@@ -105,7 +141,7 @@ limitations under the License.
<!-- SPARK -->
<dependency>
<groupId>org.apache.spark</groupId>
- <artifactId>spark-core_2.12</artifactId>
+ <artifactId>spark-core_2.13</artifactId>
<version>${spark.version}</version>
<exclusions>
<!-- prefer hadoop protobuf -->
@@ -195,7 +231,7 @@ limitations under the License.
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
- <version>4.2.19</version>
+ <version>4.2.37</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
@@ -244,23 +280,20 @@ limitations under the License.
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
- <version>2.12.15</version>
+ <version>2.13.17</version>
</dependency>
- <!-- use jackson 2.13.5 to fit better with spark 2.3.3 where Scala
module 2.13.4 requires Jackson Databind version >= 2.13.0 and < 2.14.0 -->
+ <!-- jackson versions are managed by the jackson-bom import above so
that they match Spark 4.x -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
- <version>2.15.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
- <version>2.15.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
- <version>2.15.4</version>
</dependency>
<!-- TEST -->
<dependency>
@@ -366,7 +399,7 @@ limitations under the License.
<archive>
<manifestEntries>
<Gremlin-Plugin-Dependencies>
-
org.apache.hadoop:hadoop-client:${hadoop.version};org.apache.hadoop:hadoop-yarn-server-web-proxy:${hadoop.version};org.apache.spark:spark-yarn_2.12:${spark.version}
+
org.apache.hadoop:hadoop-client:${hadoop.version};org.apache.hadoop:hadoop-yarn-server-web-proxy:${hadoop.version};org.apache.spark:spark-yarn_2.13:${spark.version}
</Gremlin-Plugin-Dependencies>
</manifestEntries>
</archive>
diff --git
a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/Spark.java
b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/Spark.java
index 694b25e382..afb3ff62a0 100644
---
a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/Spark.java
+++
b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/Spark.java
@@ -23,7 +23,7 @@ import org.apache.commons.configuration2.Configuration;
import org.apache.spark.SparkConf;
import org.apache.spark.SparkContext;
import org.apache.spark.rdd.RDD;
-import scala.collection.JavaConversions;
+import scala.jdk.javaapi.CollectionConverters;
import java.util.ArrayList;
import java.util.HashSet;
@@ -108,7 +108,7 @@ public class Spark {
recreateStopped();
final Set<String> keepNames = new HashSet<>();
- for (final RDD<?> rdd :
JavaConversions.asJavaIterable(CONTEXT.persistentRdds().values())) {
+ for (final RDD<?> rdd :
CollectionConverters.asJava(CONTEXT.persistentRdds().values())) {
if (null != rdd.name()) {
keepNames.add(rdd.name());
NAME_TO_RDD.put(rdd.name(), rdd);
diff --git
a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
index 4cf871d0e9..705d883a73 100644
---
a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
+++
b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoRegistrator.java
@@ -51,7 +51,7 @@ import org.apache.tinkerpop.gremlin.util.SystemUtil;
import org.javatuples.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import scala.collection.mutable.WrappedArray;
+import scala.collection.immutable.ArraySeq;
import java.util.Collections;
import java.util.HashSet;
@@ -206,7 +206,7 @@ public class GryoRegistrator implements KryoRegistrator {
} catch (final ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}
- m.put(WrappedArray.ofRef.class, null);
+ m.put(ArraySeq.ofRef.class, null);
m.put(MessagePayload.class, null);
m.put(ViewIncomingPayload.class, null);
m.put(ViewOutgoingPayload.class, null);
diff --git
a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoSerializer.java
b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoSerializer.java
index 58fa16bcac..35f631703d 100644
---
a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoSerializer.java
+++
b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/GryoSerializer.java
@@ -51,7 +51,7 @@ import
org.apache.tinkerpop.shaded.kryo.serializers.ExternalizableSerializer;
import org.apache.tinkerpop.shaded.kryo.serializers.JavaSerializer;
import scala.Tuple2;
import scala.Tuple3;
-import scala.collection.mutable.WrappedArray;
+import scala.collection.immutable.ArraySeq;
import scala.runtime.BoxedUnit;
import java.io.Serializable;
@@ -147,7 +147,7 @@ public final class GryoSerializer extends Serializer
implements Serializable {
super.register(GryoIo.class, Class.forName("scala.None$"), new
JavaSerializer());
super.register(GryoIo.class, Class.forName("scala.Some$"), new
JavaSerializer());
super.register(GryoIo.class, Class.forName("scala.Some"), new
JavaSerializer());
- super.register(GryoIo.class, WrappedArray.ofRef.class, new
WrappedArraySerializer());
+ super.register(GryoIo.class, ArraySeq.ofRef.class, new
WrappedArraySerializer());
super.register(GryoIo.class, MessagePayload.class, null);
super.register(GryoIo.class, ViewIncomingPayload.class, null);
super.register(GryoIo.class, ViewOutgoingPayload.class, null);
diff --git
a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/WrappedArraySerializer.java
b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/WrappedArraySerializer.java
index 1de17f1a90..8d6be792f2 100644
---
a/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/WrappedArraySerializer.java
+++
b/spark-gremlin/src/main/java/org/apache/tinkerpop/gremlin/spark/structure/io/gryo/WrappedArraySerializer.java
@@ -23,29 +23,32 @@ import org.apache.tinkerpop.shaded.kryo.Kryo;
import org.apache.tinkerpop.shaded.kryo.Serializer;
import org.apache.tinkerpop.shaded.kryo.io.Input;
import org.apache.tinkerpop.shaded.kryo.io.Output;
-import scala.collection.JavaConversions;
-import scala.collection.mutable.WrappedArray;
+import scala.collection.immutable.ArraySeq;
/**
+ * Serializer for Scala's immutable {@link ArraySeq}. In Scala 2.13 (the Scala
version Spark is built against) wrapping
+ * a reference array produces an {@code immutable.ArraySeq.ofRef}, which
replaced the {@code WrappedArray} used under
+ * Scala 2.12.
+ *
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
-public final class WrappedArraySerializer<T> extends
Serializer<WrappedArray<T>> {
+public final class WrappedArraySerializer<T> extends Serializer<ArraySeq<T>> {
@Override
- public void write(final Kryo kryo, final Output output, final
WrappedArray<T> iterable) {
+ public void write(final Kryo kryo, final Output output, final ArraySeq<T>
iterable) {
output.writeVarInt(iterable.size(), true);
- JavaConversions.asJavaCollection(iterable).forEach(t -> {
- kryo.writeClassAndObject(output, t);
- });
+ for (int i = 0; i < iterable.size(); i++) {
+ kryo.writeClassAndObject(output, iterable.apply(i));
+ }
}
@Override
- public WrappedArray<T> read(final Kryo kryo, final Input input, final
Class<WrappedArray<T>> aClass) {
+ public ArraySeq<T> read(final Kryo kryo, final Input input, final
Class<ArraySeq<T>> aClass) {
final int size = input.readVarInt(true);
final Object[] array = new Object[size];
for (int i = 0; i < size; i++) {
array[i] = kryo.readClassAndObject(input);
}
- return new WrappedArray.ofRef<>((T[]) array);
+ return new ArraySeq.ofRef<>((T[]) array);
}
}
diff --git
a/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/SparkTest.java
b/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/SparkTest.java
index d77f359ccc..59e87ee473 100644
---
a/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/SparkTest.java
+++
b/spark-gremlin/src/test/java/org/apache/tinkerpop/gremlin/spark/structure/SparkTest.java
@@ -38,7 +38,7 @@ import
org.apache.tinkerpop.gremlin.spark.structure.io.gryo.GryoSerializer;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.util.GraphFactory;
import org.junit.Test;
-import scala.collection.JavaConversions;
+import scala.jdk.javaapi.CollectionConverters;
import java.io.File;
@@ -112,7 +112,7 @@ public class SparkTest extends AbstractSparkTest {
}
private static boolean hasPersistedRDD(final String name) {
- for (final RDD<?> rdd :
JavaConversions.asJavaIterable(Spark.getContext().persistentRdds().values())) {
+ for (final RDD<?> rdd :
CollectionConverters.asJava(Spark.getContext().persistentRdds().values())) {
if (null != rdd.name() && rdd.name().equals(name))
return true;
}
@@ -121,7 +121,7 @@ public class SparkTest extends AbstractSparkTest {
private static int getPersistedRDDSize() {
int counter = 0;
- for (final RDD<?> rdd :
JavaConversions.asJavaIterable(Spark.getContext().persistentRdds().values())) {
+ for (final RDD<?> rdd :
CollectionConverters.asJava(Spark.getContext().persistentRdds().values())) {
if (null != rdd.name())
counter++;
}