mirror of
https://github.com/wgtunnel/Nucleus.git
synced 2026-10-09 14:40:54 -07:00
* feat(graalvm): run AWT/Compose native images on Oracle GraalVM (macOS) Oracle GraalVM's mainline SubstrateVM — unlike BellSoft Liberica NIK — lacks the AWT startup wiring needed to run Compose Desktop apps that touch AWT (fonts, Java2D). This adds the macOS pieces so images built with Oracle GraalVM behave like Liberica ones. All changes are additive and vendor- agnostic (harmless under Liberica). - Platform (JNU) encoding: Oracle's SVM never calls the JDK's InitializeEncoding, so the bundled libjava.dylib's fastEncoding stays uninitialized and the first AWT JNI_OnLoad aborts with "platform encoding not initialized" / "Could not allocate library name". PlatformEncodingInitializer calls it via a C shim (nucleus_init_platform_encoding, compiled into the image with the cursor stub) that dlopens the SAME bundled libjava.dylib dyld shares by path with libawt/libfontmanager. macOS-only, guarded accordingly. - fontconfig: SunFontManager reads <java.home>/lib/fontconfig.bfc at startup; bundle it so FontConfiguration.getVersion() no longer throws "Fontconfig head is null" on Font.createFont / BufferedImage.createGraphics. - L3 macOS reachability metadata: register the freetype font scaler (sun.font.FreetypeFontScaler + the createFont path) and the CGL/OpenGL Java2D pipeline (OGLSurfaceData, CGLSurfaceData, CGraphicsEnvironment, ...) that the macOS native graphics code resolves via JNI FindClass — the agent cannot capture these native FindClass calls. Validated on macOS aarch64 (Oracle GraalVM 25.1.3) with cmp-demo, compose-demo, nucleus-demo and jewel-demo. Opt in per app via jvmVendor = JvmVendorSpec.ORACLE. Windows/Linux Oracle support (same encoding wiring) is not yet ported. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(graalvm): add allCharsets toggle for embedding all JDK charsets (#348) native-image ships only a minimal charset set (US-ASCII, ISO-8859-1, UTF-8, UTF-16 + platform default) by default; any other charset requested via Charset.forName(...) throws UnsupportedCharsetException at runtime. Apps that decode bytes in a legacy encoding (e.g. windows-1255, ISO-8859-8, Shift_JIS) previously had to pass the raw -H:+AddAllCharsets in buildArgs. Expose it as a named DSL toggle mirroring optimizeForSize: graalvm { allCharsets = true } Off by default to match GraalVM's own default (no size regression). Note this is unrelated to displaying/typing non-Latin text, which is Unicode-internal. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(graalvm): keep nucleus_init_platform_encoding symbol out of non-macOS images The @CFunction("nucleus_init_platform_encoding") binding was reachable on all platforms, so SVM emitted its external symbol into every image. The C shim that defines it is compiled only on macOS, breaking the Linux/Windows link with "undefined reference to nucleus_init_platform_encoding". Move the @CFunction into a @Platforms(DARWIN) class so it is excluded from non-macOS images, and guard the call with the build-time Platform.includedIn fold. A runtime platform check does not help: SVM registers the @CFunction symbol per reachable declaring class, not per call site. Also switch nucleus-demo/jewel-demo to Oracle GraalVM and the optimizeForSize DSL. * feat(examples): migrate cmp-demo and compose-demo to Oracle GraalVM - Wrap cmp-demo App composable in MaterialTheme + Surface - Switch compose-demo JVM vendor from BellSoft to Oracle - Replace manual nativeDistributions/nativeImage config with simplified DSL using TargetFormat and CompressionLevel * fix(examples): make cmp-demo title text white for readability * feat(plugin-build): copy fontconfig.bfc for proper AWT font initialization in GraalVM native apps Adds a task to ensure `fontconfig.bfc` is copied to the `lib/` directory under the native image output. Prevents "Fontconfig head is null" errors during AWT font operations. Updates the `graalvmNative` task dependencies accordingly. * refactor(build.bat): improve JDK and MSVC validation, streamline build logic - Added validation for JNI headers in JAVA_HOME. - Enhanced MSVC toolchain location via `vswhere` with fallback paths, reducing manual setup. - Consolidated source and library dependencies into variables for better maintainability. - Improved isolation of `vcvarsall` environments to avoid PATH overflow in CI systems. - Simplified handling of ARM64 builds with clear comments. * use consistent GraalVM settings across demos: enable `optimizeForSize`, switch `jvmVendor` to Oracle * update(setup-nucleus): switch from Liberica NIK to Oracle GraalVM, default Java version to 25.1 - Updated action.yml to use Oracle GraalVM for AWT and `native-image` support. - Adjusted graalvm-related inputs and descriptions, aligning them with Oracle GraalVM. - Updated CI configuration to install Oracle GraalVM via `graalvm/setup-graalvm`. * update(setup-nucleus): refine GraalVM version * feat(examples): add reachability metadata for Compose UI Skia layer in system-info-demo * ci(graalvm): install Oracle GraalVM 25.1 via setup-graalvm version input Builds request jvmVendor = ORACLE, but CI installed Liberica NIK, so Gradle auto-provisioned a plain Oracle JDK without native-image. Use setup-graalvm with distribution 'graalvm' and version '25.1'; fall back to 25.0 LTS on Intel macOS, which has no 25.1 build. * feat(plugin-build): add `mlProfileInference` to GraalVM settings Introduced `mlProfileInference` configuration to align with Oracle GraalVM's machine-learning-inferred PGO profiling. Added the ability to disable it by appending `-H:-MLProfileInference` to build arguments when opted out. * feat(build): replace `optimizeForSize` with `optimization` for fine-grained native-image control Replaced the `optimizeForSize` flag with the more flexible `optimization` setting across examples and plugin configuration. Added support for advanced GraalVM native-image optimization levels, such as `SIZE` and `LEVEL_3`. Expanded target formats to include `.rpm` in the `cmp-demo`. * fix(window-tao): keep VSync on during resize to stop native-image leak Dropping VSync (eglSwapInterval(0)) for the OS modal resize/move loop let WM_SIZE render at ~1 kHz: every new window size minted a fresh BackendRenderTarget + Surface + Skia stencil/scratch, reclaimed only lazily by the GrResourceCache purge and the skiko Cleaner after a GC. Under native-image's Serial GC that reclamation never caught up for lean apps (cmp-demo, system-info-demo), so RSS climbed past 1 GB and stayed there on Windows only — macOS (CVDisplayLink) and Linux (EGL swap thread) never leaked because their resize paints are display-rate paced, and HotSpot collects old gen automatically. Keep VSync on throughout so the per-WM_SIZE present paces off the display refresh, matching the non-leaking platforms. Logs confirmed a border drag now renders at <=90 Hz (WM_SIZE-arrival-bound) instead of ~1 kHz. Also bound the DirectContext GPU resource cache (256 MB) and purge it on drag end, and defer the size push into the next paint so surface resize + present stay atomic. * feat(plugin-build, window-tao): add advanced GraalVM optimizations and cross-platform view factories - Introduced `NativeImageOptimization` enum for fine-grained GraalVM `native-image` optimization control. - Added `NucleusPlatformViewFactory` with cross-platform support for macOS, Windows, and Linux platform views. * update(system-info-demo): bump Lets-Plot dependencies and adjust native image optimization to SIZE --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>