ministero-salute / it-dgc-verificac19-sdk-android

Digital Covid Certificate SDK
Apache License 2.0
57 stars 29 forks source link

Problemi legati a Realm con versione 1.1.0 #90

Closed albertocappellina closed 1 year ago

albertocappellina commented 2 years ago

Buongiorno, ho aggiornato l'sdk dalla release 1.0.4 al tag 1.1.0 (tra l'altro perchè non trovo questa versione tra le release?)

A quel punto la nostra app non riesce più a partire a causa di crash legati a realm, ovvero

1) non trova più alcune classi all'interno dello schema di realm

E/CoroutineScopeExtensionKt$launchWithExceptionHandler: io.realm.exceptions.RealmException: 'class it.[REDACTED].common.persistency.model.EtagData' is not part of the schema for this Realm.

2) se provengo da una app precedente il crash è dovuto ad una migrazione mancante (RevokedPass) che non fa parte delle classi realm dell'app

Come posso risolvere?

Grazie, Alberto

rawmain commented 2 years ago

Buongiorno @albertocappellina

ho aggiornato l'sdk dalla release 1.0.4 al tag 1.1.0 (tra l'altro perchè non trovo questa versione tra le release?)

E' stato evidentemente deciso di non mantenerla, considerando che il codice TAG 1.1.0 è allineato 100% con codice release DGC-SDK 1.1.0 usato da whitelabel-app VerificaC19 prodrelease 1.2.0 (a differenza p.es. di branch release 1.0.4 vs TAG 1.0.4 - pubblicato prima di ultimi commit confluiti in produzione).

la nostra app non riesce più a partire a causa di crash legati a realm, ovvero

  1. non trova più alcune classi all'interno dello schema di realm

E/CoroutineScopeExtensionKt$launchWithExceptionHandler: io.realm.exceptions.RealmException: 'class it.[REDACTED].common.persistency.model.EtagData' is not part of the schema for this Realm.

  1. se provengo da una app precedente il crash è dovuto ad una migrazione mancante (RevokedPass) che non fa parte delle classi realm dell'app

Switchando da DGC-SDK 1.0.4 a 1.1.0->1.1.1, stai comunque aggiungendo alla tua app un'ulteriore nuova Realm Model class.

@RealmClass
open class RevokedPass(@PrimaryKey var hashedUVCI: String = "") : RealmObject()

alle 57 Realm Class già definite nel codice tua App/UI (stando ad ultima storerelease), tra cui appunto

public class EtagData extends RealmObject implements it_i******_d***************_common_persistency_model_EtagDataRealmProxyInterface { [...]

Pertanto, devi comunque controllare & aggiustare isolamento path/schema per i RealmConfiguration multipli - istanziati dalla tua app, in modo da avere OK persistency per i RealmObject nei diversi moduli (app / project:dgc-sdk).

Altrimenti, è normale che non vengano richiamati i corretti RealmObject distinti per progetto/modulo = runtime exception per model class RevokedPass non definita p.es. nello schema di Realm build (GreenPassPersistencyManager tua app) e/o le altre non definite per Realm VerificaC19 (name realm per le entry CRL/DRL ex DGC-SDK 1.1.0/1.1.1).

albertocappellina commented 2 years ago

Grazie per la risposta @rawmain quindi di fatto devo fixare lo schema della configurazione della nostra istanza realm perche' non cerchi realm object al di fuori del proprio schema.

Quello che non capisco è perchè, solo con questo update riscontro il problema ? Prima non erano state introdotte nuove classi (diciamo dalla 1.0.2) ?

Grazie ancora Alberto

rawmain commented 2 years ago

Ciao @albertocappellina

Grazie per la risposta

Prego ;)

quindi di fatto devo fixare lo schema della configurazione della nostra istanza realm perche' non cerchi realm object al di fuori del proprio schema.

Corretto.

Dato che project:dgc-sdk aggiunge con release 1.1.0 la RealmConfiguration con DB name VerificaC19, contenente dati non correlati con Realm DB già in uso da tua app, devi impostare l'isolamento schema/moduli in modo che i DB contengano/usino solo tabelle per i RealmObject, che devono contenere.

In questo modo eviti appunto di ritrovarti la tabella RevokedPass in DB .realm tua app & altrettanto quelle delle tue classi app in DB VerificaC19 (gestione default schema, per cui tutte le classi in progetto, che estendono RealmObject, finiscono come tabelle in ogni DB) & non ottieni KO in getinstance/migration.


Quello che non capisco è perchè, solo con questo update riscontro il problema ? Prima non erano state introdotte nuove classi (diciamo dalla 1.0.2) ?

I commit per aggiunta CRL/DRL - inclusa quindi l'implementazione di Realm DB (solo per gestione revoke) in aggiunta a layer Room SQLite (Rules/KIDs) - sono stati finalizzati nei rami feature/revoke* il 23/11 per release SDK 1.0.3 .

Tale release & i commit specifici CRL/DRL non furono però passati allora in produzione.

La prodrelease 1.0.4 (finalizzata 02/12 in correlazione a prodrelease 1.1.8 VerificaC19) è infatti basata sul codice precedente prodrelease 1.0.2 con la sola aggiunta dei commit per il supporto SGP - scanmode 3G/2G (modalità base/rafforzata).

I commit CRL/DRL sono stati passati quindi in produzione solo per prodrelease 1.1.0 (finalizzata 17/12 in correlazione a prodrelease 1.2.0 VerificaC19), a seguito anche del relativo OK da parte del Garante Privacy (provv. GPDP n. 430 13/12/2021).

albertocappellina commented 2 years ago

Perfetto @rawmain, sempre gentile!

Ho definito il module per la nostra istanza realm

@RealmModule(classes = [LocationData::class, ... GPSData::class ]) class RealmAppModule

e con il variant di debug tutto bene tuttavia in release la procedura di build ritorna il seguente errore

ERROR:/Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/project_dex_archive/productionRelease/out/io/realm/DefaultRealmModule.dex: D8: Type io.realm.DefaultRealmModule is defined multiple times: /Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/project_dex_archive/productionRelease/out/io/realm/DefaultRealmModule.dex, /Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/sub_project_dex_archive/productionRelease/out/2bf871a8aaabff35b7d919a366c5f8db67b4b57740f48fd2666e9cccb30fb138_2.jar:classes.dex com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: Type io.realm.DefaultRealmModule is defined multiple times: /Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/project_dex_archive/productionRelease/out/io/realm/DefaultRealmModule.dex, /Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/sub_project_dex_archive/productionRelease/out/2bf871a8aaabff35b7d919a366c5f8db67b4b57740f48fd2666e9cccb30fb138_2.jar:classes.dex

pero' il DefaultRealmModule è creato (2 volte?) nel sotto progetto dgc-sdk

Puo' essere dovuto al fatto che non specificate, nella configurazione dell'instanza realm, alcun modulo? Da quello che ho capito se viene usata una sottolibreria che "offre" realm il module va specificato come

RealmModule(allClasses = true, library = true)

albertocappellina commented 2 years ago

@Rawmain, Confermo che se modifico (in locale) il sorgente per dgc-sdk definendo il modulo

`@RealmModule(library = true, allClasses = true) public class LibraryModule {

}`

e aggiungendo ad ogni chiamata

RealmConfiguration.Builder().name(REALM_NAME)

che trovo .modules(LibraryModule()) la creazione dell'apk in release termina correttamente e simulando la procedura di update (adb install -r) questa viene eseguita correttamente.

conviene incorporare la modifica nel vostro branch ? (sto usando la release 1.1.1)

rawmain commented 2 years ago

Ciao @albertocappellina

Ho definito il module per la nostra istanza realm

@RealmModule(classes = [LocationData::class, ... GPSData::class ]) class RealmAppModule

e con il variant di debug tutto bene tuttavia in release la procedura di build ritorna il seguente errore

`ERROR:/Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/project_dex_archive/productionRelease/out/io/realm/DefaultRealmModule.dex: D8: Type io.realm.DefaultRealmModule is defined multiple times:

Non mi torna però tale differenza di esito in build - a meno che compaia comunque l'indicazione come build-warning - visto che non c'è differenza debug/release di dichiarazione/gestione Realm Module in DGC-SDK e non la sto ritrovando, passando (velocemente) in rassegna il codice vs. app.

Visto che non hai riscontrato quindi la medesima build exception nel 1° passaggio build-variant debug, ti chiedo anche comunque una verifica di eventuali variazioni - anche a seguito di full clean+rebuild, già senza modificare il codice in DGC-SDK per l'esposizione esplicita dello schema di REALM_NAME VerificaC19 :

  1. Selezione di build-variant release per app/moduli

  2. Azzeramento cache = Build/Clean project + Invalidate cache & restart da Android Studio (o clean + cleanBuildCache da gradle task)

  3. Nuovo gradle sync in build-variant release

  4. Nuovo project build

........................................

Confermo che se modifico (in locale) il sorgente per dgc-sdk definendo il modulo [...] conviene incorporare la modifica nel vostro branch ? (sto usando la release 1.1.1)

Tale modifica locale espone in app schema e Realm Class del Realm DB VerificaC19, dichiarando esplicitamente un nome Realm Module (onde evitare build DefaultRealmModule per dgc-sdk) & indicando library = true & allClasses = true per considerare solo le classi definite in project:dgc-sdk senza elencarle manualmente.

E' semplice da implementare con alcune modifiche. Infatti la testerò cmq dopo, onde verificare in primis che non ci siano problemi con whitelabel-app (non dovrebbero esserci, visto che modulo app non definisce/usa ulteriori Realm DB, ma posso confermarlo solo dopo test n.d.r.).

Le modifiche di base consisterebbero cmq in :

  1. Import + definizione RealmModule class in RevokedPass.kt
import io.realm.annotations.RealmModule

[...]

@RealmModule(library = true, classes = [RevokedPass::class])
class VerificaC19sdkLibraryModule
  1. Import Arrangement per Data\Local & Replacement definizioni config in VerifierRepositoryImpl.kt e VerificationViewModel.kt
import it.ministerodellasalute.verificaC19sdk.data.local.*

[...]

            val config = RealmConfiguration.Builder()
            .name(REALM_NAME)
            .modules(VerificaC19sdkLibraryModule())
            .allowWritesOnUiThread(true)
            .build()

A quel punto, in base a quanto mi indicherai in merito ad A. esito verifica veloce rebuild + B. assenza di problemi in runtime x gestione tabelle/DB con tua app, posso anche valutare la relativa PR e/o altri workaround.

Considera comunque che :

  1. Prodrelease DGC-SDK 1.1.1 è già finalizzata per rilascio in correlazione a nuova prodrelease 1.2.1 VerificaC19

  2. Non è detto che un'eventuale PR di modifica locale passi a status approved & merged...

Per cui - a breve termine & volendo/dovendo mantenere inalterato codice dgc-sdk 1.1.1 - potresti solo reimpostare codice tua app in modo che usasse impostazioni custom per Realm (invece di quelle predefinite Realm in virtù di setDefaultConfiguration / getdefault).

rawmain commented 2 years ago

Ciao @albertocappellina

Ho provveduto intanto ad inoltrare la PR #96 - contenente le modifiche riportate prima per l'impostazione del RealmModule VerificaC19sdkLibraryModule, onde evitare a priori la generazione di DefaultRealmModule per DGC-SDK.

Non sono infatti emerse disruption nelle verifiche d'integrazione con whitelabel-app VerificaC19 (altrimenti non avrei inoltrato tale PR n.d.r.) = vedasi test-release RLM (basata su prodrelease 1.2.1 app/UI + fixed DGC-SDK 1.1.1).

L'ho classificata come FIX (non come enhancement), dato che - seppur non prioritario - mira comunque a risolvere potenziali criticità/exception in build di app/progetti terzi, che integrano/usano DGC-SDK in conformità a commi 12-13 DPCM 12/10/2021.

albertocappellina commented 2 years ago

Buongiorno e come sempre, grazie per la risposta super completa, @rawmain !

Ho fatto quanto richiesto:

1) rimosso il realm module per dgc-sdk creato ieri 2) invalidate cache and restart 3) ./gradlew clean 4) ./gradlew assembleProductionDebug

apk creato

5) invalidate cache and restart 6) ./gradlew clean 7) ./gradlew assembleProductionRelease

apk non creato con errore

ERROR:/Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/project_dex_archive/productionRelease/out/io/realm/DefaultRealmModule.dex: D8: Type io.realm.DefaultRealmModule is defined multiple times: /Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/project_dex_archive/productionRelease/out/io/realm/DefaultRealmModule.dex, /Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/sub_project_dex_archive/productionRelease/out/4774b79c78d793adb0c4cab5d0337d97b94874a351ac58b5520036e9a6ba9cfa_2.jar:classes.dex com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: Learn how to resolve the issue at https://developer.android.com/studio/build/dependencies#duplicate_classes. Type io.realm.DefaultRealmModule is defined multiple times: /Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/project_dex_archive/productionRelease/out/io/realm/DefaultRealmModule.dex, /Users/alberto.cappellina/sources/dssandroid/app/build/intermediates/sub_project_dex_archive/productionRelease/out/4774b79c78d793adb0c4cab5d0337d97b94874a351ac58b5520036e9a6ba9cfa_2.jar:classes.dex

Per quanto riguarda la parte

Per cui - a breve termine & volendo/dovendo mantenere inalterato codice dgc-sdk 1.1.1 - potresti solo reimpostare codice tua app in modo che usasse impostazioni custom per Realm (invece di quelle predefinite Realm in virtù di setDefaultConfiguration / getdefault).

purtroppo gia' la nostra configurazione e' custom

Realm.setDefaultConfiguration( RealmConfiguration.Builder() .allowWritesOnUiThread(true) .schemaVersion(19L) .migration(RealmMigrationProvider.getMigration()) .modules(RealmAppModule()) .build() )

ma D8 comunque genera quell'errore

Grazie Alberto

rawmain commented 2 years ago

Buongiorno @albertocappellina

Buongiorno e come sempre, grazie per la risposta super completa, @rawmain !

Prego ;).

Una volta che i test hanno escluso disruption con la whitelabel-app, mi è parso cmq opportuno sottoporre direttamente la PR, onde esporre in modo preciso l'issue & consentire - quando verrà presa in carico per official review - la valutazione di tale "keep it simple" remediation o eventuali alternative.

Ho fatto quanto richiesto: [...] apk non creato con errore

Ok, grazie per la conferma. A questo punto è plausibile che la differenza in build-trace debug/release sia semplicemente dovuta alle Proguard rules per annotations in release type = il conflitto c'è cmq anche per debug build, pur non comportando build exception.

Per quanto riguarda la parte

Per cui - a breve termine & volendo/dovendo mantenere inalterato codice dgc-sdk 1.1.1 - potresti solo reimpostare codice tua app in modo che usasse impostazioni custom per Realm (invece di quelle predefinite Realm in virtù di setDefaultConfiguration / getdefault).

purtroppo gia' la nostra configurazione e' custom

L'impostazione predefinita annotation processor di Realm è shouldCreateDefaultModule = true , che è appunto quella, che porta alla creazione di :

@io.realm.annotations.RealmModule(allClasses = true)
class DefaultRealmModule

Con le versioni legacy - in ambito di test - era possibile disabilitare la generazione predefinita della classe DefaultRealmModule anche per app project, agendo sulle opzioni per annotation processors.

Onestamente, non ho verificato però se sia ancora possibile con attuali implementazioni/dipendenze progetto per gradle / kapt / realm. Provo a guardare più tardi e - qualora sia ancora applicabile tale override - vedo anche se richieda ulteriori modifiche (e.g. anche switch da default.realm impostato tramite setDefaultConfiguration a custom realm).

astagi commented 2 years ago

@albertocappellina @rawmain ho mergiato la PR attinente, se tutto è ok chiudiamo questa issue?

rawmain commented 2 years ago

Ciao @astagi

@albertocappellina @rawmain ho mergiato la PR attinente, se tutto è ok chiudiamo questa issue?

Good. Per me tutto ok.

Appena fatto anche controllo per (scrupolo) con codice refactoring/update delle dependency - tanto per DGC-SDK (merged) quanto per whitelabel-app (WIP).

Nessun problema di gestione Realm.

Riscontrata infatti solo una questione diversa & dovuta al cambio WIP per dependency mockk, di cui ho cmq già lasciato nota in merito a @Kaizen-7 con indicazione del relativo revert fix (cioè riportare a name: 'mockk-android').

astagi commented 2 years ago

Ciao @astagi

@albertocappellina @rawmain ho mergiato la PR attinente, se tutto è ok chiudiamo questa issue?

Good. Per me tutto ok.

Appena fatto anche controllo per (scrupolo) con codice refactoring/update delle dependency - tanto per DGC-SDK (merged) quanto per whitelabel-app (WIP).

Nessun problema di gestione Realm.

Riscontrata infatti solo una questione diversa & dovuta al cambio WIP per dependency mockk, di cui ho cmq già lasciato nota in merito a @Kaizen-7 con indicazione del relativo revert fix (cioè riportare a name: 'mockk-android').

fantastico grazie @rawmain , attendiamo riscontro da @albertocappellina

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.