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
andDetected 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 parsingorg.jboss.netty.handler.ssl.SslHandler.unwrap
andorg.jboss.netty.handler.ssl.SslHandler.wrap
. This is a limitation in the Graal compiler, but haven't seen it before withnetty
. I guess thenetty
version shadowed injboss
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.