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,