This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new 297c34506 feat(java): add java9/16 module-info support (#3721)
297c34506 is described below

commit 297c34506ab7c6f57dee875f090002a38ce7478e
Author: Shawn Yang <[email protected]>
AuthorDate: Sun May 31 02:43:48 2026 +0800

    feat(java): add java9/16 module-info support (#3721)
    
    ## Why?
    
    
    
    ## What does this PR do?
    
    
    
    ## Related issues
    
    
    
    ## AI Contribution Checklist
    
    
    
    - [ ] Substantial AI assistance was used in this PR: `yes` / `no`
    - [ ] If `yes`, I included a completed [AI Contribution
    
Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs)
    in this PR description and the required `AI Usage Disclosure`.
    - [ ] If `yes`, my PR description includes the required `ai_review`
    summary and screenshot evidence of the final clean AI review results
    from both fresh reviewers on the current PR diff or current HEAD after
    the latest code changes.
    
    
    
    ## Does this PR introduce any user-facing change?
    
    
    
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    ## Benchmark
---
 ci/run_ci.sh                                       |   1 +
 integration_tests/jpms_tests/run_jlink_smoke.sh    | 200 +++++++++++++++++++++
 java/fory-core/pom.xml                             | 191 ++++++++++++++++++++
 java/fory-core/src/main/java16/module-info.java    |  59 ++++++
 .../serializer/CompressedArraySerializers.java     |   2 +-
 .../apache/fory/util/ArrayCompressionUtils.java    | 129 ++++++-------
 .../fory/util/PrimitiveArrayCompressionType.java   |  22 ++-
 java/fory-core/src/main/java9/module-info.java     |  58 ++++++
 java/fory-format/pom.xml                           |  68 +++++++
 .../apache/fory/format/encoder/LazyArrayData.java  |   2 +-
 java/fory-format/src/main/java11/module-info.java  |  33 ++++
 java/fory-simd/pom.xml                             |  94 ----------
 java/fory-testsuite/pom.xml                        |  59 ++++++
 .../fory/serializer/ArrayCompressionTest.java      |   1 -
 .../fory/serializer/ArrayCompressionUtilsTest.java |   1 -
 java/pom.xml                                       |   1 -
 16 files changed, 739 insertions(+), 182 deletions(-)

diff --git a/ci/run_ci.sh b/ci/run_ci.sh
index 45e096a45..fafe3185d 100755
--- a/ci/run_ci.sh
+++ b/ci/run_ci.sh
@@ -98,6 +98,7 @@ integration_tests() {
   echo "Start JPMS tests"
   cd "$ROOT"/integration_tests/jpms_tests
   mvn -T10 -B --no-transfer-progress clean compile
+  ./run_jlink_smoke.sh
   echo "Start jdk compatibility tests"
   cd "$ROOT"/integration_tests/jdk_compatibility_tests
   mvn -T10 -B --no-transfer-progress clean test
diff --git a/integration_tests/jpms_tests/run_jlink_smoke.sh 
b/integration_tests/jpms_tests/run_jlink_smoke.sh
new file mode 100755
index 000000000..08364dc48
--- /dev/null
+++ b/integration_tests/jpms_tests/run_jlink_smoke.sh
@@ -0,0 +1,200 @@
+#!/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 -euo pipefail
+
+ROOT="$(git rev-parse --show-toplevel)"
+JAVA_ROOT="$ROOT/java"
+VERSION="$(mvn -q -B -f "$JAVA_ROOT/pom.xml" help:evaluate 
-Dexpression=project.version -DforceStdout)"
+JAVA_HOME="${JAVA_HOME:-$(
+  java -XshowSettings:properties -version 2>&1 \
+    | awk -F= '/java.home =/ { gsub(/^ +| +$/, "", $2); print $2; exit }'
+)}"
+JAVA_MAJOR="$(
+  java -version 2>&1 \
+    | awk -F '"' '/version/ {print $2; exit}' \
+    | awk -F. '{ if ($1 == "1") print $2; else print $1 }'
+)"
+
+if [[ "$JAVA_MAJOR" -lt 11 ]]; then
+  echo "Skipping jlink smoke test on JDK $JAVA_MAJOR; fory-format is Java 11+."
+  exit 0
+fi
+if [[ ! -d "$JAVA_HOME/jmods" ]]; then
+  echo "Cannot find JDK modules under JAVA_HOME=$JAVA_HOME; jlink smoke 
requires a JDK." >&2
+  exit 1
+fi
+
+artifact_jar() {
+  local artifact="$1"
+  local module="$2"
+  local target_jar="$JAVA_ROOT/$module/target/$artifact-$VERSION.jar"
+  local 
repo_jar="$HOME/.m2/repository/org/apache/fory/$artifact/$VERSION/$artifact-$VERSION.jar"
+  if [[ -f "$target_jar" ]]; then
+    echo "$target_jar"
+  elif [[ -f "$repo_jar" ]]; then
+    echo "$repo_jar"
+  else
+    echo "Cannot find $artifact jar; run java/fory-core and java/fory-format 
package/install first." >&2
+    exit 1
+  fi
+}
+
+CORE_JAR="$(artifact_jar fory-core fory-core)"
+FORMAT_JAR="$(artifact_jar fory-format fory-format)"
+WORK_DIR="$(mktemp -d "${TMPDIR:-/tmp}/fory-jpms-jlink.XXXXXX")"
+trap 'rm -rf "$WORK_DIR"' EXIT
+
+require_jar_entry() {
+  local jar_file="$1"
+  local entry="$2"
+  if ! jar tf "$jar_file" | grep -qx "$entry"; then
+    echo "Missing $entry in $jar_file" >&2
+    exit 1
+  fi
+}
+
+reject_jar_entry() {
+  local jar_file="$1"
+  local entry="$2"
+  if jar tf "$jar_file" | grep -qx "$entry"; then
+    echo "Unexpected root $entry in $jar_file" >&2
+    exit 1
+  fi
+}
+
+require_jar_entry "$CORE_JAR" "META-INF/versions/9/module-info.class"
+reject_jar_entry "$CORE_JAR" "module-info.class"
+require_jar_entry "$FORMAT_JAR" "META-INF/versions/11/module-info.class"
+reject_jar_entry "$FORMAT_JAR" "module-info.class"
+
+if [[ "$JAVA_MAJOR" -ge 16 ]] \
+  && jar tf "$CORE_JAR" | grep -qx "META-INF/versions/16/module-info.class"; 
then
+  require_jar_entry "$CORE_JAR" 
"META-INF/versions/16/org/apache/fory/serializer/CompressedArraySerializers.class"
+  require_jar_entry "$CORE_JAR" 
"META-INF/versions/16/org/apache/fory/util/ArrayCompressionUtils.class"
+  require_jar_entry "$CORE_JAR" 
"META-INF/versions/16/org/apache/fory/util/PrimitiveArrayCompressionType.class"
+  reject_jar_entry "$CORE_JAR" 
"org/apache/fory/serializer/CompressedArraySerializers.class"
+  reject_jar_entry "$CORE_JAR" 
"org/apache/fory/util/ArrayCompressionUtils.class"
+  reject_jar_entry "$CORE_JAR" 
"org/apache/fory/util/PrimitiveArrayCompressionType.class"
+  jar --file "$CORE_JAR" --describe-module --release 16 | grep -q "requires 
jdk.incubator.vector static"
+fi
+
+jar --file "$CORE_JAR" --describe-module --release 9 | grep -q "requires 
java.sql static"
+jar --file "$CORE_JAR" --describe-module --release 9 | grep -q "requires 
com.google.common static"
+jar --file "$FORMAT_JAR" --describe-module --release 11 | grep -q "requires 
java.sql static"
+jar --file "$FORMAT_JAR" --describe-module --release 11 | grep -q "requires 
org.apache.arrow.vector static transitive"
+jar --file "$FORMAT_JAR" --describe-module --release 11 | grep -q "requires 
org.apache.arrow.memory.core static transitive"
+
+DEPS_FILE="$WORK_DIR/format-deps.txt"
+mvn -q -B -f "$JAVA_ROOT/pom.xml" -pl fory-format dependency:list \
+  -DincludeScope=compile \
+  -DoutputAbsoluteArtifactFilename=true \
+  -DexcludeTransitive=false \
+  -DoutputFile="$DEPS_FILE" \
+  -Dstyle.color=never
+
+COMPILE_MODULE_PATH="$WORK_DIR/compile-module-path.txt"
+awk -F: '/:jar:/ {
+  path = $NF
+  sub(/ .*/, "", path)
+  if (path ~ /^\// && path ~ /\.jar$/ && path !~ 
/\/org\/apache\/fory\/fory-core\//) {
+    print path
+  }
+}' "$DEPS_FILE" > "$COMPILE_MODULE_PATH"
+
+mkdir -p "$WORK_DIR/src/jpms.smoke/org/apache/fory/jpms" "$WORK_DIR/mods"
+cat > "$WORK_DIR/src/jpms.smoke/module-info.java" <<'EOF'
+module jpms.smoke {
+  requires org.apache.fory.core;
+  requires org.apache.fory.format;
+}
+EOF
+cat > "$WORK_DIR/src/jpms.smoke/org/apache/fory/jpms/Smoke.java" <<'EOF'
+package org.apache.fory.jpms;
+
+import org.apache.fory.Fory;
+
+public final class Smoke {
+  public static void main(String[] args) throws Exception {
+    Fory.builder().build();
+    Class.forName("org.apache.fory.format.encoder.Encoders");
+    System.out.println("ok");
+  }
+}
+EOF
+
+JOINED_COMPILE_MODULE_PATH="$CORE_JAR:$FORMAT_JAR"
+if [[ -s "$COMPILE_MODULE_PATH" ]]; then
+  JOINED_COMPILE_MODULE_PATH="$JOINED_COMPILE_MODULE_PATH:$(paste -sd: 
"$COMPILE_MODULE_PATH")"
+fi
+
+javac \
+  --module-path "$JOINED_COMPILE_MODULE_PATH" \
+  -d "$WORK_DIR/mods" \
+  --module-source-path "$WORK_DIR/src" \
+  -m jpms.smoke
+
+jlink \
+  --module-path "$JAVA_HOME/jmods:$CORE_JAR:$FORMAT_JAR:$WORK_DIR/mods" \
+  --add-modules jpms.smoke \
+  --output "$WORK_DIR/image"
+
+"$WORK_DIR/image/bin/java" -m jpms.smoke/org.apache.fory.jpms.Smoke | grep -qx 
"ok"
+
+IMAGE_MODULES="$("$WORK_DIR/image/bin/java" --list-modules)"
+echo "$IMAGE_MODULES" | grep -q "^org.apache.fory.core"
+echo "$IMAGE_MODULES" | grep -q "^org.apache.fory.format"
+if echo "$IMAGE_MODULES" \
+  | grep -Eq 
"^(java\.sql|com\.google|jsr305|org\.apache\.arrow|org\.slf4j|jdk\.incubator\.vector)";
 then
+  echo "Optional static modules leaked into the minimal jlink image:" >&2
+  echo "$IMAGE_MODULES" \
+    | grep -E 
"^(java\.sql|com\.google|jsr305|org\.apache\.arrow|org\.slf4j|jdk\.incubator\.vector)"
 >&2
+  exit 1
+fi
+
+if [[ "$JAVA_MAJOR" -ge 16 ]] \
+  && jar tf "$CORE_JAR" | grep -qx 
"META-INF/versions/16/org/apache/fory/util/ArrayCompressionUtils.class"; then
+  mkdir -p "$WORK_DIR/vector-classes"
+  cat > "$WORK_DIR/VectorSmoke.java" <<'EOF'
+import org.apache.fory.util.ArrayCompressionUtils;
+import org.apache.fory.util.PrimitiveArrayCompressionType;
+
+public final class VectorSmoke {
+  public static void main(String[] args) throws Exception {
+    int[] values = new int[1024];
+    for (int i = 0; i < values.length; i++) {
+      values[i] = (i & 0xff) - 128;
+    }
+    if (ArrayCompressionUtils.determineIntCompressionType(values)
+        != PrimitiveArrayCompressionType.INT_TO_BYTE) {
+      throw new AssertionError("Vector compression returned the wrong range");
+    }
+    System.out.println("vector-ok");
+  }
+}
+EOF
+  javac -cp "$CORE_JAR" -d "$WORK_DIR/vector-classes" 
"$WORK_DIR/VectorSmoke.java"
+  java \
+    --add-modules jdk.incubator.vector \
+    -cp "$CORE_JAR:$WORK_DIR/vector-classes" \
+    VectorSmoke \
+    | grep -qx "vector-ok"
+fi
+
+echo "JPMS jlink smoke test passed with minimal optional dependencies."
diff --git a/java/fory-core/pom.xml b/java/fory-core/pom.xml
index 4176d7418..23d05bd6a 100644
--- a/java/fory-core/pom.xml
+++ b/java/fory-core/pom.xml
@@ -78,6 +78,7 @@
           <archive>
             <manifestEntries>
               
<Automatic-Module-Name>org.apache.fory.core</Automatic-Module-Name>
+              <Multi-Release>true</Multi-Release>
             </manifestEntries>
           </archive>
         </configuration>
@@ -119,6 +120,7 @@
                 <transformer 
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                   <manifestEntries>
                     
<Automatic-Module-Name>org.apache.fory.core</Automatic-Module-Name>
+                    <Multi-Release>true</Multi-Release>
                   </manifestEntries>
                 </transformer>
                 <transformer 
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
@@ -135,6 +137,195 @@
   </build>
 
   <profiles>
+    <profile>
+      <id>jpms-java9</id>
+      <activation>
+        <jdk>[9,)</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <version>3.1.0</version>
+            <executions>
+              <execution>
+                <id>compile-java9-module-info</id>
+                <phase>process-classes</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <target>
+                    <mkdir 
dir="${project.build.directory}/jpms-classes/java9"/>
+                    <pathconvert property="compile.module.path" 
refid="maven.compile.classpath"
+                                 pathsep="${path.separator}"/>
+                    <javac srcdir="${project.basedir}/src/main/java9"
+                           
destdir="${project.build.directory}/jpms-classes/java9"
+                           includeantruntime="false"
+                           fork="true"
+                           executable="${java.home}/bin/javac"
+                           debug="true">
+                      <include name="module-info.java"/>
+                      <compilerarg value="--release"/>
+                      <compilerarg value="9"/>
+                      <compilerarg value="--module-path"/>
+                      <compilerarg path="${compile.module.path}"/>
+                      <compilerarg value="--patch-module"/>
+                      <compilerarg 
value="org.apache.fory.core=${project.build.outputDirectory}"/>
+                    </javac>
+                  </target>
+                </configuration>
+              </execution>
+              <execution>
+                <id>inject-java9-module-info</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <target>
+                    <jar 
destfile="${project.build.directory}/${project.build.finalName}.jar" 
update="true">
+                      <zipfileset 
dir="${project.build.outputDirectory}/META-INF/versions/9"
+                                  prefix="META-INF/versions/9"
+                                  includes="module-info.class"/>
+                    </jar>
+                  </target>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-resources-plugin</artifactId>
+            <version>3.3.1</version>
+            <executions>
+              <execution>
+                <id>copy-java9-module-info</id>
+                <phase>prepare-package</phase>
+                <goals>
+                  <goal>copy-resources</goal>
+                </goals>
+                <configuration>
+                  
<outputDirectory>${project.build.outputDirectory}/META-INF/versions/9</outputDirectory>
+                  <resources>
+                    <resource>
+                      
<directory>${project.build.directory}/jpms-classes/java9</directory>
+                      <includes>
+                        <include>module-info.class</include>
+                      </includes>
+                    </resource>
+                  </resources>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>jpms-java16</id>
+      <activation>
+        <jdk>[16,)</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <version>3.1.0</version>
+            <executions>
+              <execution>
+                <id>compile-java16-sources</id>
+                <phase>process-classes</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <target>
+                    <delete 
dir="${project.build.directory}/jpms-classes/java16"/>
+                    <mkdir 
dir="${project.build.directory}/jpms-classes/java16"/>
+                    <pathconvert property="compile.module.path" 
refid="maven.compile.classpath"
+                                 pathsep="${path.separator}"/>
+                    <javac srcdir="${project.basedir}/src/main/java16"
+                           
destdir="${project.build.directory}/jpms-classes/java16"
+                           includeantruntime="false"
+                           fork="true"
+                           executable="${java.home}/bin/javac"
+                           debug="true">
+                      <include name="**/*.java"/>
+                      <compilerarg value="--source"/>
+                      <compilerarg value="16"/>
+                      <compilerarg value="--target"/>
+                      <compilerarg value="16"/>
+                      <compilerarg value="--module-path"/>
+                      <compilerarg path="${compile.module.path}"/>
+                      <compilerarg value="--add-modules"/>
+                      <compilerarg value="jdk.incubator.vector"/>
+                      <compilerarg value="--patch-module"/>
+                      <compilerarg 
value="org.apache.fory.core=${project.build.outputDirectory}"/>
+                    </javac>
+                  </target>
+                </configuration>
+              </execution>
+              <execution>
+                <id>clean-java16-package-classes</id>
+                <phase>prepare-package</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <target>
+                    <delete 
dir="${project.build.outputDirectory}/META-INF/versions/16"/>
+                  </target>
+                </configuration>
+              </execution>
+              <execution>
+                <id>inject-java16-classes</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <target>
+                    <jar 
destfile="${project.build.directory}/${project.build.finalName}.jar" 
update="true">
+                      <zipfileset 
dir="${project.build.outputDirectory}/META-INF/versions/16"
+                                  prefix="META-INF/versions/16"
+                                  includes="**/*.class"/>
+                    </jar>
+                  </target>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-resources-plugin</artifactId>
+            <version>3.3.1</version>
+            <executions>
+              <execution>
+                <id>copy-java16-classes</id>
+                <phase>prepare-package</phase>
+                <goals>
+                  <goal>copy-resources</goal>
+                </goals>
+                <configuration>
+                  
<outputDirectory>${project.build.outputDirectory}/META-INF/versions/16</outputDirectory>
+                  <resources>
+                    <resource>
+                      
<directory>${project.build.directory}/jpms-classes/java16</directory>
+                      <includes>
+                        <include>**/*.class</include>
+                      </includes>
+                    </resource>
+                  </resources>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
     <profile>
       <id>xlang-parallel</id>
       <activation>
diff --git a/java/fory-core/src/main/java16/module-info.java 
b/java/fory-core/src/main/java16/module-info.java
new file mode 100644
index 000000000..40c773b6a
--- /dev/null
+++ b/java/fory-core/src/main/java16/module-info.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+module org.apache.fory.core {
+  requires java.logging;
+  requires jdk.unsupported;
+
+  requires static java.sql;
+  requires static com.google.common;
+  requires static org.slf4j;
+  requires static jsr305;
+  requires static jdk.incubator.vector;
+
+  exports org.apache.fory;
+  exports org.apache.fory.annotation;
+  exports org.apache.fory.builder;
+  exports org.apache.fory.codegen;
+  exports org.apache.fory.collection;
+  exports org.apache.fory.config;
+  exports org.apache.fory.context;
+  exports org.apache.fory.exception;
+  exports org.apache.fory.io;
+  exports org.apache.fory.logging;
+  exports org.apache.fory.memory;
+  exports org.apache.fory.meta;
+  exports org.apache.fory.platform;
+  exports org.apache.fory.pool;
+  exports org.apache.fory.reflect;
+  exports org.apache.fory.resolver;
+  exports org.apache.fory.serializer;
+  exports org.apache.fory.serializer.collection;
+  exports org.apache.fory.serializer.converter;
+  exports org.apache.fory.serializer.scala;
+  exports org.apache.fory.serializer.struct;
+  exports org.apache.fory.type;
+  exports org.apache.fory.type.union;
+  exports org.apache.fory.type.unsigned;
+  exports org.apache.fory.util;
+  exports org.apache.fory.util.function;
+  exports org.apache.fory.util.record;
+  exports org.apache.fory.util.unsafe to
+      org.apache.fory.format;
+}
diff --git 
a/java/fory-simd/src/main/java/org/apache/fory/serializer/CompressedArraySerializers.java
 
b/java/fory-core/src/main/java16/org/apache/fory/serializer/CompressedArraySerializers.java
similarity index 99%
rename from 
java/fory-simd/src/main/java/org/apache/fory/serializer/CompressedArraySerializers.java
rename to 
java/fory-core/src/main/java16/org/apache/fory/serializer/CompressedArraySerializers.java
index ba4f2e247..9f4eee99c 100644
--- 
a/java/fory-simd/src/main/java/org/apache/fory/serializer/CompressedArraySerializers.java
+++ 
b/java/fory-core/src/main/java16/org/apache/fory/serializer/CompressedArraySerializers.java
@@ -36,7 +36,7 @@ import org.apache.fory.util.ArrayCompressionUtils;
 import org.apache.fory.util.PrimitiveArrayCompressionType;
 
 /**
- * Compressed array serializers using Java 16+ Vector API for SIMD 
acceleration.
+ * Compressed array serializers with optional Java 16+ Vector API acceleration.
  *
  * <p>To use these serializers, simply call {@code 
CompressedArraySerializers.register(fory)} on
  * your Fory instance. These will override the default array serializers for 
{@code int[]} and
diff --git 
a/java/fory-simd/src/main/java/org/apache/fory/util/ArrayCompressionUtils.java 
b/java/fory-core/src/main/java16/org/apache/fory/util/ArrayCompressionUtils.java
similarity index 60%
rename from 
java/fory-simd/src/main/java/org/apache/fory/util/ArrayCompressionUtils.java
rename to 
java/fory-core/src/main/java16/org/apache/fory/util/ArrayCompressionUtils.java
index a55a53da8..08d2111df 100644
--- 
a/java/fory-simd/src/main/java/org/apache/fory/util/ArrayCompressionUtils.java
+++ 
b/java/fory-core/src/main/java16/org/apache/fory/util/ArrayCompressionUtils.java
@@ -25,75 +25,64 @@ import jdk.incubator.vector.VectorOperators;
 import jdk.incubator.vector.VectorSpecies;
 
 /**
- * Utility class for primitive array compression operations. It uses 
SIMD-accelerated array
- * compression using Java 16+ Vector API.
+ * Utility methods for optional primitive array compression.
  *
- * <p>This utility provides compression for primitive arrays by detecting when 
values can fit in
- * smaller data types:
+ * <p>The compressed array serializers use these helpers when every value in a 
primitive array fits
+ * in a narrower primitive type:
  *
  * <ul>
- *   <li>int[] → byte[] when all values are in [-128, 127] range (75% size 
reduction)
- *   <li>int[] → short[] when all values are in [-32768, 32767] range (50% 
size reduction)
- *   <li>long[] → int[] when all values fit in integer range (50% size 
reduction)
+ *   <li>{@code int[]} to {@code byte[]} when all values are in byte range.
+ *   <li>{@code int[]} to {@code short[]} when all values are in short range.
+ *   <li>{@code long[]} to {@code int[]} when all values are in int range.
  * </ul>
- *
- * <p>Uses the best available compression provider via ServiceLoader pattern. 
SIMD optimizations are
- * used when fory-simd module is available. When no compression provider is 
available, compression
- * is disabled entirely.
  */
 public final class ArrayCompressionUtils {
+  // Minimum array size to justify compression analysis and the compressed 
payload marker overhead.
+  static final int MIN_COMPRESSION_SIZE = 1 << 9;
   private static final VectorSpecies<Integer> INT_SPECIES = 
IntVector.SPECIES_PREFERRED;
   private static final VectorSpecies<Long> LONG_SPECIES = 
LongVector.SPECIES_PREFERRED;
 
-  // Minimum array size to justify compression overhead
-  private static final int MIN_COMPRESSION_SIZE = 1 << 9; // 512 elements
+  private ArrayCompressionUtils() {}
 
   /**
-   * Determine the best compression type for int array.
+   * Determines the best compression type for an int array.
    *
-   * @param array the int array to analyze
-   * @return compression type (NONE, INT_TO_BYTE, or INT_TO_SHORT)
-   * @throws NullPointerException if array is null
+   * @param array the array to analyze
+   * @return {@link PrimitiveArrayCompressionType#INT_TO_BYTE}, {@link
+   *     PrimitiveArrayCompressionType#INT_TO_SHORT}, or {@link 
PrimitiveArrayCompressionType#NONE}
+   * @throws NullPointerException if {@code array} is null
    */
   public static PrimitiveArrayCompressionType 
determineIntCompressionType(int[] array) {
     if (array == null) {
       throw new NullPointerException("Input array cannot be null");
     }
     if (array.length < MIN_COMPRESSION_SIZE) {
-      // No compression for empty or too small arrays
       return PrimitiveArrayCompressionType.NONE;
     }
-
     boolean canCompressToByte = true;
     boolean canCompressToShort = true;
-
     int i = 0;
-    final int upperBound = INT_SPECIES.loopBound(array.length);
+    int upperBound = INT_SPECIES.loopBound(array.length);
 
-    // SIMD loop
+    // Vector loop: test each lane against the target primitive ranges and 
stop checking a narrower
+    // representation once any lane exceeds its range.
     for (; i < upperBound && (canCompressToByte || canCompressToShort); i += 
INT_SPECIES.length()) {
       IntVector vector = IntVector.fromArray(INT_SPECIES, array, i);
-
-      // Check byte compression using mask operations
       if (canCompressToByte) {
-        var byteMaxMask = vector.compare(VectorOperators.GT, Byte.MAX_VALUE);
-        var byteMinMask = vector.compare(VectorOperators.LT, Byte.MIN_VALUE);
-        if (byteMaxMask.anyTrue() || byteMinMask.anyTrue()) {
+        if (vector.compare(VectorOperators.GT, Byte.MAX_VALUE).anyTrue()
+            || vector.compare(VectorOperators.LT, Byte.MIN_VALUE).anyTrue()) {
           canCompressToByte = false;
         }
       }
-
-      // Check short compression using mask operations
       if (canCompressToShort) {
-        var shortMaxMask = vector.compare(VectorOperators.GT, Short.MAX_VALUE);
-        var shortMinMask = vector.compare(VectorOperators.LT, Short.MIN_VALUE);
-        if (shortMaxMask.anyTrue() || shortMinMask.anyTrue()) {
+        if (vector.compare(VectorOperators.GT, Short.MAX_VALUE).anyTrue()
+            || vector.compare(VectorOperators.LT, Short.MIN_VALUE).anyTrue()) {
           canCompressToShort = false;
         }
       }
     }
 
-    // Handle remaining elements with scalar code
+    // Scalar tail for elements that do not fill a complete vector.
     for (; i < array.length && (canCompressToByte || canCompressToShort); i++) 
{
       int value = array[i];
       if (canCompressToByte && (value < Byte.MIN_VALUE || value > 
Byte.MAX_VALUE)) {
@@ -103,22 +92,21 @@ public final class ArrayCompressionUtils {
         canCompressToShort = false;
       }
     }
-
     if (canCompressToByte) {
       return PrimitiveArrayCompressionType.INT_TO_BYTE;
-    } else if (canCompressToShort) {
-      return PrimitiveArrayCompressionType.INT_TO_SHORT;
-    } else {
-      return PrimitiveArrayCompressionType.NONE;
     }
+    return canCompressToShort
+        ? PrimitiveArrayCompressionType.INT_TO_SHORT
+        : PrimitiveArrayCompressionType.NONE;
   }
 
   /**
-   * Determine the best compression type for long array.
+   * Determines the best compression type for a long array.
    *
-   * @param array the long array to analyze
-   * @return compression type (NONE or LONG_TO_INT)
-   * @throws NullPointerException if array is null
+   * @param array the array to analyze
+   * @return {@link PrimitiveArrayCompressionType#LONG_TO_INT} or {@link
+   *     PrimitiveArrayCompressionType#NONE}
+   * @throws NullPointerException if {@code array} is null
    */
   public static PrimitiveArrayCompressionType 
determineLongCompressionType(long[] array) {
     if (array == null) {
@@ -127,42 +115,34 @@ public final class ArrayCompressionUtils {
     if (array.length < MIN_COMPRESSION_SIZE) {
       return PrimitiveArrayCompressionType.NONE;
     }
-    boolean canCompressToInt = true;
-
     int i = 0;
     int upperBound = LONG_SPECIES.loopBound(array.length);
 
-    // SIMD loop
-    for (; i < upperBound && canCompressToInt; i += LONG_SPECIES.length()) {
+    // Vector loop: any lane outside int range means long-to-int compression 
is not safe.
+    for (; i < upperBound; i += LONG_SPECIES.length()) {
       LongVector vector = LongVector.fromArray(LONG_SPECIES, array, i);
-
-      // Check int compression using mask operations
-      var maxMask = vector.compare(VectorOperators.GT, Integer.MAX_VALUE);
-      var minMask = vector.compare(VectorOperators.LT, Integer.MIN_VALUE);
-      if (maxMask.anyTrue() || minMask.anyTrue()) {
-        canCompressToInt = false;
+      if (vector.compare(VectorOperators.GT, Integer.MAX_VALUE).anyTrue()
+          || vector.compare(VectorOperators.LT, Integer.MIN_VALUE).anyTrue()) {
+        return PrimitiveArrayCompressionType.NONE;
       }
     }
 
-    // Handle remaining elements
-    for (; i < array.length && canCompressToInt; i++) {
+    // Scalar tail for elements that do not fill a complete vector.
+    for (; i < array.length; i++) {
       long value = array[i];
       if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
-        canCompressToInt = false;
+        return PrimitiveArrayCompressionType.NONE;
       }
     }
-
-    return canCompressToInt
-        ? PrimitiveArrayCompressionType.LONG_TO_INT
-        : PrimitiveArrayCompressionType.NONE;
+    return PrimitiveArrayCompressionType.LONG_TO_INT;
   }
 
   /**
-   * Compress int array to byte array.
+   * Compresses an int array to a byte array.
    *
-   * @param array the int array to compress
+   * @param array the int array to compress; values must be in byte range
    * @return compressed byte array
-   * @throws NullPointerException if array is null
+   * @throws NullPointerException if {@code array} is null
    */
   public static byte[] compressToBytes(int[] array) {
     if (array == null) {
@@ -176,11 +156,11 @@ public final class ArrayCompressionUtils {
   }
 
   /**
-   * Compress int array to short array.
+   * Compresses an int array to a short array.
    *
-   * @param array the int array to compress (values must be in short range)
+   * @param array the int array to compress; values must be in short range
    * @return compressed short array
-   * @throws NullPointerException if array is null
+   * @throws NullPointerException if {@code array} is null
    */
   public static short[] compressToShorts(int[] array) {
     if (array == null) {
@@ -194,11 +174,11 @@ public final class ArrayCompressionUtils {
   }
 
   /**
-   * Compress long array to int array.
+   * Compresses a long array to an int array.
    *
-   * @param array the long array to compress (values must be in int range)
+   * @param array the long array to compress; values must be in int range
    * @return compressed int array
-   * @throws NullPointerException if array is null
+   * @throws NullPointerException if {@code array} is null
    */
   public static int[] compressToInts(long[] array) {
     if (array == null) {
@@ -212,11 +192,11 @@ public final class ArrayCompressionUtils {
   }
 
   /**
-   * Decompress byte array to int array.
+   * Decompresses a byte array to an int array.
    *
    * @param array the byte array to decompress
    * @return decompressed int array
-   * @throws NullPointerException if array is null
+   * @throws NullPointerException if {@code array} is null
    */
   public static int[] decompressFromBytes(byte[] array) {
     if (array == null) {
@@ -230,11 +210,11 @@ public final class ArrayCompressionUtils {
   }
 
   /**
-   * Decompress short array to int array.
+   * Decompresses a short array to an int array.
    *
    * @param array the short array to decompress
    * @return decompressed int array
-   * @throws NullPointerException if array is null
+   * @throws NullPointerException if {@code array} is null
    */
   public static int[] decompressFromShorts(short[] array) {
     if (array == null) {
@@ -248,17 +228,16 @@ public final class ArrayCompressionUtils {
   }
 
   /**
-   * Decompress int array to long array.
+   * Decompresses an int array to a long array.
    *
    * @param array the int array to decompress
    * @return decompressed long array
-   * @throws NullPointerException if array is null
+   * @throws NullPointerException if {@code array} is null
    */
   public static long[] decompressFromInts(int[] array) {
     if (array == null) {
       throw new NullPointerException("Array cannot be null");
     }
-
     long[] decompressed = new long[array.length];
     for (int i = 0; i < array.length; i++) {
       decompressed[i] = array[i];
diff --git 
a/java/fory-simd/src/main/java/org/apache/fory/util/PrimitiveArrayCompressionType.java
 
b/java/fory-core/src/main/java16/org/apache/fory/util/PrimitiveArrayCompressionType.java
similarity index 82%
rename from 
java/fory-simd/src/main/java/org/apache/fory/util/PrimitiveArrayCompressionType.java
rename to 
java/fory-core/src/main/java16/org/apache/fory/util/PrimitiveArrayCompressionType.java
index 61e7c6fe6..477b2037b 100644
--- 
a/java/fory-simd/src/main/java/org/apache/fory/util/PrimitiveArrayCompressionType.java
+++ 
b/java/fory-core/src/main/java16/org/apache/fory/util/PrimitiveArrayCompressionType.java
@@ -23,18 +23,19 @@ package org.apache.fory.util;
  * Compression types for primitive arrays.
  *
  * <p>Defines the available compression strategies for reducing the size of 
primitive arrays by
- * detecting when values can fit in smaller data types.
+ * detecting when values can be stored with a narrower primitive type.
  */
 public enum PrimitiveArrayCompressionType {
-  // No compression applied
+  /** No compression applied. */
   NONE(0),
 
-  // Compression for int arrays:
-  // int[] → byte[] compression (75% size reduction)
+  /** Compresses {@code int[]} values to {@code byte[]} when every value fits 
in byte range. */
   INT_TO_BYTE(1),
-  // int[] → short[] compression (50% size reduction)
+
+  /** Compresses {@code int[]} values to {@code short[]} when every value fits 
in short range. */
   INT_TO_SHORT(2),
-  // Compression for long arrays: long[] → int[] compression (50% size 
reduction)
+
+  /** Compresses {@code long[]} values to {@code int[]} when every value fits 
in int range. */
   LONG_TO_INT(3);
 
   private final int value;
@@ -46,7 +47,7 @@ public enum PrimitiveArrayCompressionType {
   /**
    * Gets the numeric value for this compression type.
    *
-   * @return the numeric value
+   * @return the numeric value written to the serialized payload
    */
   public int getValue() {
     return value;
@@ -55,7 +56,7 @@ public enum PrimitiveArrayCompressionType {
   /**
    * Gets the compression type from its numeric value.
    *
-   * @param value the numeric value
+   * @param value the numeric value read from the serialized payload
    * @return the corresponding compression type
    * @throws IllegalArgumentException if the value is not valid
    */
@@ -76,6 +77,8 @@ public enum PrimitiveArrayCompressionType {
 
   /** Compression utilities for int arrays. Supports compression to byte[] and 
short[] formats. */
   public static final class IntArrayCompression {
+    private IntArrayCompression() {}
+
     /**
      * Determines the best compression type for the given int array.
      *
@@ -97,7 +100,10 @@ public enum PrimitiveArrayCompressionType {
     }
   }
 
+  /** Compression utilities for long arrays. Supports compression to int[] 
format. */
   public static final class LongArrayCompression {
+    private LongArrayCompression() {}
+
     /**
      * Determines the best compression type for the given long array.
      *
diff --git a/java/fory-core/src/main/java9/module-info.java 
b/java/fory-core/src/main/java9/module-info.java
new file mode 100644
index 000000000..e381802ca
--- /dev/null
+++ b/java/fory-core/src/main/java9/module-info.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+module org.apache.fory.core {
+  requires java.logging;
+  requires jdk.unsupported;
+
+  requires static java.sql;
+  requires static com.google.common;
+  requires static org.slf4j;
+  requires static jsr305;
+
+  exports org.apache.fory;
+  exports org.apache.fory.annotation;
+  exports org.apache.fory.builder;
+  exports org.apache.fory.codegen;
+  exports org.apache.fory.collection;
+  exports org.apache.fory.config;
+  exports org.apache.fory.context;
+  exports org.apache.fory.exception;
+  exports org.apache.fory.io;
+  exports org.apache.fory.logging;
+  exports org.apache.fory.memory;
+  exports org.apache.fory.meta;
+  exports org.apache.fory.platform;
+  exports org.apache.fory.pool;
+  exports org.apache.fory.reflect;
+  exports org.apache.fory.resolver;
+  exports org.apache.fory.serializer;
+  exports org.apache.fory.serializer.collection;
+  exports org.apache.fory.serializer.converter;
+  exports org.apache.fory.serializer.scala;
+  exports org.apache.fory.serializer.struct;
+  exports org.apache.fory.type;
+  exports org.apache.fory.type.union;
+  exports org.apache.fory.type.unsigned;
+  exports org.apache.fory.util;
+  exports org.apache.fory.util.function;
+  exports org.apache.fory.util.record;
+  exports org.apache.fory.util.unsafe to
+      org.apache.fory.format;
+}
diff --git a/java/fory-format/pom.xml b/java/fory-format/pom.xml
index 01cdd773e..a1fecb2ef 100644
--- a/java/fory-format/pom.xml
+++ b/java/fory-format/pom.xml
@@ -106,6 +106,7 @@
           <archive>
             <manifestEntries>
               
<Automatic-Module-Name>org.apache.fory.format</Automatic-Module-Name>
+              <Multi-Release>true</Multi-Release>
             </manifestEntries>
           </archive>
         </configuration>
@@ -121,6 +122,71 @@
   </build>
 
   <profiles>
+    <profile>
+      <id>jpms-java11</id>
+      <activation>
+        <jdk>[11,)</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <version>3.1.0</version>
+            <executions>
+              <execution>
+                <id>compile-java11-module-info</id>
+                <phase>process-classes</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <target>
+                    <mkdir 
dir="${project.build.directory}/jpms-classes/java11"/>
+                    <path id="compile.module.path.elements">
+                      <pathelement 
location="${project.basedir}/../fory-core/target/jpms-classes/java9"/>
+                      <path refid="maven.compile.classpath"/>
+                    </path>
+                    <pathconvert property="compile.module.path" 
refid="compile.module.path.elements"
+                                 pathsep="${path.separator}"/>
+                    <javac srcdir="${project.basedir}/src/main/java11"
+                           
destdir="${project.build.directory}/jpms-classes/java11"
+                           includeantruntime="false"
+                           fork="true"
+                           executable="${java.home}/bin/javac"
+                           debug="true">
+                      <include name="module-info.java"/>
+                      <compilerarg value="--release"/>
+                      <compilerarg value="11"/>
+                      <compilerarg value="--module-path"/>
+                      <compilerarg path="${compile.module.path}"/>
+                      <compilerarg value="--patch-module"/>
+                      <compilerarg 
value="org.apache.fory.format=${project.build.outputDirectory}"/>
+                    </javac>
+                  </target>
+                </configuration>
+              </execution>
+              <execution>
+                <id>inject-java11-module-info</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <target>
+                    <jar 
destfile="${project.build.directory}/${project.build.finalName}.jar" 
update="true">
+                      <zipfileset 
dir="${project.build.directory}/jpms-classes/java11"
+                                  prefix="META-INF/versions/11"
+                                  includes="module-info.class"/>
+                    </jar>
+                  </target>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
     <profile>
       <id>releaseShade</id>
       <activation>
@@ -170,6 +236,8 @@
                     <filter>
                       <artifact>*:*</artifact>
                       <excludes>
+                        <exclude>module-info.class</exclude>
+                        
<exclude>META-INF/versions/**/module-info.class</exclude>
                         <exclude>META-INF/*.SF</exclude>
                         <exclude>META-INF/*.DSA</exclude>
                         <exclude>META-INF/*.RSA</exclude>
diff --git 
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/LazyArrayData.java
 
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/LazyArrayData.java
index 38a9b92b5..c75f5b222 100644
--- 
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/LazyArrayData.java
+++ 
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/LazyArrayData.java
@@ -21,7 +21,7 @@ package org.apache.fory.format.encoder;
 
 import static org.apache.fory.type.TypeUtils.getRawType;
 
-import java.awt.List;
+import java.util.List;
 import org.apache.fory.annotation.Internal;
 import org.apache.fory.codegen.ClosureVisitable;
 import org.apache.fory.codegen.Code;
diff --git a/java/fory-format/src/main/java11/module-info.java 
b/java/fory-format/src/main/java11/module-info.java
new file mode 100644
index 000000000..0f6064b8e
--- /dev/null
+++ b/java/fory-format/src/main/java11/module-info.java
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+module org.apache.fory.format {
+  requires transitive org.apache.fory.core;
+
+  requires static java.sql;
+  requires static transitive org.apache.arrow.memory.core;
+  requires static transitive org.apache.arrow.vector;
+
+  exports org.apache.fory.format.encoder;
+  exports org.apache.fory.format.row;
+  exports org.apache.fory.format.row.binary;
+  exports org.apache.fory.format.row.binary.writer;
+  exports org.apache.fory.format.type;
+  exports org.apache.fory.format.vectorized;
+}
diff --git a/java/fory-simd/pom.xml b/java/fory-simd/pom.xml
deleted file mode 100644
index 675e18374..000000000
--- a/java/fory-simd/pom.xml
+++ /dev/null
@@ -1,94 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    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.
-
--->
-<project  xmlns="http://maven.apache.org/POM/4.0.0";
-          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
-  <parent>
-    <groupId>org.apache.fory</groupId>
-    <artifactId>fory-parent</artifactId>
-    <version>1.1.0-SNAPSHOT</version>
-  </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-  <artifactId>fory-simd</artifactId>
-
-    <description>
-        Apache Fory™ is a blazingly fast multi-language serialization 
framework powered by jit and zero-copy.
-    </description>
-
-  <properties>
-    <maven.compiler.source>17</maven.compiler.source>
-    <maven.compiler.target>17</maven.compiler.target>
-  <fory.java.rootdir>${basedir}/..</fory.java.rootdir>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.fory</groupId>
-      <artifactId>fory-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-
-    <!-- Test dependencies -->
-    <dependency>
-      <groupId>org.testng</groupId>
-      <artifactId>testng</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <configuration>
-          <source>16</source>
-          <target>16</target>
-          <compilerArgs>
-            <arg>--add-modules=jdk.incubator.vector</arg>
-          </compilerArgs>
-        </configuration>
-      </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <argLine>--add-modules=jdk.incubator.vector</argLine>
-        </configuration>
-      </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <configuration>
-          <!-- Turn this on once 
https://github.com/apache/maven-javadoc-plugin/issues/1310 is resolved -->
-          <failOnWarnings>false</failOnWarnings>
-          <additionalOptions>
-            
<additionalOption>--add-modules=jdk.incubator.vector</additionalOption>
-          </additionalOptions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
diff --git a/java/fory-testsuite/pom.xml b/java/fory-testsuite/pom.xml
index 7831d56dc..736307343 100644
--- a/java/fory-testsuite/pom.xml
+++ b/java/fory-testsuite/pom.xml
@@ -142,4 +142,63 @@
     </plugins>
   </build>
 
+  <profiles>
+    <profile>
+      <id>java16-compression-tests</id>
+      <activation>
+        <jdk>[16,)</jdk>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <version>3.1.0</version>
+            <executions>
+              <execution>
+                <id>compile-java16-compression-tests</id>
+                <phase>test-compile</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <target>
+                    <mkdir dir="${project.build.testOutputDirectory}"/>
+                    <pathconvert property="java16.test.classpath" 
refid="maven.test.classpath"
+                                 pathsep="${path.separator}"/>
+                    <javac srcdir="${project.basedir}/src/test/java16"
+                           destdir="${project.build.testOutputDirectory}"
+                           
classpath="${project.basedir}/../fory-core/target/jpms-classes/java16${path.separator}${java16.test.classpath}"
+                           includeantruntime="false"
+                           fork="true"
+                           executable="${java.home}/bin/javac"
+                           debug="true">
+                      <include name="**/*.java"/>
+                      <compilerarg value="--source"/>
+                      <compilerarg value="16"/>
+                      <compilerarg value="--target"/>
+                      <compilerarg value="16"/>
+                      <compilerarg value="--add-modules"/>
+                      <compilerarg value="jdk.incubator.vector"/>
+                    </javac>
+                  </target>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <argLine>--add-modules=jdk.incubator.vector</argLine>
+              <additionalClasspathElements>
+                
<additionalClasspathElement>${project.basedir}/../fory-core/target/jpms-classes/java16</additionalClasspathElement>
+              </additionalClasspathElements>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
 </project>
diff --git 
a/java/fory-simd/src/test/java/org/apache/fory/serializer/ArrayCompressionTest.java
 
b/java/fory-testsuite/src/test/java16/org/apache/fory/serializer/ArrayCompressionTest.java
similarity index 99%
rename from 
java/fory-simd/src/test/java/org/apache/fory/serializer/ArrayCompressionTest.java
rename to 
java/fory-testsuite/src/test/java16/org/apache/fory/serializer/ArrayCompressionTest.java
index 665026410..a248b84c3 100644
--- 
a/java/fory-simd/src/test/java/org/apache/fory/serializer/ArrayCompressionTest.java
+++ 
b/java/fory-testsuite/src/test/java16/org/apache/fory/serializer/ArrayCompressionTest.java
@@ -29,7 +29,6 @@ import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 public class ArrayCompressionTest {
-
   @DataProvider(name = "intArrayData")
   public Object[][] intArrayData() {
     return new Object[][] {
diff --git 
a/java/fory-simd/src/test/java/org/apache/fory/serializer/ArrayCompressionUtilsTest.java
 
b/java/fory-testsuite/src/test/java16/org/apache/fory/serializer/ArrayCompressionUtilsTest.java
similarity index 99%
rename from 
java/fory-simd/src/test/java/org/apache/fory/serializer/ArrayCompressionUtilsTest.java
rename to 
java/fory-testsuite/src/test/java16/org/apache/fory/serializer/ArrayCompressionUtilsTest.java
index 29145b7a7..6c3b64a0a 100644
--- 
a/java/fory-simd/src/test/java/org/apache/fory/serializer/ArrayCompressionUtilsTest.java
+++ 
b/java/fory-testsuite/src/test/java16/org/apache/fory/serializer/ArrayCompressionUtilsTest.java
@@ -28,7 +28,6 @@ import org.apache.fory.util.PrimitiveArrayCompressionType;
 import org.testng.annotations.Test;
 
 public class ArrayCompressionUtilsTest {
-
   @Test
   public void testIntArrayCompressionDetection() {
     // Test byte range compression - make array size >= 512
diff --git a/java/pom.xml b/java/pom.xml
index 4e1d14ae4..473b2c6a9 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -105,7 +105,6 @@
         <jdk>[21,]</jdk>
       </activation>
       <modules>
-        <module>fory-simd</module>
         <module>fory-latest-jdk-tests</module>
       </modules>
     </profile>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to