EAS Android build problem

Hello eas build fails in Android,perfectly works in ios
Any help would be appreciated.

  • managed workflow
  • eas 0.50, expo 44
some of error messages in expo console
[stderr] FAILURE: Build failed with an exception.
[stderr] * What went wrong:
[stderr] Execution failed for task ':app:mergeDebugNativeLibs'.
[stderr] > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
[stderr]    > More than one file was found with OS independent path 'lib/x86_64/libreactnativejni.so'. If you are using jniLibs and CMake IMPORTED targets, see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake
[stderr] * Try:
[stderr] 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.
[stderr] * Get more help at https://help.gradle.org
[stderr] BUILD FAILED in 9m 28s

........

[stderr] Note: Some input files use or override a deprecated API.
[stderr] Note: Recompile with -Xlint:deprecation for details.
[stderr] Note: /home/expo/workingdir/build/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebView

.....

[stderr] Note: Recompile with -Xlint:unchecked for details.
> Task :app:compileDebugJavaWithJavac
> Task :app:compileDebugSources
> Task :app:mergeDebugNativeDebugMetadata NO-SOURCE
[stderr] Note: /home/expo/workingdir/build/android/app/src/debug/java/io/batyr/expostarter/ReactNativeFlipper.java uses or overrides a deprecated API.
[stderr] Note: Recompile with -Xlint:deprecation for details.

....

[stderr] Note: /home/expo/workingdir/build/node_modules/react-native-purchases/android/src/main/java/com/revenuecat/purchases/react/RNPurchasesModule.java uses or overrides a deprecated API.
[stderr] Note: Recompile with -Xlint:deprecation for details.
[stderr] Note: /home/expo/workingdir/build/node_modules/react-native-purchases/android/src/main/java/com/revenuecat/purchases/react/RNPurchasesModule.java uses unchecked or unsafe operations.

I tried building dev client locally . I got this messages

FAILURE: Build completed with 2 failures.

1: Task failed with an exception.
-----------
* Where:
Build file '/Users/slhdemirel/Code/flex/node_modules/expo-gl-cpp/android/build.gradle' line: 307

* What went wrong:
A problem occurred evaluating project ':expo-gl-cpp'.
> SDK location not found. Define location with an ANDROID_SDK_ROOT environment variable or by setting the sdk.dir path in your project's local properties file at '/Users/slhdemirel/Code/flex/android/local.properties'.

* 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.
==============================================================================

2: Task failed with an exception.
-----------
* What went wrong:
A problem occurred configuring project ':expo'.
> compileSdkVersion is not specified. Please add it to build.gradle

* 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

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.9/userguide/command_line_interface.html#sec:command_line_warnings
 package.json;

  "dependencies": {
    "@kanzitelli/if-component": "^0.3.0",
    "@react-native-community/masked-view": "^0.1.11",
    "@react-native-community/netinfo": "7.1.3",
    "@react-native-picker/picker": "2.2.1",
    "@react-navigation/bottom-tabs": "^6.0.9",
    "@react-navigation/native": "^6.0.6",
    "@react-navigation/native-stack": "^6.2.5",
    "@react-navigation/stack": "^6.0.11",
    "add": "^2.0.6",
    "crypto": "^1.0.1",
    "date-fns": "^2.28.0",
    "dayjs": "^1.11.0",
    "expo": "^44.0.0",
    "expo-ads-admob": "~12.0.0",
    "expo-asset": "~8.4.6",
    "expo-camera": "~12.1.2",
    "expo-crypto": "~10.1.1",
    "expo-dev-client": "~0.8.4",
    "expo-device": "~4.1.0",
    "expo-face-detector": "~11.1.3",
    "expo-font": "~10.0.4",
    "expo-gl": "~11.1.1",
    "expo-image-crop": "^1.0.4",
    "expo-image-manipulator": "~10.2.0",
    "expo-image-picker": "~12.0.1",
    "expo-linear-gradient": "~11.0.3",
    "expo-linking": "~3.0.0",
    "expo-localization": "~12.0.0",
    "expo-notifications": "~0.14.0",
    "expo-permissions": "~13.1.0",
    "expo-secure-store": "~11.1.0",
    "expo-sharing": "~10.1.0",
    "expo-splash-screen": "~0.14.1",
    "expo-sqlite": "~10.1.0",
    "expo-status-bar": "~1.2.0",
    "expo-updates": "~0.11.6",
    "expo-web-browser": "~10.1.0",
    "formik": "^2.2.9",
    "i18n-js": "^3.8.0",
    "lodash": "^4.17.21",
    "lottie-react-native": "5.0.1",
    "mobx": "^6.3.12",
    "mobx-persist-store": "^1.0.4",
    "mobx-react": "^7.2.1",
    "no-scroll": "^2.1.1",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "react-native-animated-loader": "^0.0.9",
    "react-native-barcode-mask": "^1.2.4",
    "react-native-fast-image": "^8.5.11",
    "react-native-floating-label-input": "^1.3.13",
    "react-native-gesture-handler": "~2.1.0",
    "react-native-get-random-values": "~1.7.0",
    "react-native-icon-badge": "^1.1.3",
    "react-native-keyboard-aware-scroll-view": "^0.9.5",
    "react-native-mmkv": "1.3.2",
    "react-native-modal": "^13.0.0",
    "react-native-purchases": "^4.5.1",
    "react-native-reanimated": "~2.3.1",
    "react-native-redash": "^16.2.3",
    "react-native-responsive-fontsize": "^0.5.1",
    "react-native-safe-area-context": "3.3.2",
    "react-native-screens": "~3.10.1",
    "react-native-star-rating": "^1.1.0",
    "react-native-svg": "12.1.1",
    "react-native-svg-animations": "^0.2.6",
    "react-native-ui-lib": "^6.7.0",
    "react-native-web": "0.17.1",
    "react-native-webview": "11.15.0",
    "recoil": "^0.5.2",
    "recompose": "^0.30.0",
    "recyclerlistview": "^3.0.5",
    "rn-bounceable": "^1.1.0",
    "yup": "^0.32.11"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@expo/config-plugins": "^4.0.15",
    "@expo/webpack-config": "~0.16.2",
    "@react-native-community/eslint-config": "^3.0.1",
    "@types/i18n-js": "^3.8.2",
    "@types/lodash": "^4.14.178",
    "@types/react": "~17.0.21",
    "@types/react-dom": "~17.0.9",
    "@types/react-native": "~0.64.12",
    "@typescript-eslint/parser": "^5.9.0",
    "dotenv-cli": "^4.1.1",
    "prettier": "^2.4.1",
    "react-native-svg-transformer": "^1.0.0",
    "release-it": "^14.11.8",
    "typescript": "~4.3.5"
  }
}

Hi @emrahc

A local build worked for me after I set the ANDROID_NDK_HOME environment variable to point to where Android Studio installed the NDK. But during the build it downloaded over 3G of a different version of the NDK :angry:. Anyway, the build worked fine.

Then I tried a build on the build servers and that failed similarly to yours. I have seen errors like that that can be worked around with a config plugin, but I thought I’d first try using a build environment on the build server that is closer to my local environment.

I think the main difference between my local environment and the build server is that I’m using Java 11 and the build server uses Java 8 by default. Fortunately you can configure the build server’s build environment. See also Build schema for eas.json:

eas.json:

{
  "cli": {
    "version": ">= 0.46.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "android": {
        "image": "ubuntu-20.04-jdk-11-ndk-r21e"
      }
    },
    "preview": {
      "distribution": "internal",
      "android": {
        "image": "ubuntu-20.04-jdk-11-ndk-r21e"
      }
    },
    "production": {
      "android": {
        "image": "ubuntu-20.04-jdk-11-ndk-r21e"
      }
    }
  },
  "submit": {
    "production": {}
  }
}

Unfortunately that still failed in the same way :frowning:

So a plugin it is. Fortunately I’ve written one before. See here:

I built the app successfully using this config plugin and the following plugins section in app.json:

[...]
    "plugins": [
      [
        "./plugins/withAndroidPickFirst",
        {
          "paths": [
            "lib/**/libreactnativejni.so"
          ]
        }
      ]
    ]
[...]

Thanks for your detailed, explanatory answer. I have tried that but no luck. I was able to build android. That config plugin cancels others as well.

my plugins

    "plugins": [
      "./plugins/withMMKV",
      [
        "./plugins/withAndroidPickFirst",
        {
          "paths": ["lib/**/libreactnativejni.so"]
        }
      ]
    ],

When i try it in dev-client got this message

Error: Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!, js engine: hermes
- ... 12 more stack frames from framework internals

Thank you

hmmm… That sort of error normally happens if you build with expo build or try to run the code in Expo Go.

So you built with eas build -p android --profile development?

And you opened the app by running expo start --dev-client on your PC and running the dev client app on your phone? Not the Expo Go app?

Yes i built with;

eas build -p android --profile development
command.

And opened it with expo custom dev client

expo start --dev-client

I’ve just given it a try. Here are my dependencies:

  "dependencies": {
    "expo": "^44.0.0",
    "expo-asset": "~8.4.6",
    "expo-dev-client": "~0.8.4",
    "expo-splash-screen": "~0.14.1",
    "expo-status-bar": "~1.2.0",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "react-native-mmkv": "^2.3.3"
  },

NOTE: I did not need to add a plugin to support MMKV. (Except for the previously mentioned withAndroidPickFirst)

I built the app locally with JDK 11 (but of course this should work with the Expo build servers too):

eas build -p android --profile development --local

My eas.json is still as per my previous message. The “image” keys do not affect local builds. You may or may not need them.

At this point, App.js was still the default as created by expo init.

I installed the APK on my phone and logged in. I ran expo start --dev-client and pressed on the “Refetch development servers” button. The app showed up and I selected it. The default Expo app ran as expected.

Then I edited App.js to contain the following and it was able to store and retrieve items from the database:

import { useEffect } from "react";
import { StatusBar } from "expo-status-bar";
import { Button, StyleSheet, Text, View } from "react-native";
import {
  MMKV,
  useMMKVBoolean,
  useMMKVListener,
  useMMKVNumber,
  useMMKVString,
} from "react-native-mmkv";

export const storage = new MMKV();

function KV({ k: key, v: value }) {
  return (
    <View
      style={{
        width: "90%",
        flexDirection: "row",
        justifyContent: "center",
        alignItems: "center",
      }}
    >
      <Text style={{ width: "30%" }}>{key}:</Text>
      <Text style={{ width: "10%" }}>{value}</Text>
    </View>
  );
}

export default function App() {
  const [name, setName] = useMMKVString("user.name");
  const [age, setAge] = useMMKVNumber("user.age");
  const [isPremiumUser, setIsPremiumUser] = useMMKVBoolean("user.isPremium");

  useMMKVListener((key) => {
    console.log(`Value for "${key}" changed!`);
  });

  useEffect(() => {
    storage.clearAll();
    setName("Fred");
    setAge(99);
    setIsPremiumUser(true);
  }, []);

  return (
    <View style={styles.container}>
      <KV k="Name" v={name} />
      <KV k="Age" v={age} />
      <KV k="Premium" v={isPremiumUser.toString()} />
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
    marginTop: 20,
  },
});

I removed the line from app.json

“./plugins/withMMKV”,

kept

withAndroidPickFirst

Built a custom client in eas cloud. Run the expo got that same error

Error: Failed to create a new MMKV instance, the native initializer function does not exist. Is the native MMKV library correctly installed? Make sure to disable any remote debugger (e.g. Chrome) to use JSI!, js engine: hermes
- ... 12 more stack frames from framework internals

I tried to built with MMKV & withAndroidPickFirst ,and without any plugin got the same error.

Can you try stripping your app down to the bare minimum, but still with MMKV and see if that builds? Mine was just a newly created Expo app with react-native-mmkv added.

I actually think it was one of your other dependencies that wanted the pickFirst stuff, rather than react-native-mmkv. Give it a try without that plugin too.