|
300 | 300 | </execution> |
301 | 301 | <execution> |
302 | 302 | <!-- |
303 | | - jpackage lays out the embedded JDK runtime the same way Oracle/OpenJDK |
304 | | - macOS distributions do, which includes symlinks such as |
305 | | - Contents/runtime/Contents/MacOS/libjli.dylib -> ../Home/lib/libjli.dylib |
306 | | - (purely so the runtime folder has a CFBundleExecutable and looks like a |
307 | | - bundle). rcodesign signs the real file once at its regular path, then |
308 | | - signs it again through the symlink under a different bundle role (e.g. |
309 | | - as the runtime bundle's "main executable") - the same physical bytes get |
310 | | - mutated after the first pass's bundle manifest already hashed them, and |
311 | | - Apple's notary service rejects it with "The signature of the binary is |
312 | | - invalid." for that path. Replacing every symlink under Contents/runtime |
313 | | - with an independent real copy of its target before signing means each |
314 | | - path is its own file, signed once, self-consistent - no change needed to |
315 | | - the signing step itself, and no need to enumerate which files are |
316 | | - symlinks by hand (this varies by JDK vendor/version). |
| 303 | + Contents/runtime/Contents/Info.plist declares libjli.dylib as |
| 304 | + CFBundleExecutable, which is what makes rcodesign treat |
| 305 | + Contents/runtime as a nested bundle with a "main executable" to sign |
| 306 | + specially. That file also gets swept up generically while signing |
| 307 | + Contents/Home/lib/*.dylib, so it ends up processed twice under two |
| 308 | + different roles - and Apple's notary service then rejects it with |
| 309 | + "The signature of the binary is invalid." for that path. This is a |
| 310 | + known, long-standing jpackage quirk independent of any one signing |
| 311 | + tool (OpenJDK JDK-8237490; codesign-based scripts have hit the same |
| 312 | + Contents/runtime/Contents/MacOS/libjli.dylib failure). Stripping |
| 313 | + CFBundleExecutable means rcodesign no longer recognizes |
| 314 | + Contents/runtime as a bundle with a main executable at all - it |
| 315 | + already handles that case gracefully ("bundle has no main executable |
| 316 | + to sign specially", seen earlier in this same pipeline), so |
| 317 | + libjli.dylib just gets signed once, generically, like every other |
| 318 | + dylib in the runtime. |
317 | 319 | --> |
318 | | - <id>fix-runtime-symlinks</id> |
| 320 | + <id>strip-runtime-bundle-executable</id> |
319 | 321 | <phase>package</phase> |
320 | 322 | <goals> |
321 | 323 | <goal>exec</goal> |
322 | 324 | </goals> |
323 | 325 | <configuration> |
324 | | - <executable>/bin/sh</executable> |
| 326 | + <executable>python3</executable> |
325 | 327 | <arguments> |
326 | 328 | <argument>-c</argument> |
327 | 329 | <argument> |
328 | | - set -eu; |
329 | | - RUNTIME_DIR="${project.build.directory}/CertWizard.app/Contents/runtime"; |
330 | | - if [ -d "$RUNTIME_DIR" ]; then |
331 | | - find "$RUNTIME_DIR" -type l | while IFS= read -r link; do |
332 | | - real=$(python3 -c "import os,sys; print(os.path.realpath(sys.argv[1]))" "$link"); |
333 | | - rm "$link"; |
334 | | - cp "$real" "$link"; |
335 | | - done; |
336 | | - fi |
| 330 | +import plistlib, sys, os |
| 331 | +p = sys.argv[1] |
| 332 | +if os.path.exists(p): |
| 333 | + with open(p, 'rb') as f: |
| 334 | + d = plistlib.load(f) |
| 335 | + d.pop('CFBundleExecutable', None) |
| 336 | + with open(p, 'wb') as f: |
| 337 | + plistlib.dump(d, f) |
337 | 338 | </argument> |
| 339 | + <argument>${project.build.directory}/CertWizard.app/Contents/runtime/Contents/Info.plist</argument> |
338 | 340 | </arguments> |
339 | 341 | </configuration> |
340 | 342 | </execution> |
|
0 commit comments