user10981072
user10981072

Reputation:

Android dnsjava NoClassDefFoundError: Failed resolution of: Ljava/time/Duration;

I'm getting a NoClassDefFoundError with my app. I'm using dnsjava, okhttp3 and retrofit. My min API is 19.

I read that the java.time package was added in API 26. Does this mean that I can't use dnsjava for Android API lower than 26? Or does something else cause this error (proguard for example)? Can using an older dnsjava version help? I couldn't find any information about the minimum API of dnsjava.

Edit: I found this on the dnsjava Github page.

Migrating from version 2.1.x to v3

Methods using java.util.Date are deprecated. Use the new versions with java.time.Instant or java.time.Duration instead

So does this mean I can use version 2.1.x?

 FATAL EXCEPTION: OkHttp Dispatcher
Process: de.url.myproject, PID: 10723
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/Duration;
    at org.xbill.DNS.ExtendedResolver.<clinit>(ExtendedResolver.java)
    at org.xbill.DNS.Lookup.refreshDefault(Lookup.java:1)
    at org.xbill.DNS.Lookup.<clinit>(Lookup.java:1)
    at org.xbill.DNS.Lookup.getDefaultResolver(Lookup.java)
    at de.url.myproject.MyDNS.init(MyDNS.java)
    at de.url.myproject.MyDNS.lookup(MyDNS.java)
    at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:19)
    at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:19)
    at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:19)
    at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:19)
    at okhttp3.internal.connection.StreamAllocation.e(StreamAllocation.java)
    at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:10)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:10)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:2)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:103)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:103)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:2)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:27)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:27)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:2)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:7)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:2)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:12)
    at okhttp3.RealCall$AsyncCall.a(RealCall.java)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:776)
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.time.Duration" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/androidx.test.tools.crawler-1/base.apk", zip file "/data/app/de.url.myproject-1/base.apk", zip file "/data/app/de.url.myproject-1/split_config.xxhdpi.apk"],nativeLibraryDirectories=[/data/app/androidx.test.tools.crawler-1/lib/arm64, /data/app/de.url.myproject-1/lib/arm64, /system/lib64, /vendor/lib64, /system/vendor/lib64, /product/lib64]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    ... 22 more
    Suppressed: java.io.IOException: No original dex files found for dex location /data/app/de.url.myproject-1/split_config.xxhdpi.apk
    at dalvik.system.DexFile.openDexFileNative(DexFile.java)
    at dalvik.system.DexFile.openDexFile(DexFile.java:373)
    at dalvik.system.DexFile.<init>(DexFile.java:113)
    at dalvik.system.DexFile.<init>(DexFile.java:78)
    at dalvik.system.DexPathList.loadDexFile(DexPathList.java:359)
    at dalvik.system.DexPathList.makeElements(DexPathList.java:323)
    at dalvik.system.DexPathList.makeDexElements(DexPathList.java:263)
    at dalvik.system.DexPathList.<init>(DexPathList.java:126)
    at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:48)
    at dalvik.system.PathClassLoader.<init>(PathClassLoader.java:64)
    at com.android.internal.os.PathClassLoaderFactory.createClassLoader(PathClassLoaderFactory.java:43)
    at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:58)
    at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:540)
    at android.app.LoadedApk.getClassLoader(LoadedApk.java:573)
    at android.app.ActivityThread.getTopLevelResources(ActivityThread.java:1990)
    at android.app.LoadedApk.getResources(LoadedApk.java:799)
    at android.app.ContextImpl.<init>(ContextImpl.java:2217)
    at android.app.ContextImpl.createAppContext(ContextImpl.java:2162)
    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5547)
    at android.app.ActivityThread.-wrap2(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1637)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:156)
    at android.app.ActivityThread.main(ActivityThread.java:6524)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:831)

My code:

package de.url.myproject;

import android.util.Log;

import androidx.annotation.NonNull;

import org.xbill.DNS.Address;
import org.xbill.DNS.ExtendedResolver;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Resolver;
import org.xbill.DNS.SimpleResolver;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;

import okhttp3.Dns;

public class MyDNS implements Dns {

    private static final String LIVE_API_HOST = "api.myproject.de";
    private static final String LIVE_API_IP = "12.345.67.890";

    private boolean mInitialized;
    private InetAddress mLiveApiStaticIpAddress;

    @NonNull
    @Override
    public List<InetAddress> lookup(@NonNull String hostname) throws UnknownHostException {
        // I'm initializing the DNS resolvers here to take advantage of this method being called in a background-thread managed by OkHttp
        init();
        try {
            return Collections.singletonList(Address.getByName(hostname));
        } catch (UnknownHostException e) {
            // fallback to the API's static IP
            if (LIVE_API_HOST.equals(hostname) && mLiveApiStaticIpAddress != null) {
                return Collections.singletonList(mLiveApiStaticIpAddress);
            } else {
                throw e;
            }
        }
    }

    private void init() {
        if (mInitialized) return; else mInitialized = true;

        try {
            mLiveApiStaticIpAddress = InetAddress.getByName(LIVE_API_IP);
        } catch (UnknownHostException e) {
            Log.w("DNS", "Couldn't initialize static IP address");
        }

        try {
            // configure the resolvers, starting with the default ones (based on the current network connection)
            Resolver defaultResolver = Lookup.getDefaultResolver();
            // use Google's public DNS services
            Resolver googleFirstResolver = new SimpleResolver("8.8.8.8");
            Resolver googleSecondResolver = new SimpleResolver("8.8.4.4");
            // also try using Amazon
            Resolver amazonResolver = new SimpleResolver("205.251.198.30");
            Lookup.setDefaultResolver(new ExtendedResolver(new Resolver[]{
                    defaultResolver, googleFirstResolver, googleSecondResolver, amazonResolver}));
        } catch (UnknownHostException e) {
            Log.w("DNS", "Couldn't initialize custom resolvers");
        }
    }

}

Upvotes: 2

Views: 2203

Answers (2)

bigbigwhite
bigbigwhite

Reputation: 1

I met the same problem and solved it by adding try ... catch. If you want to keep the function going, you can switch to another downloading method when Android is under 1.8.

try {

            if (client == null) {
                notifyFail("System does not support")

            } else {

                val result = client?.startStreamTranscription(getRequest(22000), AudioStreamPublisher(FileInputStream(File(fileName))), getResponseHandler())
                if (NetworkUtils.isAvailable(BaseApp.context)) {
                    result?.get()
                    client?.close()
                }

            }


        } catch (e: Exception) {
            logee { "startTrans ${e.message}" }
        }

Another way is that you can copy the whole time package into local:

enter image description here

Upvotes: 0

Gintoki Sakata
Gintoki Sakata

Reputation: 1

I had the same trouble yet,not i use the "minidns" to replaced,It's friendly to android.

implementation 'de.measite.minidns:minidns:0.1.7'

Upvotes: 0

Related Questions