Oof. I think I'm done with JavaHL for the next few years.

We're not keeping up with core library changes again. There are a few deprecation warnings and I think at least some of them should lead to changes in the JavaHL API that we can only ship in a minor release. This is a technically easy but thankless slog through C++ and Java interfaces and native function declarations and possibly tests et cetera ad nauseam.

Here's an idea, maybe let an AI agent go wild on the warning messages and who knows, we may end up with a Rust implementation written in Clojure that works only on one very specific micro version of Azul's JVM build. With ads and in-app purchases.

-- Brane


On 6. 5. 26 20:54, [email protected] wrote:
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