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

Write advice on using a javac that can (a) read type-use annotations from class files and (b) understand MODULE #537

Open
cpovirk opened this issue Jun 26, 2024 · 6 comments
Labels
documentation For issues related to user-facing documentation

Comments

@cpovirk
Copy link
Collaborator

cpovirk commented Jun 26, 2024

Very rough notes for later cleanup:

Things you want (each of which should come with a justification for why you want it):

  • You really want a javac with the fix for JDK-8225377. Currently, that means JDK 22 or higher. The fix may someday be backported, but we would have to convince OpenJDK that the benefits to users outweigh the compatibility impact.
  • Ideally, you also want fixes for JDK-8043226 and JDK-8291643. Both are reasonably likely (not guaranteed) to be part of JDK 23. I don't know if backports are likely.
  • You normally want a javac that recognizes @Target(MODULE, ...), which we use for @NullMarked. That means JDK 9 or higher, and probably everyone in practice wants JDK 11+, given that 9 and 10 don't seem to have been widely adopted.
    • Lack of this is not typically catastrophic. Is the only problem -Werror? It's been a while since I looked.
  • There might have been other fixes for type-use annotations (or other JSpecify-relevant features) between 11 and 22. If anyone knows any, please share.

How to get them:

  • Use the newest version of Java you can for your build tools.
    • This can be good advice independent of nullness, since newer versions pick up other fixes (and features?) and since you can absorb any incompatibilities gradually.
    • But running whole build systems like Gradle under new versions might not work well.
    • So use "toolchains" to use the newest JDK to compile while still potentially running under the build system under older versions. This is probably nicer for your users in additional ways, since the build tool can automatically download the appropriate JDK.
      • Presumably you need for your runtime toolchain (for running tests and maybe other things?) to still be the version that you're targeting. Hopefully there's a way to set this up?
  • To ensure compatibility with the version you're targeting, you have various options. From simplest to most complex:
    • Use --release.
    • If that doesn't work because you rely on Unsafe, maybe ideally perform multiple builds and use multi-release jars or something, or maybe hack around it? Maybe don't bother with this and instead just try the options below?
    • If that doesn't work because you rely on APIs hidden by JDK modules, then use --system. Build-system integration for this seems to not be great.
  • Gradle and Kotlin and probably other people tend recommend setting your toolchain to the version that you target. There is appealing simplicity in this advice (as you can see from my point about using a different runtime toolchain above), and it saves you from some problems that arise from lack of support for new JDKs in other build tools. But it fundamentally prevents you from picking up javac fixes.
@cpovirk cpovirk added the documentation For issues related to user-facing documentation label Jun 26, 2024
@cpovirk
Copy link
Collaborator Author

cpovirk commented Jun 26, 2024

(previously: #302 (comment), which created https://github.com/jspecify/jspecify/wiki/version-compatibility, which also mentions runtime effects)

@cpovirk cpovirk changed the title Write advice on using a javac that supports type-use annotations and MODULE Write advice on using a javac that can (a) read type-use annotations from class files and (b) understand MODULE Jul 3, 2024
@cpovirk
Copy link
Collaborator Author

cpovirk commented Jul 10, 2024

I need to check into where we stand with using a javac 11+ but with --release 8. This suggests that it's OK, but this and this suggest that it's not. I suspect that it's not....

And as noted above, Gradle steers users toward using old versions of javac, so no matter what, I'd expect some users to be on javac 8....

@cpovirk
Copy link
Collaborator Author

cpovirk commented Jul 11, 2024

Setting the MODULE discussion aside, I just came across: Jake Wharton: Gradle toolchains are rarely a good idea, covering much of the ground above and more.

@cpovirk
Copy link
Collaborator Author

cpovirk commented Jul 12, 2024

I have an update on the --release question from above in #302 (comment).

Note that the next versions of Error Prone [edit: 2.29.0, now released] and Truth [edit: 1.4.4, now released] will both help address this.

@ExE-Boss
Copy link

You’re also gonna want the fix for JDK‑8337795:

@cpovirk
Copy link
Collaborator Author

cpovirk commented Aug 19, 2024

Some discussion of uber/NullAway#1022 is suggesting that the fix for JDK-8332230 may also end up being important to nullness checkers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation For issues related to user-facing documentation
Projects
None yet
Development

No branches or pull requests

2 participants