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

okhttp:5.0.0-alpha.10 can run into java.lang.ClassNotFoundException: kotlin.time.DurationUnit #7361

Closed
staktrace opened this issue Jun 28, 2022 · 15 comments
Labels
bug Bug in existing code

Comments

@staktrace
Copy link
Contributor

See previous discussions in #7267, #7329, and #7343. This is a continuation of that thread of problems, trying to iron out issues when using okhttp in a gradle plugin where the runtime kotlin version is restricted to 1.5.

Now I have put together a minimal standalone reproduction of the problem. It can be found at https://github.com/staktrace/20220627-okhttp-durationunit/tree/57afefa7bbe4f1cf1ae0b1dd8b6d4e01c4b738ff. To reproduce, clone the repo and run the ./reproduce.sh script. The setup is that there are two separate gradle projects - one is a plugin that uses okhttp, and the other is a consumer that uses the plugin.

Some things I discovered along the way of creating this reproducer:

  • If the plugin lives in the buildSrc folder of the consumer project, the problem doesn't reproduce
  • The kotlin-dsl plugin being applied is important since it seems to be the thing that actually pins the gradle version to 1.5.31.
@staktrace
Copy link
Contributor Author

For the cases I care about, I was able to work around this issue by doing this - adding the kotlin 1.6 jvm plugin to the consumer repo made the DurationUnit class available and everything worked fine. In a bunch of cases the consumer already had the kotlin-dsl plugin which I had to replace with kotlin("jvm") instead, but this effectively solved all the problems I was seeing in downstream projects.

@yschimke
Copy link
Collaborator

yschimke commented Jul 3, 2022

@staktrace do you still have that repro repo?

@staktrace
Copy link
Contributor Author

The repro is linked in the top comment - https://github.com/staktrace/20220627-okhttp-durationunit (main branch)

@yschimke
Copy link
Collaborator

yschimke commented Jul 4, 2022

@staktrace is it private?

@staktrace
Copy link
Contributor Author

Ah sorry! Yes, it was private. Made it public now.

@yschimke
Copy link
Collaborator

yschimke commented Jul 23, 2022

I'm a bi confused, so want to kick off the discussion of whether this is still needed?

I think this gradle/gradle#19539

and this gradle/gradle#16345, discussed here https://twitter.com/martinbonnin/status/1550035276604522498

Mean that we can revert this. So suggest that we do, I'll put a PR up and compile against 1.6.21.

@yschimke
Copy link
Collaborator

Or is this the issue? gradle/gradle#19568

Gradle 7.5 will ship with Kotlin 1.6.21 but still target language/api 1/4 for backwards compatibility reasons. This can only be changed in a major version, next one being Gradle 8.0.

@yschimke
Copy link
Collaborator

yschimke commented Jul 23, 2022

Your test PR, with 7.6 works. So going to revert this!

Can you try gradle 7.6 snapshot, or 7.5 release with an older version that you previously had problems with?

I tried your reproducer with the following and it appears to work

implementation("com.squareup.okhttp3:okhttp:5.0.0-alpha.8")

@yschimke
Copy link
Collaborator

@martinbonnin
Copy link

If the plugin lives in the buildSrc folder of the consumer project, the problem doesn't reproduce

Got curious and made a small test there https://github.com/martinbonnin/classloaders. Looks like the dependencies of buildSrc are also put in the classpath albeit with a lower precedence than the embedded Kotlin jar. This way, you effectively end up with 2 versions of kotlin-stdlib on the classpath. So kotlin-stdlib symbols will resolve to the 1.5.31 version, except those that are not present that will fallback and load from the 1.6.10 jar. Gradle classloaders never cease to amaze 🙃 .

In all cases, Gradle 7.5 will fix the issue as it will put 1.6.something by default and this one has DurationUnit available.

@yschimke
Copy link
Collaborator

@martinbonnin sounds like you agree we can revert the existing attempts and ask people to upgrade to 7.5?

@martinbonnin
Copy link

Yep, users that want to use OkHttp in Gradle plugin should be able to do so with Gradle 7.5. Maybe you could add a runtime check when building a new client to point to this issue or give an actionable error message?

@yschimke
Copy link
Collaborator

I know OkHttp already understands Android vs JVM platforms, but doing so for a build system seems a step too far.

@martinbonnin
Copy link

Yup, that's fair 👍

@staktrace
Copy link
Contributor Author

I also confirmed that the original problem I was seeing goes away with gradle 7.5. So 👍 from me for reverting all the things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug in existing code
Projects
None yet
Development

No branches or pull requests

3 participants