Contextраздавался прием WarningContextClassLoader вместо PathClassLoader вызывает пролетный врезаться
В моем андроид приложения, я использую пролетный путь обновить мою Db схему. До сих пор у меня есть одна и только одна миграция, которая создает 3 таблицы. Простой и обычный бизнес для пролета. Он работает очень хорошо ... большую часть времени! Иногда он выходит из строя с этой ошибкой (полный стек) по настоящему Договору:
java.lang.ClassCastException: android.app.LoadedApk$WarningContextClassLoader
cannot be cast to dalvik.system.PathClassLoader
У меня есть несколько вопросов, связанных с этой ошибкой:
- Что такое LoadedApk.WarningContextClassLoader?
- Почему это иногда используется вместо dalvik.system.PathClassLoader?
- Это ошибка в моем приложении, в Android-системе или в Flyway?
Я также заметил, что я могу вводить явно загрузчик классов внутри пролетного (Flyway.setClassLoader())
- Как я могу получить наверняка правый загрузчик классов?
Обратите внимание, что я вставляю контекст приложения в пролетный, а не в конкретный контекст активности.
Версии
Я использую org.flywaydb: пролетный путь-ядро: 4.0.2
Я заметил эту проблему в Android 4.2.2 (Jellybean, уровень апи 17) и 4.4 (KitKat, API уровень 19). AFAIK, это никогда не происходило на более высоких версиях.
Стек след
Exception java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mycompany.myapp.free.debug/com.mycompany.MainActivity}: java.lang.ClassCastException: android.app.LoadedApk$WarningContextClassLoader cannot be cast to dalvik.system.PathClassLoader
android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2306)
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2358)
android.app.ActivityThread.access$600 (ActivityThread.java:156)
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1340)
android.os.Handler.dispatchMessage (Handler.java:99)
android.os.Looper.loop (Looper.java:153)
android.app.ActivityThread.main (ActivityThread.java:5299)
java.lang.reflect.Method.invokeNative (Method.java)
java.lang.reflect.Method.invoke (Method.java:511)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:833)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:600)
dalvik.system.NativeStart.main (NativeStart.java)
Caused by java.lang.ClassCastException: android.app.LoadedApk$WarningContextClassLoader cannot be cast to dalvik.system.PathClassLoader
org.flywaydb.core.internal.util.scanner.classpath.android.AndroidScanner.<init> (AndroidScanner.java:46)
org.flywaydb.core.internal.util.scanner.Scanner.<init> (Scanner.java:38)
org.flywaydb.core.Flyway.execute (Flyway.java:1353)
org.flywaydb.core.Flyway.info (Flyway.java:1040)
com.mycompany.db.FlywayHelper.info (FlywayHelper.java:54)
com.mycompany.db.FlywayHelper.migrate (FlywayHelper.java:45)
com.mycompany.db.GW2DatabaseHelper.migrate (GW2DatabaseHelper.java:56)
com.mycompany.db.DbInit.initKeyGuild (DbInit.java:62)
com.mycompany.db.DbInit.init (DbInit.java:42)
com.mycompany.business.BootApp.boot (BootApp.java:79)
com.mycompany.MainActivity.onCreate (MainActivity.java:51)
android.app.Activity.performCreate (Activity.java:5122)
android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1081)
android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2270)
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2358)
android.app.ActivityThread.access$600 (ActivityThread.java:156)
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1340)
android.os.Handler.dispatchMessage (Handler.java:99)
android.os.Looper.loop (Looper.java:153)
android.app.ActivityThread.main (ActivityThread.java:5299)
java.lang.reflect.Method.invokeNative (Method.java)
java.lang.reflect.Method.invoke (Method.java:511)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:833)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:600)
dalvik.system.NativeStart.main (NativeStart.java)
Исследования обновление
Хотя его цель не ясна мне, LoadedApk.WarningContextClassLoader кажется, действительный загрузчик классов, а затем должен быть поддержан Flyway , A pull request.
В период, обходной путь должен быть реализован, чтобы ввести ожидаемый загрузчик классов:
private void injectClassLoader(Flyway flyway) {
ClassLoader classLoader = flyway.getClassLoader();
if (classLoader != null && !(classLoader instanceof PathClassLoader)){
flyway.setClassLoader(classLoader.getParent());
}
}
Нет, это не так. Я проверил (flyway is open-source), контекст не используется для захвата загрузчика классов. Фактически flyway просто инициализирует свой загрузчик классов следующим образом: 'private ClassLoader classLoader = Thread.currentThread(). GetContextClassLoader();' Но спасибо за обмен! – Benoit