Skip to content

Runtime uses jvm methods that are deprecated and may be soon removed #15387

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

Closed
szymon-rd opened this issue Jun 6, 2022 · 13 comments
Closed

Runtime uses jvm methods that are deprecated and may be soon removed #15387

szymon-rd opened this issue Jun 6, 2022 · 13 comments

Comments

@szymon-rd
Copy link
Contributor

szymon-rd commented Jun 6, 2022

Compiler version

At current main - 1ea177d, and also previous versions.

The problem

The problem is caused by usage of Unsafe.objectFieldOffset in runtime. When compiling the compiler on JVM 18, the following errors appear:

sbt:scala3> testCompilation
[error] -- Error: /Users/srodziewicz/Documents/Projects/VirtusLab/dotty/library/src/scala/runtime/LazyVals.scala:103:19 
[error] 103 |    val r = unsafe.objectFieldOffset(clz.getDeclaredField(name))
[error]     |            ^^^^^^^^^^^^^^^^^^^^^^^^
[error]     |method objectFieldOffset in class Unsafe is deprecated since : see corresponding Javadoc for more information.
[error] -- Error: /Users/srodziewicz/Documents/Projects/VirtusLab/dotty/library/src/scala/runtime/LazyVals.scala:110:19 
[error] 110 |    val r = unsafe.objectFieldOffset(field)
[error]     |            ^^^^^^^^^^^^^^^^^^^^^^^^
[error]     |method objectFieldOffset in class Unsafe is deprecated since : see corresponding Javadoc for more information.

It's not a problem per se, as we don't use this version of JDK on compiling. But, per the documentation:

The guarantee that a field will always have the same offset
and base may not be true in a future release. The ability to provide an
offset and object reference to a heap memory accessor will be removed
in a future release. Use {@link java.lang.invoke.VarHandle} instead.

And we heavily rely on this feature in the current and the new lazy vals implementation. It's not a problem now, but soon lazy vals can stop working on new jvms as we don't have any guarantee on their stability.

Proposal

Use MethodHandles to execute the Unsafe methods if the currently running jvm version == 1.8. In other case, use the VarHandles. It's a pretty complex approach and there may be another simpler solution.

@szymon-rd szymon-rd changed the title Runtime uses methods that are depreciated and may be soon removed Runtime uses jvm methods that are depreciated and may be soon removed Jun 6, 2022
@Kordyjan Kordyjan added the area:library Standard library label Jun 6, 2022
@smarter
Copy link
Member

smarter commented Jun 6, 2022

This is tracked by #9013, as noted in that issue it doesn't seem possible to decide whether we can use VarHandle at runtime without ruining the performance of VarHandle

@smarter
Copy link
Member

smarter commented Jun 6, 2022

What we could do is 1) under -release >= 9, use VarHandle properly 2) under -release 8, keep using unsafe but have a (potentially slower) runtime fallback if the method is not available

@smarter
Copy link
Member

smarter commented Jun 6, 2022

Also I'm not sure if we already changed the default of -release to match the currently used jvm, I think we wanted to do that for 3.2

@prolativ
Copy link
Contributor

prolativ commented Jun 6, 2022

It looks like currently the default value is java 8

@Kordyjan
Copy link
Contributor

Kordyjan commented Jun 6, 2022

@smarter You want to have both (or even all three possible) implementations of lazy vals in the stdlib. Then, depending on the -release flag set in the user project, choose the proper implementation during desugaring.

Am I getting it right?

@michelou
Copy link
Contributor

michelou commented Jun 6, 2022

Two thoughts here :

  • if 3.2 and newer require JVM 9+ as default (which I would welcome) the Dotty team must emphasize the change and must be ready to publish one or more 3.1 versions (after 3.1.3 final) to keep support for JVM 8 for a while (transition period to be announced).
  • the above change must discussed with the Scala team at Lightbend to keep both Scala 2 and Scala 3 in synch in respect to the default (JVM 8 resp. JVM 9+).

@smarter
Copy link
Member

smarter commented Jun 6, 2022

@Kordyjan yes
@michelou There's no plan to drop java 8 support

@michelou
Copy link
Contributor

michelou commented Jun 6, 2022

@smarter That's fine (and also my expectation). I was focused primarily on the "default" JVM.

@smarter
Copy link
Member

smarter commented Jun 6, 2022

The "default" is whatever is installed on your system, this is already the case now but it's not reflected in the class file version number we emit.

@som-snytt
Copy link
Contributor

If whining helps, it is annoying to go to try something out and it errors because my current jdk is 18.

Perhaps if I read up on the linked ticket and the "new lazy val" PR, I'll understand the end game. -release is awesome.

@smarter
Copy link
Member

smarter commented Jun 24, 2022

I think it's important for the compiler to compile on every jdk people might use, so a PR that would silence the deprecation would be welcome.

@som-snytt
Copy link
Contributor

Just for silence #15520

@SethTisue SethTisue changed the title Runtime uses jvm methods that are depreciated and may be soon removed Runtime uses jvm methods that are deprecated and may be soon removed Feb 23, 2023
@Gedochao
Copy link
Contributor

Let's track this under #9013.
Closing this as duplicate.

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

No branches or pull requests

7 participants