Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Execution failed for task ':app:mergeLibDexDebug' #253

Closed
ToberoCat opened this issue Sep 26, 2024 · 4 comments
Closed

Execution failed for task ':app:mergeLibDexDebug' #253

ToberoCat opened this issue Sep 26, 2024 · 4 comments

Comments

@ToberoCat
Copy link

Description

When trying to build the Android debug version of the app, the following error occurs during the :app:mergeLibDexDebug task:

Execution failed for task ':app:mergeLibDexDebug'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.DexMergingTaskDelegate
   > There was a failure while executing work items
      > A failure occurred while executing com.android.build.gradle.internal.tasks.DexMergingWorkAction
         > com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
           Type eu.simonbinder.sqlite3_flutter_libs.BuildConfig is defined multiple times: /path/to/project/build/sqlcipher_flutter_libs/.transforms/d5eea9ac0c34de1057b7743aacfccd02/transformed/classes/classes.dex, /path/to/project/build/sqlite3_flutter_libs/.transforms/f96da8f27d0ddf7a4891aa6d0a486253/transformed/classes/classes.dex
           Learn how to resolve the issue at https://developer.android.com/studio/build/dependencies#duplicate_classes.

Steps to Reproduce

  1. Attempt to build the Android debug file in the following project path:
    /path/to/project/android
    
  2. Command used:
    flutter build apk --debug

Flutter Version

Flutter 3.24.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 5874a72aa4 (5 weeks ago) • 2024-08-20 16:46:00 -0500
Engine • revision c9b9d5780d
Tools • Dart 3.5.1 • DevTools 2.37.2

Dependencies Used:

dependencies:
  flutter:
    sdk: flutter
  intl: ^0.19.0
  provider: ^6.1.2
  flutter_svg: ^2.0.10+1
  flutter_typeahead: ^4.0.0
  drift: ^2.20.2
  path: ^1.9.0
  path_provider: ^2.1.4
  sqlcipher_flutter_libs: ^0.6.4
  sqlite3: ^2.4.6
  sqlite3_flutter_libs: ^0.5.24

Additional Context

  • The error seems to be caused by duplicate class definitions in sqlcipher_flutter_libs and sqlite3_flutter_libs.
  • I’ve already tried to resolve this by following the suggestion to check for duplicate classes in dependencies but have not yet found a solution.
  • It seems likely that this issue is related to this issue: Error if use sqlcipher_flutter_libs drift#3226

Any help or guidance on resolving this would be appreciated.

@simolus3 simolus3 transferred this issue from simolus3/drift Sep 26, 2024
@simolus3
Copy link
Owner

This is actually intentional - sqlcipher_flutter_libs and sqlite3_flutter_libs are fundamentally incompatible with each other and cannot be used in the same project.
That is because sqlite3/SQLCipher is statically linked on iOS, and we can't do that with both sqlite3 and SQLCipher in the same project with Flutter's current build setup (as they define the same symbol names).

Can you remove the dependency on sqlite_flutter_libs?

@ToberoCat
Copy link
Author

ToberoCat commented Sep 27, 2024

Removing the sqlite_flutter_libs did work - The build is now compiling.

I'm now having a issue with running the app:

E/flutter ( 9234): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library '/data/data/at.janusobjecttueren.complaint_email_app/lib/libsqlite3.so': dlopen failed: library "/data/data/at.janusobjecttueren.complaint_email_app/lib/libsqlite3.so" not found
E/flutter ( 9234): #0      _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:11:43)
E/flutter ( 9234): #1      new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:22:12)
E/flutter ( 9234): #2      _defaultOpen (package:sqlite3/src/ffi/load_library.dart:40:29)
E/flutter ( 9234): #3      OpenDynamicLibrary.openSqlite (package:sqlite3/src/ffi/load_library.dart:127:12)
E/flutter ( 9234): #4      sqlite3 (package:sqlite3/src/ffi/api.dart:13:39)
E/flutter ( 9234): #5      AppDatabase._openConnection.<anonymous closure> (package:janus_app/database/database.dart:43:7)
E/flutter ( 9234): <asynchronous suspension>
E/flutter ( 9234): #6      LazyDatabase._awaitOpened.<anonymous closure> (package:drift/src/utils/lazy_database.dart:47:32)
E/flutter ( 9234): <asynchronous suspension>
E/flutter ( 9234): 

I use this method to create the database:

import 'dart:ffi';
import 'dart:io';

import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:sqlcipher_flutter_libs/sqlcipher_flutter_libs.dart';
import 'package:sqlite3/open.dart';
import 'package:sqlite3/sqlite3.dart';
part 'database.g.dart';

const _encryptionPassword = '7832aeb781b006aa57144875b4a3ea69';

  static QueryExecutor _openConnection() {
    return LazyDatabase(() async {
      final dbFolder = await getApplicationDocumentsDirectory();
      final file = File(p.join(dbFolder.path, 'db.sqlite'));

      final cachebase = (await getTemporaryDirectory()).path;
      sqlite3.tempDirectory = cachebase;

      return NativeDatabase.createInBackground(
        file,
        isolateSetup: () async {
          open
            ..overrideFor(OperatingSystem.android, openCipherOnAndroid)
            ..overrideFor(OperatingSystem.linux,
                () => DynamicLibrary.open('libsqlcipher.so'))
            ..overrideFor(OperatingSystem.windows,
                () => DynamicLibrary.open('sqlcipher.dll'));
        },
        setup: (db) {
          final result = db.select('pragma cipher_version');
          if (result.isEmpty) {
            throw UnsupportedError(
              'This database needs to run with SQLCipher, but that library is '
              'not available!',
            );
          }

          db.execute(
              "pragma key = '${_encryptionPassword.replaceAll("'", "''")}'");
          db.execute('select count(*) from sqlite_master');
        },
      );
    });
  }

I use this to get the items:

void doStuff(AppDatabase database) async {
  database.todo.select().watch().listen((event) {
    print(event);
  });
}

Is there anything I've missed with the installation? On the sqlite3 website it says that using the sqlcipher_flutter_libs will also include the library - But apparently it didn't.

When searching the built apk, I couldn't find the sqlite3.so in it, only libsqlcipher.so.

But thank you for the quick response :)

@simolus3
Copy link
Owner

simolus3 commented Sep 27, 2024

You're using sqlite3.tempDirectory before applying the opening override, so it will still try to use the regular sqlite3 library.

You could copy the part you have in isolateSetup and call it before setting tempDirectory, or just apply tempDirectory in isolateSetup instead.

@ToberoCat
Copy link
Author

Amazing, thank you - That fixed it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants