patrol icon indicating copy to clipboard operation
patrol copied to clipboard

Out of memory error during some patrol builds on Codemagic device

Open martin1080p opened this issue 1 year ago • 8 comments

Steps to reproduce

  1. Set up a Codemagic workflow configured to run on a macOS environment (specifically, a Mac Mini M2).
  2. In the workflow, use the following build commands:
dart pub global activate patrol_cli
flutter build apk --config-only -t lib/$RUN_FILE --flavor $FLAVOR
patrol build android -t integration_test --verbose
  1. Trigger the workflow to build and run patrol tests. Ensure all necessary environment variables ($RUN_FILE, $FLAVOR, etc.) are properly configured.
  2. Observe the results of the build, noting any inconsistencies in the success or failure of the patrol test build step.

Actual results

Expected Outcome: The workflow completes successfully, with the patrol tests built and executed without errors.

Intermittent Issue: Occasionally, the patrol test build step fails with an "Out of memory" error.

Current Configuration: The org.gradle.jvmargs setting in gradle.properties is set to -Xmx8g.

Observation: Despite the 8 GB memory allocation, the build inconsistently fails due to memory constraints—sometimes succeeding and sometimes failing without any changes to the code or configuration.

Is there a way to correctly test whether gradle has correctly alocated 8 GB in memore?

Logs

Logs of FAILED build
	: > Task :permission_handler_android:copyDebugJniLibsProjectOnly
	: > Task :share_plus:mergeDebugJniLibFolders
	: > Task :share_plus:mergeDebugNativeLibs NO-SOURCE
	: > Task :share_plus:copyDebugJniLibsProjectOnly
	: > Task :shared_preferences_android:mergeDebugJniLibFolders
	: > Task :shared_preferences_android:mergeDebugNativeLibs NO-SOURCE
	: > Task :shared_preferences_android:copyDebugJniLibsProjectOnly
	: > Task :sqflite:mergeDebugJniLibFolders
	: > Task :sqflite:mergeDebugNativeLibs NO-SOURCE
	: > Task :sqflite:copyDebugJniLibsProjectOnly
	: > Task :sqlcipher_flutter_libs:mergeDebugJniLibFolders
	: > Task :sqlcipher_flutter_libs:mergeDebugNativeLibs NO-SOURCE
	: > Task :sqlcipher_flutter_libs:copyDebugJniLibsProjectOnly
	: > Task :url_launcher_android:mergeDebugJniLibFolders
	: > Task :url_launcher_android:mergeDebugNativeLibs NO-SOURCE
	: > Task :url_launcher_android:copyDebugJniLibsProjectOnly
	: > Task :video_player_android:mergeDebugJniLibFolders
	: > Task :video_player_android:mergeDebugNativeLibs NO-SOURCE
	: > Task :video_player_android:copyDebugJniLibsProjectOnly
	: > Task :wakelock_plus:mergeDebugJniLibFolders
	: > Task :wakelock_plus:mergeDebugNativeLibs NO-SOURCE
	: > Task :wakelock_plus:copyDebugJniLibsProjectOnly
	: > Task :webview_flutter_android:mergeDebugJniLibFolders
	: > Task :webview_flutter_android:mergeDebugNativeLibs NO-SOURCE
	: > Task :webview_flutter_android:copyDebugJniLibsProjectOnly
	: > Task :app:validateSigningDevDebug
	: > Task :app:writeDevDebugAppMetadata
	: > Task :app:writeDevDebugSigningConfigVersions
	: > Task :app:mergeDevDebugNativeLibs
	: > Task :app:stripDevDebugDebugSymbols
	: > Task :app:packageDevDebug FAILED
	: ASM Instrumentation process wasn't able to resolve some classes, this means that
	: the instrumented classes might contain corrupt stack frames. Make sure the
	: dependencies that contain these classes are on the runtime or the provided
	: classpath. Otherwise, the jvm might fail to load the corrupt classes at runtime
	: when running in a jvm environment like unit tests.
	: 
	: Classes that weren't resolved:
	: > androidx.window.extensions.embedding.ActivityEmbeddingComponent
	: > androidx.window.extensions.layout.WindowLayoutComponent
	: > androidx.window.sidecar.SidecarDeviceState
	: > androidx.window.sidecar.SidecarInterface
	: > com.google.common.util.concurrent.ListenableFuture
	: > java.net.http.HttpTimeoutException
	: > javax.naming.NamingException
	: > javax.naming.directory.Attributes
	: > sun.misc.Unsafe
	: > androidx.compose.animation.tooling.ComposeAnimatedProperty
	: 
	: 
	: Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
	: 
	: You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
	: 
	: For more on this, please refer to https://docs.gradle.org/8.4/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
	: 714 actionable tasks: 713 executed, 1 up-to-date
	
	FAILURE: Build failed with an exception.
	
	* What went wrong:
	Execution failed for task ':app:packageDevDebug'.
	> A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable
	   > java.lang.OutOfMemoryError (no error message)
	
	* Try:
	> Run with --stacktrace option to get the stack trace.
	> Run with --info or --debug option to get more log output.
	> Run with --scan to get full insights.
	> Get more help at https://help.gradle.org.
	
	BUILD FAILED in 6m 12s
✗ Failed to build apk with entrypoint test_bundle.dart (Gradle build failed with code 1) (373.5s)
Exception: Gradle build failed with code 1
#0      AndroidTestBackend.build.<anonymous closure> (package:patrol_cli/src/android/android_test_backend.dart:79:9)
<asynchronous suspension>
#1      DisposeScope.run (package:dispose_scope/src/dispose_scope.dart:46:7)
<asynchronous suspension>
#2      AndroidTestBackend.build (package:patrol_cli/src/android/android_test_backend.dart:49:5)
<asynchronous suspension>
#3      BuildAndroidCommand.run (package:patrol_cli/src/commands/build_android.dart:160:7)
<asynchronous suspension>
#4      CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#5      PatrolCommandRunner.runCommand (package:patrol_cli/src/runner/patrol_command_runner.dart:366:18)
<asynchronous suspension>
#6      PatrolCommandRunner.run (package:patrol_cli/src/runner/patrol_command_runner.dart:310:18)
<asynchronous suspension>
#7      patrolCommandRunner (package:patrol_cli/src/runner/patrol_command_runner.dart:71:20)
<asynchronous suspension>
#8      main (file:///Users/builder/.pub-cache/hosted/pub.dev/patrol_cli-3.2.1/bin/main.dart:6:20)
<asynchronous suspension>

See the logs above to learn what happened. Also consider running with --verbose. If the logs still aren't useful, then it's a bug - please report it.
Exception: Gradle build failed with code 1
#0      AndroidTestBackend.build.<anonymous closure> (package:patrol_cli/src/android/android_test_backend.dart:79:9)
<asynchronous suspension>
#1      DisposeScope.run (package:dispose_scope/src/dispose_scope.dart:46:7)
<asynchronous suspension>
#2      AndroidTestBackend.build (package:patrol_cli/src/android/android_test_backend.dart:49:5)
<asynchronous suspension>
#3      BuildAndroidCommand.run (package:patrol_cli/src/commands/build_android.dart:160:7)
<asynchronous suspension>
#4      CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#5      PatrolCommandRunner.runCommand (package:patrol_cli/src/runner/patrol_command_runner.dart:366:18)
<asynchronous suspension>
#6      PatrolCommandRunner.run (package:patrol_cli/src/runner/patrol_command_runner.dart:310:18)
<asynchronous suspension>
#7      patrolCommandRunner (package:patrol_cli/src/runner/patrol_command_runner.dart:71:20)
<asynchronous suspension>
#8      main (file:///Users/builder/.pub-cache/hosted/pub.dev/patrol_cli-3.2.1/bin/main.dart:6:20)
<asynchronous suspension>



Build failed :|
Step 8 script `Build Patrol` exited with status code 1
Logs of SUCCESSFUL build
	: > Task :patrol:mergeDebugJniLibFolders UP-TO-DATE
	: > Task :patrol:mergeDebugNativeLibs NO-SOURCE
	: > Task :patrol:copyDebugJniLibsProjectOnly UP-TO-DATE
	: > Task :permission_handler_android:mergeDebugJniLibFolders UP-TO-DATE
	: > Task :permission_handler_android:mergeDebugNativeLibs NO-SOURCE
	: > Task :permission_handler_android:copyDebugJniLibsProjectOnly UP-TO-DATE
	: > Task :share_plus:mergeDebugJniLibFolders UP-TO-DATE
	: > Task :share_plus:mergeDebugNativeLibs NO-SOURCE
	: > Task :share_plus:copyDebugJniLibsProjectOnly UP-TO-DATE
	: > Task :shared_preferences_android:mergeDebugJniLibFolders UP-TO-DATE
	: > Task :shared_preferences_android:mergeDebugNativeLibs NO-SOURCE
	: > Task :shared_preferences_android:copyDebugJniLibsProjectOnly UP-TO-DATE
	: > Task :sqflite:mergeDebugJniLibFolders UP-TO-DATE
	: > Task :sqflite:mergeDebugNativeLibs NO-SOURCE
	: > Task :sqflite:copyDebugJniLibsProjectOnly UP-TO-DATE
	: > Task :sqlcipher_flutter_libs:mergeDebugJniLibFolders UP-TO-DATE
	: > Task :sqlcipher_flutter_libs:mergeDebugNativeLibs NO-SOURCE
	: > Task :sqlcipher_flutter_libs:copyDebugJniLibsProjectOnly UP-TO-DATE
	: > Task :url_launcher_android:mergeDebugJniLibFolders UP-TO-DATE
	: > Task :url_launcher_android:mergeDebugNativeLibs NO-SOURCE
	: > Task :url_launcher_android:copyDebugJniLibsProjectOnly UP-TO-DATE
	: > Task :video_player_android:mergeDebugJniLibFolders UP-TO-DATE
	: > Task :video_player_android:mergeDebugNativeLibs NO-SOURCE
	: > Task :video_player_android:copyDebugJniLibsProjectOnly UP-TO-DATE
	: > Task :wakelock_plus:mergeDebugJniLibFolders UP-TO-DATE
	: > Task :wakelock_plus:mergeDebugNativeLibs NO-SOURCE
	: > Task :wakelock_plus:copyDebugJniLibsProjectOnly UP-TO-DATE
	: > Task :webview_flutter_android:mergeDebugJniLibFolders UP-TO-DATE
	: > Task :webview_flutter_android:mergeDebugNativeLibs NO-SOURCE
	: > Task :webview_flutter_android:copyDebugJniLibsProjectOnly UP-TO-DATE
	: > Task :app:mergeDevDebugAndroidTestNativeLibs NO-SOURCE
	: > Task :app:checkDevDebugAndroidTestDuplicateClasses
	: > Task :app:validateSigningDevDebugAndroidTest
	: > Task :app:mergeExtDexDevDebugAndroidTest
	: > Task :app:mergeLibDexDevDebugAndroidTest
	: > Task :app:writeDevDebugAndroidTestSigningConfigVersions
	: > Task :app:mergeProjectDexDevDebugAndroidTest
	: > Task :app:packageDevDebugAndroidTest
	: > Task :app:createDevDebugAndroidTestApkListingFileRedirect
	: > Task :app:assembleDevDebugAndroidTest
	: 
	: Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
	: 
	: You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
	: 
	: For more on this, please refer to https://docs.gradle.org/8.4/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
	: 
	: BUILD SUCCESSFUL in 8s
	: 715 actionable tasks: 47 executed, 668 up-to-date
✓ Completed building apk with entrypoint test_bundle.dart (315.8s)

Patrol version

patrol: ^3.11.0

Patrol Doctor output

Patrol Doctor output
Patrol CLI version: 3.2.1
Flutter command: flutter 
  Flutter 3.24.1 • channel stable
Android: 
• Program adb found in /usr/local/share/android-sdk/platform-tools/adb
• Env var $ANDROID_HOME set to /usr/local/share/android-sdk
iOS / macOS: 
• Program xcodebuild found in /usr/bin/xcodebuild
• Program ideviceinstaller not found (install with `brew install ideviceinstaller`)

Flutter Doctor output

Flutter Doctor output
<!-- Replace this line with your logs. Do not remove the backticks! -->

martin1080p avatar Oct 29 '24 11:10 martin1080p

Hi @martin1080p ! Some additional questions:

  • Have this error occurred locally as well?
  • Can you provide a project with Codemagic CI configured so we can debug this?

I checked my project and org.gradle.jvmargs is set to Xmx4608m, so even less and I never encountered this error. Do you build the tests multiple times on the same workflow, so the machine is not clean? Or this happens on a clean machine?

Maybe this much memory is indeed needed, but it is unlikely imo. Did you try to increase this parameter?

jBorkowska avatar Oct 29 '24 12:10 jBorkowska

This error hasn't occurred when tested locally on Win, Linux and Mac.

This parameter was already increased from -Xms2048M, where the same error occurred as well. But sometimes like with this setting, it has been built successfully.

Unfortunately I am unable to share the whole project since it's commercial. However I might be able to share some pieces of code on demand.

martin1080p avatar Oct 29 '24 13:10 martin1080p

I think we should search for solution around the workflow or codemagic machines. Could you share what your workflow looks like? Can be just steps names, maybe there is something that consumes most of the memory before building

We also found this, maybe you'll find it helpful: https://docs.codemagic.io/troubleshooting/common-android-issues/#java-heap-space-out-of-memory-error

jBorkowska avatar Oct 31 '24 11:10 jBorkowska

@jBorkowska

android-integration-tests:
    name: Android Integration tests
    environment:
      <<: *android-apk-environment
      vars: *dev-variables
    scripts:
      - *tools-setup
      - *android-local-props-setup
      - *project-setup
      # - *analyze
      # - *dcm
      # - *tests
      - name: Patrol and GCloud setup
        script: |
          echo "Install patrol_cli"
          dart pub global activate patrol_cli
          patrol doctor

          echo "Setting up GCloud"
          echo $FIREBASE_INTEGRATION_KEY > ./gcloud_key_file.json
          gcloud auth activate-service-account --key-file=gcloud_key_file.json
          gcloud projects list
          gcloud --quiet config set project $FIREBASE_PROJECT_ID
          # TODO: TEMP solution
          gcloud components update
      #- *build-apk-android
      - name: Build Patrol
        working_directory: apps/bakalari
        script: |
          # Generate gradlew first
          flutter build apk --config-only -t lib/$RUN_FILE --flavor $FLAVOR
          patrol build android -t integration_test --verbose
      - name: Wakeup server
        script: curl --head --connect-timeout 60 --max-time 90 https://11.ext.bakalari.cz/
      - name: Run test
        working_directory: apps/bakalari
        script: |
          echo "Starting tests"
          ./scripts/firebase-test-lab-android.sh -l "$PROJECT_BUILD_NUMBER" -t 5m -p android-preset-small
  • In tools-setup it just setups cloudsmith and melos
  • android-local-props-setup is setting environment variables
  • project-setup runs melos

martin1080p avatar Nov 01 '24 08:11 martin1080p

@jBorkowska Hi can we investigate it further? For us it is currently blocker and we would like to run tests automatically with codemagic

petrnymsa avatar Dec 29 '24 12:12 petrnymsa

You can try adding this line to android/gradle.properties:

org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError

A heap dump can be helpful in pinpointing the cause.

bartekpacia avatar Jan 23 '25 01:01 bartekpacia

@bartekpacia Thanks for help, unfortunately the build still fails due to memory overflow.

Log
	: > Task :webview_flutter_android:copyDebugJniLibsProjectOnly
	: > Task :app:validateSigningDevDebug
	: > Task :app:writeDevDebugAppMetadata
	: > Task :app:writeDevDebugSigningConfigVersions
	: > Task :app:mergeDevDebugNativeLibs
	: > Task :app:stripDevDebugDebugSymbols
	: > Task :app:packageDevDebug FAILED
	: ASM Instrumentation process wasn't able to resolve some classes, this means that
	: the instrumented classes might contain corrupt stack frames. Make sure the
	: dependencies that contain these classes are on the runtime or the provided
	: classpath. Otherwise, the jvm might fail to load the corrupt classes at runtime
	: when running in a jvm environment like unit tests.
	: 
	: Classes that weren't resolved:
	: > com.google.common.util.concurrent.ListenableFuture
	: > sun.misc.Unsafe
	: > androidx.window.extensions.embedding.ActivityEmbeddingComponent
	: > androidx.window.extensions.layout.WindowLayoutComponent
	: > androidx.window.sidecar.SidecarDeviceState
	: > androidx.window.sidecar.SidecarInterface
	: > androidx.compose.animation.tooling.ComposeAnimatedProperty
	: > java.net.http.HttpTimeoutException
	: > javax.naming.NamingException
	: > javax.naming.directory.Attributes
	: 
	
	FAILURE: Build failed with an exception.
	
	* What went wrong:
	Execution failed for task ':app:packageDevDebug'.
	> A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable
	   > java.lang.OutOfMemoryError (no error message)
	
	* Try:
	> Run with --stacktrace option to get the stack trace.
	> Run with --info or --debug option to get more log output.
	> Run with --scan to get full insights.
	> Get more help at https://help.gradle.org.
	
	BUILD FAILED in 3m 8s
	: 
	: Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
	: 
	: You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
	: 
	: For more on this, please refer to https://docs.gradle.org/8.4/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
	: 714 actionable tasks: 709 executed, 5 up-to-date
✗ Failed to build apk with entrypoint test_bundle.dart (Gradle build failed with code 1) (189.7s)
Exception: Gradle build failed with code 1
#0      AndroidTestBackend.build.<anonymous closure> (package:patrol_cli/src/android/android_test_backend.dart:81:9)
<asynchronous suspension>
#1      DisposeScope.run (package:dispose_scope/src/dispose_scope.dart:46:7)
<asynchronous suspension>
#2      AndroidTestBackend.build (package:patrol_cli/src/android/android_test_backend.dart:51:5)
<asynchronous suspension>
#3      BuildAndroidCommand.run (package:patrol_cli/src/commands/build_android.dart:160:7)
<asynchronous suspension>
#4      CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#5      PatrolCommandRunner.runCommand (package:patrol_cli/src/runner/patrol_command_runner.dart:384:18)
<asynchronous suspension>
#6      PatrolCommandRunner.run (package:patrol_cli/src/runner/patrol_command_runner.dart:328:18)
<asynchronous suspension>
#7      patrolCommandRunner (package:patrol_cli/src/runner/patrol_command_runner.dart:75:20)
<asynchronous suspension>
#8      main (file:///Users/builder/.pub-cache/hosted/pub.dev/patrol_cli-3.5.0/bin/main.dart:6:20)
<asynchronous suspension>

See the logs above to learn what happened. Also consider running with --verbose. If the logs still aren't useful, then it's a bug - please report it.
Exception: Gradle build failed with code 1
#0      AndroidTestBackend.build.<anonymous closure> (package:patrol_cli/src/android/android_test_backend.dart:81:9)
<asynchronous suspension>
#1      DisposeScope.run (package:dispose_scope/src/dispose_scope.dart:46:7)
<asynchronous suspension>
#2      AndroidTestBackend.build (package:patrol_cli/src/android/android_test_backend.dart:51:5)
<asynchronous suspension>
#3      BuildAndroidCommand.run (package:patrol_cli/src/commands/build_android.dart:160:7)
<asynchronous suspension>
#4      CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#5      PatrolCommandRunner.runCommand (package:patrol_cli/src/runner/patrol_command_runner.dart:384:18)
<asynchronous suspension>
#6      PatrolCommandRunner.run (package:patrol_cli/src/runner/patrol_command_runner.dart:328:18)
<asynchronous suspension>
#7      patrolCommandRunner (package:patrol_cli/src/runner/patrol_command_runner.dart:75:20)
<asynchronous suspension>
#8      main (file:///Users/builder/.pub-cache/hosted/pub.dev/patrol_cli-3.5.0/bin/main.dart:6:20)
<asynchronous suspension>

Build failed :|
Step 8 script `Build Patrol` exited with status code 1

martin1080p avatar Jan 23 '25 09:01 martin1080p

@bartekpacia @jBorkowska Do you think we can move on somehow with this issue? We've tried everyting suggested but no luck.

For our, quite big project, it is show stopper and really blocker.

petrnymsa avatar Feb 27 '25 10:02 petrnymsa

Hey @martin1080p did you try solution suggested by codemagic there: https://docs.codemagic.io/troubleshooting/common-android-issues/#java-heap-space-out-of-memory-error-or-jvm-garbage-collector-is-thrashing? Set JAVA_TOOL_OPTIONS: "-Xmx5g" in the Codemagic workflow setup

  workflows:
    android-workflow:
      # ....
      environment:
        groups:
          # ...
        vars:
          JAVA_TOOL_OPTIONS: "-Xmx5g"

There's a thread about this issue in the Codemagic discord: https://discord.com/channels/1131597315707261018/1345307837190115328

pdenert avatar Aug 01 '25 19:08 pdenert

Without additional information, we can't resolve this issue. We're therefore reluctantly going to close it. Feel free to open a new issue with all the required information provided, including a [minimal, reproducible sample]. Make sure to diligently fill out the issue template. Thanks for your contribution. [minimal, reproducible sample]: https://stackoverflow.com/help/minimal-reproducible-example

github-actions[bot] avatar Aug 15 '25 13:08 github-actions[bot]

This issue has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar problem, please file a new issue. Make sure to follow the template and provide all the information necessary to reproduce the issue.

github-actions[bot] avatar Aug 22 '25 13:08 github-actions[bot]