Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No field host in class Ljava/net/URL

When I'm trying to request an API with khttp I'm having this issue in an emulator on Android Studio with SDK 28 (Android Pie 9.0)

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
    Process: com.example.corentin.myapplication, PID: 3168
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$3.done(AsyncTask.java:354)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
        at java.util.concurrent.FutureTask.run(FutureTask.java:271)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.lang.NoSuchFieldException: No field host in class Ljava/net/URL; (declaration of 'java.net.URL' appears in /system/framework/core-oj.jar)
        at java.lang.Class.getDeclaredField(Native Method)
        at khttp.requests.GenericRequest.toIDN(GenericRequest.kt:193)
        at khttp.requests.GenericRequest.makeRoute(GenericRequest.kt:198)
        at khttp.requests.GenericRequest.<init>(GenericRequest.kt:128)
        at khttp.KHttp.request(KHttp.kt:58)
        at khttp.KHttp.get(KHttp.kt:28)
        at khttp.KHttp.get$default(KHttp.kt:27)
        at com.example.corentin.myapplication.InfoUser.run(InfoUser.kt:29)
        at com.example.corentin.myapplication.InfoUser$onCreate$1.invoke(InfoUser.kt:23)
        at com.example.corentin.myapplication.InfoUser$onCreate$1.invoke(InfoUser.kt:16)
        at com.example.corentin.myapplication.doAsync.doInBackground(InfoUser.kt:11)
        at com.example.corentin.myapplication.doAsync.doInBackground(InfoUser.kt:9)
        at android.os.AsyncTask$2.call(AsyncTask.java:333)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:764) 

And this is where the error comes from:

class doAsync(val handler: () -> Unit) : AsyncTask<Void, Void, Void>() {
    override fun doInBackground(vararg params: Void?): Void? {
        handler()
        return null
    }
}

class InfoUser : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_info_user)

        doAsync {
            run("https://api.imgur.com/3/account/xcoco55?client_id=CLIENT ID")
        }.execute()
    }


    fun run(url: String) {
        val response  = khttp.get(url)

        println("Coucou")
        if (response.statusCode == 200) {
            runOnUiThread {textView.text = response.text}
        }
    }
}

When I delete the line val response = khttp.get(url), or when I launch the application on my mobile phone (Android Oreo 8.1), everything works fine.

Do you think that the error comes from Android 9.0 or from the emulator?

like image 496
Corentin M Avatar asked Nov 01 '18 17:11

Corentin M


2 Answers

Disclaimer: I was referred to this post via the following request.

This is an issue that is faced when you are targeting Android 9.0 and occurs as @Torben Kohlmeier mentioned because the field is no longer accessible.

You can instead replace your khttp implementation in your modules build.gradle with the following, which should work as expected.

implementation "io.karn:khttp-android:0.1.0"

The khttp-android library is a fork of the original khttp library by jkcclemens.

like image 124
Karn Avatar answered Sep 17 '22 14:09

Karn


khttp is trying to use reflection to assign a value to the field host of java.net.URL.

This is the code: https://github.com/jkcclemens/khttp/blob/94ddc375f77f6b8b4bffd5415f136fe31fc663ae/src/main/kotlin/khttp/requests/GenericRequest.kt#L198

The URL implementation in core-oj.jar obviously does not have that field anymore.

This can only be fixed by changing the khttp code. But it looks like the library is no longer being maintained. The last commit was in September 2017.

I suggest switching to another library like fuel.

like image 43
Torben Kohlmeier Avatar answered Sep 19 '22 14:09

Torben Kohlmeier