brunoborges/fx2048/notarized-javafx-macos
Claude Code and agent skill by brunoborges/fx2048
- community
Checking that the SKILL.md file is still in the repository.
Build, sign, notarize, staple, validate, and troubleshoot macOS DMG releases for Java and JavaFX applications packaged with jlink/jpackage. Use when creating Developer ID signed Java desktop apps, configuring GitHub Actions release workflows, handling Apple notarization, or debugging Gatekeeper, hardened runtime, JVM JIT, JavaFX native library, DMG signing, and macOS launch failures.
Install
npx vskill@latest install brunoborges/fx2048/notarized-javafx-macosSKILL.md
Notarized Java/JavaFX macOS app releases
Use this skill when an agent needs to package a Java or JavaFX desktop app for macOS with Developer ID signing, notarization, stapling, and Gatekeeper validation. It is especially useful for apps built with jlink and jpackage that ship as .app, .dmg, or .pkg artifacts.
Outcomes
A successful release should produce a macOS artifact that:
- Contains a signed
.appbundle. - Uses hardened runtime.
- Has JVM/JavaFX-compatible entitlements when needed.
- Is packaged into a signed DMG or PKG.
- Is accepted by Apple notarization.
- Is stapled successfully.
- Passes Gatekeeper validation.
- Launches from Finder after the standard first-run "downloaded from the internet" prompt.
Required Apple and CI inputs
For GitHub Actions, configure these as repository or environment secrets:
| Secret | Purpose | |
|---|---|---|
MACOS_CERTIFICATE_BASE64 | Base64-encoded Developer ID Application .p12 certificate | |
MACOS_CERTIFICATE_PASSWORD | Password for the exported .p12 | |
MACOS_SIGNING_KEY_USER_NAME | Developer ID Application identity, usually Developer ID Application: Name (TEAMID) | |
APPLE_ID | Apple ID email used for notarization | |
APPLE_TEAM_ID | Apple Developer Team ID | |
APPLE_APP_SPECIFIC_PASSWORD | App-specific password for notarization |
What to put in each GitHub secret
Use a Developer ID Application certificate, not a Mac Developer, Apple Development, or Developer ID Installer certificate, when signing a .app or .dmg.
MACOS_CERTIFICATE_BASE64: export the Developer ID Application certificate and its private key from Keychain Access as a password-protected.p12, then base64-encode the.p12as a single line.
``bash security find-identity -v -p codesigning base64 -i path/to/developer-id-application.p12 | tr -d '\n' ``
MACOS_CERTIFICATE_PASSWORD: use the password entered when exporting the.p12file.
MACOS_SIGNING_KEY_USER_NAME: use the exact identity string fromsecurity find-identity -v -p codesigning, usually:
``text Developer ID Application: Example Name (TEAMID) ``
Do not use the SHA-1 hash at the start of the security find-identity output.
APPLE_ID: use the Apple ID email address for the Apple Developer account that has access to the team.
APPLE_TEAM_ID: use the 10-character Apple Developer Team ID. It usually appears in parentheses at the end of the Developer ID Application identity and in the Apple Developer Membership details.
APPLE_APP_SPECIFIC_PASSWORD: generate an app-specific password athttps://appleid.apple.com/account/managefor notarization. Use this app-specific password, not the normal Apple ID password.
Set repository secrets with the GitHub CLI, preferably by reading values from environment variables so secrets do not appear in shell history:
Recommended release workflow
1. Create and unlock a temporary keychain
In CI, import the .p12 certificate into a temporary keychain and make it usable by codesign.
2. Build a runtime image and signed app image
Prefer a two-stage macOS package flow:
- Build the application and
jlinkruntime. - Create a signed
app-image. - Explicitly re-sign the
.appwith known entitlements. - Build the DMG from that signed app image.
This avoids silently losing entitlements during direct jpackage --type dmg packaging.
Example:
3. Use JVM/JavaFX-compatible entitlements
JavaFX and HotSpot may need hardened-runtime exceptions for the JVM JIT and JavaFX native libraries. Use the narrowest entitlements that make the app launch reliably.
Recommended starting point for JavaFX apps:
Why these matter:
allow-jit: permits the JVM JIT to toggle JIT write protection.allow-unsigned-executable-memory: helps JVM-generated executable memory under hardened runtime.disable-library-validation: permits JavaFX native libraries extracted to user cache locations, such as~/.openjfx/cache, to load even when signed by a different team.
4. Re-sign and verify the app image explicitly
After jpackage --type app-image, explicitly re-sign the .app bundle with hardened runtime and entitlements. Then verify that the entitlement keys are actually present.
Do not assume jpackage --mac-entitlements worked just because the build succeeded. Always inspect the installed or generated .app entitlements.
5. Build the DMG from the signed app image
6. Sign the DMG
Some DMGs notarize successfully but still fail Gatekeeper with source=no usable signature unless the disk image itself has a usable Developer ID signature.
7. Notarize, staple, and validate
Diagnostics and common failures
Normal first-launch prompt
It is normal for a signed and notarized app downloaded from GitHub to show a first-run warning like "downloaded from the internet." It should identify the developer and allow the app to open. It should not say "cannot verify developer," "app is damaged," or "cannot be opened."
Check an installed app
Launching the executable from Terminal is often the fastest way to see Java or JavaFX errors that Finder hides.
pthread_jit_write_protect_np crash during JVM startup
Symptom:
Cause: hardened runtime blocked JVM JIT behavior.
Fix: ensure the signed .app has com.apple.security.cs.allow-jit and often com.apple.security.cs.allow-unsigned-executable-memory. Re-sign and verify the app image before creating the DMG.
JavaFX fails with different Team IDs
Symptom:
Cause: JavaFX extracted native libraries to ~/.openjfx/cache, and hardened runtime library validation rejected them.
Fix: add com.apple.security.cs.disable-library-validation to the signed app entitlements and verify it is present on the installed app.
source=no usable signature after notarization
Symptom:
Cause: the DMG itself is not signed with a usable primary signature, even if the app inside it was signed and Apple accepted notarization.
Fix: codesign the DMG before notarization, then staple and validate it.
Notarization succeeds but the app still does not launch
Notarization confirms Apple accepted the submitted artifact. It does not prove the app can initialize the JVM or JavaFX. Always smoke test the installed .app after downloading the release artifact:
Pull request checklist
Before declaring the macOS release fix complete:
- The entitlements plist passes
plutil -lint. - The workflow YAML parses.
- The
.appsignature is verified withcodesign --verify --deep --strict. codesign -d --entitlements - App.appshows required entitlement keys.- The DMG is signed.
notarytool submit --waitreturnsAccepted.stapler stapleandstapler validatepass.spctl -a -t open --context context:primary-signature -v App.dmgpasses.- The app launches from Terminal and Finder after installation.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/notarized-javafx-macos/SKILL.md
Popularity
- Repository stars
- 291
- Repository forks
- 127
- 7-day trend score
- 28
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 22 Jun 2026, 4 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/brunoborges/fx2048/notarized-javafx-macos)