JDK-8306886 : Building macOS libraries can be non-deterministic
  • Type: Bug
  • Component: javafx
  • Sub-Component: build
  • Affected Version: jfx21
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: os_x
  • CPU: x86_64
  • Submitted: 2023-04-26
  • Updated: 2023-05-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Blocks :  
Description
Building the native libraries on macOS is not always deterministic. Some of the shared libraries can be different from one build to the next on the same system with the same project path, such as 'libgstreamer-lite.dylib', 'libjavafx_font.dylib', and 'libjavafx_iio.dylib'.

SYSTEM / OS / JAVA RUNTIME INFORMATION

The following build tools were used:

- cmake version 3.26.3
- Command Line Tools for Xcode 14.2 version 14.2.0.0.1.1668646533
- OpenJDK Runtime Environment (build 19.0.2+7-44)
- Apache Ant(TM) version 1.10.13 compiled on January 4 2023

STEPS TO REPRODUCE

Set the environment variables by sourcing the file called 'jfxbuild.env'. Then run the Bash script called 'actions.sh' to build two copies of a simulated JavaFX GitHub Actions build and run the unit tests.

Both files are included in the SOURCE section below.

EXPECTED RESULTS

When the build script completes, the following command should show no output:

$ diff -qr build3 build4

ACTUAL RESULT

Instead, the command shows differences in some of the shared libraries and in the archives that include them:

$ diff -qr build3 build4
Files build3/artifacts/bundles/javafx-jmods-21.zip and build4/artifacts/bundles/javafx-jmods-21.zip differ
Files build3/artifacts/bundles/javafx-sdk-21.zip and build4/artifacts/bundles/javafx-sdk-21.zip differ
Files build3/artifacts/javafx-jmods-21/javafx.graphics.jmod and build4/artifacts/javafx-jmods-21/javafx.graphics.jmod differ
Files build3/artifacts/javafx-sdk-21/lib/libjavafx_font.dylib and build4/artifacts/javafx-sdk-21/lib/libjavafx_font.dylib differ
Files build3/artifacts/javafx-sdk-21/lib/libjavafx_iio.dylib and build4/artifacts/javafx-sdk-21/lib/libjavafx_iio.dylib differ
Files build3/javafx-exports.zip and build4/javafx-exports.zip differ
Files build3/jmods/javafx.graphics.jmod and build4/jmods/javafx.graphics.jmod differ
Files build3/modular-sdk/modules_libs/javafx.graphics/libjavafx_font.dylib and build4/modular-sdk/modules_libs/javafx.graphics/libjavafx_font.dylib differ
Files build3/modular-sdk/modules_libs/javafx.graphics/libjavafx_iio.dylib and build4/modular-sdk/modules_libs/javafx.graphics/libjavafx_iio.dylib differ
Files build3/publications/javafx.graphics-mac.jar and build4/publications/javafx.graphics-mac.jar differ
Files build3/sdk/lib/libjavafx_font.dylib and build4/sdk/lib/libjavafx_font.dylib differ
Files build3/sdk/lib/libjavafx_iio.dylib and build4/sdk/lib/libjavafx_iio.dylib differ

SOURCE CODE FOR AN EXECUTABLE TEST CASE

The file 'jfxbuild.env' that sets the environment variables:

-----------
#!/bin/bash
# Sets up the environment for building JavaFX
syspath=/usr/sbin:/usr/bin:/sbin:/bin

export CMAKE_HOME=$HOME/opt/cmake-3.26.3-macos-universal/CMake.app/Contents
export JAVA_HOME=$HOME/opt/jdk-19.0.2.jdk/Contents/Home
export ANT_HOME=$HOME/opt/apache-ant-1.10.13

SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
export SOURCE_DATE_EPOCH

# JDK_HOME and PATH are required by the build
export JDK_HOME=$JAVA_HOME
export PATH=$ANT_HOME/bin:$JAVA_HOME/bin:$CMAKE_HOME/bin:$syspath
-----------

The file 'actions.sh' that runs the two builds and the unit tests:

-----------
#!/bin/bash
# Creates two GitHub Actions builds and runs unit tests
trap exit INT TERM
set -o errexit

dir1=build3
dir2=build4

if [ -d $dir1 ] || [ -d $dir2 ]; then
    printf "Target directories exist: %s %s\n" $dir1 $dir2 >&2
    exit 1
fi

gradle () (
    set -o xtrace
    bash gradlew --no-daemon "$@"
)

printf "SOURCE_DATE_EPOCH=%s\n" "$SOURCE_DATE_EPOCH"
for dir in $dir1 $dir2; do
    gradle cleanAll
    gradle all
    mv build "$dir"
done
gradle all test -x :web:test
-----------

WORKAROUND

None.

Comments
Thank you, Kevin. I think it will take months of creating reproducible builds with Xcode 14.3 before I'll be confident it's working. I'm occasionally getting reproducible builds on macOS even using Xcode 14.2, so it's hard to tell when it's just by chance. I declared victory once before back in June 2021, only to discover five months later in November that it might have been due to using the Gradle Daemon. (See [1] and [2].) That same month I got reproducible builds on Linux and Windows, only to have some of their builds start to differ again this year. (See [3].) At least the "developer" builds ('bash gradlew --no-daemon sdk jmods javadoc') seem pretty solid by now. [1]: https://github.com/openjdk/jfx/pull/446#issuecomment-861000786 [2]: https://github.com/openjdk/jfx/pull/446#issuecomment-975932690 [3]: https://github.com/openjdk/jfx/pull/446#issuecomment-1522741112
26-04-2023

I'll do a local test + CI test build with Xcode 14.3 plus the patch for JDK-8264449 / https://github.com/openjdk/jfx/pull/446
26-04-2023

FWIW, Xcode 14.3 does run (although you might not be able to install it easily) on macOS 12.x Monterey. It wouldn't be suitable for production, though. I can confirm that it does not work at all on Big Sur.
26-04-2023

Removing myself as Assignee because I'm unable to run the latest Xcode 14.3 on my current Mac hardware.
26-04-2023

That's good news! I think that counts me out, though, for verifying the fix. Xcode 14.2 is the last version that I'm able to install on my Mac mini (Late 2014). Xcode 14.3 requires a Mac running macOS Ventura 13.0 or later, yet macOS Ventura is supported only on Mac mini models from 2018 or later. My Mac mini is running macOS Monterey 12.0 and works great, so I'm unlikely to buy a new one while Apple is still releasing updates for Monterey. My guess is that pushes out thoughts of a new Mac until late 2024.
26-04-2023

When the JDK team was testing Xcode 14.2 they ran into a similar issue. It appears to be fixed in 14.3, which is the next likely upgrade target (currently we use Xcode 12.4 to build the JavaFX production libraries).
26-04-2023