Description
Compiler version
3.1.0
Background
GraalVM Native Image Ahead-of-Time compiles JVM apps into native executables. To do the AOT compilation, reflection points must be specified.
Issue 1
Scala's scala.runtime.LazyVals
uses reflection so it must be declared. This could be done in the Scala stdlib so that others don't need to do it themselves. But this approach is a bit brittle. Any chance of removing the use of sun.misc.Unsafe
there? If not, then I can send a PR to include the GraalVM reflection config:
{
"name":"sun.misc.Unsafe",
"allDeclaredFields":true
}
Issue 2
Code generated by the compiler for lazy vals also uses reflection and must be declared, like:
{
"name":"App$package$",
"fields":[{"name":"0bitmap$1"}]
}
Also, ideally reflection is not required. But I haven't looked into what the reflection is doing. If someone uses a Scala library that uses lazy vals, and does NOT provide their reflection config for GraalVM, then the user must specify the config for the library on their own. Ideally the library authors nor the users need to specify this info.
Steps to Reproduce
- Clone
https://github.com/jamesward/scala3-graalvm-tester.git
- Switch to the
lazy-reflect-broke
branch - Run
./sbt nativeImage nativeImageRun
You will see a runtime error showing Issue 1:
Exception in thread "main" scala.runtime.LazyVals$$anon$1
at scala.runtime.LazyVals$.$init$$$anonfun$3(LazyVals.scala:18)
at scala.Option.getOrElse(Option.scala:201)
at scala.runtime.LazyVals$.<clinit>(LazyVals.scala:19)
at App$package$.<clinit>(App.scala:2)
at run.main(App.scala:4)
(Note: It should be possible to fail the build in this case instead of producing a runtime error but there seems to be a bug: oracle/graal#4010)
If you switch to the lazy-reflect-works
branch and re-run ./sbt nativeImage nativeImageRun
you will see that it works given the requisite config for the app in that repo that has one lazy val.
One Approach (If Reflection Must Stay)
The Spring team has developed a set of annotations which provide the reflection info, like:
https://docs.spring.io/spring-native/docs/0.9.1-SNAPSHOT/api/org/springframework/nativex/hint/TypeHint.html
There has been talk that this work will merge in some way into GraalVM itself. In that case, the Scala compiler could generate the necessary TypeHint
annotations for places it generates code that uses reflection.