oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀

Home Page:https://www.graalvm.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error bulding Scala project with native-image

torkelrogstad opened this issue · comments

I'm building a Scala project with native-image through SBT Native Packager. After doing sbt graalvm-native-image:packageBin I get this error message:

[error] Error: Class that is marked for delaying initialization to run time got initialized during image building: scala.Function3. Try marking this class for build-time initialization with --initialize-at-build-time=scala.Function3
[error] com.oracle.svm.core.util.UserError$UserException: Class that is marked for delaying initialization to run time got initialized during image building: scala.Function3. Try marking this class for build-time initialization with --initialize-at-build-time=scala.Function3
[error]         at com.oracle.svm.core.util.UserError.abort(UserError.java:65)
[error]         at com.oracle.svm.hosted.classinitialization.ConfigurableClassInitialization.checkDelayedInitialization(ConfigurableClassInitialization.java:291)
[error]         at com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.duringAnalysis(ClassInitializationFeature.java:182)
[error]         at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$8(NativeImageGenerator.java:707)
[error]         at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:64)
[error]         at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:707)
[error]         at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:523)
[error]         at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:441)
[error]         at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
[error]         at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
[error]         at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
[error]         at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
[error]         at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
[error] Error: Image build request failed with exit status 1
[error] java.lang.RuntimeException: Failed to run native-image, exit status: 1
[error]         at scala.sys.package$.error(package.scala:26)
[error]         at com.typesafe.sbt.packager.graalvmnativeimage.GraalVMNativeImagePlugin$.$anonfun$projectSettings$3(GraalVMNativeImagePlugin.scala:52)
[error]         at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error]         at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:40)
[error]         at sbt.std.Transform$$anon$4.work(System.scala:67)
[error]         at sbt.Execute.$anonfun$submit$2(Execute.scala:269)
[error]         at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error]         at sbt.Execute.work(Execute.scala:278)
[error]         at sbt.Execute.$anonfun$submit$1(Execute.scala:269)
[error]         at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178)
[error]         at sbt.CompletionService$$anon$2.call(CompletionService.scala:37)
[error]         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error]         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error]         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[error]         at java.lang.Thread.run(Thread.java:748)
[error] (cli / Graalvm-native-image / packageBin) Failed to run native-image, exit status: 1
[error] Total time: 13 s, completed Jul 17, 2019 11:43:38 AM

If I follow the suggestion from the error message, I get this:

[error] Warning: Reflection method java.lang.Class.getMethods invoked at scala.Enumeration.populateNameMap(Enumeration.scala:193)
[error] Warning: Reflection method java.lang.Class.getDeclaredFields invoked at scala.Enumeration.populateNameMap(Enumeration.scala:189)
[error] Warning: Aborting stand-alone image build due to reflection use without configuration.
[error] com.oracle.svm.hosted.FallbackFeature$FallbackImageRequest: Reflection method java.lang.Class.getMethods invoked at scala.Enumeration.populateNameMap(Enumeration.scala:193)
[error] Reflection method java.lang.Class.getDeclaredFields invoked at scala.Enumeration.populateNameMap(Enumeration.scala:189)
[error] Aborting stand-alone image build due to reflection use without configuration.
[error]         at com.oracle.svm.hosted.FallbackFeature.afterAnalysis(FallbackFeature.java:303)
[error]         at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$9(NativeImageGenerator.java:721)
[error]         at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:64)
[error]         at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:721)
[error]         at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:523)
[error]         at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:441)
[error]         at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
[error]         at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
[error]         at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
[error]         at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
[error]         at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Is it possible to see where in my project either scala.Function3 or scala.Enumeration.populateNameMap is used?

You can use the native-image-agent to automatically detect reflectively accessed elements.

I tried adding the native-image-agent as the document you linked described, but reflect-config.json is completely empty after running the program multiple times with different inputs.

I got reflect-config.json by native-image-agent successfully, then I tried generating the image that is Playframework project coded with scala by sbt demo/graalvm-native-image:packageBin with below graalVMNativeImageOptions.

graalVMNativeImageOptions ++= Seq(
      "--report-unsupported-elements-at-runtime",
      "-H:+ReportExceptionStackTraces",
      "--verbose",
      "--allow-incomplete-classpath",
      "--initialize-at-build-time",
      "--no-fallback",
      "-H:ConfigurationFileDirectories=/work/code/github/graalvm-demo/demo/conf/",
    )

but native-image can not parsing some class under reflect-config.json, such as

{
  "name":"com.google.inject.util.Providers$GuicifiedProviderWithDependencies$$FastClassByGuice$$2a7177aa",
  "methods":[{"name":"<init>","parameterTypes":["java.lang.Class"] }]
}

Error log:

[error] com.oracle.svm.core.util.UserError$UserException: Error parsing reflection configuration in /work/code/github/graalvm-demo/demo/conf/reflect-config.json:
[error] Class com.google.inject.util.Providers$GuicifiedProviderWithDependencies$$FastClassByGuice$$2a7177aa not found
[error] Verify that the configuration matches the schema described in the -H:PrintFlags=+ output for option ReflectionConfigurationFiles.
[error] 	at com.oracle.svm.core.util.UserError.abort(UserError.java:65)
[error] 	at com.oracle.svm.hosted.config.ConfigurationParserUtils.doParseAndRegister(ConfigurationParserUtils.java:108)
[error] 	at com.oracle.svm.hosted.config.ConfigurationParserUtils.lambda$parseAndRegisterConfigurations$0(ConfigurationParserUtils.java:75)

Then I added -H:PrintFlags=+ under graalVMNativeImageOptions and run sbt demo/graalvm-native-image:packageBin again, but I got other error below.
Error log:

[error] Error: Unrecognized option: play.core.server.ProdServerStart
[error] com.oracle.svm.driver.NativeImage$NativeImageError: Unrecognized option: play.core.server.ProdServerStart
[error] 	at com.oracle.svm.driver.NativeImage.showError(NativeImage.java:1405)
[error] 	at com.oracle.svm.driver.NativeImage.completeImageBuild(NativeImage.java:1036)
[error] 	at com.oracle.svm.driver.NativeImage.build(NativeImage.java:1175)
[error] 	at com.oracle.svm.driver.NativeImage.performBuild(NativeImage.java:1145)
[error] 	at com.oracle.svm.driver.NativeImage.main(NativeImage.java:1104)
[error] java.lang.RuntimeException: Failed to run native-image, exit status: 1
[error] 	at scala.sys.package$.error(package.scala:26)
[error] 	at com.typesafe.sbt.packager.graalvmnativeimage.GraalVMNativeImagePlugin$.$anonfun$projectSettings$3(GraalVMNativeImagePlugin.scala:52)

Both graalvm and native-image version are 19.1.1, OS is macOS Mojave 10.14.5.
My sample project that recreates the issue is available here

Any suggestions?

@deanzz In 19.3.0-dev you can enable --allow-incomplete-classpath to avoid the Class XYZ not found errors during reflection configuration parsing. This way the errors are caught and reported as warnings: WARNING: Could not resolve XXX for reflection configuration. The problem there is that the application accesses generated classes via reflection, the native-image-agent observes this, but of course the lifetime of those classes is limited to the profiling run and are not available afterwards.

After this the compilation progresses however there are other erorrs:

  • Missing unsafe offset computation:
    [error] Caused by: com.oracle.svm.hosted.analysis.flow.SVMMethodTypeFlowBuilder$UnsafeOffsetError: Field AnalysisField<LightArrayRevolverScheduler$.akka$actor$LightArrayRevolverScheduler$$taskOffset accessed: false reads: true written: false> is used as an offset in an unsafe operation, but no value recomputation found. This error can be ignored for now using -H:-ThrowUnsafeOffsetErrors, but it should really be fixed by an offset substitution.

  • Then Error: Class initialization of akka.protobuf.DescriptorProtos failed. Use the option --initialize-at-run-time=akka.protobuf.DescriptorProtos to explicitly request delayed initialization of this class.
    As the error message suggests just use --initialize-at-run-time=akka.protobuf.DescriptorProtos.

  • A number initialization errors like Detected a ZipFile object in the image heap and Detected a FileDescriptor in the image heap. You can use the -H:+TraceClassInitialization option to find the classes that need to be initialized at run time. See also this blog article.

  • Even if you fix all those then you will bump into the org.graalvm.compiler.java.JsrNotSupportedBailout: unstructured control flow errors while parsing org.jboss.netty.handler.ssl.SslHandler.unwrap and org.jboss.netty.handler.ssl.SslHandler.wrap. This is a limitation in the Graal compiler, but haven't seen it before with netty. I guess the netty version shadowed in jboss is older.

@torkelrogstad note that -agentlib must be specified before a -jar option or a class name or any application parameters in the java command line. Missplacing it may be the reason why your reflect-config.json is empty.