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,
