beeware / briefcase

Tools to support converting a Python project into a standalone native application.
https://briefcase.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
2.67k stars 371 forks source link

Validate the word size (bitness) of JDK #1461

Open rmartin16 opened 1 year ago

rmartin16 commented 1 year ago

Describe the bug

Building an Android app is not compatible with a 32bit JDK and Gradle outputs a bit of a cryptic error when such a JDK is used with Briefcase.

[helloworld] Building Android APK...
>>> Android emulator is already installed.

>>> Running Command:
>>>     'C:\Users\user\github\beeware\briefcase\tmp\helloworld\build\helloworld\android\gradle\gradlew.bat' --console plain assembleDebug
>>> Working Directory:
>>>     C:\Users\user\github\beeware\briefcase\tmp\helloworld\build\helloworld\android\gradle
>>> Environment Overrides:
>>>     ANDROID_HOME=C:\Users\user\AppData\Local\BeeWare\briefcase\Cache\tools\android_sdk
>>>     ANDROID_SDK_ROOT=C:\Users\user\AppData\Local\BeeWare\briefcase\Cache\tools\android_sdk
>>>     JAVA_HOME=C:\Users\user\Desktop\jdk-17.0.8.1+1 32bit
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details

FAILURE: Build failed with an exception.

* What went wrong:
Unable to start the daemon process.
This problem might be caused by incorrect configuration of the daemon.
For example, an unrecognized jvm option is used.
Please refer to the User Manual chapter on the daemon at https://docs.gradle.org/8.0/userguide/gradle_daemon.html
Process command line: C:\Users\user\Desktop\jdk-17.0.8.1+1 32bit\bin\java.exe --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant -cp C:\Users\user\.gradle\wrapper\dists\gradle-8.0-all\a2o1xoguejy6msdh0lk99lxza\gradle-8.0\lib\gradle-launcher-8.0.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.0
Please read the following process output to find out more:
-----------------------
Error occurred during initialization of VM
Could not reserve enough space for 2097152KB object heap

Steps to reproduce

  1. Download and extract https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.8.1%2B1/OpenJDK17U-testimage_x86-32_windows_hotspot_17.0.8.1_1.zip
  2. Set JAVA_HOME to the extracted directory
  3. Run briefcase build android

Expected behavior

Briefcase enforces that the bitness of the JDK must match the bitness of the OS.

Of note, I learned in #1360 that bitness checks are deceptively difficult in the general case....so, beware...

Determining the bitness of the JDK may also be non-trivial given users can use any ole JDK. The java -XshowSettings:properties -version command includes with but it isn't entirely clear if arbitrary builds of JDK include the same information....and format it consistently...

64bit `java -XshowSettings:properties -version` output ``` ❯ java -XshowSettings:properties Property settings: file.encoding = UTF-8 file.separator = / java.class.path = java.class.version = 61.0 java.home = /usr/lib/jvm/java-17-amazon-corretto java.io.tmpdir = /tmp java.library.path = /usr/java/packages/lib /usr/lib64 /lib64 /lib /usr/lib java.runtime.name = OpenJDK Runtime Environment java.runtime.version = 17.0.7+7-LTS java.specification.name = Java Platform API Specification java.specification.vendor = Oracle Corporation java.specification.version = 17 java.vendor = Amazon.com Inc. java.vendor.url = https://aws.amazon.com/corretto/ java.vendor.url.bug = https://github.com/corretto/corretto-17/issues/ java.vendor.version = Corretto-17.0.7.7.1 java.version = 17.0.7 java.version.date = 2023-04-18 java.vm.compressedOopsMode = Zero based java.vm.info = mixed mode, sharing java.vm.name = OpenJDK 64-Bit Server VM java.vm.specification.name = Java Virtual Machine Specification java.vm.specification.vendor = Oracle Corporation java.vm.specification.version = 17 java.vm.vendor = Amazon.com Inc. java.vm.version = 17.0.7+7-LTS jdk.debug = release line.separator = \n native.encoding = UTF-8 os.arch = amd64 os.name = Linux os.version = 6.4.6-76060406-generic path.separator = : sun.arch.data.model = 64 sun.boot.library.path = /usr/lib/jvm/java-17-amazon-corretto/lib sun.cpu.endian = little sun.io.unicode.encoding = UnicodeLittle sun.java.launcher = SUN_STANDARD sun.jnu.encoding = UTF-8 sun.management.compiler = HotSpot 64-Bit Tiered Compilers sun.stderr.encoding = UTF-8 sun.stdout.encoding = UTF-8 user.country = US user.dir = /home/russell user.home = /home/russell user.language = en user.name = russell openjdk version "17.0.7" 2023-04-18 LTS OpenJDK Runtime Environment Corretto-17.0.7.7.1 (build 17.0.7+7-LTS) OpenJDK 64-Bit Server VM Corretto-17.0.7.7.1 (build 17.0.7+7-LTS, mixed mode, sharing) ```
32bit `java -XshowSettings:properties -version` output ``` ❯ ~/zulu17.44.53-ca-fx-jdk17.0.8.1-linux_i686/bin/java -XshowSettings:properties -version Property settings: file.encoding = UTF-8 file.separator = / java.class.path = java.class.version = 61.0 java.home = /home/russell/zulu17.44.53-ca-fx-jdk17.0.8.1-linux_i686 java.io.tmpdir = /tmp java.library.path = /usr/java/packages/lib /lib /usr/lib java.runtime.name = OpenJDK Runtime Environment java.runtime.version = 17.0.8.1+1-LTS java.specification.name = Java Platform API Specification java.specification.vendor = Oracle Corporation java.specification.version = 17 java.vendor = Azul Systems, Inc. java.vendor.url = http://www.azul.com/ java.vendor.url.bug = http://www.azul.com/support/ java.vendor.version = Zulu17.44+53-CA java.version = 17.0.8.1 java.version.date = 2023-08-24 java.vm.info = mixed mode, sharing java.vm.name = OpenJDK Server VM java.vm.specification.name = Java Virtual Machine Specification java.vm.specification.vendor = Oracle Corporation java.vm.specification.version = 17 java.vm.vendor = Azul Systems, Inc. java.vm.version = 17.0.8.1+1-LTS jdk.debug = release line.separator = \n native.encoding = UTF-8 os.arch = i386 os.name = Linux os.version = 6.4.6-76060406-generic path.separator = : sun.arch.data.model = 32 sun.boot.library.path = /home/russell/zulu17.44.53-ca-fx-jdk17.0.8.1-linux_i686/lib sun.cpu.endian = little sun.io.unicode.encoding = UnicodeLittle sun.java.launcher = SUN_STANDARD sun.jnu.encoding = UTF-8 sun.management.compiler = HotSpot Tiered Compilers sun.stderr.encoding = UTF-8 sun.stdout.encoding = UTF-8 user.country = US user.dir = /home/russell user.home = /home/russell user.language = en user.name = russell openjdk version "17.0.8.1" 2023-08-24 LTS OpenJDK Runtime Environment Zulu17.44+53-CA (build 17.0.8.1+1-LTS) OpenJDK Server VM Zulu17.44+53-CA (build 17.0.8.1+1-LTS, mixed mode, sharing) ```

Screenshots

No response

Environment

Logs

Windows build log with 32bit JDK briefcase.2023_09_23-11_43_47.build.log

Additional context

Of note, I was able to use a 32bit JDK on Linux....although, there's probably no need to allow this.

Linux build log with 32bit JDK briefcase.2023_09_23-11_54_16.build.log

mhsmith commented 1 year ago

Could not reserve enough space for 2097152KB object heap

This will be because of the -Xmx setting in gradle.properties. The current version of that file in the template is identical to the one generated by the Android Studio new project wizard, and I think they probably increased it to 2048 MB around the same time that Android Studio stopped supporting 32-bit build machines.

rmartin16 commented 1 year ago

Could not reserve enough space for 2097152KB object heap

This will be because of the -Xmx setting in gradle.properties. The current version of that file in the template is identical to the one generated by the Android Studio new project wizard, and I think they probably increased it to 2048 MB around the same time that Android Studio stopped supporting 32-bit build machines.

Right. Are you suggesting, though, that we shouldn't enforce such a bitness check?

FWIW, when I change this to 1024m, the build succeeds on Windows for a 32bit JDK.

mhsmith commented 1 year ago

Reducing the limit would be a bad idea becuase all testing of both the Android and Chaquopy Gradle plugins will be done at the default limit. So I agree the bitness check is the way to go.

rmartin16 commented 1 year ago

Reducing the limit would be a bad idea becuase all testing of both the Android and Chaquopy Gradle plugins will be done at the default limit. So I agree the bitness check is the way to go.

All right; that definitely makes sense. Given a 32bit JDK is technically feasible, it might be reasonable then to just implement a warning for the user instead of a hard stop error.