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

geertjanw pushed a commit to branch issue-138-skip-runtime-signing
in repository https://gitbox.apache.org/repos/asf/netbeans-nbpackage.git

commit 587b5f7246d2627ace48a843df07de464c2eb4d9
Author: Geertjan Wielenga <[email protected]>
AuthorDate: Thu Oct 1 12:14:58 2026 +0200

    Add option to skip signing of JDK runtime on macOS (#138)
    
    By default NBPackage re-signs the whole installation payload on macOS,
    including the bundled JDK runtime. Re-signing rewrites each runtime
    binary's signature, which changes the hash that jlink verifies against
    and leads to "modified runtime" errors.
    
    Add a package.macos.codesign-runtime option (boolean, default true) to
    keep the runtime's existing signatures. When false, native binaries
    under Contents/Home are excluded from the signing list; the final
    bundle codesign does not use --deep so the runtime is left untouched.
    
    AI-Session-Id: 0b8457c0-865e-4b90-863f-78cf3492bbf6
    AI-Tool: claude-code
    AI-Model: global.anthropic.claude-opus-4-8
---
 README.md                                          |  6 +++++
 .../netbeans/nbpackage/macos/AppBundleTask.java    |  8 ++++++
 .../org/apache/netbeans/nbpackage/macos/MacOS.java |  9 +++++++
 .../netbeans/nbpackage/macos/PkgPackager.java      |  1 +
 .../netbeans/nbpackage/macos/Messages.properties   |  2 ++
 .../netbeans/nbpackage/macos/PkgPackagerTest.java  | 29 ++++++++++++++++++++++
 6 files changed, 55 insertions(+)

diff --git a/README.md b/README.md
index 3c86353..6d9443b 100644
--- a/README.md
+++ b/README.md
@@ -79,6 +79,12 @@ native binaries and JAR files with native binaries can be 
adapted if necessary.
 The built package should then pass the Apple notarization process (submission 
and
 stapling must be done manually).
 
+By default the bundled JDK runtime is also re-signed. This can be disabled by
+setting `package.macos.codesign-runtime` to `false`, so that the runtime's
+existing signatures are kept unchanged. This is useful where re-signing is
+unnecessary and causes problems, such as `jlink` reporting a modified runtime,
+but note it may affect notarization in some cases.
+
 ### `--type windows-innosetup`
 
 Create a Windows [Inno Setup][innosetup] installer. Requires download of the
diff --git 
a/src/main/java/org/apache/netbeans/nbpackage/macos/AppBundleTask.java 
b/src/main/java/org/apache/netbeans/nbpackage/macos/AppBundleTask.java
index d2b44cd..f008e6c 100644
--- a/src/main/java/org/apache/netbeans/nbpackage/macos/AppBundleTask.java
+++ b/src/main/java/org/apache/netbeans/nbpackage/macos/AppBundleTask.java
@@ -284,6 +284,14 @@ class AppBundleTask extends AbstractPackagerTask {
                 StandardOpenOption.CREATE_NEW);
         List<Path> nativeBinaries = FileUtils.find(bundle,
                 context().getValue(MacOS.SIGNING_FILES).orElseThrow());
+        if (!context().getValue(MacOS.CODESIGN_RUNTIME).orElse(Boolean.TRUE)) {
+            Path runtime = bundle.resolve("Contents").resolve("Home");
+            nativeBinaries = nativeBinaries.stream()
+                    .filter(path -> !path.startsWith(runtime))
+                    .toList();
+            context().infoHandler().accept(
+                    MacOS.MESSAGES.getString("message.skippingruntime"));
+        }
         Files.writeString(image.resolve(NATIVE_BIN_FILENAME),
                 nativeBinaries.stream()
                         .map(path -> image.relativize(path))
diff --git a/src/main/java/org/apache/netbeans/nbpackage/macos/MacOS.java 
b/src/main/java/org/apache/netbeans/nbpackage/macos/MacOS.java
index fe5a65c..71b8d78 100644
--- a/src/main/java/org/apache/netbeans/nbpackage/macos/MacOS.java
+++ b/src/main/java/org/apache/netbeans/nbpackage/macos/MacOS.java
@@ -118,6 +118,15 @@ class MacOS {
             = Option.ofString("package.macos.codesign-jars", 
DEFAULT_JAR_BIN_GLOB,
                     MESSAGES.getString("option.codesign_jars.help"));
 
+    /**
+     * Whether to code sign the bundled JDK runtime. When {@code false}, the
+     * runtime's existing signatures are left untouched.
+     */
+    static final Option<Boolean> CODESIGN_RUNTIME
+            = Option.of("package.macos.codesign-runtime", Boolean.class, 
"true",
+                    Boolean::parseBoolean,
+                    MESSAGES.getString("option.codesign_runtime.help"));
+
     /**
      * Codesign ID for signing binaries and app bundle.
      */
diff --git a/src/main/java/org/apache/netbeans/nbpackage/macos/PkgPackager.java 
b/src/main/java/org/apache/netbeans/nbpackage/macos/PkgPackager.java
index d357c5e..2d8b09d 100644
--- a/src/main/java/org/apache/netbeans/nbpackage/macos/PkgPackager.java
+++ b/src/main/java/org/apache/netbeans/nbpackage/macos/PkgPackager.java
@@ -39,6 +39,7 @@ public class PkgPackager implements Packager {
             MacOS.ENTITLEMENTS_TEMPLATE_PATH,
             MacOS.SIGNING_FILES,
             MacOS.SIGNING_JARS,
+            MacOS.CODESIGN_RUNTIME,
             MacOS.CODESIGN_ID,
             MacOS.PKGBUILD_ID);
 
diff --git 
a/src/main/resources/org/apache/netbeans/nbpackage/macos/Messages.properties 
b/src/main/resources/org/apache/netbeans/nbpackage/macos/Messages.properties
index 12c3a15..513bbb7 100644
--- a/src/main/resources/org/apache/netbeans/nbpackage/macos/Messages.properties
+++ b/src/main/resources/org/apache/netbeans/nbpackage/macos/Messages.properties
@@ -24,6 +24,7 @@ option.launcher_template.help=Optional path to launcher 
(main.swift) template.
 option.entitlements_template.help=Optional path to codesign entitlements 
template.
 option.codesign_files.help=Search pattern for native binaries that need to be 
code signed.
 option.codesign_jars.help=Search pattern for JARs that bundle native binaries 
that need to be code signed.
+option.codesign_runtime.help=Whether to code sign the bundled JDK runtime 
(default true). Set to false to keep the runtime's existing signatures, eg. to 
avoid jlink "modified runtime" errors. May affect notarization.
 option.codesign_id.help=Code signing identity as passed to Codesign.
 option.pkgbuild_id.help=Installer signing identity as passed to Pkgbuild.
 
@@ -31,5 +32,6 @@ option.pkgbuild_id.help=Installer signing identity as passed 
to Pkgbuild.
 message.validatingtools=Validating required tools - {0}
 message.missingtool=Cannot find required tool - {0}
 message.nocodesignid=No codesign ID has been configured. App bundle will be 
unsigned.
+message.skippingruntime=Skipping code signing of bundled JDK runtime. Existing 
signatures will be kept.
 message.nopkgbuildid=No pkgbuild ID has been configured. Installer will be 
unsigned.
 message.unknownarch=Architecture is not recognised, defaulting to universal.
diff --git 
a/src/test/java/org/apache/netbeans/nbpackage/macos/PkgPackagerTest.java 
b/src/test/java/org/apache/netbeans/nbpackage/macos/PkgPackagerTest.java
index 105c82a..cf5c8ac 100644
--- a/src/test/java/org/apache/netbeans/nbpackage/macos/PkgPackagerTest.java
+++ b/src/test/java/org/apache/netbeans/nbpackage/macos/PkgPackagerTest.java
@@ -88,6 +88,35 @@ public class PkgPackagerTest {
         assertTrue(Files.exists(resolve(app, "Contents", "Home", "bin", 
"java")));
         assertTrue(Files.exists(resolve(app, "Contents", "Resources", 
"app.icns")));
         assertTrue(Files.exists(resolve(app, "Contents", "Resources", "app", 
"bin", "app")));
+        // runtime binaries are included in the signing list by default
+        assertTrue(Files.readString(resolve(image, "nativeBinaries"))
+                .contains("Contents/Home/bin/java"));
+    }
+
+    @Test
+    public void testImageSkippingRuntimeSigning() throws Exception {
+        Path input = tmpDir.resolve("App-1.0-b1.zip");
+        FileUtils.createZipArchive(
+                buildFakeApp(tmpDir, "App-1.0-b1", "app"),
+                input);
+        String runtimeName = "OpenJDK24U-jdk_aarch64_mac_hotspot_24.0.1_9";
+        Path runtime = tmpDir.resolve(runtimeName + ".zip");
+        FileUtils.createZipArchive(
+                buildFakeJDK(tmpDir, runtimeName, false),
+                runtime);
+        Configuration config = Configuration.builder()
+                .set(NBPackage.PACKAGE_NAME, "App")
+                .set(NBPackage.PACKAGE_VERSION, "1.0-b1")
+                .set(NBPackage.PACKAGE_RUNTIME, runtime.toString())
+                .set(MacOS.CODESIGN_RUNTIME, "false")
+                .build();
+        Path image = buildImage(new PkgPackager(), input, config, tmpDir);
+        Path app = resolve(image, "App.app");
+        // runtime is still bundled, but excluded from the signing list
+        assertTrue(Files.exists(resolve(app, "Contents", "Home", "bin", 
"java")));
+        assertTrue(Files.exists(resolve(image, "nativeBinaries")));
+        assertFalse(Files.readString(resolve(image, "nativeBinaries"))
+                .contains("Contents/Home"));
     }
 
 }


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

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to