question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

GraalVM Native Image Requires Config for lazy vals

See original GitHub issue

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

  1. Clone https://github.com/jamesward/scala3-graalvm-tester.git
  2. Switch to the lazy-reflect-broke branch
  3. 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: https://github.com/oracle/graal/issues/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.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:16
  • Comments:25 (8 by maintainers)

github_iconTop GitHub Comments

4reactions
jameswardcommented, Aug 14, 2022

I bumped the https://github.com/jamesward/scala3-graalvm-tester.git branch lazy-reflect-broke to 3.2.0-RC3 and still have the issue.

2reactions
carlosedpcommented, Dec 10, 2022

An FYI, scala-cli does one of the options mentioned by @szymon-rd. It manipulates the bytecode and patches the jars to “fix” lazyvals on current libraries.

https://github.com/VirtusLab/scala-cli/tree/main/modules/scala3-graal/src/main/scala/scala/cli/graal

Read more comments on GitHub >

github_iconTop Results From Across the Web

GraalVM Native Image Support - Spring
The application classpath is fixed at build time and cannot change. There is no lazy class loading, everything shipped in the executables will ......
Read more >
The --no-fallback option seems to be quietly enabling --allow ...
Describe the issue When I run native-image without --no-fallback ... GraalVM Native Image Requires Config for lazy vals lampepfl/dotty#13985.
Read more >
Native Image Compatibility and Optimization Guide - GraalVM
If the native image building cis unable to optimize an application, it generates a so-called “fallback file” that requires a Java VM to...
Read more >
GraalVM native-image with Scala 3 reflection hell - Reddit
The reason seems to be Scala 3's new encoding for lazy vals , where a reflective access to a variable called bitmap takes...
Read more >
GraalVM Native Image · Cats Effect - Typelevel
Cats Effect jars contain extra metadata that makes building native images seamless, without the need of extra configuration. The only caveat is that...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found