Исключение во время выполнения, которое говорит: java.lang.NoSuchMethodError: Нет виртуального метода getOutputContext()Lcom/fastxml/jackson/core/json/JsonWriteContext;
Я столкнулся с Исключением, которое на самом деле не кажется информативным о том, что на самом деле произошло.
Я предполагаю, что это может быть что-то из-за некоторых зависимостей.
Чтобы быть конкретным, исключение заключается в следующем:
E /AndroidRuntime: ИСКЛЮЧИТЕЛЬНОЕ ИСКЛЮЧЕНИЕ: pool-8-thread-1 Процесс:app, PID: 28729 java.lang.NoSuchMethodError: Нет виртуального метода getOutputContext()Lcom/ rapidxml/jackson/core/json/JsonWriteContext; в классе Lcom/fastxml/jackson/dataformat/smile/SmileGenerator; или его суперклассы (объявление com.fasterxml.jackson.dataformat.smile.SmileGenerator'появляется в /data/app/myapp.dev-1/split_lib_dependencies_apk.apk) в com.fasterxml.jackson.dataformat.smile.SmileGenerator. закрыть (SmileGenerator.java:1537) в com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3898) в com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java.3147).BasicCache$2.run(BasicCache.java:190) в java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) в java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoava:7)..lang.Thread.run(Thread.java:762)
И мой BasicCache выглядит так:
public class BasicCache<T> {
private static final int SCHEDULED_SAVING_DELAY_SECONDS = 30;
public enum CacheEncoding {
NONE,
BASE64,
ENCRYPTED,
}
private CacheManager mCacheManager;
private final File mFile;
private final CacheEncoding mCacheEncoding;
private final boolean mSmileSerialization;
private final String mUser;
private T mData;
private Semaphore mSemaphore = new Semaphore(1, true);
private boolean mSaveScheduled;
private ScheduledExecutorService mScheduledExecutor;
private final Object mSchedulingMonitor = new Object();
public BasicCache(CacheManager cacheManager, String storageFilename, CacheEncoding cacheEncoding) {
mCacheManager = cacheManager;
mCacheEncoding = cacheEncoding;
mSmileSerialization = false;
mFile = new File(mCacheManager.getRootFolder(), storageFilename);
mUser = null;
}
public BasicCache(CacheManager cacheManager, String user, String storageFilename, CacheEncoding cacheEncoding) {
this(cacheManager, user, storageFilename, cacheEncoding, false);
}
public BasicCache(CacheManager cacheManager, String user, String storageFilename, CacheEncoding cacheEncoding, boolean smileSerialziation) {
mCacheManager = cacheManager;
mCacheEncoding = cacheEncoding;
mSmileSerialization = smileSerialziation;
mUser = user;
File userFolder = new File(mCacheManager.getRootFolder(), mCacheManager.getUsersFolderName(user));
userFolder.mkdirs();
mFile = new File(userFolder, storageFilename);
}
protected T initData() {
try {
//noinspection unchecked
return (T) (getDataJavaType().getRawClass().newInstance());
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
private JavaType getDataJavaType() {
Type parentType = getClass().getGenericSuperclass();
Type t = ((ParameterizedType) parentType).getActualTypeArguments()[0];
return mCacheManager.getController().getJsonMapper().constructType(t);
}
public T getAndLock() {
lock();
return getInternal();
}
public T getUnlocked() {
if (mData != null)
return mData;
try {
lock();
return getInternal();
} finally {
unlock();
}
}
private T getInternal() {
if (mData != null)
return mData;
mData = loadFromDisk();
if (mData == null) {
mData = initData();
return mData;
} else
return mData;
}
public void setAndUnlock(T data) {
mData = data;
unlock();
}
private void lock() {
try {
mSemaphore.acquire();
} catch (InterruptedException e) {
unlock();
}
}
public void unlock() {
mSemaphore.release();
}
public void scheduleSave() {
synchronized (mSchedulingMonitor) {
if (!mSaveScheduled) {
if (mScheduledExecutor == null)
mScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
mScheduledExecutor.schedule(new Runnable() {
@Override
public void run() {
synchronized (mSchedulingMonitor) {
mSaveScheduled = false;
save();
}
}
},
SCHEDULED_SAVING_DELAY_SECONDS, TimeUnit.SECONDS);
mSaveScheduled = true;
}
}
}
public void save() {
lock();
getCacheManager().getController().getCacheSavingExecutor().execute(new Runnable() {
@SuppressLint("TrulyRandom")
@Override
public void run() {
if (mData != null) {
try {
if (mCacheEncoding == CacheEncoding.ENCRYPTED) {
String secure = Settings.Secure.getString(
mCacheManager.getController().getContext().getContentResolver(),
Settings.Secure.ANDROID_ID);
getObjectMapper().writeValue(EncryptionUtils.encrypt(new FileOutputStream(mFile), secure), mData);
} else if (mCacheEncoding == CacheEncoding.BASE64)
getObjectMapper().writeValue(new Base64OutputStream(new FileOutputStream(mFile), Base64.DEFAULT), mData);
else
getObjectMapper().writeValue(mFile, mData);
} catch (IOException e) {
e.printStackTrace();
}
}
unlock();
}
});
}
private T loadFromDisk() {
try {
if (mCacheEncoding == CacheEncoding.ENCRYPTED) {
String secure = Settings.Secure.getString(
mCacheManager.getController().getContext().getContentResolver(),
Settings.Secure.ANDROID_ID);
mData = getObjectMapper().readValue(EncryptionUtils.decrypt(new FileInputStream(mFile), secure), getDataJavaType());
} else if (mCacheEncoding == CacheEncoding.BASE64)
mData = getObjectMapper().readValue(new Base64InputStream(new FileInputStream(mFile), Base64.DEFAULT), getDataJavaType());
else
mData = getObjectMapper().readValue(mFile, getDataJavaType());
return mData;
} catch (IOException e) {
return null;
}
}
private ObjectMapper getObjectMapper() {
if (mSmileSerialization)
return mCacheManager.getController().getSmileMapper();
else
return mCacheManager.getController().getJsonMapper();
}
public boolean isValidUser(String user) {
return TextUtils.equals(user, mUser);
}
protected CacheManager getCacheManager() {
return mCacheManager;
}
protected String getUser() {
return mUser;
}
}
Таким образом, ошибка указывает на эту строку в моем методе сохранения в BasicCache:
getObjectMapper().writeValue(mFile, mData);
Здесь также мои зависимости в gradle:
ext.daggerVersion = '2.11'
ext.roomVersion = '1.0.0-alpha9'
ext.lifecycleVersion = '1.0.0-alpha9'
ext.supportLibraryVersion = '27.0.1'
ext.jacksonVersion = '2.5.1'
ext.icePickVersion = '3.2.0'
ext.fragmentArgsVersion = '3.0.2'
ext.dartVersion = '2.0.2'
ext.hensonVersion = '2.0.2'
ext.parcelerVersion = '1.1.9'
ext.retrofitVersion = '2.2.0'
ext.okHttpVersion = '3.6.0'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
// Tests
testCompile 'junit:junit:4.12'
// Multidex
compile 'com.android.support:multidex:1.0.2'
// Kotlin
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
// Support libraries
implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
implementation "com.android.support:design:$supportLibraryVersion"
implementation "com.android.support:gridlayout-v7:$supportLibraryVersion"
implementation "com.android.support:recyclerview-v7:$supportLibraryVersion"
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.google.android.gms:play-services-location:10.2.6'
compile 'com.squareup:otto:1.3.6'
// Jackson
compile "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
compile "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
compile "com.fasterxml.jackson.core:jackson-annotations:$jacksonVersion"
compile "com.fasterxml.jackson.dataformat:jackson-dataformat-smile:$jacksonVersion"
// Butterknife
compile "com.jakewharton:butterknife:$butterKnifeVersion"
annotationProcessor "com.jakewharton:butterknife-compiler:$butterKnifeVersion"
// Room
compile "android.arch.persistence.room:runtime:$roomVersion"
compile "android.arch.persistence.room:rxjava2:$roomVersion"
annotationProcessor "android.arch.persistence.room:compiler:$roomVersion"
// Lifecycle
compile "android.arch.lifecycle:runtime:$lifecycleVersion"
compile "android.arch.lifecycle:extensions:$lifecycleVersion"
annotationProcessor "android.arch.lifecycle:compiler:$lifecycleVersion"
// Dagger
compile "com.google.dagger:dagger:$daggerVersion"
compile "com.google.dagger:dagger-android:$daggerVersion"
compile "com.google.dagger:dagger-android-support:$daggerVersion"
annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
annotationProcessor "com.google.dagger:dagger-android-processor:$daggerVersion"
compile 'com.github.PhilJay:MPAndroidChart:v3.0.2'
compile ('org.simpleframework:simple-xml:2.7.1') {
exclude module: 'stax'
exclude module: 'stax-api'
exclude module: 'xpp3'
}
// Parceler
compile "org.parceler:parceler-api:$parcelerVersion"
annotationProcessor "org.parceler:parceler:$parcelerVersion"
// Fragment args
compile "com.hannesdorfmann.fragmentargs:annotation:$fragmentArgsVersion"
compile "com.hannesdorfmann.fragmentargs:bundler-parceler:$fragmentArgsVersion"
annotationProcessor "com.hannesdorfmann.fragmentargs:processor:$fragmentArgsVersion"
// Okhttp
implementation "com.squareup.okhttp3:logging-interceptor:$okHttpVersion"
implementation "com.squareup.okhttp3:okhttp:$okHttpVersion"
// IcePick
compile "frankiesardo:icepick:$icePickVersion"
annotationProcessor "frankiesardo:icepick-processor:$icePickVersion"
// RxJava
implementation 'io.reactivex.rxjava2:rxjava:2.1.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
// Retrofit
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
implementation "com.squareup.retrofit2:converter-jackson:$retrofitVersion"
// Dart
compile "com.f2prateek.dart:dart:$dartVersion"
annotationProcessor "com.f2prateek.dart:dart-processor:$dartVersion"
// Henson
compile "com.f2prateek.dart:henson:$hensonVersion"
annotationProcessor "com.f2prateek.dart:henson-processor:$hensonVersion"
compile 'org.altbeacon:android-beacon-library:2.9'
compile 'me.dm7.barcodescanner:zxing:1.9'
compile('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
transitive = true
}
compile('com.github.afollestad.material-dialogs:core:0.8.5.8@aar') {
transitive = true
}
provided "com.google.auto.value:auto-value:1.4.1"
annotationProcessor "com.google.auto.value:auto-value:1.4.1"
provided fileTree(include: ['com.symbol.emdk.jar'], dir: '..\\emdk\\libs')
compile fileTree(exclude: ['com.symbol.emdk.jar'], dir: 'libs')
dependencies {
compile project(":nexo")
}
compile 'com.android.support:support-vector-drawable:27.0.1'
}
ОБНОВЛЕНИЕ: Похоже, что когда я изменил свой JacksonVersion на 2.9.3, проблема не возникает. Но я не уверен в этом.
1 ответ
Чтобы jackson-module-kotlin работал на Android <API 24, вы должны оставаться на версии 2.9.6.
https://github.com/FasterXML/jackson-module-kotlin/issues/176
Поскольку Moshi также может создавать адаптеры для вас и не требует использования библиотеки Reflect, в большинстве случаев это лучший выбор для Android-разработчиков.