mapbox-maps-android
mapbox-maps-android copied to clipboard
conflict issue occurs because the libc++_shared.so versions
Environment
- Android OS version: 14
- Devices affected: galaxy S22+ samsung
- Maps SDK Version: 11.0.0 and 11.1.0
Observed behavior and steps to reproduce
It is used by adding a 3dr party library called ZTA_release in a multi-module environment. It appears that a conflict issue occurs because the libc++_shared.so versions of ZTA lib and Mapbox's common-24.1.0 library are different.
2 files found with path 'lib/arm64-v8a/libc++_shared.so' from inputs:
- /Users/smj/.gradle/caches/transforms-3/8a5c0298a03bd21724b03309be68e201/transformed/ZTA_release/jni/arm64-v8a/libc++_shared.so
- /Users/smj/.gradle/caches/transforms-3/785aa80556add9db0dba40a83d4139cf/transformed/common-24.1.0/jni/arm64-v8a/libc++_shared.so If you are using jniLibs and CMake IMPORTED targets, see
So I tried one method. packagingOptions { pickFirst '/armeabi-v7a/libc++_shared.so' pickFirst '/arm64-v8a/libc++_shared.so' }
However, the following issue occurs.
ATAL EXCEPTION: main
Process: com.routo.mapsdkapp, PID: 30708
java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String com.mapbox.common.MapboxOptionsImpl.getAccessToken() (tried Java_com_mapbox_common_MapboxOptionsImpl_getAccessToken and Java_com_mapbox_common_MapboxOptionsImpl_getAccessToken__) - is the library loaded, e.g. System.loadLibrary?
at com.mapbox.common.MapboxOptionsImpl.getAccessToken(Native Method)
at com.mapbox.common.MapboxOptions.getAccessToken(MapboxOptions.kt:17)
at com.mapbox.maps.MapController.
Expected behavior
Notes / preliminary analysis
Additional links and references
@SeoMyungjun hi! The workaround you added should work in general, again if the libc++ binaries are both compatible with each other. The build issue you see does not mean incompatible libc++ is used, gradle fails if more then one libc++ are provided by the dependencies, even if they are of same or compatible version.
Process: com.routo.mapsdkapp, PID: 30708
java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String com.mapbox.common.MapboxOptionsImpl.getAccessToken()
means that our internal library function is not available in the native module. How do you integrate Mapbox dependencies, could you provide build.gradle config with it?
PS. More details on libc++ compatibility. If the ZTA_release lib contains libc++ it is indeed should be compatible with the libc++ that is provided in Maps. We build our libs with NDK 23 at the moment hence ZTA_release lib should be also built with the same or more recent version as there is a known issue that NDK 22/23 are not compatible.
In addition to @yunikkk 's comment above explicitly noting that Maps v11 are built with NDK 23 while Maps v10 are built with NDK 21 so it may be an option for you to use Maps v10.
@yunikkk here is my build.gradle config I need to use v11 or higher.
dependencies {
implementation(project(":mapsdk"))
implementation fileTree(dir: 'libs', include: ['*.aar'])
implementation "androidx.startup:startup-runtime:1.1.1"
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation "androidx.work:work-runtime-ktx:2.8.1" // kotlin
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.recyclerview:recyclerview:1.3.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.asynclayoutinflater:asynclayoutinflater:1.0.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
// // retrofit2 implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // okhttp3 implementation 'com.squareup.okhttp3:okhttp:4.10.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
implementation("com.mapbox.maps:android:11.1.0")
//add
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:5.4.1'
// implementation 'com.mapbox.mapboxsdk:mapbox-sdk-geojson:6.9.0' implementation 'com.mapbox.mapboxsdk:mapbox-sdk-services:5.4.1'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.3'
}
android { packagingOptions {
// pickFirst 'lib/x86/libc++_shared.so' // pickFirst 'lib/x86_64/libc++_shared.so' pickFirst '/armeabi-v7a/libc++_shared.so' pickFirst '/arm64-v8a/libc++_shared.so' resources { exclude 'META-INF/NOTICE.md' exclude 'META-INF/LICENSE.md' excludes += '/META-INF/{AL2.0,LGPL2.1}' } } }
@SeoMyungjun few additional questions :
- the gradle entries
implementation("com.mapbox.maps:android:11.1.0")
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:5.4.1'
// implementation 'com.mapbox.mapboxsdk:mapbox-sdk-geojson:6.9.0'
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-services:5.4.1'
is the only place where mapbox dependencies are being added, correct? No local aars are present in the project?
- do you somehow configure
androidx.startup.InitializationProvidermaybe? Could you check the merged manifest (typically lives inapp/build/intermediates/merged_manifest/debug/AndroidManifest.xml) to see how it is configured? Merged manifest should contain provider config e.g. :
...
<provider
android:name="androidx.startup.InitializationProvider"
...
</provider>
...
)
@yunikkk I tried provider but I'm not using it right now.
<!-- <provider-->
<!-- android:name="androidx.startup.InitializationProvider"-->
<!-- android:authorities="${applicationId}.androidx-startup"-->
<!-- tools:node="remove">-->
<!-- </provider>-->
<!-- <provider-->
<!-- android:name="androidx.startup.InitializationProvider"-->
<!-- android:authorities="${applicationId}.androidx-startup"-->
<!-- android:exported="false"-->
<!-- tools:node="merge">-->
<!-- <meta-data-->
<!-- android:name="com.mapbox.maps.loader.MapboxMapsInitializer"-->
<!-- android:value="androidx.startup"-->
<!-- tools:node="remove" />-->
<!-- </provider>-->
Okay, but Maps has it's own provider and it should be added to the merged manifest, otherwise native libraries will not be loaded. Could you check the merged manifest provider entries?
@yunikkk here is AndroidManifest.xml (app/build/intermediates/merged_manifest/debug/AndroidManifest.xml)
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="com.routo.mapsdkapp.androidx-startup"
android:exported="false" >
<meta-data
android:name="com.mapbox.maps.loader.MapboxMapsInitializer"
android:value="androidx.startup" />
<!-- This entry makes MapboxSDKCommonInitializer discoverable. -->
<meta-data
android:name="com.mapbox.common.MapboxSDKCommonInitializer"
android:value="androidx.startup" />
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup" />
<meta-data
android:name="androidx.emoji2.text.EmojiCompatInitializer"
android:value="androidx.startup" />
<meta-data
android:name="androidx.lifecycle.ProcessLifecycleInitializer"
android:value="androidx.startup" />
</provider>
<receiver
android:name="com.mapbox.common.location.LocationUpdatesReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="com.mapbox.common.location.LocationUpdatesReceiver.ACTION_PROCESS_LOCATION_UPDATES" />
</intent-filter>
</receiver>
<service
android:name="com.mapbox.common.LifecycleService"
android:exported="false" /> <!-- Needs to be explicitly declared on P+ -->
@SeoMyungjun ok, both MapboxSDKCommonInitializer and MapboxMapsInitializer are there so this means native libraries should load, when those initializers are triggered. I see couple possible reasons here :
mapbox-commonnative lib was not bundled in the build for some reason. You could check in the Android Studio - open the built APK and you should seelib/YOUR_ABI/bothlibmapbox-maps.so/libmapbox-common.sothere- initializers were not launched. Which should be fine since you have them in the manifest. Could you share the full logcat when this crash happens to double check?