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

Build fs2 with JDK 8 #2659

Closed
wants to merge 14 commits into from
Closed

Build fs2 with JDK 8 #2659

wants to merge 14 commits into from

Conversation

vasilmkd
Copy link
Member

@vasilmkd vasilmkd commented Oct 1, 2021

This PR shows how to use java.lang.MethodHandle to essentially do reflection, just without the bad APIs. If initialized (lazily), these MethodHandles will try to find the appropriate methods that are available only on JDK16+ (mainly for Unix sockets) and link to them. This linking only happens once, so any further calls will be directly linked and are subject to optimizations by the JIT (unlike reflection).

This allows the project to be built using JDK 8, and be sure that JDK 8 platform specification is respected when linking against some problematic APIs like byte buffers (which is not exactly the same as building with a newer JDK and targeting an old one). How highly this feature is desired, is another debate.

Usage of new APIs works and it is tested in the CI.

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 1, 2021

WatcherSuite

  1. supports watching a file - for modifications
  2. supports watching a directory - static recursive watching
    are two unit tests that seem to deadlock when run on JDK 8.

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 1, 2021

No, it is an issue with munit-cats-effect-3 1.0.6, specifically typelevel/munit-cats-effect#124 and I shouldn't have merged this PR #2656.

Edit, still not completely sure about this, this is frustrating.

@mpilquist
Copy link
Member

This is a lot of complexity. What do we get in return?

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 1, 2021

Nothing really, other than being able to build with JDK 8. I wanted to see how hard it would be. Feel free to close the PR.

@mpilquist
Copy link
Member

OK gotcha. Definitely interesting as a proof of concept and happy to keep PR open, just very much afraid of build complexity.

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 1, 2021

Or I will close it, I still want to experiment with a few things before that.

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 1, 2021

I updated the description, but overall, there is not much going on for this PR. The diff is large because of Java's verbosity and ceremony around try/catch and checked exceptions. Some code may be factored out, but we then get bitten by Java's package visibility problems, and the duplication starts to seem necessary. This will forever be the case, until Scala decides to support annotations for creating guaranteed static final fields. These are necessary for GraalVM native image to be able to resolve them at compile time.

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 1, 2021

WatcherSuite

  1. supports watching a file - for modifications
  2. supports watching a directory - static recursive watching
    are two unit tests that seem to deadlock when run on JDK 8.

@mpilquist Regardless of the outcome of this PR, I'd be interested to hear your thoughts on this, it seems that these 2 tests just hang on JDK 8, at least they do on my local machine. Is there anything particular about these 2 tests and can you maybe try to reproduce the issue? Thanks.

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 2, 2021

The Modified events seem to not trigger every time on MacOS with JDK 8, seems like a platform issue.

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 2, 2021

I'm still experimenting, it might be possible to define everything in Scala and cut down on the boilerplate.

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 2, 2021

Scala 3 does not have enough support for this feature however. Scala 2 works just fine.

scala/scala3#11332

@rossabaker
Copy link
Member

I broke Java 8 compatibility in a PR yesterday, only caught by @mpilquist's watchful eye. An http4s PR is now hung only on Java 8 starting with the fs2-3.1.4 upgrade. CI on Java 8 would be highly beneficial!

@mpilquist
Copy link
Member

Note that mistake would not have been caught by running a Java 8 build. We'd only see that by compiling with Java 9+ and then running tests against Java 8, which SBT does not support. If you try to compile with 9+, switch JDKs, and run tests, it will recompile with the new JDK before running the tests.

@rossabaker
Copy link
Member

Oh, right. Shit.

I'll report back when I figure out what broke on JDK8 with fs2-3.1.4. I strongly suspect it's related to my encoder change.

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 6, 2021

But releasing fs2 compiled using JDK8 would circumvent all of these problems, wouldn't it?

@mpilquist
Copy link
Member

Yes, that's correct. At the cost of the complexity in this PR though.

@vasilmkd
Copy link
Member Author

vasilmkd commented Oct 6, 2021

This isn't ideal, I agree, I don't want to merge it either. We will be able to write all of this in Scala, but dotty is missing some features for the support of these methods. I am trying to port the Scala 2 support to dotty, but it's not going great at the moment.

@mpilquist
Copy link
Member

Agreed. Even if we could write it in Scala, I'd still lean against using varhandles to this degree. If it was only 1 or 2 methods we had to call, then sure, but it's a lot more than that. :)

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

Successfully merging this pull request may close these issues.

3 participants