Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Accessing shaded OkHttpClient properties from Kotlin fails with NoSuchMethodException #179

Open
vootelerotov opened this issue Feb 4, 2024 · 2 comments
Labels
kotlin wontfix This will not be worked on

Comments

@vootelerotov
Copy link
Contributor

Issue

Trying to access dispatcher property of the shaded OkHttpClient from Kotlin results in

java.lang.NoSuchMethodError: 'com.spotify.githubclient.shade.okhttp3.Dispatcher com.spotify.githubclient.shade.okhttp3.OkHttpClient.getDispatcher()

See reproducing test here.

Note that this also affects other fields in OkHttpClient.

Possible cause

In #157, the okhttp package was bumped from 3.x to 4.x.

In version 4.x of okhttp, the way Kotlin access to fields of OkHttpClient works was reworked for Kotlin, the direct access from Kotlin to the dispatcher method was deprecated:

  @JvmName("-deprecated_dispatcher")
  @Deprecated(
    message = "moved to val",
    replaceWith = ReplaceWith(expression = "dispatcher"),
    level = DeprecationLevel.ERROR,
  )
  fun dispatcher(): Dispatcher = dispatcher

Instead, the getter, that Kotlin generates for property access, was renamed to dispatcher:

  @get:JvmName("dispatcher")
  val dispatcher: Dispatcher = builder.dispatcher

See here for the class.

From Java point of view, nothing functionally changed -- previously dispatch() hit the manually added method, now dispatch() hit the getter generated by Kotlin with the same name.

However, from Kotlin, accessing dispatcher with dispatcher() is now a compile time error and instead one should use the property access syntax (okHttpClient.disptacher). This is exemplified in the reproducing test here.

In this project, the OkHttpClient is shaded into a different package. And I am speculating that the migration of packages does not cover all the metadata that Kotlin compiles into the class file. What seems to go missing is the information that dispatcher should be accessed by a method called dispatcher, instead of using the default name for property getter what would be getDispatcher -- this would explain the exception thrown.

In the reproducing test class, there is also one test that demonstrates that accessing metainfo about the property getter via kotlin-reflect does not succeed. This could also be explained by incomplete migration of packages.

Workaround

A Java class in (otherwise) Kotlin project, with static methods along the lines of:

    public static ExecutorService getExecutorService(Dispatcher dispatcher) {
        return dispatcher.executorService();
    }
@vootelerotov
Copy link
Contributor Author

As extra context, I do not really expect this to get fixed, unless there is an easy way to do it that I am missing.

But perhaps there is room for documenting this issue, and the possible workaround, somewhere. It was not trivial to figure out, might save some time for someone.

@Abhi347
Copy link
Member

Abhi347 commented May 28, 2024

Hey, apologies for delay int he response. We do not support Kotlin at this moment, so I don't think this will get priortised anytime soon.
You are free to create a PR though.

@Abhi347 Abhi347 added wontfix This will not be worked on kotlin labels May 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kotlin wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants