Author: brane
Date: Wed May  6 18:54:21 2026
New Revision: 1933892

Log:
Make the JavaHL JAR an automatic module.

As described in [1], since version 24, the JVM will issue a warning for every
module that uses a restricted function (such as JNI calls). Later versions of
the JDK will default to throwing an exception.

To give our uses fine-grained control over access to restricted functions,
these changes declare the JavaHL JAR as a module and change the way we run
the JavaHL tests by building it first and running tests from there instead
of from the compiled classes tree. We explicitly allow JNI access only to
the org.apache.subversion.javahl module and deny it to anything else.

[1] https://inside.java/2024/12/09/quality-heads-up/


* build.conf: Make all Java targets depend on the $(JAVAHL_JAR).
* configure.ac: Look for the 'head' tool.
* build/ac-macros/java.m4
  (SVN_FIND_JDK): Extract the Java version from the 'java' tool instead
   of the 'javac' tool. If the Java version is 24 or greater, define ...
  (JAVAHL_CHECK_FLAGS): ... to declare the module permissions for tests.

* Makefile.in
  (INSTALL_EXTRA_JAVAHL_JAVA): Remove the install-time JAR creation. Instead,
  ($(JAVAHL_JAR):): ... add an explicit target to build the JAR.
  (JAVAHL_CHECK_FLAGS): Gather common flags for JavaHL testing in one place.
  (check-tigris-javahl, check-apache-javahl, check-deprecated-authn-javahl):
   Depend on $(JAVAHL_JAR) and use $(JAVAHL_CHECK_FLAGS).

* subversion/bindings/javahl/Manifest.in: Add Automatic-Module-Name property.

Modified:
   subversion/trunk/Makefile.in
   subversion/trunk/build.conf
   subversion/trunk/build/ac-macros/java.m4
   subversion/trunk/configure.ac
   subversion/trunk/subversion/bindings/javahl/Manifest.in

Modified: subversion/trunk/Makefile.in
==============================================================================
--- subversion/trunk/Makefile.in        Wed May  6 18:30:37 2026        
(r1933891)
+++ subversion/trunk/Makefile.in        Wed May  6 18:54:21 2026        
(r1933892)
@@ -378,8 +378,6 @@ SWIG_RB_SRC_DIR = $(abs_srcdir)/subversi
 JAVAHL_MANIFEST_IN = $(abs_srcdir)/subversion/bindings/javahl/Manifest.in
 JAVAHL_MANIFEST = subversion/bindings/javahl/Manifest
 INSTALL_EXTRA_JAVAHL_JAVA=\
-       sed s/%bundleVersion/$(PACKAGE_VERSION)/ $(JAVAHL_MANIFEST_IN) > 
$(JAVAHL_MANIFEST); \
-       $(JAR) cfm $(JAVAHL_JAR) $(JAVAHL_MANIFEST) -C 
subversion/bindings/javahl/classes org; \
        $(INSTALL_DATA) $(JAVAHL_JAR) $(DESTDIR)$(javahl_javadir);
 
 INSTALL_EXTRA_JAVAHL_LIB=@INSTALL_EXTRA_JAVAHL_LIB@
@@ -524,20 +522,26 @@ clean-javahl:
        rm -f $(libsvnjavahl_PATH)/*.lo
        rm -f $(libsvnjavahl_PATH)/*.o
 
-check-tigris-javahl: javahl-compat
+JAVAHL_CHECK_FLAGS = @JAVAHL_CHECK_FLAGS@ -Xcheck:jni 
"-Dtest.rootdir=$(javahl_test_rootdir)" "-Dtest.srcdir=$(javahl_test_srcdir)" 
"-Dtest.rooturl=$(BASE_URL)" "-Dtest.fstype=$(FS_TYPE)" 
"-Djava.library.path=@JAVAHL_OBJDIR@:$(libdir)" 
"-Dtest.cleanup=$(JAVAHL_CLEANUP)" "-Dtest.tests=$(JAVAHL_TESTS)" -classpath 
"$(JAVAHL_JAR):$(javahl_tests_CLASSPATH)"
+
+$(JAVAHL_JAR): $(JAVAHL_MANIFEST_IN) $(javahl_callback_java_OBJECTS) 
$(javahl_compat_java_OBJECTS) $(javahl_compat_tests_OBJECTS) 
$(javahl_java_OBJECTS) $(javahl_remote_java_OBJECT) $(javahl_tests_OBJECTS) 
$(javahl_types_java_OBJECTS) $(javahl_util_java_OBJECTS)
+       sed s/%bundleVersion/$(PACKAGE_VERSION)/ $(JAVAHL_MANIFEST_IN) > 
$(JAVAHL_MANIFEST) && \
+       $(JAR) cfm $(JAVAHL_JAR) $(JAVAHL_MANIFEST) -C 
subversion/bindings/javahl/classes org
+
+check-tigris-javahl: javahl-compat $(JAVAHL_JAR)
        @FIX_JAVAHL_LIB@
        $(TEST_SHLIB_VAR_JAVAHL) \
-       $(JAVA) -Xcheck:jni "-Dtest.rootdir=$(javahl_test_rootdir)" 
"-Dtest.srcdir=$(javahl_test_srcdir)" "-Dtest.rooturl=$(BASE_URL)" 
"-Dtest.fstype=$(FS_TYPE)" "-Djava.library.path=@JAVAHL_OBJDIR@:$(libdir)" 
-classpath "$(javahl_compat_tests_PATH):$(javahl_tests_CLASSPATH)" 
"-Dtest.cleanup=$(JAVAHL_CLEANUP)" "-Dtest.tests=$(JAVAHL_TESTS)" 
org.tigris.subversion.javahl.RunTests
+       $(JAVA) $(JAVAHL_CHECK_FLAGS) org.tigris.subversion.javahl.RunTests
 
-check-apache-javahl: javahl
+check-apache-javahl: javahl $(JAVAHL_JAR)
        @FIX_JAVAHL_LIB@
        $(TEST_SHLIB_VAR_JAVAHL) \
-       $(JAVA) -Xcheck:jni "-Dtest.rootdir=$(javahl_test_rootdir)" 
"-Dtest.srcdir=$(javahl_test_srcdir)" "-Dtest.rooturl=$(BASE_URL)" 
"-Dtest.fstype=$(FS_TYPE)" "-Djava.library.path=@JAVAHL_OBJDIR@:$(libdir)" 
-classpath "$(javahl_tests_PATH):$(javahl_tests_CLASSPATH)" 
"-Dtest.cleanup=$(JAVAHL_CLEANUP)" "-Dtest.tests=$(JAVAHL_TESTS)" 
org.apache.subversion.javahl.RunTests
+       $(JAVA) $(JAVAHL_CHECK_FLAGS) org.apache.subversion.javahl.RunTests
 
-check-deprecated-authn-javahl: javahl
+check-deprecated-authn-javahl: javahl $(JAVAHL_JAR)
        @FIX_JAVAHL_LIB@
        $(TEST_SHLIB_VAR_JAVAHL) \
-       $(JAVA) -Xcheck:jni "-Dtest.rootdir=$(javahl_test_rootdir)" 
"-Dtest.srcdir=$(javahl_test_srcdir)" "-Dtest.rooturl=$(BASE_URL)" 
"-Dtest.fstype=$(FS_TYPE)" "-Djava.library.path=@JAVAHL_OBJDIR@:$(libdir)" 
-classpath "$(javahl_tests_PATH):$(javahl_tests_CLASSPATH)" 
"-Dtest.cleanup=$(JAVAHL_CLEANUP)" "-Dtest.tests=$(JAVAHL_TESTS)" 
"-Dtest.authn.deprecated=true" org.apache.subversion.javahl.RunTests
+       $(JAVA) $(JAVAHL_CHECK_FLAGS) "-Dtest.authn.deprecated=true" 
org.apache.subversion.javahl.RunTests
 
 check-javahl: check-apache-javahl
 

Modified: subversion/trunk/build.conf
==============================================================================
--- subversion/trunk/build.conf Wed May  6 18:30:37 2026        (r1933891)
+++ subversion/trunk/build.conf Wed May  6 18:54:21 2026        (r1933892)
@@ -647,6 +647,7 @@ sources = *.java
 native = CommitItemStateFlags.java NativeResources.java SVNClient.java
          SVNRepos.java
 install = javahl-java
+add-install-deps = $(JAVAHL_JAR)
 link-cmd = $(COMPILE_JAVAHL_JAVAC)
 classes = subversion/bindings/javahl/classes
 headers = subversion/bindings/javahl/include
@@ -656,7 +657,8 @@ package = org.apache.subversion.javahl
 type = java
 path = subversion/bindings/javahl/src/org/tigris/subversion/javahl
 sources = *.java
-install = javahl-java
+install = javahl-compat-java
+add-install-deps = $(JAVAHL_JAR)
 link-cmd = $(COMPILE_JAVAHL_COMPAT_JAVAC)
 classes = subversion/bindings/javahl/classes
 add-deps = $(javahl_callback_java_DEPS) $(javahl_remote_java_DEPS)
@@ -670,7 +672,8 @@ package = org.tigris.subversion.javahl
 type = java
 path = subversion/bindings/javahl/tests/org/apache/subversion/javahl
 sources = *.java
-install = javahl-java
+install = javahl-tests
+add-install-deps = $(JAVAHL_JAR)
 link-cmd = $(COMPILE_JAVAHL_JAVAC)
 classes = subversion/bindings/javahl/classes
 package = org.apache.subversion.javahl
@@ -684,7 +687,8 @@ add-deps = $(javahl_callback_java_DEPS)
 type = java
 path = subversion/bindings/javahl/tests/org/tigris/subversion/javahl
 sources = *.java
-install = javahl-java
+install = javahl-compat-tests
+add-install-deps = $(JAVAHL_JAR)
 link-cmd = $(COMPILE_JAVAHL_COMPAT_JAVAC)
 classes = subversion/bindings/javahl/classes
 package = org.tigris.subversion.javahl
@@ -700,7 +704,8 @@ headers = subversion/bindings/javahl/inc
 package = org.apache.subversion.javahl.callback
 sources = *.java
 native = UserPasswordCallback.java
-install = javahl-java
+install = javahl-callback-java
+add-install-deps = $(JAVAHL_JAR)
 link-cmd = $(COMPILE_JAVAHL_JAVAC)
 
 [javahl-remote-java]
@@ -712,7 +717,8 @@ package = org.apache.subversion.javahl.r
 sources = *.java
 native = CommitEditor.java RemoteFactory.java RemoteSession.java
          StateReporter.java
-install = javahl-java
+install = javahl-remote-java
+add-install-deps = $(JAVAHL_JAR)
 link-cmd = $(COMPILE_JAVAHL_JAVAC)
 
 [javahl-types-java]
@@ -725,7 +731,8 @@ sources = *.java
 native = NativeInputStream.java NativeOutputStream.java Revision.java
          RevisionRangeList.java RuntimeVersion.java VersionExtended.java
          Version.java
-install = javahl-java
+install = javahl-types-java
+add-install-deps = $(JAVAHL_JAR)
 link-cmd = $(COMPILE_JAVAHL_JAVAC)
 
 [javahl-util-java]
@@ -738,7 +745,8 @@ sources = *.java
 native = ConfigImpl.java ConfigLib.java DiffLib.java PropLib.java
          RequestChannel.java ResponseChannel.java SubstLib.java
          TunnelChannel.java
-install = javahl-java
+install = javahl-util-java
+add-install-deps = $(JAVAHL_JAR)
 link-cmd = $(COMPILE_JAVAHL_JAVAC)
 
 [libsvnjavahl]

Modified: subversion/trunk/build/ac-macros/java.m4
==============================================================================
--- subversion/trunk/build/ac-macros/java.m4    Wed May  6 18:30:37 2026        
(r1933891)
+++ subversion/trunk/build/ac-macros/java.m4    Wed May  6 18:54:21 2026        
(r1933892)
@@ -162,18 +162,37 @@ AC_DEFUN(SVN_FIND_JDK,
       fi
     ])
 
+    dnl Get the Java release version
+    java_version=[`"$JDK/bin/java" -version 2>&1 | $HEAD -1 | $SED -e 
's/^[^0-9]*//' -e 's/\.[^.]*$//'`]
+    java_major=[`echo $java_version | $SED -e 's/\.[^.]*$//'`]
+    java_minor=[`echo $java_version | $SED -e 's/^[^.]*\.//'`]
+    dnl versions older than 11 report '1.V.x' instead of 'V.x.y'
+    if test "$java_major" -eq 1; then
+      java_release="$java_minor"
+    else
+      java_release="$java_major"
+      java_version="$java_release"
+    fi
+    AC_MSG_NOTICE([Compiling with Java $java_version for target Java 
$JAVA_OLDEST_WORKING_VER])
+
+    dnl Java 24 and above restrict native access.
+    dnl See: https://inside.java/2024/12/09/quality-heads-up/
+    if test "$java_release" -ge 24; then
+      JAVAHL_CHECK_FLAGS='--module-path "$(abs_builddir)/$(JAVAHL_JAR)"'
+      JAVAHL_CHECK_FLAGS="$JAVAHL_CHECK_FLAGS --add-modules 
org.apache.subversion.javahl"
+      JAVAHL_CHECK_FLAGS="$JAVAHL_CHECK_FLAGS 
--enable-native-access=org.apache.subversion.javahl"
+      JAVAHL_CHECK_FLAGS="$JAVAHL_CHECK_FLAGS --illegal-native-access=deny"
+    fi
+
     dnl Add javac flags.
-    # The release for "-source" could actually be greater than that
-    # of "-target", if we want to cross-compile for lesser JVMs.
     if test -z "$JAVAC_FLAGS"; then
-      java_version=[`"$JDK/bin/javac" -version 2>&1 | $SED -e 's/^[^0-9]*//' 
-e 's/\.[^.]*$//'`]
-      java_major=[`echo $java_version | $SED -e 's/\.[^.]*$//'`]
-      java_minor=[`echo $java_version | $SED -e 's/^[^.]*\.//'`]
-      if test "$java_major" -eq 1 && test "$java_minor" -lt 9; then
+      dnl The release for "-source" could actually be greater than that
+      dnl of "-target", if we want to cross-compile for lesser JVMs.
+      if test "$java_release" -lt 9; then
         JAVAC_FLAGS="-target $JAVA_OLDEST_WORKING_VER -source 1.8"
       else
-        java_release=[`echo $JAVA_OLDEST_WORKING_VER | $SED -e 's/^[^.]*\.//'`]
-        JAVAC_FLAGS="--release $java_release"
+        java_oldest_release=[`echo $JAVA_OLDEST_WORKING_VER | $SED -e 
's/^1\.//'`]
+        JAVAC_FLAGS="--release $java_oldest_release"
       fi
 
       if test "$enable_debugging" = "yes"; then
@@ -205,4 +224,5 @@ AC_DEFUN(SVN_FIND_JDK,
   AC_SUBST(JAVAH)
   AC_SUBST(JAR)
   AC_SUBST(JNI_INCLUDES)
+  AC_SUBST(JAVAHL_CHECK_FLAGS)
 ])

Modified: subversion/trunk/configure.ac
==============================================================================
--- subversion/trunk/configure.ac       Wed May  6 18:30:37 2026        
(r1933891)
+++ subversion/trunk/configure.ac       Wed May  6 18:54:21 2026        
(r1933892)
@@ -192,6 +192,9 @@ if test -z "$MKDIR"; then
 fi
 AC_SUBST([MKDIR])
 
+# Look for 'head'
+AC_CHECK_TOOL([HEAD], [head], [SED="${HEAD:-head}"])
+
 # ==== Libraries, for which we may have source to build ======================
 
 dnl verify apr version and set apr flags

Modified: subversion/trunk/subversion/bindings/javahl/Manifest.in
==============================================================================
--- subversion/trunk/subversion/bindings/javahl/Manifest.in     Wed May  6 
18:30:37 2026        (r1933891)
+++ subversion/trunk/subversion/bindings/javahl/Manifest.in     Wed May  6 
18:54:21 2026        (r1933892)
@@ -2,8 +2,9 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: Apache Subversion JavaHL API
 Bundle-Vendor: Apache Subversion
-Bundle-SymbolicName: org.apache.subversion.javahl
 Bundle-Version: %bundleVersion
+Bundle-SymbolicName: org.apache.subversion.javahl
+Automatic-Module-Name: org.apache.subversion.javahl
 Export-Package: org.apache.subversion.javahl,
  org.apache.subversion.javahl.callback,
  org.apache.subversion.javahl.types,

Reply via email to